checkGradients, but the objective function has two inputs: x and xdata?
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I'm using lsqcurvefit with the following objective function and Jacobian:
function [f, jacF] = semiCircle(p, Q)
P0 = p(1);
Q0 = p(2);
r = p(3);
f = P0 + sqrt(r^2 - (Q-Q0).^2);
if nargout > 1 % need Jacobian
jacF = [1, (Q-Q0)./sqrt(r^2-(Q0-Q).^2), r./sqrt(r^2-(Q0-Q).^2)];
end
end
I'd like to use checkGradients to verify if the Jacobian is correct. However, all of the examples in the documentation just have objective functions with one input, the parameters 'x'. Whereas my function semiCircle has two inputs: the parameters 'p' and the xdata 'Q'. Is there a way to use checkGradients for such a function?
採用された回答
valid = checkGradients(@(p)semiCircle(p, Q),p0)
10 件のコメント
Many thanks, this seems to work.
From a seperate mistake, I had to modify the Jacobian a bit because there was an error with concatenating the arrays:
function [f, jacF] = semiCircle(p, Q)
P0 = p(1);
Q0 = p(2);
r = p(3);
f = P0 + sqrt(r^2 - (Q-Q0).^2);
if nargout > 1 % need Jacobian
jacF = zeros(length(Q), length(p));
for i = 1:length(Q)
jacF(i,:) = [1, (Q(i)-Q0)/sqrt(r^2-(Q0-Q(i))^2), r/sqrt(r^2-(Q0-Q(i))^2)];
end
end
This runs and the checkGradients returns logical 1 (true).
However, the code was running before even though the Jacobian was wrong. Also, the solution lsqcurve gives is the same whether or not 'SpecifyObjectiveGradient' is set to 'true'. This suggests that its somehow ignoring whether the gradient is specified or not. Do you have any insights regarding this?
If you specified a wrong Jacobian in the sense that you concatenated the arrays incorrectly, MATLAB should have thrown an error.
If you specified a wrong Jacobian in the sense that some elements were not computed correctly, it may happen that nonetheless the code is running and converging.
And it should be the case that whether you specify 'SpecifyObjectiveGradient' to be true or not, the solution MATLAB gives should be the same. What else do you expect in this case ?
When I concatenated the arrays incorrectly, MATLAB did not throw an error for lsqcurvefit. However, it did throw an error for checkGradients.
I expected that the answers would be similar, but maybe some slight differences. For fmincon, I tried with and without a Jacobian, and the answers were different in some cases (specifying the gradient tended to improve the solution).
When I concatenated the arrays incorrectly, MATLAB did not throw an error for lsqcurvefit. However, it did throw an error for checkGradients.
Does it throw an error if you don't check the gradients, but set 'SpecifyObjectiveGradient' to true ?
If it doesn't, lsqcurvefit does not recognize your analytical gradients.
Benjamin
2024 年 11 月 14 日
移動済み: Steven Lord
2024 年 11 月 14 日
Does it throw an error if you don't check the gradients, but set 'SpecifyObjectiveGradient' to true ?
No, it seems it does not throw an error for this.
That's strange and seems to indicate that "lsqcurvefit" does not use your analytical gradients. Can you supply the full code to test ?
Here's the code and attachments:
load('data.mat')
Vb_ll_rms = 690;
% Inital guess
p10 = 5e6;
p20 = 2.5e7;
p30 = 3e7;
p0 = [p10, p20, p30];
[Rls, Xls, Vgls, gradientCheck] = lsqcurvefitNLS(p0, Q, P, Vb_ll_rms)
Rls = 0.0024
Xls = 0.0238
Vgls = 689.9365
gradientCheck = logical
1
lsqcurvefirNLS calls lsqcurvefit with box and linear constraints, which in turn calls the semiCircle function. Rls, Xls, and Vgls are the estimated parameters, and gradientCheck verifies the objective gradient given.
Here, the code runs fine. However, in my desktop MATLAB it returns the following error:
Error using -
Too many output arguments.
Error in lsqcurvefit>@(X)feval(FUN,X,XDATA)-YDATA (line 237)
[xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = cnls(caller, @(X) feval(FUN, X, XDATA) - YDATA,...
Error in cnls/funExt (line 355)
[Fvec,JACOBIAN] = feval(FUN, Xk);
Error in cnls/objective (line 319)
[f,F] = funExt(xIn);
Error in cnls>@(x)objective(x,true) (line 188)
fungrad = @(x) objective(x, true);
Error in fmincon (line 598)
initVals.g = feval(funfcn{4},X,varargin{:});
Error in cnls (line 215)
[X,~,EXITFLAG,OUTPUT,LAMBDA] = fmincon({fun,fungrad},X(:),...
Error in lsqcurvefit (line 237)
[xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = cnls(caller, @(X) feval(FUN, X, XDATA) - YDATA,...
Error in lsqcurvefitNLS (line 19)
p = lsqcurvefit(@semiCircle, p0, Q, P, lb, ub, A, b, [], [], [], options);
Caused by:
Failure in initial objective gradient function evaluation. FMINCON cannot continue.
lsqcurvefit cannot continue.
This might be because there are square-root terms in the Jacobian/objective gradient which are maybe giving complex values:
jacF(i,:) = [1, (Q(i)-Q0)/sqrt(r^2-(Q0-Q(i))^2), r/sqrt(r^2-(Q0-Q(i))^2)]
However, the linear contraints are designed to prevent the solution from entering that region. And, the code seems to run here online without any problems.
I could try updating my MATLAB to the 2024b version?
Could you include the .m-files instead of the .mlx-files ?
I reached my daily uploads limit, so I'll just put the functions here:
load('data.mat')
Vb_ll_rms = 690;
% Inital guess
p10 = 5e6;
p20 = 2.5e7;
p30 = 3e7;
p0 = [p10, p20, p30];
[Rls, Xls, Vgls, gradientCheck] = lsqcurvefitNLS(p0, Q, P, Vb_ll_rms)
Rls = 0.0024
Xls = 0.0238
Vgls = 689.9365
gradientCheck = logical
1
function [R, X, Vg, gradientCheck] = lsqcurvefitNLS(p0, Q, P, Vo)
% Box constraints
p1_ub = min(P);
p2_lb = max(Q);
p3_lb = max(Q) - min(Q);
lb = [0, p2_lb, p3_lb];
ub = [p1_ub, inf, inf];
% Linear constraints
A = [0, 1, -1];
b = min(Q);
gradientCheck = checkGradients(@(p)semiCircle(p,Q),p0);
options = optimoptions('lsqcurvefit','Display','off','SpecifyObjectiveGradient',true);
p = lsqcurvefit(@semiCircle, p0, Q, P, lb, ub, A, b, [], [], [], options);
P0 = p(1);
Q0 = p(2);
r = p(3);
R = P0/(P0^2 + Q0^2)*Vo^2;
X = Q0/(P0^2 + Q0^2)*Vo^2;
Vg = sqrt(r^2/(P0^2 + Q0^2)*Vo^2);
end
And the other one:
function [f, jacF] = semiCircle(p, Q)
P0 = p(1);
Q0 = p(2);
r = p(3);
f = P0 + sqrt(r^2 - (Q-Q0).^2);
if nargout > 1 % need Jacobian
jacF = zeros(length(Q), length(p));
for i = 1:length(Q)
jacF(i,:) = [1, (Q(i)-Q0)/sqrt(r^2-(Q0-Q(i))^2), r/sqrt(r^2-(Q0-Q(i))^2)];
end
end
end
As you said: the code works fine with R2024b.
But note that the call to "lsqcurvefit" has changed in R2023a to the actual call that you use in the code. So if your desktop MATLAB version is older than R2023a, linear constraints (A,b) are not yet accepted.
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Matrix Indexing についてさらに検索
参考
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
