How can I check the needed inputs in an function handle?

12 次查看(过去 30 天)
Hello, I have to plot a phase portrait and vectorfield of a dynamical system. The idea is, that my functions takes a cell array with symbolic functions. To use ode45, I have to convert this symbolic function to a matlab function after I've substituted the parameters.
My problem is, that it depends on the given differential equation, how many and which arguments (x or y) the matlab function takes. But without knowing which function the user will input, I need to check the needed arguments. How can I do that? Or is there another approach?
The structure of the differential equation input and the arguments of the function phase_portrait(dgl,axis,paremeter) are given. The only restriction is, that the dynamical system consists of one second order differential equation or two first order differential equations ('mapend'/'harmos' are examples for second order differential equations).
The comments are in german, I hope that's not a problem.
syms x y mu rho om;
harmos = {y,-om*x*rho*y,'Gedämpfter harmonischer Oszillator'};
mapend = {y,-sin(x)-rho*y,'Gedämpftes mathematisches Pendel'};
phase_portrait(mapend,[-2*pi 2*pi -3 3],'rho',0.1)
% Funktion, die ein Phasenportrait erstellt, mit flexibeln Axen und
% Parametern
function phase_portrait(dgl,varargin)
% Optionale Parameter
defaultaxis = [-10 10 -10 10];
defaultom = 1;
defaultrho = 1;
defaultmu = 1;
p = inputParser;
addRequired(p,'dgl');
addOptional(p,'axis',defaultaxis);
addOptional(p,'om',defaultom);
addOptional(p,'rho',defaultrho);
addOptional(p,'mu',defaultmu);
parse(p,dgl,varargin{:});
pdgl = p.Results.dgl;
paxis = p.Results.axis;
pom = p.Results.om;
prho = p.Results.rho;
pmu = p.Results.mu;
% Substituiert vorhandene Parameter in den Funktionen
dgl1 = subs(pdgl(1),{'mu','rho','om'},{pmu,prho,pom});
dgl2 = subs(pdgl(2),{'mu','rho','om'},{pmu,prho,pom});
% Wandelt die symoblischen Funktionen in numerische Funktionen um
eq1 = matlabFunction(dgl1);
eq2 = matlabFunction(dgl2);
% Erstellt ein Fenster
figure(1)
axis(paxis)
title('Phasenportrait', pdgl(3))
hold on
% Zeitspanne über die Integriert wird
tspanflow = [0 10];
% Anfangszeitpunkte
for x0 = paxis(1):0.5:paxis(2)
for y0 = paxis(3):0.5:paxis(4)
xyinitial = [x0;y0];
% Löst die Dgl für die betrachteten Anfangszeitpunkte
[tout,sout] = ode45(@Derivatives,tspanflow,xyinitial);
xout = sout(:,1);
yout = sout(:,2);
% Plottet das Phasenportrait
plot(xout,yout)
% % Zeichnet die Linien sichtbar nacheinander
% drawnow
end
end
% Erstellt ein zweites Fenster
figure(2)
axis(paxis)
title('Vektorfeld')
hold on
% Erstellt ein Gitter
[xgrid,ygrid] = meshgrid(paxis(1):.35:paxis(2),paxis(3):.35:paxis(4));
dxdtgrid = eq1(xgrid,ygrid);
dydtgrid = eq2(xgrid,ygrid);
% Plottet die Pfleile mit Normierungsfaktor norm
norm = sqrt(dxdtgrid.^2 + dydtgrid.^2);
quiver(xgrid,ygrid,dxdtgrid./norm,dydtgrid./norm)
function dsdt = Derivatives(t,s)
x = s(1);
y = s(2);
dsdt = [eq1(x,y);eq2(x,y)];
end
end
The occuring error is as expected:
Error using symengine>@(y)y
Too many input arguments.
Error in VariablesPhasenportrait>phase_portrait/Derivatives (line 86)
dsdt = [eq1(x,y);eq2(x,y)];
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options,
varargin);
Error in VariablesPhasenportrait>phase_portrait (line 54)
[tout,sout] = ode45(@Derivatives,tspanflow,xyinitial);
Error in VariablesPhasenportrait (line 5)
phase_portrait(mapend,[-2*pi 2*pi -3 3],'rho',0.1)

采纳的回答

Walter Roberson
Walter Roberson 2021-6-12
编辑:Walter Roberson 2021-6-12
eq1 = matlabFunction(dgl1);
Your pdgl are symbolic expressions that might involve just x, just y, both x and y, or neither. When you use matlabFunction in that form, matlab will scan the expression and will create a function that expects the same number of inputs as the number of symbolic variables in the expression... so @(x) or @(y) or @(x,y) or @().
But then you invoke the function with two parameters. Which is a problem if the expression did not involve both x and y.
You need to force the expression to expect two variables. See the 'vars' option of matlabFunction

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Symbolic Math Toolbox 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by