0

I am very new to C program. I have a function like this :

void lfit( float x[], float y[], float sig[], int ndat, float a[], int ia[], int ma,float **covar, float *chisq, float (*funcs)(float, float [], int))

//Given a set of data points x[1..ndat], y[1..ndat] with individual standard deviations
//sig[1..ndat], use χ2 minimization to fit for some or all of the coefficients a[1..ma] of
//a function that depends linearly on a, y =i ai × afunci(x). The input array ia[1..ma]
//indicates by nonzero entries those components of a that should be fitted for, and by zero entries
//those components that should be held fixed at their input values. The program returns values
//for a[1..ma], χ2 = chisq, and the covariance matrix covar[1..ma][1..ma]. (Parameters
//held fixed will return zero covariances.)Th e user supplies a routine funcs(x,afunc,ma) that
//returns the ma basis functions evaluated at x = x in the array afunc[1..ma].

{
void gaussj(float **a, int n, float **b, int m);

int i,j,k,l,m,mfit=0;
float ym,wt,sum,sig2i,**beta, *afunc;


afunc=vector(1,ma);
beta=matrix(1,ma,1,1);

for (j=1;j<=ma;j++)
    if (ia[j]) 
        mfit++;

if (mfit == 0) 
    nrerror("lfit: no parameters to be fitted");
for (j=1;j<=mfit;j++) {                       //Initialize the (symmetric)matrix.
    for (k=1;k<=mfit;k++) 
        covar[j][k]=0.0;
    beta[j][1]=0.0;
}

for (i=0;i<ndat;i++) {                       //Loop over data to accumulate coefficients of the normal equations.

(*funcs)(x[i], afunc ,ma);
ym=y[i];
if (mfit < ma) {                              //Subtract off dependences on known pieces of the fitting function.
    for (j=1;j<=ma;j++)                
        if (!ia[j]) 
            ym -= a[j]*afunc[j];
}


sig2i=1.0/SQR(sig[i]);
for (j=0,k=0,l=1;l<=ma;l++) {

    if (ia[l]) {
        wt=afunc[l]*sig2i;
        for (j++,k=0,m=1;m<=ma;m++)
            if (ia[m]) 
                covar[j][++k] += wt*afunc[m];

        beta[j][1] += ym*wt;
    }

}


for (j=2;j<=mfit;j++)                    //Fill in above the diagonal from symmetry.
    for (k=1;k<j;k++)
        covar[k][j]=covar[j][k];

gaussj(covar,mfit,beta,1);              //Matrix solution.

for (j=0,l=1;l<=ma;l++) 
    if (ia[l]) 
        a[l]=beta[++j][1];              //Partition solution to appropriate coefficients a Evaluate χ2 of the fit.

*chisq=0.0;

for (i=1;i<=ndat;i++) { 
        (*funcs)(x[i], afunc,ma);
        for (sum=0.0,j=1;j<=ma;j++) 
            sum += a[j]*afunc[j];
*chisq += SQR((y[i]-sum)/sig[i]);

}
//covsrt(covar,ma,ia,mfit);              //Sort covariance matrix to true order of fitting coefficients.
free_vector(afunc,1,ma); 
free_matrix(beta,1,ma,1,1);
}
}

in int main() part when i want to call this function i have some problems. the main part that i am writing is like this for example:

