Evaluating variable if statement in C++ - c++

I am trying to evaluate a statistics problem via a Monte Carlo method. In this problem I am generating a random number and comparing it to a fixed probability number stored in a vector array titled comms_reliability. Assuming there is only one variable in the vector array, I am comparing the random number and the probability and tallying the results if the random number is greater than the reliability number. However, the vector array could also have two values, in which case I am producing two random numbers and comparing them to the two reliability numbers and. If both random numbers are bigger than the reliability numbers, I am tallying the scenarios. Theoretically this could continue on and on for as many values in the vector array as I want. However, through a failure of imagination I only know how to code this where the for statement is contained in multiple if statements
for each possible scenario. In this implementation I have to copy the same lines of code multiple times, and it also limits the commms_reliability array sizes that can be evaluated based on how many times I have copied these lines of code to handle the next array point. How can I do this where I only need one if statement. An example of how I have it coded currently is shown below.
int main(int argc, const char * argv[]) {
int sample_size = 1000000;
std::vector<float> comms_reliability = {0.6,0.6};
float tally = 0.0;
// rang() = random number generator
// if statement for comms_reliability array of size 1
if (comms_reliability.size() == 1) {
for (int i = 0; i < sample_size; i++){
if (rang() > comms_reliability[0]) tally = tally + 1.0;
}
}
// if statement 2 for comms_reliability array of size 2
if (comms_reliability.size() == 2) {
for (int i = 0; i < sample_size; i++){
if (rang() > comms_reliability[0] && rang() > comms_reliability[1]) tally = tally + 1.0;
}
}
// if statement 3 for comms_reliability array of size 3
if (comms_reliability.size() == 3) {
for (int i = 0; i < sample_size; i++){
if (rang() > comms_reliability[0] && rang() > comms_reliability[1] &&
rang() > comms_reliability[2]) tally = tally + 1.0;
}
}

If I understand you correctly you want to make sure that all elements of comms_reliability satisfy some criterion (namely being less than rang()) for each sample.
So make a loop over all elements and test each, or just use std::all_of:
// Lambda function used to test a single comm_reliability
auto is_reliable = [] (float r) { return rang() > r; };
// Iterate over your samples
for (int i = 0; i < sample_size; ++i) {
// If all elements satisfy your criterion ...
if (std::all_of(std::begin(comms_reliability),
std::end(comms_reliability),
is_reliable)) {
// .. perform your action
tally += 1.0;
}
}
Instead of the lambda function you could also use a normal function defined somewhere before:
bool is_reliable(float r) {
return rang() > r;
}
Note: Try to improve your variable/function naming.

use a flag to keep the value
int main(int argc, const char * argv[]) {
int sample_size = 1000000;
std::vector<float> comms_reliability = {0.6,0.6};
float tally = 0.0;
// rang() = random number generator
for (int i = 0; i < sample_size; i++){
boolean flag = true;
for(int j = 0; j < comms_reliability.size(); j++)
{
if (rang() <= comms_reliability[j])
{
flag = false;
break;
}
}
tally = flag ? tally + 1.0 : tally;
}

Related

How to compare values of two vectors

Is anybody there who has a code on how to compare values of two arrays ?
I have two vectors and I am looking for the biggest and equal value of the both list.
Here is the code:
void fractionInLowestTerm(int fNumerator, int fDenominator)
{
//let's get the dividers of fNumerator and fDenominator
std::vector<int> dividerOfNumerator;
std::vector<int> dividerOfDenominator;
for (int i = 1; i <= fNumerator; i++) {
if (fNumerator % i == 0) {
dividerOfNumerator.push_back(i);
}
}
for (int j = 1; fDenominator <= j; j++) {
if (fDenominator % j == 0) {
dividerOfDenominator.push_back(j);
}
}
// let's get the greatest common divider of a and b;
int pgcd = 1;
// I do not know how to compare the values of dividers to get the greatest common value on a and b there is the code I started writing to get that
for (int m = 0; m <= dividerOfNumerator.size() && m <= dividerOfDenominator.size(); m++) {
}
}
If I understand the problem correctly, you want to compare the elements in two arrays for each index and save the greater one into a third array. In this case, just use your favourite max function for each index. For example:
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
array3[member] = std::max(array1[member], array2[member]);
}
}
or if you want to compare lists and write into third array that which array has bigger value in that index you can use following code
void compare(int* array1, int* array2, int* array3, int size)
{
for (int member = 0; member < size; ++member) {
if (array1[member] > array2[member]) {
array3[member] = 1;
}
else if (array1[member] < array2[member]) {
array3[member] = 2;
}
else if (array1[member] == array2[member]) {
array3[member] = 0;
}
}
}
Since the vectors containing the divisors are already sorted, you can use the std::set_intersection algorithm like this:
std::vector<int> commonDivisors;
std::set_intersection(dividerOfNumerator.begin(), dividerOfNumerator.end(),
dividerOfDenominator.begin(), dividerOfDenominator.end(),
std::back_inserter(commonDivisors));
int pgcd = commonDivisors.back(); // guaranteed to be non-empty since 1 is always a divisor
Here's a demo.
Hello as you can see on the function name I wanted to write a function which put a function on the lowest term. I wanted to go through the gcd but I saw that it would consumes too much memory so here is what I've done. If it can help any member of the forum.
void fractionInLowestTerm(int fNumerator, int fDenominator){
//let's get on the divider of the number
for (int i = 1; i < fNumerator and i <fDenominator; i++) {
if (fNumerator%i == 0 and fDenominator%i == 0) {
fNumerator /= i;
fDenominator /= i;
i = 1;
}
}
}

