I am trying to find a solution for a non-linear system in MATLAB using the fsolve function. I have an idea of the region the solution is, so my initial points are a random variation inside this area. The code follows:
%MATLAB parameters
digits = 32;
format shortEng
%Initialization of solving process
min_norm = realmax;
options = optimoptions('fsolve', 'Algorithm', 'trust-region-dogleg',...
'Display', 'off', 'FunValCheck', 'on', 'Jacobian', 'on',...
'DerivativeCheck', 'on');
%Solving loop
while 1
%Refreshes seed after 100000 iterations
rng('shuffle');
for n=1:100000
%Initial points are randomly placed in solving region
x_0 = zeros(1, 3);
x_0(1) = 20*(10^-3)+ abs(3*(10^-3)*randn);
x_0(2) = abs(10^(-90) + 10^-89*randn);
x_0(3) = abs(10*randn);
%Solving
[x, fval] = fsolve(@fbnd, x_0, options);
norm_fval = norm(fval);
%If norm is minimum, result is displayed
if all(x > 0.0) && (norm_fval < min_norm)
iter_solu = x;
display(norm_fval);
display(iter_solu);
min_norm = norm_fval;
end
end
end
The function to be optimized and its jacobian follow:
function [F, J] = fbnd(x)
F(1) = x(1) - x(2)*(exp(7.56/(1.5*0.025))-1);
F(2) = x(1) - x(2)*(exp((x(3)*0.02)/(1.5*0.025))-1)-0.02;
F(3) = x(1) - x(2)*(exp((6.06+x(3)*0.018)/(1.5*0.025))-1)-0.018;
J = [[1.0, -3.5790482371355382991651020082214*10^87, 0.0];...
[1.0, 1.0-exp((8/15)*x(3)),-(8/15)*x(2)*exp((8/15)*x(3))];...
[1.0, 1.0-exp(0.48*x(3)+161.6), -0.48*x(2)*exp(0.48*x(3)+161.6)]];
end
When I turn DerivativeCheck on, I get the following error:
Objective function derivatives:
Maximum relative difference between user-supplied
and finite-difference derivatives = 1.
User-supplied derivative element (1,1): 1
Finite-difference derivative element (1,1): 0
For some reason, it things dF(1)/dx(1) should be zero instead of 1, when it is obvious it is 1. So I went ahead and replaced the J(1,1) by 0, and now I get the same problem with J(3,1):
Objective function derivatives:
Maximum relative difference between user-supplied
and finite-difference derivatives = 1.
User-supplied derivative element (3,1): 1
Finite-difference derivative element (3,1): 0
So, I replaced J(3,1) by 0 and it catches only minor precision errors. Is there an explanation why it thinks J(1,1) and J(3,1) should be zero? It seems really strange to me.