# poly fit for n=1 and 2

The current fit usage for a polynomial curve fit in Igor starts at order n=3 (quadratic).  This seems reasonable since there is a line fit that handles orders 1 and 2 (constant and line).

However, I have applications where I want to systematically investigate polynomial fits of different orders, starting at n=1.  It's a pain to have to write a program for the two classes of cases (n=1,2 and n=3, ... 20).  Is it possible to amend the code to allow this usage?  I note that poly(coefs,x) allows the n=1,2 cases.

___________________________________________

From the help file:

poly n    Polynomial: y = K0+K1*x+K2*x^2+...
n  is from 3 to 20. n is the number of terms or the degree plus one.
poly_XOffset n    Polynomial: y = K0+K1*(x-x0)+K2*(x-x0)^2+...
n  is from 3 to 20. n is the number of terms or the degree plus one.

As a quick thought: Why not create one master function call that runs the fit function(s) and saves the results after each time? Something akin to this ...

Function MyMasterFit(nmin,nmax)
variable nmin, nmax

variable ic
string fitresults
string fitsigmas

for (ic=nmin;ic<nmax;ic+=1)
switch(ic)
case 1:
... do line fit
...
case 2:
... do line fit
...
default:
... do poly fit
...
endswitch
fitresults = "results" + num2str(ic)
fitsigmas = "sigmas" + num2str(ic)
duplicate/O ... // move fit results to new storage
duplicate/O ... // move fit sigmas to new storage
endfor
return 0
end

This isn't so different from what has already been discussed, but I think you could also using Curvefit poly 3 to fit a constant or a line:

make/o/d/n=(3) coefs = {0,0,0}; curvefit/H="011" poly 3, kwCWave=coefs, waveToFit       //only allow K0 to vary, fitting a constant f(x) = K0
make/o/d/n=(3) coefs = {0,0,0}; curvefit/H="001" poly 3, kwCWave=coefs, waveToFit       //only allow K0 and K1 to vary, fitting a line f(x) = K0 + K1*x

You could also look into a user-defined fit function (displayHelpTopic "FuncFit"), where the poly(coefs,x) function would work nicely for building a polynomial fit function that can take 0 to any number of terms. I think there would be a (potentially severe) downside, which is that you would have to supply your own initial guesses.

Thanks, jjweimer and gsb, for the suggestions.  Yes, one can use switch to select cases or Curvefit poly 3 to fit a constant or line, but I want to loop over all orders (up to n=20, the highest allowed).  These solutions require code to handle n=1 and 2, and I was hoping to eliminate such special-case coding.  Admittedly, the need comes from an unusual application (comparing AIC and BIC model-selection criteria), but I also see no reason why poly couldn't (or shouldn't) handle the n=1,2 cases.  (The line-fit option obviously shouldn't go away, either.  One can have multiple ways of doing things.)

A user-defined function wouldn't use the same solver code (presumably based on the normal equations), meaning that the fit can end up in a local minimum -- so that is not a good solution here, either.

I’m lost on the problem you are trying to solve and/or why you believe that switching functions will change the answer.

Do this test: Do a fit to a line n=1 and then do a fit to the polynomial but hold the first coefficients at zero. The answers should be the same.

Another option is to write your own fitting function that selects the polynomial term.

You can use a user-defined function based on the poly() function. It will use the iterative nonlinear fitter, of course, which will almost certainly take longer. There are no local minima when fitting a function that is linear in the coefficients, so that's not a problem. And since the chi-square surface is truly quadratic for a linear function, you don't need good initial guesses. All 1's should work for anything, as long as it doesn't result in some sort of overflow (possibly the residuals, and therefore the Hessian matrix could be wonky if you're fitting data that has huge numbers).

I will consider your request for Igor 9. We're technically in feature freeze, though, so no promises. In fact, the poly2d fit function allows order=1. Can't recall if it accepts order=0, though.