fsolve handling a composition of functions gives the error, "not enough input arguments"
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Noob
el 8 de Sept. de 2020
I'm having some trouble using fsolve on a composition of functions.
I've tried fsolve on a much simpler composition, and it worked just fine, so my code for the "real" problem probably needs to be tweaked.
My real problem starts with a Matlab function, f, that embeds nonlinear modeling code and the solutions gotten from the ode45 solver, and gives me as output only certain ODE solutions I'm interested in, e.g. solutions at the end, time T.
Then, in a separate function file, I write a function, g, that's a difference mapping that uses the outputs from f. So, it's g composed with f.
(The function g has the same inputs as the function f, and gives differences as outputs.)
Now I want to find multivariable roots of the difference mapping g, i.e. solving g = 0, using fsolve; however, I've been getting the message, "not enough input arguments".
Here's the gist of the code from my script file that's calling fsolve:
g = @DifferenceMap;
f = @ODE_solutions_time_T;
% An initial guess at a multivariable root:
xdot_0 = 5;
ydot_0 = 8;
thetadot_0 = 1;
% Multivariable root finding via the fsolve algorithm:
[ xdot_0, ydot_0, thetadot_0] = fsolve( g( f ) , [ xdot_0, ydot_0, thetadot_0 ] );
What am I missing?
Thanks,
2 comentarios
Walter Roberson
el 8 de Sept. de 2020
Could you confirm that you intend to call DifferenceMap passing in the function handle to DOE_solutions_time_T, and that you intend to have DifferenceMap return a function handle that will be invoked repeatedly by fsolve? And that whatever function handle it returns will be a function of one variable, and that DifferenceMap expects only the single function handle input?
Respuesta aceptada
Steven Lord
el 8 de Sept. de 2020
This:
g(f)
attempts to call the function handle stored in f with 0 input arguments and 1 output argument then call the function handle stored in g with the output argument from f as input. You don't want to call the function handles yourself and pass their outputs into fsolve.
This:
@(x) g(f(x))
defines an anonymous function to be called with 1 input argument. When it is called with an input argument, it calls f with that same input argument and 1 output argument. The output argument from that call to f is then passed into g as its input argument.
g = @sin;
f = @cos;
h = @(x) g(f(x));
% Try calling h
check = [h(5); sin(cos(5))]
check(1) == check(2) % true
13 comentarios
Más respuestas (1)
Walter Roberson
el 8 de Sept. de 2020
Editada: Walter Roberson
el 8 de Sept. de 2020
fsolve() needs to be passed a function handle that accepts one input and returns one output.
If you have a function that returns multiple separate outputs (as opposed to returning a vector with multiple values) then to use the function with fsolve, you need to construct a true function (cannot be done with an anonymous function) that does something like
function single_output = gather_outputs(fun, varargin)
n = nargout(fun);
[outputs{1:n}] = fun(varargin{:});
single_output = cell2mat(outputs);
end
and then you would
outputs = fsolve(@(x) gather_outputs(@YourFunction, x), [ xdot_0, ydot_0, thetadot_0 ]);
xdot_0 = outputs(1);
ydot_0 = outputs(2);
thetadot_0 = outputs(3);
Notice that the output from fsolve() is not a list of variable values: the first output from fsolve is a vector of values, and the second output is a the value of the function at that final location, and the third output is the exit flag giving status information.
The function handle you pass in as the first parameter to fsolve must be of a function that expects a vector as input. If you are calling a function that expects individual parameters, then you can break them up in an anonymous function, such as
outputs = fsolve(@(x) gather_outputs(@YourFunction, x(1), x(2), x(3)), [ xdot_0, ydot_0, thetadot_0 ]);
... But if you have choice, we would recommend that you rewrite the functions to expect a vector of input and return a vector output.
5 comentarios
Walter Roberson
el 9 de Sept. de 2020
f has 3 inputs and 3 outputs
Then you must use a true function (not anonymous) similar to what I show to gather the outputs.
It is impossible in MATLAB to capture multiple output variables of a function except by using a true assignment statement. Even subsasgn() cannot do it.
The three inputs can be handled like I showed,
@(x) gather_outputs(@YourFunction, x(1), x(2), x(3))
Ver también
Categorías
Más información sobre Solver Outputs and Iterative Display en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!