Calculating mean of an array - c++

Hello I'm having issues calculating the mean of in my function, the program compiles however I don't get the intended answer of 64.2 to print out and instead get a random set of integers and characters.
This is not the entirety of the code but only the appropriate variables and functions.
// main function and prototyping would be here
int size=0;
float values[]={10.1, 9.2, 7.9, 9.2, 13.0, 12.7, 11.3};
float mean(float values[], int size)
{
float sum = 0;
float mean = 0;
for (size = 0; size > 7; size++)
{
sum += values[size];
mean = sum / 7;
}
return mean;
}

Change your loop like so:
for (size = 0; size < 7; size++)
{
sum += values[size];
}
mean = sum / 7;
Your terminating condition for for loop isn't right.
Move the mean out of for loop.

for (size = 0; size > 7; size++)
Since size is initialized as 0, and it is incremented by 1, it becomes 1 at the end of the first iteration and fails the test (it is not > 7). Thus, it immediately exits the loop.
Secondly, you calculate mean inside the loop when you should calculate it after the loop is complete. Theoretically, you should get a correct value since you redo it as the mean of the sums to that point in the loop, but it is a waste of time. You also wipe out size by redefining it.
float mean(float values[], int size)
{
float sum = 0;
float mymean = 0;
for (int i = 0; i < size; i++)
{
sum += values[i];
}
mymean = sum / size;
return mymean;
}

Why is the test size > 7 there? Expecting your initial value to have an unusually large value of zero? It's likely that you mean size < 7, though using arbitrary magic numbers like that is trouble.
What you probably want is:
float mean(float* values, int size)
{
float sum = 0;
for (int i = 0; i < size; ++i)
sum += values[i];
return sum / size;
}
To be more C++ you'd want that signature to be:
float mean(const float* values, const size_t size)
That way you'd catch any mistakes with modifying those values.

Related

vector subscript out of range for loop in C++

I keep on receiving this error vector subscript out of range when I run the below section of my code its triggered on this line interval.push_back (peaks_position_vector[n+1]-peaks_position_vector[n]);
I think the issue is with the victor size as im going over the vector size. I tried to initialize n with 100 to test it and decrements n. the error didn't occur. can some one help how can I fix it according to my requirements ? thanks in advance. ( feel free to ask about other sections of the code I only mentioned this part as this is where the error occurred only.)
double ECG::compute_heart_rate(vector<double>& peaks_position_vector)
{
const int s = 60; // 'const' for good practice such that the variable s never changes in execution
vector<double> interval;
// compute pair-wise differences
for (unsigned int n = 0; n < peaks_position_vector.size()-1; n++)
{
interval.push_back (peaks_position_vector[n+1]-peaks_position_vector[n]);
// create heart rate vector
vector<double> heart_rate;
for (unsigned int j = 0; j < interval.size()-1; j++)
{
double hh = s/interval[j];
heart_rate.push_back(hh);
// calculate mean heart rate
double mean_heart_rate, return_value = 0;
int x= 0;
for (unsigned int i=0; i < heart_rate.size(); i++)
{
return_value += heart_rate[i];
x++;
mean_heart_rate = return_value / x;
}
}
}
} // end of code block
I'm guessing that
n < peaks_position_vector.size()-1
should be
n + 1 < peaks_position_vector.size()
Suppose peaks_position_vector.size() equals zero, what do you think that peaks_position_vector.size()-1 evaluates to given that size() returns an unsigned value, and zero is the smallest possible unsigned value?
The implementation you have mention have a bug with divided by zero problem. Where you are doing this you consider a vector input as {4,4,4,4,5,5,5,5}
interval.push_back (peaks_position_vector[n+1]-peaks_position_vector[n]);
....
....
double hh = s/interval[j];
heart_rate.push_back(hh)
...
...
return_value += heart_rate[i];
as you can see that would mess up return_value in your case( should have a value of inf ). And of course what #john have mentioned in the earlier answer also holds true.

Why am I getting the error message, expected unqualified id before 'for'

I have to write a code that does this for a university assignment. I have written the average function of the code but I'm getting an error message for the other function.
The DEVBOARD_readAccelerometer function will read x,y,z components of acceleration
Firstly, you will need to write a function:
int average(int *array, int nLen);
which returns the average value of an array of integer values. (To prevent overflow, it is suggested to use a long internal variable).
The Spirit Level function will run a loop. For each iteration the Z-component of gravitational acceleration will be sampled four times at 50ms intervals and stored in a suitably sized array.
Using the average() function you have written, determine the average value and analyze
int average(int* array, int nlen) { // assuming array is int
long sum = 0L; // sum will be larger than an item, long for safety.
for (int i = 0; i < nlen; i++) {
sum += array[i];
}
return ((long)sum) / nlen;
}
float sum[3];
int j;
for (int j = 0; j < 3; j++) {
i = DEVBOARD_readAccelerometer(int* xAccel, int* yAccel, int* zAccel);
sum[j] = int * zAccel;
}
average(float* sum[j], float nlen);
printf("The average zcomponent is %f\n");
}
unqualified-id before for
You declared variable j 2 times. One before the for loop and one inside the for definition.

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.

C++ What's a way to access an array struct using a function?

