Solve a non-linear system of equations with differentiation in Matlab

172 Views Asked by At

I would like to solve a system of non-linear equations in Matlab with fsolve, but I also have to differentiate the functions with respect to two variables. Here is the problem in steps:

Step 1: I define the system of non-linear functions F:

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

end

Step 2: I want to find the derivative of F(1) with respect to x(1) and the derivative of F(2) with respect to x(2) such that:

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1))
f1_d=diff(F(2),x(2))

end

Step 3: I want my function to be the original one plus the derivative:

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));

F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;

end

Step 4: In the main file I would use this function with fsolve to solve the system of non-linear equations for x(1) and x(2):

syms x
fun = @root2d;
x0 = [0,0];
x = fsolve(fun,x0);
root2d(x)


function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));

F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;
end

Can you please help me, how can a rewrite my code in order to solve the derivatives and then calculate and solve the system? Calculation of the derivates by hand is not an option because later I have to develop this program and I will have about 100 equations instead of 2.

1

There are 1 best solutions below

3
horchler On

A fundamental problem that you're making is that you're solving this system numerically with fsolve but then mixing in symbolic math.

Since your functions, F don't seem to vary, their derivatives shouldn't either, so you can create them as symbolic functions and calculate their derivatives symbolically once:

syms x [1 2] real; % Create 1-by-2 symbolic vector

F = exp(-x+2)/(1+exp(-x(1)+2)+exp(-x(2)+1));

F_d(1) = diff(F(1),x(1));
F_d(2) = diff(F(2),x(2));

F = F+F_d; % Add derivatives to original functions

Then you can convert these to a numerical form and solve with fsolve:

root2d = matlabFunction(F,'Vars',{x}); % Convert symbolic function to vectorized numeric function
x0 = [0 0];
x = fsolve(root2d,x0)
root2d(x)

Note that fsolve only finds a single root (if it succeeds) for a given initial guess. It's strongly suggested that you plot your function to understand it's behavior and how many roots it may have. From my limited plotting it doesn't look like this function, as defined above, has any zeros. Separately, you should also look into the tolerance options for fsolve.

You can look into purely numerical (non-symbolic) methods to solve this, but you'll need properly calculate the derivative numerically. You might look into this approach for that.