Least squares fit to multiple differently-sized data sets simultaneously
조회 수: 12 (최근 30일)
이전 댓글 표시
I can use lsqcurvefit to simultaneously fit a system of non-linear equations using matrix arguments. However, I think the matrix requirement to have every element defined means that all data sets must be the same size? I can't find a way around that.
To make it clearer, if I make up some simple data sets which are the same size:
x=[1 3 5 7; 5 7 9 11; 9 11 13 15];
y=[10 11 12 13; 10 11 12 13; 10 11 12 13];
and want to fit each with a straight line, where they all share the same gradient (and so the solver must simulatenously fit that across all three data sets, but fit the individual offset to each set separately):
%variables v(1:4) are m, c1, c2, c3
fn = @(v,xdata)[v(1).*xdata(1,:) + v(2); v(1).*xdata(2,:) + v(3); v(1).*xdata(3,:) + v(4)];
I can set up a guess and solve using:
x0 = [1; 10; 9; 8];
fitvars = lsqcurvefit(fn,x0,x,y);
The problem comes when the data sets don't have the same number of points - if the second row of xdata and ydata only had three points, how do I pass the data to lsqcurvefit?
I've tried padding the matrices with NaN but then the objective function returns undefined numbers and the solver complains. I tried converting the data and the function to cell arrays to allow different lengths, but lsqcurvefit won't take it.
I'm aware this particular example can be solved trivially, but the real functions and data sets are non-linear (which explains why I'm using lsqcurvefit) and the system has a minimum of five data sets to solve with one shared variable between each function, as well as several unique variables and constants to each.
Thanks for any help.
댓글 수: 0
채택된 답변
John D'Errico
2016년 9월 2일
편집: John D'Errico
2016년 9월 2일
Yes. There is a way. Simply store the data in a cell array. Make the vectors COLUMN vectors. I was lazy here when I did that, using transposes.
x={[1 3 5 7]' [5 7 9 11]' [9 11 13 15]'};
y={[10 11 12 13]' [10 11 12 13]' [10 11 12 13]'};
yy = vertcat(y{;});
%variables v(1:4) are m, c1, c2, c3
fn = @(v,xdata) [v(1).*xdata{1} + v(2); v(1).*xdata{2} + v(3); v(1).*xdata(3,:) + v(4)];
x0 = [1; 10; 9; 8];
fitvars = lsqcurvefit(fn,x0,x,yy);
댓글 수: 5
John D'Errico
2022년 11월 4일
There are so many unspoken things in your question that I cannot easily answer you. Is this a LINEAR regression? Or a nonlinear regression, as the original question asked?
Do you really mean to compute the weights as you did?
weight1 = 1./(err1.^1); weight2 = 1./(err2.^2);
Note that weight1 only uses err1.^1, yet you are squaring the weights for weight2. Was that intentional, or a typo?
The original question was a complicated one, where some of the parameters are shared between models, but you did not seem to indicate that.
In fact, it looks like all you are asking to do is a weighted linear regression, perhaps of the form y=a*x+b, and to do it several times. As such, you could just use a loop, calling the function lscov each time, for each subproblem. (lscov is perhaps the simplest tool to perform a weighted regression, that I know you will have because it is not part of any toolbox.) Could you do that for all of the unknowns at once, in one big call? Well, yes, but that is surely more effort than you need, and unless you understand how to use sparse matrices, it would be inefficient.
Riccardo Marinelli
2022년 11월 5일
My situation was this: I needed to perform a simultaneous fit of seven curves with shared parameters since I didn't possess enough data to do many fits. I also desired to weight the fit as it is usually done on the squared inverse of the uncertainties
I found the aweseome custom function nlinmultifit() that allows me also to obtain easily the confidence interval of the fits, so yesterday I stuck with this function.
If you are interested, here is what I obtained with some made up data to make a test:![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1182008/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1182008/image.png)
추가 답변 (1개)
Qu Cao
2016년 8월 24일
The data sets should have the same number of points. The 'xdata' and 'ydata' should be well defined vetors or matrices.
참고 항목
카테고리
Help Center 및 File Exchange에서 Least Squares에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!