CURVEFIT Function
Non-linear least squares fit to a function of an arbitrary number of parameters. The function may be any non-linear function where the partial derivatives are known or can be approximated.
Usage
result = CURVEFIT(x, y, wt, parms, [sigma])
Input Parameters
x—A vector of independent variables.
y—A vector of dependent variable, same length as x.
wt—A vector of weights, same length as x. For no weighting set wt(i) = 1.0, for instrumental weighting wt(i) = 1./y(i), etc.
parms—On input, a vector containing the initial estimates of the parameters. The length of params must equal the number of parameters in the function that is trying to be fit to the x,y data.
Output Parameters
parms—A vector of the calculated parameters of the fitted function.
sigma—(optional) A vector of standard deviations of the parameters.
Returned Value
result—A vector of fitted dependent variable values.
Keywords
None.
Discussion
CURVEFIT uses a nonlinear least-squares method to fit an arbitrary function in which the partial derivatives are known or can be approximated. This is in contrast to linear least-squares fitting methods that would require their fitting functions to be linear in their coefficients.
The initial estimates of parms should be as close to the actual values as possible or the solution may not converge. CURVEFIT performs iterations of the fitting function until the chi-squared value for the goodness of fit changes by less than 0.1 percent, or until 20 iterations are reached.
 
note
These initial estimates for parms can be calculated from the result of the POLY_FIT function when it is used to fit a straight line through data.
The function to be fit must be defined and called with FUNCT.
CURVEFIT is modified from the program CURFIT found in Data Reduction and Error Analysis for the Physical Sciences, by Philip Bevington, McGraw-Hill, New York, 1969. It combines a gradient search with an analytical solution developed from linearizing the fitting function. This method is termed a “gradient-expansion algorithm.”
Weighting Factor
Weighting is useful when you want to correct for potential errors in the data you are fitting to a curve. The weighting factor, wt, adjusts the parameters of the curve so that the error at each point of the curve is minimized.
wt can have any value, as long as its size is correct. Some possible ways to weight a curve are suggested below (where i is an index into y, the vector of Y values):
*For statistical weighting, use wt = 1/yi
*For instrumental weighting, use wt = 1/(Std dev of yi)
*For no weighting, use wt = 1
*Statistical Weighting—Statistical weighting is useful when you arrived at your dependent values by measuring a number of discrete events with respect to the independent variable, such as counting the number of cars passing through an intersection over 10-minute intervals.
*Instrumental Weighting—Instrumental weighting is useful when you are measuring things from a scale, such as length, mass, voltage, or current, and you suspect that unequal errors have been introduced into the data by the measuring device. For example, if an ohm meter has three different scales (one for 0 to 1 ohm, one for 2 to 99 ohms, and one for 100 ohms or more), the weighting factor would be the same for each measurement taken with the same scale.
 
note
In most cases, you would use a different weighting factor for each scale or instrument that was used to measure your original data.
*No Weighting—If you feel that fluctuations in your data are due to instrument error but that the uncertainties of the measuring device used are equal for all the data collected, you would probably specify no weighting (wt = 1).
Example
Save these code blocks as curvefit_example.pro. Once saved, enter curvefit_example at the PV-WAVE prompt to execute the example. Note the zoom window functionality when mousing over the plot window, serving as a visual comparison of the polynomial versus user-function fit to the x,y data.
PRO FUNCT, x, p, f, dfdp
   ; Define f = F(X,P), the function of x and three parameters 
   ; that should be fit to the x,y data 
   f = p(0)*EXP(-(((x-p(1))/p(2))^2)/2) 
   ; Define the derivative dF/dP
   dFdP = [[EXP(-(((x-p(1))/p(2))^2)/2)],  $ 
      [p(0)*EXP(-(((x-p(1))/p(2))^2)/2)*(x-p(1))/p(2)^2],  $
      [p(0)*EXP(-(((x-p(1))/p(2))^2)/2)*(x-p(1))^2/p(2)^3]]
END
 
; In this example, the y-data is coming from a known equation
; of three parameters, f = p(0)*EXP(-(((x-p(1))/p(2))^2)/2) 
; where p0=2, p1=3, p2=4. This function is also what will be
; fit to the x,y data. Thus, CURVEFIT should return the output
; parameter p with p(0)=2, p(1)=3, and p(2)=4.
PRO curvefit_example
   ; Define independent and dependent data to fit function to.
   x = FINDGEN(601)/100
   y = 2*EXP(-(((x-3)/4)^2)/2) 
   ; Create a vector of weights, all with a value equal to 1 
   w = FLTARR(601) + 1
   ; Fit second degree polynomial to data. The returned 
   ; polynomial coefficients serve as the initial guess for the
   ; curve fit. 
   p = POLY_FIT(x, y, 2, yft)
   p = [p(0), p(1), p(2)]
   yfit = CURVEFIT(x, y, w, p)
   ; Set up PLOT colors and fonts, and plot every 20th data point.
   TEK_COLOR
   oldFont = !P.font
   !P.font = 0
   subset = INDGEN(30)*20
   PLOT, x(subset), y(subset), Thick=2, Psym=1, $
      Yrange=[MIN(y)-.05,MAX(y)+.05], /Ynozero, $
      Charsize=1.1, Title='Data Points To Fit With F(x,p) =' $
      + 'p!D0!N*e!U-(((x-p1)/p2)!S!E2!R )/2!N'
   ; Overplot the 2nd degree polynomial fit.
   OPLOT, x, yft, Color=WoColorConvert(3)
   ; Overplot curve fit, where curve fit to data was defined in 
   ; the FUNCT function definition above.
   OPLOT, x, yfit, Color=WoColorConvert(2)
   ; Create a legend for the plot. 
   XYOUTS, 0.20, 0.85, '-- 2nd degree polynomial fit', /Normal, $
      Color=WoColorConvert(3)
   p0 = STRTRIM(STRING(p(0), Format='(F3.1)'), 2)
   p1 = STRTRIM(STRING(p(1), Format='(F3.1)'), 2)
   p2 = STRTRIM(STRING(p(2), Format='(F3.1)'), 2)
   XYOUTS, 0.20, 0.80, '-- F(x, p) fit with p0='+p0+$
      ',p1='+p1+', p2='+p2, /Normal, Color=WoColorConvert(2)
   ; Use zoom window to compare polynomial fit to user-function fit.
   ZOOM, /Continuous, Xsize=200, Ysize=200
   !P.font = oldFont
END
See Also