int main()
{

float x1[]={100.000000f,88.00000f,76.199997f,68.599998f,54.500000f,37.599998f,26.500000f,17.000000f,8.300000f,0.900000f,-7.200000f,-17.000000f,-24.900000f,-33.799999f,-42.500000f,-51.000000f,-60.500000f,-69.500000f,-75.300003f,-83.099998f,-94.099998f,-103.000000f,-110.099998f};
float y1[]={-2.876821f,-2.788704f,-2.596228f,-2.468143f,-1.898085f,-1.296223f,-0.664981f,-0.245603f,-0.280993f,-0.094657f,-0.184912f,-0.263328f,-0.181819f,-0.132037f,-0.029368f,0.134307f,0.257734f,0.305223f,0.091159f,0.063768f,-0.163334f,-0.136314f,-0.372106f};
float sig1[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
float a1[]={1.8f,1.6f,1.7f,1.3f};
int ia1[]={2,3,4,2}; 
int ma=4, ndat=23 ;
float chisq1, **covar;



lfit(x1,y1,sig1,ndat,a1,ia1,ma,covar,&chisq1, &funcs);


return 0;
}

the error that i always get is this: Run-Time Check Failure #3 - The variable 'covar' is being used without being initialized. i tried different ways to initialize it but non of them worked.

what is your idea? how can i solve this problem ?

I really appreciate any help!

7
  • float **covar = NULL; doesn't work? Commented Dec 3, 2012 at 10:39
  • I would suggest std::array and std::vector instead of C-arrays - easier and less error prone Commented Dec 3, 2012 at 10:41
  • What exactly didn't work? What you wan't that double ponter to point to? Commented Dec 3, 2012 at 10:42
  • You are not actually allocating any memory for it as far as I can tell. You need to do this or point it to another 2D array if you want this code to do what you want. Commented Dec 3, 2012 at 10:43
  • @Marrow Gnower i tried this before, but i get another error which is Access violation reading location and after checking the program i found out this error is related to covar, then i thought may be it is not a good way to define covar ! Do you think it is the best way to define it? Commented Dec 3, 2012 at 10:46

2 Answers 2

2

First thing: your array indexes must be zero-based, so for loops are for(i=0; i < max; i++)

The easy way to get a 2D array is:

float covar[4][4]; // Or whatever size is correct for you

If you need to malloc it you can just do this:

float ** Malloc2DFloat(int x, int y)
{
    float **MainArray = (float**)malloc(sizeof(float*) * x);
    int i;
    for (i=0; i < x; i++)
        MainArray[i] = (float*)malloc(sizeof(float) * y);

    return MainArray;
}
float **covar = Malloc2DFloat(4,4);

You need to do this in main, or pass in a pointer to that to your function and malloc it in there:

func(float ***covar)
{
    *covar = Malloc2DFloat(mfit, mfit); // Allocate like this
    (*covar)[0][0] = 3.41f; // Reference it like this
}
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately, that is not the correct way to get a multi-dimensional array with malloc
Thanks @BartvanIngenSchenau. How's that?
0

You have to allocate memory for covar before you filling it. you can allocate memory into the lfit function. To do:

you have to update your input covar in the function lfit

void lfit( float x[], float y[], float sig[], int ndat, float a[], int ia[], int ma,float ***covar, float *chisq, float (*funcs)(float, float [], int))

and then when you initialize matrix you have to do it in this way

*covar = calloc(mfit,sizeof(float *));   
for (j=1;j<=mfit;j++) {   //Initialize the (symmetric)matrix.
    (*covar)[j] = calloc(mfit,sizeof(float)); //calloc will initialize the matrix to 0
    beta[j][1]=0.0;
}

instead of the old way

for (j=1;j<=mfit;j++) {                       //Initialize the (symmetric)matrix.
    for (k=1;k<=mfit;k++) 
        covar[j][k]=0.0;
    beta[j][1]=0.0;
}

and to access to covar data in the lfit function:

float x=(*covar)[j][k];
(*covar)[j][k]=5.2;

so for example this line

covar[j][++k] += wt*afunc[m];

should be updated to

(*covar)[j][++k] += wt*afunc[m];

and when you call the function lfit

lfit(x1,y1,sig1,ndat,a1,ia1,ma,&covar,&chisq1, &funcs);

6 Comments

thanks for your answer , but when i use 'float covar[][]` in my lfit function i get this eeror error C2087: 'covar' : missing subscript
try to change it by covar[100][] or covar[][100]
Thanks Mohamed, can you please tell where should i write this way of initialization that you have suggested me? inside main() or where?
in the place where you initialize your old covar matrix
thanks @Mohamed , i could use your information and run the program finally :) but i have one more question, can you please tell me how can i print covar matrix ? should i write like printf("%f c \n", covar[i][j]); or printf("%f c \n", &covar[i][j]);? the difference is only in &. Thanks alot
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.