Technical Solutions
How can I use the LSQNONLIN function within the Optimization Toolbox to obtain the weighted least squares fit?
Date Last Modified: Friday, June 26, 2009
| Solution ID: |
|
1-18DGY |
| Product: |
|
Optimization Toolbox |
| Reported in Release: |
|
No Release |
| Platform: |
|
All Platforms |
| Operating System: |
|
All OS |
Subject:
How can I use the LSQNONLIN function within the Optimization Toolbox to obtain the weighted least squares fit?
Problem Description:
The LSQNONLIN and LSQCURVEFIT functions determine the least squares fit without weighting. I would like to introduce weights to the error used in the least squares fit.
Solution:
To use LSQNONLIN to do a weighted least square fit, you need an equation to which you want to fit your data. Below is a short example demonstrating how to use LSQNONLIN to obtain a weighted fit. First it creates a data set using two different equations, adding in some noise. Then it calls LSQNONLIN, using a handle to the nested function, MYCURVE. Finally, it plots the data and the fitted line. To run this example copy all the M-code below into a single file, save it as myFit.m, and then run the function MYFIT.
function myFit %% create the first half of the data xdata1 = 0:.01:1; ydata1 = exp(-3*xdata1) + randn(size(xdata1))*.05; weight1 = ones(size(xdata1))*1;
%% create the second half of the data % use a different function and with higher weights xdata2 = 1:.01:2; ydata2 = (xdata2-1).^2 + randn(size(xdata2))*.05; weight2 = ones(size(xdata2))*10;
%% combine the two data sets xdata = [ xdata1 xdata2 ]; ydata = [ ydata1 ydata2 ]; weight = [ weight1 weight2 ];
%% call |LSQNONLIN| parameter_hat = lsqnonlin(@mycurve,[.10 -1],[],[],[],xdata,ydata)
%% plot the original data and fitted function plot(xdata,ydata,'b.') hold on fitted = exp(parameter_hat(1).*(parameter_hat(2) +xdata)); plot(xdata,fitted,'r') xlabel('x'); ylabel('y') legend('Data', 'Fit')
%% function that reports the error function err = mycurve(parameter,real_x, real_y) fit = exp(parameter(1).*(real_x + parameter(2))); err = fit - real_y;
% weight the error according to the |WEIGHT| vector err_weighted = err.*weight; err = err_weighted; end
end
Comparing the fitted line with the original data, you will find that the second half of the data is fitted well, while the first half is not. Also note that the functional form of the model being used in MYCURVE is not the same function used to create the original data. However, an exponential can approximate a second order polynomial, over a small range, well enough.
Weighting the first half of the data set more than the second half would get LSQNONLIN to only fit the decaying exponential part (first part) of the data and not the polynomial. Getting LSQNONLIN to converge to the first half of the data might also require a change in the initial solution estimate as well.
For more information on how to use LSQNONLIN syntax, please refer to the Optimization Toolbox User's Guide. This User's Guide is available online and in PDF form for printing at the URL below:
http://www.mathworks.com/access/helpdesk/help/toolbox/optim/optim.shtml
|
|
|
|