Using fsolve with array of symbolic expressions

3 views (last 30 days)
Hi there,
I have a vector of symbolic expressions, say for example
c = sym('c', [1 2]);
eqn=[c(1)^2-c(2), c(1)^3+c(2)^2];
and I want to use it to solve the nonlinear system of equations: eqn==0. (of course for this specific easy example I gave you, there are other ways to solve it, but none of them would work for a large eqn, which must be created independently of the solver and is really expensive to be created).
My initial method was to convert the expressions to a function handle:
eqn=matlabFunction(eqn)
and then solve it:
options = optimset('Display', 'off');
X = fsolve(eqn, ones(1, 2), options);
but it doesn't work, since fsolve accepts functions with one argument (which can be a vector) but matlabFunction gives me something like @(c1,c2)[-c2+c1.^2,c1.^3+c2.^2]. Do you have a recommendation?
Limitations:
1) eqn MUST be a symbolic vector and it MUST be created independently of the nonlinear solver, so solutions like
@c [c(1)^2-c(2), c(1)^3+c(2)^2]
or calling a function that creates the symbolic vector at each trial wouldn't be helpful.
2) We can't use the subs function to substitute the variables in each trial of the solver, because this takes ages.
I would really appreciate any answer.
Thanks!

Accepted Answer

John D'Errico
John D'Errico on 9 Feb 2017
Edited: John D'Errico on 9 Feb 2017
fsolve is not designed to work with symbolic expressions. PERIOD.
If you have symbolic coefficients in there, fsolve is NOT for you.
If all of the coefficients are known constants, then why do you think you need to use a symbolic form? It won't be more accurate, because fsolve can only work in standard floating point arithmetic anyway.
If the only problem you have is that the MATLABFUNCTION tool returns a function of the form:
fun = @(c1,c2)[-c2+c1.^2,c1.^3+c2.^2]
then put a wrapper around it, so fsolve can do its job.
fun2 = @(C) fun(C(1),C(2));
If you insist on a symbolic expression(s) to solve, then vpasolve is a better choice anyway.
  2 Comments
Apostolos Psaros
Apostolos Psaros on 9 Feb 2017
Perfect! Maybe I didn't make it very clear when I was talking about symbolic expressions, but it doesn't matter. It seems all I needed was the wrapper.
One last thing, if the C vector is huge and changes according to my problem, could we change this:
fun2 = @(C) fun(C(1),C(2),......,C(100));
to something more automated?
Thanks for your answer, it's really helpful!
Walter Roberson
Walter Roberson on 20 Jun 2017
No. You should never eval() a symbolic expression or symbolic function. Symbolic expressions are in a language that is not exactly MATLAB, so when you eval() them you can get errors or unexpected behaviour.
You should use matlabFunction to convert symbolic expressions into function handles, and you should use matlabFunction's 'vars' option to convert the variables into a vector.
funeqns = matlabFunction(eqns, 'Vars', {xx});
or
funeqns = matlabFunction(eqns, 'Vars', {xx.'});
depending on whether you need the vector input to be a row vector (commonly used for minimization routines) or a column vector (common used for ode*())

Sign in to comment.

More Answers (0)

Categories

Find more on Symbolic Math Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!