user-defined curve fit minimisation function
masheroz
Is there a way to define your own minimisation equation when fitting an arbitrary function to some data?
Further to this, can I use the in-built spline package to generate a curve, and then optimise the knots to minimise my custom minimisation equation?
.
I have many 1D datasets that consists of (x, D, e) - an x-ordinate, the Data, and error in the data. There are about 2800 points per dataset
I want to generate a background function, B. I would like this to be a spline with ~20 knots. The x-ordinates are spaced evenly through the above data, and don't change (at this point in time). I can generate some initial guesses for the background function to give a starting point.
I calculate a value, z=(D-B)/e, for each data point
I calculate a value f(z) = If(z<= 0, z^2, 6 Ln((2 z/Sqrt(Pi)) Erf(z/Sqrt(2)))).
I want to minimise Sqrt(Sum(f(x)^2)) by altering the y-value of the spline knots (and possibly the x-values, but at a later stage).
July 22, 2015 at 12:09 am - Permalink
July 22, 2015 at 12:15 am - Permalink
A question about your cost function:
You state that the cost function _must_ be of the form: costFunc(coefs, y_obs, y_calc, s_obs).
Are these waves used anywhere else? In your Chi2 example given in the explanation of /MINF=costFunc, you didn't use coefs. Is that just happenstance, or is coefs used somewhere else?
July 22, 2015 at 05:21 pm - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
July 22, 2015 at 09:01 am - Permalink
I looked at that but couldn't find a way to use my own cost function (in gencurvefit-speak).
Is there a way to do that?
July 22, 2015 at 05:23 pm - Permalink
Your cost function must be of that type. coefs is supplied to that function, but you don't have to use the wave if you don't want to. I send coefs to the costfunction because sometimes I want to include the overall cost to include a Lagrangian multiplier term which is calculated using the values in coefs.
July 22, 2015 at 07:24 pm - Permalink
See the discussion of Optimize in the help:
DisplayHelpTopic "Finding Minima and Maxima of Functions"
The function you pass to Optimize is the cost function (or "object function" in Optimization-speak". But to do a curve fit using Optimize, you need to look up the data waves, compute a model, and then compute some figure of merit for the model.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
July 23, 2015 at 01:05 pm - Permalink
Now I'm confused; I think it's just the nomenclature.
I've attached some data that I've mocked up, and I've made all the waves as dependent waves so you can manually change the coefficients and everything flows through.
There is some data, D, to which I want to fit a linear background, B, where each datapoint has an associated error, e.
Once I have an initial guess at B, I can calculate z = (D-B)/e.
I then calculate the piecewise function f(z) = z^2 (z<=0), 6*ln(((2*z)/(sqrt(Pi)*erf(z/sqrt(2)))))-3*ln(2) (z>0)
I can now calculate sum(f(z)).
I want to minimise the value of sum(f(z)) by altering the coefficients of my linear background.
I don't want to minimise the normal chisq, as that will give the wrong answer.
How can I set this up?
July 30, 2015 at 12:46 am - Permalink
I've got it working with gencurvefit.
function linear(coefs, x)
wave coefs
Variable x
return (coefs[0] + coefs[1]*x)
end
//the function that I want to minimise:
function costFunc(coefs, y_obs, y_calc, s_obs)
wave coefs, y_obs, y_calc, s_obs
make/o/n=(numpnts(y_obs))/free/d z_val, f_of_z
z_val = ((y_obs - y_calc) / s_obs)
f_of_z = (z_val^2)*(z_val<=0) + (6*ln(((2*z_val)/(sqrt(Pi)*erf(z_val/sqrt(2)))))-3*ln(2))*(z_val>0)
return sum(f_of_z)
end
//the command to do the curve fitting:
Gencurvefit /MINF=costFunc /W=w_e /I=1 /X=w_x linear, w_D, w_coef, "00", coef_lim
This gives the output:
Fitting: w_D to linear
V_fitIters = 20; V_Chisq = 134.896; V_npnts= 31; V_nterms= 2; V_nheld= 0; V_logBayes = -5.62338
w[0] = 346.215 +/- 11.4106
w[1] = 9.91953 +/- 2.12009
where V_Chisq is the value of my costfunc.
It matches quite nicely to my excel minimisation of 346.1406 and 9.920222, with sum(f(z))= 134.8954.
Now just to expand it to fitting splines in 2D!
July 30, 2015 at 06:09 pm - Permalink