Forcing linear fit though points is not working

_ROOT Version: 6.28.06
_Platform: Windows
Compiler: Not Provided

Hello,
I’m trying to force an 2D Fit function though two points by using different error weights. It is not working:
see this simple example:

float flat(const float x, const float y, const float mx, const float my, const float z) {
	return z + mx*x + my*y;
}

Double_t flat(Double_t *val, Double_t *par) {
	Float_t x = val[0];
	Float_t y = val[1];
	Float_t mx = par[0];
	Float_t my = par[1];
	Float_t z0 = par[2];
	Double_t f = flat(x,y,mx,my,z0);
	return f;
}


int simple() {
	
TGraph2DErrors *gr = new TGraph2DErrors();
gr->SetPoint(0,0,0,50);
gr->SetPointError(0,1e-64,1e-64,1e-64); //SMALL ERROR
gr->SetPoint(1,0,10,52);
gr->SetPointError(1,1e-64,1e-64,1); //BIG ERROR
gr->SetPoint(2,10,0,53);
gr->SetPointError(2,1e-64,1e-64,1); //BIG ERROR
gr->SetPoint(3,10,10,55);
gr->SetPointError(3,1e-64,0.1e-64,1e-64); //SMALL ERROR

TF2 *test1 = new TF2("test1",flat,0,10,0,10,3);
test1->SetParNames("mx","my","z0");


TCanvas *c1 = new TCanvas("c1","c1",1200,800);
gr->Draw("p0");

gr->Fit("test1");
test1->Draw("surf1 same");

std::cout << "SHOULD BE SMALL: " << 50 - test1->Eval(0,0) << std::endl;
std::cout << "SHOULD BE SMALL: " << 55 - test1->Eval(10,10) << std::endl;
std::cout << "SHOULD BE BIGGER: " << 52 - test1->Eval(0,10) << std::endl;
std::cout << "SHOULD BE BIGGER: " << 53 - test1->Eval(10,0) << std::endl;



return 0;
}

output is:

Processing .\simple.C...
Warning in <Fit>: Abnormal termination of minimization.
 FCN=8.92772e+129 FROM MIGRAD    STATUS=FAILED        111 CALLS         112 TOTAL
                     EDM=9.64161e+127    STRATEGY= 1      ERR MATRIX APPROXIMATE
  EXT PARAMETER                APPROXIMATE        STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  mx           4.05000e+00   2.69095e-70  -0.00000e+00  1.13493e+129
   2  my           1.70372e+00   1.85692e-70  -0.00000e+00  1.05757e+134
   3  z0           4.62743e-09   9.76288e-74   0.00000e+00 -3.55675e+128
SHOULD BE SMALL: 50
SHOULD BE SMALL: -2.53718
SHOULD BE BIGGER: 34.9628
SHOULD BE BIGGER: 12.5

Thanks for your hints
Georg

Hi Georg,

Thanks for this post.
I wonder if this is caused by the very small errors set for your points: does the nature of the problem you are treating allow to perhaps relax them?

Cheers,
Danilo

Hi, when replacing 1e-64 by 1e-3 the same error occurs.
to force the fit function through two points was a quick idea instead of doing real arithmetics to solve this problem. I thought it would be easier. Anyhow it should work :slight_smile:

Georg

Thanks for your proactiveness and for sharing the experience!

Sorry- but there is still no solution…
Is this a bug?

Georg

Georg,

Your code is a numerical and syntactical challenge: floats, doubles all mixed up. Fitting 3 parameters to 4 data points and then making the fit non-linear by setting ex and ey to non-zero values. Setting ex and ey infinitely small for the “BIG ERROR” data point did not help.

Just do

gr->SetPointError(0,0,0,1e-64)

instead of

gr->SetPointError(0,1e-64,1e-64,1e-64)

etc.

and you get what you expect.

-Eddy

Hi Eddy,
thank you very much.

Changing the SetPoint Error works pretty well for the surface fit.
Anyhow I also tried it with a more complicated fit function (I used a spherical fit), and it caused strange results.

Finally, found out that your other statement - the thing with the doubles and floats - is very relevant, too.
I do not know why, but it works pretty find for my spherical fit too, when changing everything to Double_t

Thanks a lot for your help
Georg

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.