user-defined curve fit minimisation function

Hi all

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).
Looks not too bad Andy!

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?

Hi John

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?
masheroz wrote:

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?


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.

masheroz wrote:
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?

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
Hi John

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?
linearFitDemot.pxp (21.58 KB)
and of course, as soon as I ask for help, the light bulb comes on!

I've got it working with gencurvefit.

//the function that I want to fit to my data:
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:
Genetic Optimisation Successful
  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!