How to fit imposing some conditions?

12 ビュー (過去 30 日間)
Fc Fc
Fc Fc 2018 年 4 月 4 日
編集済み: Matt J 2018 年 4 月 13 日
Hi every one, I've a matlab program. In the program there is a call to an external program for the fit function. This is the external program
function [estimates, model] = fitcurvedemo(xdata, ydata)
% Call fminsearch with a random starting point.
global ckgraconv_n ckdian
global A lambda sse R2
start_point = rand(1,2);%%scegli un valore casuale per tutti i parametri
model = @fun;
estimates = fminsearch(model, start_point);
function [sse, FittedCurve] = fun(params)
A = params(1);
lambda = params(2);
FittedCurve =( A.*ckgraconv_n + lambda.*ckdian); %%picco gaussiano allargato
ymean = mean(ydata);
SS = ydata-ymean;
SSt =sum(SS.^2);
ErrorVector = FittedCurve - ydata;
sse = sum(ErrorVector .^ 2);
R2 = 1 - sse/SSt;
end
end
The y data are called ydata and the fit function is:
A.*ckgraconv_n + lambda.*ckdian
I must edit the fit so that the residual values are all positive, that is
(ydata-A.*ckgraconv_n - lambda.*ckdian)>0.
Then I must fit the data (finding A and lambda values) and imposing the condition
(ydata-A.*ckgraconv_n - lambda.*ckdian)>0.
I tried writing
function [sse, FittedCurve] = fun(params)
params=fminsearch(model,ydata-params(1).*ckgraconv_n - params(2).*ckdian>0);
A = params(1);
lambda = params(2);
but I get the error
Error using fminsearch (line 96)
FMINSEARCH accepts inputs only of data type double.
Error in fitcurvedemo/fun (line 11)
params=fminsearch(model,ydata-params(1)*ckgraconv_n - params(2)*ckdian>0);
Error in fminsearch (line 200)
fv(:,1) = funfcn(x,varargin{:});
Error in fitcurvedemo (line 8)
estimates = fminsearch(model, start_point);
Error in sp2sp3diff_Titantah (line 659)
[estimates, model] = fitcurvedemo(xdata,ydata);
Please, can someone help me? Best regards

採用された回答

Matt J
Matt J 2018 年 4 月 4 日
It is a linear fit, so lsqlin would be appropriate
C=[ckgraconv_n(:) , ckdian(:)];
d=ydata(:);
Aineq=C;
bineq=d;
solution=lsqlin(C,d,Aineq,bineq);
  12 件のコメント
Matt J
Matt J 2018 年 4 月 13 日
As Walter said, just use the options input to select a different algorithm
Fc Fc
Fc Fc 2018 年 4 月 13 日
編集済み: Matt J 2018 年 4 月 13 日
Thank you, I will try it! Please, can you help me also in this https://it.mathworks.com/matlabcentral/answers/394080-calculating-and-plotting-fwhm please?

サインインしてコメントする。

その他の回答 (3 件)

Walter Roberson
Walter Roberson 2018 年 4 月 7 日
You are passing in
ydata-params(1).*ckgraconv_n - params(2).*ckdian>0
In MATLAB, > has lower priority than the arithmetic operations, so this expression is
(ydata-params(1).*ckgraconv_n - params(2).*ckdian)>0
which is of data type logical.
If you want to check params(2).*ckdian and subtract 1 in the locations it is greater than 0, then you would use
ydata-params(1).*ckgraconv_n - (params(2).*ckdian>0)

Jeff Miller
Jeff Miller 2018 年 4 月 7 日
If you want to keep the residuals positive, trying building in an extra penalty for negative residuals. In your original model fun, for example, you might use:
sse = sum(ErrorVector .^ 2) + 1000*sum(ErrorVector(ErrorVector<0) .^ 2);
Seems like that would quickly drive fminsearch away from solutions that give any negative residuals.

Fc Fc
Fc Fc 2018 年 4 月 7 日
編集済み: Fc Fc 2018 年 4 月 11 日
Thank you both for your reply. @Walter
(ydata-params(1).*ckgraconv_n - params(2).*ckdian)>0
it is exactly what I must obtain. To understnand it, look my plot
Residuals are plotted by red line. As you can see, in the ranges [283;285] and [290.5;294] residuals are negative. Instead, I must obtain this plot
Here you can see that in all energy range, residuals (red line) are positive.
@Jeff I edited the fitcurvedemo.m file writing your code
sse = sum(ErrorVector .^ 2) + 1000*sum(ErrorVector(ErrorVector<0) .^ 2);
instead of sse = sum(ErrorVector .^ 2) but, as you can see by next plot, in this case I obtain negative residuals in most of the range.
Thanks
PS. About your comment
Seems like that would quickly drive fminsearch away from solutions that give any negative residuals.
To obtain positive residuals, It isn't my demand, but my supervisor ones...
  1 件のコメント
Jeff Miller
Jeff Miller 2018 年 4 月 7 日
Looks like I got the sign wrong and it should have been 1000*sum(ErrorVector(ErrorVector>0) .^ 2);

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLinear Least Squares についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by