Fit a 5d hyperplane by n points, using the linear fitter directly
This macro shows some features of the TLinearFitter class
A 5-d hyperplane is fit, a constant term is assumed in the hyperplane
equation (y = a0 + a1*x0 + a2*x1 + a3*x2 + a4*x3 + a5*x4)
Author: Anna Kreshuk
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Monday, March 27, 2023 at 09:47 AM.
int n=100;
int i;
TRandom randNum;
TLinearFitter *lf=new TLinearFitter(5);
The predefined "hypN" functions are the fastest to fit
lf->SetFormula("hyp5");
double *x=new double[n*10*5];
double *y=new double[n*10];
double *e=new double[n*10];
Create the points and put them into the fitter
for (i=0; i<n; i++){
x[0 + i*5] = randNum.Uniform(-10, 10);
x[1 + i*5] = randNum.Uniform(-10, 10);
x[2 + i*5] = randNum.Uniform(-10, 10);
x[3 + i*5] = randNum.Uniform(-10, 10);
x[4 + i*5] = randNum.Uniform(-10, 10);
e[i] = 0.01;
y[i] = 4*x[0+i*5] + x[1+i*5] + 2*x[2+i*5] + 3*x[3+i*5] + 0.2*x[4+i*5] + randNum.Gaus()*e[i];
}
To avoid copying the data into the fitter, the following function can be used:
lf->AssignData(n, 5, x, y, e);
A different way to put the points into the fitter would be to use the AddPoint function for each point. This way the points are copied and stored inside the fitter
Perform the fitting and look at the results
lf->Eval();
TVectorD params;
TVectorD errors;
lf->GetParameters(params);
lf->GetErrors(errors);
for (int i=0; i<6; i++)
printf("par[%d]=%f+-%f\n", i, params(i), errors(i));
double chisquare=lf->GetChisquare();
printf("chisquare=%f\n", chisquare);
par[0]=0.000069+-0.001011 par[1]=3.999934+-0.000164 par[2]=0.999835+-0.000172 par[3]=1.999892+-0.000178 par[4]=2.999967+-0.000185 par[5]=0.199823+-0.000174 chisquare=70.148012
Now suppose you want to add some more points and see if the parameters will change
for (i=n; i<n*2; i++) {
x[0+i*5] = randNum.Uniform(-10, 10);
x[1+i*5] = randNum.Uniform(-10, 10);
x[2+i*5] = randNum.Uniform(-10, 10);
x[3+i*5] = randNum.Uniform(-10, 10);
x[4+i*5] = randNum.Uniform(-10, 10);
e[i] = 0.01;
y[i] = 4*x[0+i*5] + x[1+i*5] + 2*x[2+i*5] + 3*x[3+i*5] + 0.2*x[4+i*5] + randNum.Gaus()*e[i];
}
Assign the data the same way as before
lf->AssignData(n*2, 5, x, y, e);
lf->Eval();
lf->GetParameters(params);
lf->GetErrors(errors);
printf("\nMore Points:\n");
for (int i=0; i<6; i++)
printf("par[%d]=%f+-%f\n", i, params(i), errors(i));
chisquare=lf->GetChisquare();
printf("chisquare=%.15f\n", chisquare);
More Points: par[0]=0.000551+-0.000712 par[1]=3.999910+-0.000121 par[2]=0.999886+-0.000125 par[3]=2.000067+-0.000123 par[4]=2.999915+-0.000127 par[5]=0.199918+-0.000130 chisquare=145.050322490891915
Suppose, you are not satisfied with the result and want to try a different formula Without a constant: Since the AssignData() function was used, you don't have to add all points to the fitter again
lf->SetFormula("x0++x1++x2++x3++x4");
lf->Eval();
lf->GetParameters(params);
lf->GetErrors(errors);
printf("\nWithout Constant\n");
for (int i=0; i<5; i++)
printf("par[%d]=%f+-%f\n", i, params(i), errors(i));
chisquare=lf->GetChisquare();
printf("chisquare=%f\n", chisquare);
Without Constant par[0]=3.999913+-0.000121 par[1]=0.999890+-0.000125 par[2]=2.000057+-0.000123 par[3]=2.999919+-0.000127 par[4]=0.199918+-0.000130 chisquare=145.649621
Now suppose that you want to fix the value of one of the parameters Let's fix the first parameter at 4:
lf->SetFormula("hyp5");
lf->FixParameter(1, 4);
lf->Eval();
lf->GetParameters(params);
lf->GetErrors(errors);
printf("\nFixed Constant:\n");
for (i=0; i<6; i++)
printf("par[%d]=%f+-%f\n", i, params(i), errors(i));
chisquare=lf->GetChisquare();
printf("chisquare=%.15f\n", chisquare);
Fixed Constant: par[0]=0.000536+-0.000712 par[1]=4.000000+-1.000000 par[2]=0.999884+-0.000125 par[3]=2.000070+-0.000123 par[4]=2.999910+-0.000127 par[5]=0.199920+-0.000130 chisquare=145.602523231222818
The fixed parameters can then be released by the ReleaseParameter method
delete lf;