Is there any way in ROOT to fit an “implicit function” to data points with errors?
This question is related to a case in which, I guess, one would need to fit a function in form:
I - (V - I * Rs) / Rp = Is * (std::exp((V - I * Rs) / (n * Vth)) - 1.)
The above function is a non-ideal I-V characteristic of a p-n junction diodes, where “Is” (a scale current), “Rs” (a parasitic series resistance), “Rp” (a parasitic parallel resistance) and “n” (an ideality factor) are the parameters of the function which need to be found by the fit and “Vth” (a thermal voltage) is just a constant (around 25.852 mV @ 300 K). One can choose x = V and y = I (that’s how these characteristics are usually drawn in the literature) or x = I and y = V (that’s what is used in the original thread). Note that the “experimental data” can have errors in both variables (i.e. “V” and “I”).
Using a TGraphErrors with both errors on x and y should work in this case.
Otherwise one can try to fit the data points using a defined implicit function, and computing the 2d distance between points and error and weight that distance with the projected errors.
For this case one needs to write the least square function directly.
A similar (but simpler) example is provided in https://root.cern.ch/doc/master/line3Dfit_8C.html
In this case one fits a 3D object with a 2d function, but the concept is similar, although one would need to consider the point errors
The problem with an implicit function is that it is given by an equation F(x,y)=0 (let’s restrict to a two-dimensional case) and, in general, it cannot be rewritten into a simple explicit form y=f(x) nor x=f(y) so, no TF1 exists, which one could use to fit a TGraphErrors.
If one wants to use some standard minimizer, it is not really obvious how the “chi^2” should be defined. Well, one could simply sum up terms std:abs(F(x,y)) or std::pow(F(x,y), 2.) (for all “experimental data points”) but it is not obvious how to properly take the errors in “x” and “y” into account.