101 lines
2.2 KiB
Matlab
101 lines
2.2 KiB
Matlab
|
|
badscale = 1e-10;
|
|
|
|
% Create random Jacobian
|
|
A = [
|
|
badscale.*(rand(3)-.5) zeros(3) zeros(3,6)
|
|
zeros(3) (rand(3)-.5) zeros(3,6)
|
|
badscale.*(rand(2,6)-.5) zeros(2,6)
|
|
zeros(2,6) badscale.*(rand(2,6)-.5)
|
|
eye(6) -eye(6)
|
|
];
|
|
b = [
|
|
repmat(badscale, 3,1)
|
|
repmat(1, 3,1)
|
|
repmat(badscale, 2,1)
|
|
repmat(badscale, 2,1)
|
|
repmat(1, 6,1)
|
|
];
|
|
|
|
% Solve with MATLAB
|
|
x_true = A \ b;
|
|
|
|
% Form Hessian
|
|
L = A'*A;
|
|
l = A'*b;
|
|
|
|
% Eliminate badly-conditioned system. Use this custom choleskyNaive function
|
|
% that does no internal pivoting or scaling to simulate the case where the
|
|
% bad conditioning occurs between fronts.
|
|
R = choleskyNaive(L);
|
|
if isempty(R)
|
|
fprintf('Cholesky failed on badly-scaled system with a negative pivot\n');
|
|
else
|
|
clear opts
|
|
opts.LT = true;
|
|
d = linsolve(R', l, opts);
|
|
|
|
% Solve badly-conditioned system.
|
|
clear opts
|
|
opts.UT = true;
|
|
x = linsolve(R, d, opts);
|
|
|
|
% Compute error
|
|
fprintf('Solution error with Cholesky on badly-scaled system: %g\n', ...
|
|
max(abs(x - x_true)));
|
|
end
|
|
|
|
% Form scaled system from Jacobian
|
|
%Si = full(qr(sparse(A)));
|
|
%Si = diag(sqrt(diag(L)));
|
|
S = [
|
|
eye(6) zeros(6)
|
|
eye(6) eye(6) ];
|
|
Ap = A * S;
|
|
Lp = Ap'*Ap;
|
|
lp = Ap'*b;
|
|
|
|
% Eliminate scaled system
|
|
Rp = choleskyNaive(Lp);
|
|
if isempty(Rp)
|
|
fprintf('Cholesky failed on scaled system with a negative pivot\n');
|
|
else
|
|
clear opts
|
|
opts.LT = true;
|
|
dp = linsolve(Rp', lp, opts);
|
|
|
|
% Solve rescaled system.
|
|
clear opts
|
|
opts.UT = true;
|
|
xp = S * linsolve(Rp, dp, opts);
|
|
|
|
% Compute error
|
|
fprintf('Solution error with Cholesky from rescaled Jacobian: %g\n', ...
|
|
max(abs(xp - x_true)));
|
|
end
|
|
|
|
|
|
% Form scaled system from Hessian
|
|
Lph = S' * (L * S);
|
|
lph = S' * l;
|
|
|
|
% Eliminate scaled system
|
|
Rph = choleskyNaive(Lph);
|
|
if isempty(Rph)
|
|
fprintf('Cholesky failed on scaled system with a negative pivot\n');
|
|
else
|
|
clear opts
|
|
opts.LT = true;
|
|
dph = linsolve(Rph', lph, opts);
|
|
|
|
% Solve rescaled system.
|
|
clear opts
|
|
opts.UT = true;
|
|
xph = S * linsolve(Rph, dph, opts);
|
|
|
|
% Compute error
|
|
fprintf('Solution error with Cholesky from rescaled Hessian: %g\n', ...
|
|
max(abs(xph - x_true)));
|
|
end
|
|
|