fsolve with vectors x and y (not x(1) x(2))

I'd like to use fsolve, to solve for the vectors x and y, this nonlinear system which i wrote in a function.
function F = EquationsList(x,y)
F(1) = -0.00011 + 2 * x(1) * (cos(y(1))+sin(y(1))) + 2 * x(2) * (cos(y(2))+sin(y(2))) + 2 * x(3) * (cos(y(3))+sin(y(3)));
F(2) = -0.00013 + 2 * x(1) * (cos(y(1))+sin(y(1))) + 2 * x(2) * (cos(y(2))+sin(y(2))) + 2 * x(3) * (cos(y(3))+sin(y(3)));
...
...
F(9) = -0.00015 + 2 * x(1) * (cos(y(1))+sin(y(1))) + 2 * x(2) * (cos(y(2))+sin(y(2))) + 2 * x(3) * (cos(y(3))+sin(y(3)));
end
in the code above I only reported the first 2 equations. It's a large system.
the equations derive from the development of the sum shown below:
in which a,x,y are all scalars.
For using fsolve I coded this:
%defining constants:
N_mesh=3;
%define the problem for fsolve
problem.objective = @EquationsList;
%initial point
x0=zeros(N_mesh*N_mesh,1);
y0=zeros(N_mesh*N_mesh,1);
problem.x0 = x0;
problem.y0 = y0;
%solver
problem.solver = 'fsolve';
%set tolerances
problem.options = optimoptions('fsolve', ...
'MaxIter', 4000, ...
'MaxFunEvals',4000, ...
'StepTolerance',1e-16, ...
'FunctionTolerance',1e-16, ...
'OptimalityTolerance',1e-10,...
'Algorithm','levenberg-marquardt');
%solve
[x,y] = fsolve(problem);
But it gives me the error ' Not enough input arguments. '
Does anybody know how to use fsolve with these equations? I can't use only the vector x as the problem I'm trying to resolve requires two different output: x and y as vectors.
Thanks in advance for any replies.

4 Comments

Don't you see that the system of equations in EquationsList cannot have a solution ?
Is is equivalent to
a = 0.00011
a = 0.00013
...
a = 0.00015
with
a = 2 * x(1) * (cos(y(1))+sin(y(1))) + 2 * x(2) * (cos(y(2))+sin(y(2))) + 2 * x(3) * (cos(y(3))+sin(y(3)));
Do you know a number that is at the same time 0.00011, 0.00013 and 0.00015 ?
To handle a system written in two column vectors x and y, just put them together in a new vector Z = [x;y] and apply "fsolve" on Z.
On a side note. I noticed that the equations in EquationsList are not the same as what you show in latex equation.
Based on the latex equation, and assuming that i = 1:3 and j = 1:2, we obtain the following equations:
syms a [3 1] real
syms x [2 1] real
syms y [3 1] real
for i = 1:3
F(i,1) = a(i) + sum( 2*x*( cos(y(i))+sin(y(i)) ) );
end
F
F = 
Which is not the same as in the EquationsList.
Unless there is a typo in the latex equation off course.
Sorry, I've cutted some scalars in the LATEX equation for better clearance but you're technically right.
In reality the complete system which I'm trying to solve is including other constants which multiplies the (cos + sin) addend.
The equations are in this form, in which all parameters are scalars.
So the system of non-linear equations written in the function is something like this:
function F = MyFun(x,y)
F(1) = -0.0001121770+2*x(1)*(cos(y(1))*cos(0.0000000000)+sin(y(1))*sin(0.0000000000))*((0.0021349691)^2)*(0.1666666667)...
+2*x(2)*(cos(y(2))*cos(0.0000000000)+sin(y(2))*sin(0.0000000000))*((0.0021349690)^2)*(0.1666666667)...
+2*x(3)*(cos(y(3))*cos(0.0000000000)+sin(y(3))*sin(0.0000000000))*((0.0021349690)^2)*(0.0000000000)...
+2*x(4)*(cos(y(4))*cos(0.0000000000)+sin(y(4))*sin(0.0000000000))*((0.0021349691)^2)*(0.0000000000);
F(2)= ....
...
...
end
and so on.
I'm just trying to use a syntax which lets me use fsolve with those unknowns. Do you know how to do it?
Any help would be greatly appreciated.
well, what you show here has 4 unknowns for x and y, hence i would guess that you need to set the inital values accordingly. Why do you take the square of the number of variables?
% ...
N_mesh = 4;
% ...
x0 = zeros(N_mesh,1);
y0 = zeros(N_mesh,1);

