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

8 views (last 30 days)
anto
anto on 26 Dec 2022
Edited: Torsten on 26 Dec 2022
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
anto
anto on 26 Dec 2022
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.
Karim
Karim on 26 Dec 2022
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

Karim
Karim on 26 Dec 2022
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
anto
anto on 26 Dec 2022
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

Find more on Function Creation in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!