Skip to Main Content Skip to Search
Home |   Select Country  Choose Country  |  Contact Us  |  Cart Store 
Create Account | Log In
Products & Services Solutions Academia Support User Community Company
spacer spacer spacer spacer spacer spacer

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

Please provide feedback to help us improve this Solution
Contact support
E-mail this page
Print this page