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?
채택된 답변
Torsten
2024년 11월 14일
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에서 Systems of Nonlinear Equations에 대해 자세히 알아보기
참고 항목
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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)