Time complexity of an algorithm that finds prime numbers given a vector

I am trying to find the time complexity of the following algorithm that finds the prime numbers given the vector. Specifically I am not sure about the last for loop with another loop nested in it. I think it's O(sqrt(n)/2), and then the loop inside it is O(n)?
void PrimeFind (std::vector<bool> &vec)
{
int vsize = vec.size();
size_t sqvsize = ceil(sqrt(vsize));
std::fill(vec.begin(), vec.end(), true);
vec[0] = false;
vec[1] = false;
for (int i = 4; i < vsize; i += 2)
{
vec[i] = false;
}
for (int i = 3; i < sqrtvsize; i += 2)
{
if (vec[i])
{
for (int j = i * i; j < vsize; j += i)
{
vec[j] = false;
}
}
}
}
Work performed by basic sieve of Erastophene is almost entirely culling composite numbers and it takes
In your case you start from i * i which effectively reduces number of culling operation by i - 1 for every prime. So, we need to count number of all primes till n (vsize). This is
So, asymptotically we have
Where the last addend is the number of primes less than n.

How to access a vector inside a vector?

So I have a vector of vectors type double. I basically need to be able to set 360 numbers to cosY, and then put those 360 numbers into cosineY[0], then get another 360 numbers that are calculated with a different a now, and put them into cosineY[1].Technically my vector is going to be cosineYa I then need to be able to take out just cosY for a that I specify...
My code is saying this:
for (int a = 0; a < 8; a++)
{
for int n=0; n <= 360; n++
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
which I hope is the correct way of actually setting it.
But then I need to take cosY for a that I specify, and calculate another another 360 vector, which will be stored in another vector again as a vector of vectors.
Right now I've got:
for (int a = 0; a < 8; a++
{
for (int n = 0; n <= 360; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
The VectorOfY is besically the amplitude of an input wave. What I am doing is trying to create a cosine wave with different frequencies (a). I am then calculation the product of the input and cosine wave at each frequency. I need to be able to access these 360 points for each frequency later on in the program, and right now also I need to calculate the addition of all elements in cosProductPt, for every frequency (stored in cosProductY), and store it in a vector dotProductCos[a].
I've been trying to work it out but I don't know how to access all the elements in a vector of vectors to add them. I've been trying to do this for the whole day without any results. Right now I know so little that I don't even know how I would display or access a vector inside a vector, but I need to use that access point for the addition.
Thank you for your help.
for (int a = 0; a < 8; a++)
{
for int n=0; n < 360; n++) // note traded in <= for <. I think you had an off by one
// error here.
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
Is sound so long as cosY has been pre-allocated to contain at least 360 elements. You could
std::vector<std::vector<double>> cosineY;
std::vector<double> cosY(360); // strongly consider replacing the 360 with a well-named
// constant
for (int a = 0; a < 8; a++) // same with that 8
{
for int n=0; n < 360; n++)
{
cosY[n] = cos(a*vectorOfY[n]);
}
cosineY.push_back(cosY);
}
for example, but this hangs on to cosY longer than you need to and could cause problems later, so I'd probably scope cosY by throwing the above code into a function.
std::vector<std::vector<double>> buildStageOne(std::vector<double> &vectorOfY)
{
std::vector<std::vector<double>> cosineY;
std::vector<double> cosY(NumDegrees);
for (int a = 0; a < NumVectors; a++)
{
for int n=0; n < NumDegrees; n++)
{
cosY[n] = cos(a*vectorOfY[n]); // take radians into account if needed.
}
cosineY.push_back(cosY);
}
return cosineY;
}
This looks horrible, returning the vector by value, but the vast majority of compilers will take advantage of Copy Elision or some other sneaky optimization to eliminate the copying.
Then I'd do almost the exact same thing for the second step.
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
for (int a = 0; a < numVectors; a++)
{
for (int n = 0; n < NumDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosineY[a][n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
But we can make a couple optimizations
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
for (int a = 0; a < numVectors; a++)
{
// why risk constantly looking up cosineY[a]? grab it once and cache it
std::vector<double> & cosY = cosineY[a]; // note the reference
for (int n = 0; n < numDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
And the next is kind of an extension of the first:
std::vector<std::vector<double>> buildStageTwo(std::vector<double> &vectorOfY,
std::vector<std::vector<double>> &cosineY)
{
std::vector<std::vector<double>> CosProductY;
std::vector<double> cosProductPt(360);
for (std::vector<double> & cosY: cosineY) // range based for. Gets rid of
{
for (int n = 0; n < NumDegrees; n++)
{
cosProductPt[n] = (VectorOfY[n]*cosY[n]);
}
CosProductY.push_back(cosProductPt);
}
return CosProductY;
}
We could do the same range-based for trick for the for (int n = 0; n < NumDegrees; n++), but since we are iterating multiple arrays here it's not all that helpful.

Extract the n lowest sums from combinations of elements from m arrays for huge datasets

Let's say you have a number of unsorted arrays containing integers. Your job is to make sums of the arrays. The sums have to contain exactly one value from each array, i.e. (for 3 arrays)
sum = array1[2]+array2[12]+array3[4];
Goal: You should output the 20 combinations that generate the lowest possible sums.
The solution below is off-limits as the algorithm needs to be able to handle 10 arrays that can contain a huge number of integers. The following solution is way too slow for larger number of arrays:
//You already have int array1, array2 and array3
int top[20];
for(int i=0; i<20; i++)
top[i] = 1e99;
int sum = 0;
for(int i=0; i<array1.size(); i++) //One for loop per array is trouble for
for(int j=0; j<array2.size(); j++) //increasing numbers of arrays
for(int k=0; k<array3.size(); k++)
{
sum = array1[i] + array2[j] + array3[k];
if (sum < top[19])
swapFunction(sum, top); //Function that adds sum to top
//and sorts top in increasing order
}
printResults(top); // Outputs top 20 lowest sums in increasing order
What would you do to achieve correct results more efficiently (with a lower Big O notation)?
The answer can be found by considering how to find the absolute lowest sum, and how to find the 2nd lowest sum and so on.
As you only need 20 sums at most, you only need the lowest 20 values from each array at most. I would recommend using std::partial_sort for this.
The rest should be able to be accomplished with a priority_queue in which each element contains the current sum and the indicies of the arrays for this sum. Simply take each index of indicies and increase it by one, calculate the new sum and add that to the priority queue. The top most item of the queue should always be the one of the lowest sum. Remove the lowest sum, generate the next possibilities, and then repeat until you have enough answers.
Assuming that the number of answers needed is much less than Big O should be predominately be the efficiency of partial_sort (N + k*log(k)) * number of arrays
Here's some basic code to demonstrate the idea. There's very likely ways of improving on this. For example, I'm sure that with some work, you could avoid adding the same set of indicies multiple times, and there by eliminate the need for the do-while pop.
for (size_t i = 0; i < arrays.size(); i++)
{
auto b = arrays[i].begin();
partial_sort(b, b + numAnswers, arrays[i].end());
}
struct answer
{
answer(int s, vector<int> i)
: sum(s), indices(i)
{
}
int sum;
vector<int> indices;
bool operator <(const answer &o) const
{
return sum > o.sum;
}
};
auto getSum =[&arrays](const vector<int> &indices) {
auto retval = 0;
for (size_t i = 0; i < arrays.size(); i++)
{
retval += arrays[i][indices[i]];
}
return retval;
};
vector<int> initalIndices(arrays.size());
priority_queue<answer> q;
q.emplace(getSum(initalIndices), initalIndices );
for (auto i = 0; i < numAnswers; i++)
{
auto ans = q.top();
cout << ans.sum << endl;
do
{
q.pop();
} while (!q.empty() && q.top().indices == ans.indices);
for (size_t i = 0; i < ans.indices.size(); i++)
{
auto nextIndices = ans.indices;
nextIndices[i]++;
q.emplace(getSum(nextIndices), nextIndices);
}
}

Algorithm for smoothing

I wrote this code for smoothing of a curve .
It takes 5 points next to a point and adds them and averages it .
/* Smoothing */
void smoothing(vector<Point2D> &a)
{
//How many neighbours to smooth
int NO_OF_NEIGHBOURS=10;
vector<Point2D> tmp=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=a.at(i+j).x;
a.at(i).y+=a.at(i+j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=tmp.at(i-j).x;
a.at(i).y+=tmp.at(i-j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
}
}
But i get very high values for each point, instead of the similar values to the previous point . The shape is maximized a lot , what is going wrong in this algorithm ?
What it looks like you have here is a bass-ackwards implementation of a finite impulse response (FIR) filter that implements a boxcar window function. Thinking about the problem in terms of DSP, you need to filter your incoming vector with NO_OF_NEIGHBOURS equal FIR coefficients that each have a value of 1/NO_OF_NEIGHBOURS. It is normally best to use an established algorithm rather than reinvent the wheel.
Here is a pretty scruffy implementation that I hammered out quickly that filters doubles. You can easily modify this to filter your data type. The demo shows filtering of a few cycles of a rising saw function (0,.25,.5,1) just for demonstration purposes. It compiles, so you can play with it.
#include <iostream>
#include <vector>
using namespace std;
class boxFIR
{
int numCoeffs; //MUST be > 0
vector<double> b; //Filter coefficients
vector<double> m; //Filter memories
public:
boxFIR(int _numCoeffs) :
numCoeffs(_numCoeffs)
{
if (numCoeffs<1)
numCoeffs = 1; //Must be > 0 or bad stuff happens
double val = 1./numCoeffs;
for (int ii=0; ii<numCoeffs; ++ii) {
b.push_back(val);
m.push_back(0.);
}
}
void filter(vector<double> &a)
{
double output;
for (int nn=0; nn<a.size(); ++nn)
{
//Apply smoothing filter to signal
output = 0;
m[0] = a[nn];
for (int ii=0; ii<numCoeffs; ++ii) {
output+=b[ii]*m[ii];
}
//Reshuffle memories
for (int ii = numCoeffs-1; ii!=0; --ii) {
m[ii] = m[ii-1];
}
a[nn] = output;
}
}
};
int main(int argc, const char * argv[])
{
boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
//Make a rising saw function for demo
vector<double> a;
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
box.filter(a);
for (int nn=0; nn<a.size(); ++nn)
{
cout << a[nn] << endl;
}
}
Up the number of filter coefficients using this line to see a progressively more smoothed output. With just 1 filter coefficient, there is no smoothing.
boxFIR box(1);
The code is flexible enough that you can even change the window shape if you like. Do this by modifying the coefficients defined in the constructor.
Note: This will give a slightly different output to your implementation as this is a causal filter (only depends on current sample and previous samples). Your implementation is not causal as it looks ahead in time at future samples to make the average, and that is why you need the conditional statements for the situation where you are near the end of your vector. If you want output like what you are attempting to do with your filter using this algorithm, run the your vector through this algorithm in reverse (This works fine so long as the window function is symmetrical). That way you can get similar output without the nasty conditional part of algorithm.
in following block:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x=a.at(i).x+a.at(i+j).x;
a.at(i).y=a.at(i).y+a.at(i+j).y;
}
for each neighbour you add a.at(i)'s x and y respectively to neighbour values.
i understand correctly, it should be something like this.
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
Filtering is good for 'memory' smoothing. This is the reverse pass for the learnvst's answer, to prevent phase distortion:
for (int i = a.size(); i > 0; --i)
{
// Apply smoothing filter to signal
output = 0;
m[m.size() - 1] = a[i - 1];
for (int j = numCoeffs; j > 0; --j)
output += b[j - 1] * m[j - 1];
// Reshuffle memories
for (int j = 0; j != numCoeffs; ++j)
m[j] = m[j + 1];
a[i - 1] = output;
}
More about zero-phase distortion FIR filter in MATLAB: http://www.mathworks.com/help/signal/ref/filtfilt.html
The current-value of the point is used twice: once because you use += and once if y==0. So you are building the sum of eg 6 points but only dividing by 5. This problem is in both the IF and ELSE case. Also: you should check that the vector is long enough otherwise your ELSE-case will read at negative indices.
Following is not a problem in itself but just a thought: Have you considered to use an algorithm that only touches every point twice?: You can store a temporary x-y-value (initialized to be identical to the first point), then as you visit each point you just add the new point in and subtract the very-oldest point if it is further than your NEIGHBOURS back. You keep this "running sum" updated for every point and store this value divided by the NEIGHBOURS-number into the new point.
You make addition with point itself when you need to take neighbor points - just offset index by 1:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
This works fine for me:
for (i = 0; i < lenInput; i++)
{
float x = 0;
for (int j = -neighbours; j <= neighbours; j++)
{
x += input[(i + j <= 0) || (i + j >= lenInput) ? i : i + j];
}
output[i] = x / (neighbours * 2 + 1);
}