So I have two functions. One find the max number of an array located inside a struct. The second one finds the largest number in an array of the struct above.
Struct
struct ABC {
unsigned n;
char c;
double a[3];
};
First function
double max(const ABC & x) {
double largest = x.a[0];
for (int i = 0; i < 3; i++)
{
if (largest < x.a[i])
largest = x.a[i];
}
return largest;
}
Second function and the one I'm having trouble with.
double max(const ABC arr[], unsigned elements) {
double largest = 0;
cout << largest << endl;
if (elements == 0)
terminate("You need more than 1 element");
for (int i = 0; i < elements; i++)
{
largest = max(ABC(arr[i])));
if (largest <= max(ABC(arr[i])));
{
largest = max(ABC(arr[i]));
}
}
return largest;
}
This is what I'm calling on the main functions:
const unsigned els = 4;
ABC arr[els];
arr[0] = { 1, 'a',{ 19.0, 20.0, 3.0 } };
arr[1] = { 2, 'b',{ 4.0, 5.0, 6.0 } };
arr[2] = { 3, 'c',{ 7.0, 80.0, 9.0 } };
arr[3] = { 4, 'd',{ 10.0, 11.0, 7.0 } };
largest = max(arr, els);
The max function should be returning the max value of those arrays, but I get 11 instead. I did some testing and figured that the problem came when calling the max function inside of the loop of the second function. Does anybody know why that is?
How do I make the first max function work with the second function?
Note: This is an assignment, It's a small part of 20 other functions I had to write; however, I'm not asking people to solve it for me, all I'm asking to know is how I could use the first function with the second one. I don't consider that cheating, I just need help with something minor.
In short, the problem I'm having is that when I call the max(ABC(arr[0]))) and set the 0 to a number greater than 0 I get 11 as the max value. Why is that happening?
You wrote this:
for (int i = 0; i < elements; i++)
{
largest = max(ABC(arr[i])));
if (largest <= max(ABC(arr[i])));
{
largest = max(ABC(arr[i]));
}
}
You're resetting largest on every iteration! That's why only the last array element is counting.
Presumably it's just a typo and you meant to go straight into the conditional.
By the way, those repeated calls to max are not very efficient, and I don't see the purpose in casting the object arr[i] into a ABC copy.
Why not this:
for (size_t i = 0; i < elements; i++) {
const double this_max = max(arr[i]);
if (largest <= this_max)
largest = this_max;
}
(I swapped your int to size_t so that you're not comparing signed and unsigned integers. Didn't your compiler warn you about this?)
Remove
largest = max(ABC(arr[i]));
from the for-loop.
When you have it inside the for-loop, you reset largest to the latest max every time.

Finding least number in a set with CUDA

Suppose you had a function that would take in a vector, a set of vectors, and find which vector in the set of vectors was closest to the original vector. It may be useful if I included some code:
int findBMU(float * inputVector, float * weights){
int count = 0;
float currentDistance = 0;
int winner = 0;
float leastDistance = 99999;
for(int i = 0; i<10; i++){
for(int j = 0;j<10; j++){
for(int k = 0; k<10; k++){
int offset = (i*100+j*10+k)*644;
for(int i = offset; i<offset+644; i++){
currentDistance += abs((inputVector[count]-weights[i]))*abs((inputVector[count]-weights[i]));
count++;
}
currentDistance = sqrt(currentDistance);
count = 0;
if(currentDistance<leastDistance){
winner = offset;
leastDistance = currentDistance;
}
currentDistance = 0;
}
}
}
return winner;
}
In this example, weights is a single dimensional array, with a block of 644 elements corresponding to one vector. inputVector is the vector that's being compared, and it also has 644 elements.
To speed up my program, I decided to take a look at the CUDA framework provided by NVIDIA. This is what my code looked like once I changed it to fit CUDA's specifications.
__global__ void findBMU(float * inputVector, float * weights, int * winner, float * leastDistance){
int i = threadIdx.x+(blockIdx.x*blockDim.x);
if(i<1000){
int offset = i*644;
int count = 0;
float currentDistance = 0;
for(int w = offset; w<offset+644; w++){
currentDistance += abs((inputVector[count]-weights[w]))*abs((inputVector[count]-weights[w]));
count++;
}
currentDistance = sqrt(currentDistance);
count = 0;
if(currentDistance<*leastDistance){
*winner = offset;
*leastDistance = currentDistance;
}
currentDistance = 0;
}
}
To call the function, I used : findBMU<<<20, 50>>>(d_data, d_weights, d_winner, d_least);
But, when I would call the function, sometimes it would give me the right answer, and sometimes it wouldn't. After doing some research, I found that CUDA has some issues with reduction problems like these, but I couldn't find how to fix it. How can I modify my program to make it work with CUDA?
The issue is that threads that run concurrently will see the same leastDistance and overwrite each other's results. There are two values that are shared between threads; leastDistance and winner. You have two basic options. You can write out the results from all the threads and then do a second pass over the data with a parallel reduction to determine which vector had the best match or you can implement this with a custom atomic operation using atomicCAS().
The first method is the easiest. My guess is that it will also give you the best performance, though it does add a dependency for the the free Thrust library. You would use thrust::min_element().
The method using atomicCAS() uses the fact that atomicCAS() has a 64-bit mode, in which you can assign any semantics that you wish to a 64-bit value. In your case, you would use 32 bits to store leastDistance and 32 bits to store winner. To use this method, adapt this example in the CUDA C Programming Guide that implements a double precision floating point atomicAdd().
__device__ double atomicAdd(double* address, double val)
{
unsigned long long int* address_as_ull =
(unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val + __longlong_as_double(assumed)));
} while (assumed != old);
return __longlong_as_double(old);
}