Sign in to comment.

 Accepted Answer

Based on the comments, I would guess that you are looking for 8 parameters i.e.
syms x [1 4]; x
x = 
syms y [1 4]; y
y = 
can you try modifying your function "MyFun.m" such that:
function F = MyFun( input, numX )
% extract the variables from the input
x = input( 1:numX );
y = input( (numX+1):end );
% evaluate the equations
F(1) = -0.0001121770+2*x(1)*(cos(y(1))*cos(0.0000000000)+sin(y(1))*sin(0.0000000000))*((0.0021349691)^2)*(0.1666666667)...
+2*x(2)*(cos(y(2))*cos(0.0000000000)+sin(y(2))*sin(0.0000000000))*((0.0021349690)^2)*(0.1666666667)...
+2*x(3)*(cos(y(3))*cos(0.0000000000)+sin(y(3))*sin(0.0000000000))*((0.0021349690)^2)*(0.0000000000)...
+2*x(4)*(cos(y(4))*cos(0.0000000000)+sin(y(4))*sin(0.0000000000))*((0.0021349691)^2)*(0.0000000000);
F(2) = ...
end
and then you can call fsolve as:
% define the number of parameters
numX = 4;
numY = 4;
% define the problem for fsolve
problem.objective = @MyFun(x, numX);
% set the initial values
problem.x0 = zeros( numX+numY,1);
% set the solver
problem.solver = 'fsolve';
% set the options
problem.options = optimoptions('fsolve', ...
'MaxIter', 4000, ...
'MaxFunEvals',4000, ...
'StepTolerance',1e-16, ...
'FunctionTolerance',1e-16, ...
'OptimalityTolerance',1e-10,...
'Algorithm','levenberg-marquardt');
% solve the problem
solution = fsolve(problem);
% extract the variables
x = solution( 1:numX );
y = solution( (numX+1):end );

1 Comment

Yes, that's what I've been thinking also just now:
fsolve wants only a vector of unknowns, so we just "assign" the first numX unknowns to the first vector (which i called x in the LATEX), and the following numY unknowns as the second vector (which I called y in the LATEX).
Thanks again Karim.

Sign in to comment.

More Answers (1)

Torsten
Torsten on 26 Dec 2022
Edited: Torsten on 26 Dec 2022
%defining constants:
N_mesh=3;
%define the problem for fsolve
problem.objective = @(z)EquationsList(z,Nmesh);
%initial point
x0=zeros(1,N_mesh*N_mesh);
y0=zeros(1,N_mesh*N_mesh);
problem.x0 = [x0,y0];
%solver
problem.solver = 'fsolve';
%set tolerances
problem.options = optimoptions('fsolve', ...
'MaxIter', 4000, ...
'MaxFunEvals',4000, ...
'StepTolerance',1e-16, ...
'FunctionTolerance',1e-16, ...
'OptimalityTolerance',1e-10,...
'Algorithm','levenberg-marquardt');
%solve
z = fsolve(problem);
x = z(1:Nmesh*Nmesh);
y = z(Nmesh*Nmesh+1:2*Nmesh*Nmesh);
function F = MyFun(z,Nmesh)
x = z(1:Nmesh*Nmesh);
y = z(Nmesh*Nmesh+1:2*Nmesh*Nmesh);
F(1) = -0.0001121770+2*x(1)*(cos(y(1))*cos(0.0000000000)+sin(y(1))*sin(0.0000000000))*((0.0021349691)^2)*(0.1666666667)...
+2*x(2)*(cos(y(2))*cos(0.0000000000)+sin(y(2))*sin(0.0000000000))*((0.0021349690)^2)*(0.1666666667)...
+2*x(3)*(cos(y(3))*cos(0.0000000000)+sin(y(3))*sin(0.0000000000))*((0.0021349690)^2)*(0.0000000000)...
+2*x(4)*(cos(y(4))*cos(0.0000000000)+sin(y(4))*sin(0.0000000000))*((0.0021349691)^2)*(0.0000000000);
F(2)= ....
...
...
end

Categories

Products

Release

R2022b

Asked:

on 26 Dec 2022

Edited:

on 26 Dec 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!