functions retuning functions, fsolve

7 Ansichten (letzte 30 Tage)
Stefan Holzinger
Stefan Holzinger am 2 Aug. 2016
Kommentiert: Victoria Thomas am 13 Feb. 2022
Hallo Matlab friends,
I need some help with functions returning functions. I would like to solve nonlinear equations with fsolve for x. My Problem is, how can i put functions(x) into a function which returns functions(x) that i can use in fsolve?
Here is my Problem:
y1 = @(x) 2.*x;
y2 = @(x) x.^2;
[z1,z2] = @(x) fun(y1,y2);
F = @(x) z1(x) + z2(x)
x0 = [0 0 0]';
solu = fsolve(F,x0);
The function fun looks like
function [z1,z2] = fun(y1,y2)
z1 = 4.*y1.^2;
z2 = y2.^3;
end
If i run my code i get the error message:
Only functions can return multiple values.
How can i solve such a problem? I really need some help.
  2 Kommentare
Stefan Holzinger
Stefan Holzinger am 2 Aug. 2016
Solved it.
I modified the example a little bit.
h1 = @(x) 2*x + 1;
h2 = @(x) x + 2;
[z1,z2] = fun(h1,h2);
F = @(x) z1(x) + z2(x);
x0 = 1;
solu = fsolve(F,x0)
The function fun looks like:
function [z1,z2] = fun(a,b)
z1 = @(a) sin(a);
z2 = @(b) cos(b);
end
Stefan Holzinger
Stefan Holzinger am 2 Aug. 2016
But now i would like to know if there is a way to reformulate the example in a way such that the function fun looks like:
function [z1,z2] = fun(a,b)
z1 = sin(a);
z2 = cos(b);
end
Any ideas?

Melden Sie sich an, um zu kommentieren.

Antworten (4)

Walter Roberson
Walter Roberson am 2 Aug. 2016
function z = F
syms x
[z1, z2] = fun(x,x)
z = matlabFunction(z1 + z2);
  7 Kommentare
Stefan Holzinger
Stefan Holzinger am 3 Aug. 2016
Thank you for your support! Your suggestions are really helpfull! A last question to your note about "clear": Is this what you meant (see the following code)?
v = F;
x0 = 1;
solu = fsolve(v,x0)
Where fun is:
function [z1,z2] = fun(a,b)
z1 = sin(a);
z2 = cos(b);
end
matlab
function out = F
syms x
h1 = 2*x + 1;
h2 = cos(x) + 2;
[z1, z2] = fun(h1,h2);
z = matlabFunction(z1 + z2,'File','myfile');
clear myfile
out = @myfile;
end
Walter Roberson
Walter Roberson am 3 Aug. 2016
Yes, that should work with respect to clear.

Melden Sie sich an, um zu kommentieren.


Stefan Holzinger
Stefan Holzinger am 3 Aug. 2016
Bearbeitet: Stefan Holzinger am 3 Aug. 2016
Meanwhile i expanded my problem a little bit but when it comes to fsolve, i run into the error:
Error using symengine
Array sizes must match.
Error in sym/privBinaryOp (line 937)
Csym = mupadmex(op,args{1}.s, args{2}.s, varargin{:});
Error in + (line 7)
X = privBinaryOp(A, B, 'symobj::zip', '_plus');
Error in F (line 10)
matlabFunction(M*x + z1 + z2,'File','myfile');
Error in Test_1 (line 9)
v = F(c1,c2);
Here is what i did:
c1 = [1 2 0 0];
c2 = [2 0 0 0];
v = F(c1,c2);
x0 = [2 1 0 0]';
solu = fsolve(v,x0)
F:
function out = F(c1,c2)
syms x
h1 = 2*c1 + 4*x;
h2 = c2 + x;
[z1, z2, M] = fun(h1,h2);
matlabFunction(M*x + z1 + z2,'File','myfile');
clear myfile
out = @myfile;
end
fun:
function [z1,z2,M] = fun(a,b)
I = diag([1 1 1]);
E = @(a) [-a(2) a(1) a(4) -a(3);
-a(3) -a(4) a(1) a(2);
-a(4) a(3) -a(2) a(1)];
Gbar = 2*E(a);
M = Gbar'*I*Gbar
z1 = sin(a);
z2 = sin(b);
end
Where did i made a mistake? :/
  1 Kommentar
Walter Roberson
Walter Roberson am 3 Aug. 2016
Your M is 4 x 4, your z1 and z2 are 1 x 4. You have M*x + z1 + z2 . MATLAB always treats (resolved) symbolic names as scalars, so M*x is 4 x 4, and you cannot add 1 x 4 to that. It is not possible in MATLAB to say "in the following, assume that the symbolic name x is a matrix of appropriate size to make all of the operations work out". And even if it did, because M is 4 by 4, no matter what size x was, M*x would have to have a leading dimension of 4 and that is not going to be something you can add to the row vectors z1 and z2.
If you need x to be a matrix in F then you need to use something like
x = sym('x', 4, 1);
h1 = 2*c1.' + 4*x;
h2 = c2.' + x;
You will probably also want to http://www.mathworks.com/help/symbolic/matlabfunction.html#zmw57dd0e96800 and pay attention to the way to have a list of variables be incorporated into an input vector instead of having to appear as individual arguments.

Melden Sie sich an, um zu kommentieren.


Stefan Holzinger
Stefan Holzinger am 4 Aug. 2016
Hey Walter i solved it. :)
Here is the code of a minimum working example, if anyone else is interested:
c1 = [1 2]';
c2 = [2 0]';
v = F(c1,c2);
x0 = [1 1]';
solu = fsolve(v,x0)
Function F:
function out = F(c1,c2)
x = sym('x',size(c1));
h1 = 2*c1 + 4*x;
h2 = c2 + x;
[z1,z2] = fun(h1,h2);
DG = z1*x + z2*x + z2*h1;
matlabFunction(DG,'File','myfile','Vars',{x});
clear myfile
out = @myfile;
end
and f:
function [z1,z2] = fun(a,b)
z1 = [a(1) a(2);
a(2) a(1)];
z2 = [a(1)*b(1) a(2)*b(2);
a(2)*b(1) a(1)*b(2)];
end
  11 Kommentare
Walter Roberson
Walter Roberson am 6 Aug. 2016
c1 = bsxfun( @times, c01, 2.^(0:10) );
Stefan Holzinger
Stefan Holzinger am 6 Aug. 2016
bsxfun seems to be an interesting function. :) thanks!

Melden Sie sich an, um zu kommentieren.


Victoria Thomas
Victoria Thomas am 13 Feb. 2022
Expand f(z) = z^8 e^3z

Community Treasure Hunt

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

Start Hunting!

Translated by