lsqnonlin - error in finite differences, arrays of incompatible size
2 views (last 30 days)
Show older comments
Astrid Barzaghi
on 17 Jun 2023
Commented: Astrid Barzaghi
on 17 Jun 2023
I am trying to use lsqnonlin as a batch processor
This is the code I wrote (relevant parameters such as xx0_1_ok, T, rho_meas, t_eval and such are defined in previous portion of the code)
%% Batch processor
% Initial conditions
xx0_1_noise = xx0_1_ok + randn(size(xx0_1_ok)).*0.01.*xx0_1_ok;
xx0_2_noise = xx0_2_ok + randn(size(xx0_2_ok)).*0.01.*xx0_2_ok;
x_hat = lsqnonlin(@(x) batch_fun(x, T, rho_meas, t_eval), [xx0_1_noise xx0_2_noise]);
function F = batch_fun(x, T, rho_meas, t_eval_rho)
LU = astroConstants(7); %Transform from [LU] to [km]
TU = 2 * pi * 27.321661 * 24 * 60 * 60; %Transform from [TU] to [s]
options = odeset('Reltol',1.e-13,'Abstol',1.e-20);
% Propagate
sol1 = ode113(@CRTBP, [0 T], x(1:6), options);
t_1 = sol1.x;
sol2 = ode113(@CRTBP, [0 T], x(7:12), options);
t_2 = sol2.x;
% Evaluate orbits at same instants of time
if length(t_1) > length(t_2)
t_eval = t_1;
x2 = deval(sol2, t_eval);
x2(1:3,:) = x2(1:3,:) * LU;
x2(4:6, :) = x2(4:6,:) * LU / TU;
x1(1:3,:) = sol1.y(1:3,:) * LU;
x1(4:6,:) = sol1.y(4:6,:) * LU / TU;
else
t_eval = t_2;
x1 = deval(sol1, t_eval);
x1(1:3,:) = x1(1:3,:) * LU;
x1(4:6, :) = x1(4:6,:) * LU / TU;
x2(1:3,:) = sol2.y(1:3,:) * LU;
x2(4:6,:) = sol2.y(4:6,:) * LU / TU;
end
% Interpolate measurements at instants of time of iteration
rho_meas_iter = interp1(t_eval_rho, rho_meas, t_eval, "linear");
F = sqrt(dot(x1(1:3,:)-x2(1:3,:), x1(1:3,:)-x2(1:3,:))) - rho_meas_iter;
end
function [xx0_out, T0_out] = halo(xx0, T0)
%--------------------------------------------------------------------------
% Finds initial conditions for CRTBP in the Earth-Moon system
% Prototype: [xx0_out, T0_out] = halo(xx0, T0)
% Input:
% xx0 - [6x1] initial guess in position and velocity of orbit
% T0 - initial guess for period of orbit
% Output:
% xx0_out - [6x1] correct initial conditions in position and velocity of orbit
% T0 - correct period of orbit
%--------------------------------------------------------------------------
%% Initialization
eps = 1e-10;
iter = 1;
Fnorm = 1;
mu = 0.012150584269940;
%Set initial conditions for first integration
% Exact guess
% xx0 = [0.987582486032319, 0, 0.005261320588633, 0, 2.123290002593113, 0]; %NRHO
% T0 = 1.395647230407869;
% xx0 = [1.097286086652747, 0, 0.053070202898073, 0, 0.241115522202103, 0]; %Halo
% T0 = 3.358019851591808;
% xx0 = [0.434372438333557, 0, 0, 0, 1.423278979058999, 0]; %DRO
% T0 = 6.095332268294693;
% xx0 = [1.076513567928299, 0, 0, 0, 0.390404931659456, 0]; %Lyapunov
% T0 = 3.604707326612602;
I = eye(6);
x0 = [xx0 I(1,:) I(2,:) I(3,:) I(4,:) I(5,:) I(6,:)]';
%% Refine initial condition
while Fnorm > eps && iter < 10
tspan = [0 T0/2];
options = odeset('Reltol',1.e-13,'Abstol',1.e-20);
[~, state] = ode45(@CRTBP_STM, tspan, x0, options);
x = state(end, 1:6)';
STM = [state(end, 7:12); state(end, 13:18); state(end, 19:24); state(end, 25:30); state(end, 31:36); state(end, 37:42)];
F = [x(2); x(4); x(6)];
Fnorm = norm(F);
r1 = sqrt((x(1) + mu)^2 + x(2)^2 +x(3)^2);
r2 = sqrt((x(1) + mu - 1)^2 + x(2)^2 + x(3)^2);
ddx = x(1) - (1 - mu) * (x(1) + mu) / r1^3 - mu ...
* (x(1) + mu - 1) / r2^3 + 2 * x(5);
ddz = ((mu - 1) / r1^3 - mu / r2^3) * x(3);
DF = [STM(2,1) STM(2,5) STM(2,6) x(5);
STM(4,1) STM(4,5) STM(4,6) ddx;
STM(6,1) STM(6,5) STM(6,6) ddz];
%Correct
Xold = [x0(1) x0(5) x0(6) T0]';
invDF = (DF * DF') \ F;
Xnew = Xold - DF' * invDF;
x0(1) = Xnew(1);
x0(5) = Xnew(2);
x0(6) = Xnew(3);
T0 = Xnew(4);
iter = iter + 1;
end
xx0_out = x0(1:6);
T0_out = T0;
end
lsqnonlin seems to do a few iterations of the objective function F however in 2 or 3 iterations it returns the following error
Arrays have incompatible sizes for this operation.
Error in finitedifferences
Error in computeFinDiffGradAndJac
Error in sfdnls (line 54)
computeFinDiffGradAndJac(x,funfcn,confcn,valx, ...
Error in snls (line 165)
[A,findiffevals] = sfdnls(xcurr,fvec,Jstr,group,alpha,funfcn,l,u,...
Error in lsqncommon (line 179)
snls(funfcn,xC,lb,ub,flags.verbosity,options,defaultopt,initVals.F,initVals.J,caller, ...
Error in lsqnonlin (line 260)
lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,optimgetFlag,caller,...
Error in main (line 83)
x_hat = lsqnonlin(@(x) batch_fun(x, T, rho_meas, t_eval), [xx0_1_noise xx0_2_noise]);
Can you help me find out why? Thanks!
2 Comments
Accepted Answer
Torsten
on 17 Jun 2023
Edited: Torsten
on 17 Jun 2023
The size of your problem changes in the course of the computation from 685 to 650 functions to be minimized (see above). This will make "lsqnonlin" throw an error.
The size of the F-vector returned from "batch_fun" must remain the same.
You shouldn't use interpolation as
% Interpolate measurements at instants of time of iteration
rho_meas_iter = interp1(t_eval_rho, rho_meas, t_eval, "linear");
F = sqrt(dot(x1(1:3,:)-x2(1:3,:), x1(1:3,:)-x2(1:3,:))) - rho_meas_iter
The way to handle the problem is to force the ODE integrator to output the solution exactly at the times specified in your measurement vector t_eval_rho. For this end - instead of using [0 T ] as the tspan in the calls to ode113 - use t_eval_rho. As a consequence, you don't need to use interpolation, but you can explicitly return
F = sqrt(dot(x1(1:3,:)-x2(1:3,:), x1(1:3,:)-x2(1:3,:))) - rho_meas
More Answers (0)
See Also
Categories
Find more on Execution Speed in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!