1. ## Issue with Functions

Hey everyone,

Can anyone identify a problem with my functions because I'm not getting the values I expect, I think my logic is sound, I reckon it's just a problem with my lack of knowledge of functions. Once again no code please just point out where I've gone wrong cheers guys:

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>

float sum_xsquared_by_sigmasquared(float myarray[10000][4], int num_elements); //Create prototypes for summing values in file
float sum_y_by_sigmasquared(float myarray[10000][4], int num_elements);
float sum_x_by_sigmasquared(float myarray[10000][4], int num_elements);
float sum_xy_by_sigmasquared(float myarray[10000][4], int num_elements);
float sum_one_over_sigmasquared(float myarray[10000][4], int num_elements);

int main()
{
int i, c=10000, v=4;                   //Define
float x,y,sx,sy,myarray[c][v];         //Define Array for storage and co-ordinates
FILE *myfile;                          //Define a pointer to the file input

for(c=0; c<10000; c++)                 //Initialise Array
{
for(v=0; v<4; v++)
{
myarray[c][v]=0;
}
}

myfile=fopen("/home/sam/Documents/C Projects/LargeDataSet","r");  //Find and open File and store data
for(c=0; !feof(myfile); c++)
{
fscanf(myfile,"%f%f%f%f", &x,&sx,&y,&sy);         //Read file and store data in array
myarray[c][0]=x;
myarray[c][1]=sx;
myarray[c][2]=y;
myarray[c][3]=sy;
}

float a, b, a_sigma_squared, b_sigma_squared, a_sigma, b_sigma;           //Define values for output for Line

a=((sum_y_by_sigmasquared(myarray, c)*sum_xsquared_by_sigmasquared(myarray, c))-(sum_x_by_sigmasquared(myarray, c)*sum_xy_by_sigmasquared(myarray, c)))/((sum_one_over_sigmasquared(myarray, c)*sum_xsquared_by_sigmasquared(myarray, c))-pow(sum_x_by_sigmasquared(myarray, c),2));
b=((sum_one_over_sigmasquared(myarray, c)*sum_xy_by_sigmasquared(myarray, c))-(sum_x_by_sigmasquared(myarray, c)*sum_y_by_sigmasquared(myarray, c)))/((sum_one_over_sigmasquared(myarray, c)*sum_xsquared_by_sigmasquared(myarray, c))-pow(sum_x_by_sigmasquared(myarray, c),2));
a_sigma_squared=sum_xsquared_by_sigmasquared(myarray, c)/((sum_one_over_sigmasquared(myarray, c)*sum_xsquared_by_sigmasquared(myarray, c))-pow(sum_x_by_sigmasquared(myarray, c),2));
b_sigma_squared=sum_one_over_sigmasquared(myarray, c)/((sum_one_over_sigmasquared(myarray, c)*sum_xsquared_by_sigmasquared(myarray, c))-pow(sum_x_by_sigmasquared(myarray, c),2));
a_sigma=sqrt(a_sigma_squared);
b_sigma=sqrt(b_sigma_squared);

printf("The value of sum_xsquard/sigmasquared is: %f\n", sum_xsquared_by_sigmasquared(myarray, c));
printf("The value of sum_y/sigmasquared is: %f\n", sum_y_by_sigmasquared(myarray, c));
printf("The value of sum_x/sigmasquared is: %f\n", sum_x_by_sigmasquared(myarray, c));
printf("The value of sum_xy/sigmasquared is: %f\n", sum_xy_by_sigmasquared(myarray, c));
printf("The value of sum_one/sigmasquared is: %f\n\n", sum_one_over_sigmasquared(myarray, c));

printf("Y= Ax + B\n\n");

printf("Here follows the values for your Linear Least Squares variables:\n\n");     //Print Values
printf("The A Value is: %f\n", a);
printf("The error in A is: %f\n", a_sigma);
printf("The B Value is: %f\n", b);
printf("The error in B is: %f\n", b_sigma);

fclose(myfile);
return 0;
}

float sum_xsquared_by_sigmasquared(float myarray[10000][4], int num_elements) //Functions for summing values required for a and b calculation
{
int i, sum=0;
for (i=0; i<num_elements; i++)
{
sum = sum + pow(myarray[i][0],2)/pow(myarray[i][3],2);
}
return(sum);
}

float sum_y_by_sigmasquared(float myarray[10000][4], int num_elements)
{
int i, sum=0;
for (i=0; i<num_elements; i++)
{
sum = sum + myarray[i][2]/pow(myarray[i][3],2);
}
return(sum);
}

float sum_x_by_sigmasquared(float myarray[10000][4], int num_elements)
{
int i, sum=0;
for (i=0; i<num_elements; i++)
{
sum = sum + myarray[i][0]/pow(myarray[i][3],2);
}
return(sum);
}

