gusucode.com > symbolic工具箱matlab源码程序 > symbolic/odeToVectorField.m
function [V, Y] = odeToVectorField(varargin) %odeToVectorField Converting scalar differential equations to coupled % first order systems (vector fields). % % V = odeToVectorField('eqn1','eqn2', ...) accepts symbolic equations % representing ordinary differential equations given in terms of % strings. The differential equations must be linear in the highest % derivatives of the unknown functions involved. % % The output 'V' is a SYM object containing the components of the % coupled first order system associated with 'eqn1','eqn2', ... % The output 'V' can be used as input for matlabFunction to generate % a MATLAB function. Such a function then can be used to define input % for a numerical ODE solver in MATLAB. % % By default, the independent variable is 't'. The independent % variable may be changed from 't' to some other symbolic variable by % including that variable as the last input argument. % % The letter 'D' denotes differentiation with respect to the % independent variable, i.e. usually d/dt. A "D" followed by a digit % denotes repeated differentiation; e.g., D2 is d^2/dt^2. % Any characters immediately following these differentiation % operators are taken to be the dependent variables; % e.g., D3y denotes the third derivative of y(t). Note that the names % of symbolic variables should not contain the letter "D". % % E.g. the input 'D2x = -3*t' represents the differential equation % % d^2/dt^2 x(t) = -3*t. % % V = odeToVectorField('eqn1','eqn2', ...) returns a SYM object % containing the components of the coupled first order system % associated with 'eqn1','eqn2', ... % % [V,Y] = odeToVectorField('eqn1','eqn2', ...) additionally returns % the SYM object 'Y' listing the substitutions that have been made % for converting the input equations 'eqn1','eqn2', ... into the % components of 'V'. % % Note that the result for 'V' can directly be used as input for % matlabFunction in order to create a MATLAB function that can passed % to one of MATLAB's numerical ODE solvers. See the examples below. % % Example 1: % % V = odeToVectorField('D2x = -3*t') returns % % V = % % Y[2] % -3*t % % [V,Y] = odeToVectorField('D2x + t*Dx + x = -3*t') % % V = % % Y[2] % - 3*t - t*Y[2] - Y[1] % % % Y = % % x % Dx % % The result contained in 'V' can be used as input for % MATLABFUNCTION: % % M = matlabFunction(V,'vars', {'t', 'Y'}) % % M = @(t,Y)[Y(2),t.*-3.0-t.*Y(2)-Y(1)] % % Example 2: % You can also apply odeToVectorField on systems of scalar % differential equations: % % [V,Y] = odeToVectorField('D2f = f + g','Dg = -f + g') % % V = % % Y[1] - Y[2] % Y[3] % Y[1] + Y[2] % % Y = % % g % f % Df % % We compute the state space representation for y''=(1-y^2)*y'-y % % [V,Y] = odeToVectorField('D2y = (1-y^2)*Dy - y') % % V = % % Y[2] % - (Y[1]^2 - 1)*Y[2] - Y[1] % % Y = % % y % Dy % % use it as input for MATLABFUNCTION % % M = matlabFunction(V,'vars', {'t', 'Y'}) % % M = @(t,Y)[Y(2);-(Y(1).^2-1.0).*Y(2)-Y(1)] % % and then use MATLAB's numerical ODE solver ODE45 to create a % plot of the solution: % % sol = ode45(M,[0 20],[2 0]); % x = linspace(0,20,100); % y = deval(sol,x,1); % plot(x,y); % % % See also DSOLVE, matlabFunction. % Copyright 2011-2013 The MathWorks, Inc. eng = symengine; sol = mupadOdeToVectorField(varargin); V = eng.feval('_index',sol,'"VectorFieldComponents"'); Y = eng.feval('_index',sol,'"Substitutions"'); function T = mupadOdeToVectorField(args) narg = length(args); % The default independent variable is t. default_varname = true; x = sym('t'); % Pick up the independent variable, if specified. if isvarname(char(args{end})) default_varname = false; x = sym(args{end}); args(end) = []; narg = narg-1; end sys = args(1:narg); if ischar(sys{1}) stringInput = '"stringInput"'; else stringInput = 'null()'; end % Concatenate equation(s) into SYS. sys_class = cellfun(@class,sys,'UniformOutput',false); chars = strcmp(sys_class,'char'); sys_char = sys(chars); % look for symfuns and pick out independent variable sys_sym = [sys{~chars}]; syminputs = []; if ~isempty(sys_sym) && isa(sys_sym,'symfun') syminputs = argnames(sys_sym); end if ~isempty(syminputs) if ~isscalar(syminputs) error(message('symbolic:dsolve:OneVar')); end if default_varname x = syminputs; else sys_sym = sys_sym(x); end end sys_char(2,:) = {','}; sys_str = ['[' sys_char{1:end-1} ']']; sys = [sys_sym evalin(symengine, sys_str)]; T = feval(symengine,'symobj::odeToVectorField',sys,x,stringInput);