float sum_xy_by_sigmasquared(float myarray[10000][4], int num_elements)
{
int i, sum=0;
for (i=0; i<num_elements; i++)
{
sum = sum + (myarray[i][0]*myarray[i][2])/pow(myarray[i][3],2);
}
return(sum);
}

float sum_one_over_sigmasquared(float myarray[10000][4], int num_elements)
{
int i, sum=0;
for (i=0; i<num_elements; i++)
{
sum = sum + 1/pow(myarray[i][3 ],2);
}
return(sum);
}```

2. What are you feeding it... what are you getting ... and what do you expect?

For the moment... lines 29 to 32 are not necessary... just feed the data directly into the array in line 28, no intermediate variables. With floating point being what it is, simply passing your values through an intermediate variable might introduce least significant bit errors .

What Every Computer Scientist Should Know About Floating-Point Arithmetic

3. Originally Posted by sam.briggs
Can anyone identify a problem with my functions because I'm not getting the values I expect, I think my logic is sound, I reckon it's just a problem with my lack of knowledge of functions.
Yes. Your loop for reading input is wrong because you use feof to control the loop, yet EOF might be reached only on the first line of the loop body. Rather, control the loop with the return value of fscanf.

Of course, there may be other problems, but you were only asking for someone to identify a problem

Oh, and another thing: are you a mind reader, by any chance? I found it quite amusing that you said you did not get the values you expected, yet you did not show us your test input, expected output and actual output, as if you expected us to read your mind to find out

4. Sorry guys, the input is a huge set of data consisting of four columns of numbers pertaining to x, y and error values. I'm then calculating the a and b values for the linear least squares plot of the data. I'm supposed to get:

Data Set: LargeDataSet.txt
y = A + B x
A=4.499998E+000 sigma A= 5.771447E-003
B=1.007627E-004 sigma B= 9.988277E-007

the first chunk of the data is:

1.0091 4.5642 0.10000 0.29000
2.1215 4.1608 0.10000 0.29000
2.9278 4.9821 0.10000 0.29000
4.2826 4.2534 0.10000 0.29000

5. It seems like you have several large arrays. At least five arrays of 10000 by 4; pass by value will treat those arrays in the functions as their own, even though they are repeats of the original. I don't see commands like alloc or malloc in there to provide some fresh memory for those arrays.

There are lots of notes in the code about how it will need to use large arrays and large numbers and a big data set, but no provisions for managing the memory. If you're compiling and re-compiling over and over again, as you develop the program, and you have big arrays (or lotsa pointers) and no memory management, eventually your computer will start re-using old spots; this will dredge up the garbage and send back unexpected values. I'm not an expert on this, but it seems to me that you need to direct some more attention to memory management.

How big of an array should you have before you start providing for space in memory?

6. Your code is not ANSI C, only C99.
You should ever use the return-value from input-calls like fscanf.
You should never call feof as first statement after fopen:

Code:
```    int i=0, c=10000, v=4;
char line[1000];
float x,y,sx,sy,myarray[c][v]={0};         //Define Array for storage and co-ordinates
FILE *myfile;                          //Define a pointer to the file input

myfile=fopen("/home/sam/Documents/C Projects/LargeDataSet","r");  //Find and open File and store data
while( fgets(line,1000,myfile) )
{
if( i<c && 4==sscanf(line,"%f%f%f%f", &x,&sx,&y,&sy) ){
myarray[i][0]=x;
myarray[i][1]=sx;
myarray[i][2]=y;
myarray[i++][3]=sy;
}
}```

7. Originally Posted by BillyTKid
Your code is not ANSI C, only C99.
That is not necessarily a problem though, and I doubt it has anything to do with the "not getting the values I expect" problem.

sam.briggs: post your updated code after my suggestion. Notice that BillyTKid basically repeated my suggestion, presumably because it was unclear if you understood it.

8. No. Big C99 VLA on stack are dangerous, because they have no success-check on initialization-time.
Therefore the behaviour on access to that too big VLA memory is undefined.
ANSI C have not VLA, the user must use malloc ( -> with success-check ! ), no problems on big allocation sizes if the user check the return-value from malloc.

9. Originally Posted by BillyTKid
No. Big C99 VLA on stack are dangerous, because they have no success-check on initialization-time.
Therefore the behaviour on access to that too big VLA memory is undefined.
ANSI C have not VLA, the user must use malloc ( -> with success-check ! ), no problems on big allocation sizes if the user check the return-value from malloc.
Good catch on the use of a VLA, but then you should have just stated it. Considering that I missed it, sam.briggs would have absolutely no chance of understanding what you were hinting at.

10. It's wrong to say that "ANSI C" doesn't have what "C99" has, because C99 is ANSI C.

Quzah.