ODE45 requires more parameters than it should

1 view (last 30 days)
Hello All,
I am solving a parametric systems of ODEs in Matlab. I have defined 11 parameters in matlabfunction command, but when it comes to use the ode45 command it requires 14 parameters.
syms m A alpha theta(t) b u(t) I B n J x(t) y(t) D c cr %J=Ir
X=A*sin(alpha*t)
phi=B*sin(n*alpha*t)
%D=c*(diff(x)*cos(theta)+diff(y)*sin(theta))/2+cr*theta^2/2
lambda= m*(I+J)*(-2*diff(X,2)*sin(theta)+u*diff(theta)-(b*(J*diff(phi,2)+cr*diff(theta))/(I + J)))/(I+J+m*b^2)
ode1= diff(theta,2) == -(lambda*b+J*diff(phi,2)+cr*diff(theta))/(I+J)
ode2= diff(u) == -c*u/m+diff(theta)^2*b-2*diff(X,2)*cos(theta)
[V] = odeToVectorField(ode1,ode2)
M = matlabFunction(V,'vars', {'t','Y','A','I','alpha','b','m','B','J','n','c','cr'})
IC = [0 0 0] % Init conds for u , theta, thetadot
tspan_solve=0:0.1:20
tspan_plot=[0 20];
sol = ode45(M,tspan_solve,IC,1,0.00001,1,1,1,1,0.1,1,1,100,100) % Parameters for A, I, alpha, b, m, B, J, n, c, cr
I changed that first parameters and it seemed that has no effect on the solution, but still need to make sure what that is and fix this issue. Every time I try to change the parameters and see the results I get confused.
  2 Comments
Torsten
Torsten on 29 Nov 2022
Use
M = matlabFunction(V)
to see which parameters are included in your equations.
After this, you can arrange them as you like.
ali mohseni
ali mohseni on 29 Nov 2022
I did so. Still matlabFunction has 12 parameters which are as follows:
M = function_handle with value:
@(A,B,I,J,Y,alpha,b,c,cr,m,n,t)[b.*Y(3).^2-(c.*Y(1))./m+A.*alpha.^2.*cos(Y(2)).*sin(alpha.*t).*2.0;Y(3);-(cr.*Y(3)-B.*J.*alpha.^2.*n.^2.*sin(alpha.*n.*t)+(b.*m.*(I+J).*(Y(1).*Y(3)-(b.*(cr.*Y(3)-B.*J.*alpha.^2.*n.^2.*sin(alpha.*n.*t)))./(I+J)+A.*alpha.^2.*sin(Y(2)).*sin(alpha.*t).*2.0))./(I+J+b.^2.*m))./(I+J)]
but ode45 requires 13 output in the code above. The inputs to ode45 are
tspan_solve,IC,1,0.00001,1,1,1,1,0.1,1,1,100,100.

Sign in to comment.

Answers (3)

Cris LaPierre
Cris LaPierre on 29 Nov 2022
The first 2 inputs to your function must by t and y, which they are. Those correspond to tspan_solve and IC. The remaining input arguments must come after all other inputs for ode45 have been entered, including options.
It would appear your input A does not have much of an impact on the results.
syms m A alpha theta(t) b u(t) I B n J x(t) y(t) D c cr K X(t)%J=Ir
phi=B*sin(n*alpha*t);
%D=c*(diff(x)*cos(theta)+diff(y)*sin(theta))/2+cr*theta^2/2
lambda= m*(I+J)*(-2*diff(X,2)*sin(theta)+u*diff(theta)-(b*(J*diff(phi,2)+cr*diff(theta))/(I + J)))/(I+J+m*b^2);
ode1= diff(theta,2) == -(lambda*b+J*diff(phi,2)+cr*diff(theta))/(I+J);
ode2= diff(u) == -c*u/m+diff(theta)^2*b-2*diff(X,2)*cos(theta);
ode3= diff(X,2) == 2*lambda*sin(theta)+c*u*cos(theta)-2*K*X;
[V] = odeToVectorField(ode1,ode2,ode3);
M = matlabFunction(V,'vars', {'t','Y','A','I','alpha','b','m','B','J','n','c','cr','K'})
M = function_handle with value:
@(t,Y,A,I,alpha,b,m,B,J,n,c,cr,K)[Y(2);(I.*K.*Y(1).*-2.0-J.*K.*Y(1).*2.0-K.*b.^2.*m.*Y(1).*2.0+I.*c.*cos(Y(3)).*Y(5)+J.*c.*cos(Y(3)).*Y(5)-b.*cr.*m.*sin(Y(3)).*Y(4).*2.0+I.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+J.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+b.^2.*c.*m.*cos(Y(3)).*Y(5)+B.*J.*alpha.^2.*b.*m.*n.^2.*sin(alpha.*n.*t).*sin(Y(3)).*2.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);Y(4);-(cr.*Y(4)+cr.*m.*sin(Y(3)).^2.*Y(4).*4.0+b.*m.*Y(4).*Y(5)+K.*b.*m.*sin(Y(3)).*Y(1).*4.0-B.*J.*alpha.^2.*n.^2.*sin(alpha.*n.*t)-b.*c.*m.*cos(Y(3)).*sin(Y(3)).*Y(5).*2.0-B.*J.*alpha.^2.*m.*n.^2.*sin(alpha.*n.*t).*sin(Y(3)).^2.*4.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);-(-b.^3.*m.^2.*Y(4).^2+I.*c.*Y(5)+J.*c.*Y(5)-I.*b.*m.*Y(4).^2-J.*b.*m.*Y(4).^2+b.^2.*c.*m.*Y(5)-K.*b.^2.*m.^2.*cos(Y(3)).*Y(1).*4.0-I.*K.*m.*cos(Y(3)).*Y(1).*4.0-J.*K.*m.*cos(Y(3)).*Y(1).*4.0-I.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0-J.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0+b.^2.*c.*m.^2.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+J.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+J.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+I.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0+J.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0-b.*cr.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*4.0+B.*J.*alpha.^2.*b.*m.^2.*n.^2.*sin(alpha.*n.*t).*cos(Y(3)).*sin(Y(3)).*4.0)./(m.*(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0))]
IC = [0 0 0 1 1]; % Init conds for u , theta, thetadot, X, Xdot
tspan_solve=0:0.1:100;
tspan_plot=[0 100];
sol = ode45(M,tspan_solve,IC,[],1,5,1,1,1,1,1,1,1,1,1); % Parameters for A, I, alpha, b, m, B, J, n, c, cr
% ^^ ^ my changes
plot(sol.x,sol.y(1,:))
  2 Comments
ali mohseni
ali mohseni on 30 Nov 2022
I know that in this case the A has no effect on the odes, but still ode45 requires one extra parameters. so here I just deleted extra parameters like A and n to make the code more tidy. As you can see, now I have 11 parameters defined in matlabFunction but ode45 works only with 12 inputs.
syms m alpha theta(t) b u(t) I B J x(t) y(t) D c cr K X(t)%J=Ir
phi=B*sin(alpha*t);
lambda= m*(I+J)*(-2*diff(X,2)*sin(theta)+u*diff(theta)-(b*(J*diff(phi,2)+cr*diff(theta))/(I + J)))/(I+J+m*b^2);
ode1= diff(theta,2) == -(lambda*b+J*diff(phi,2)+cr*diff(theta))/(I+J);
ode2= diff(u) == -c*u/m+diff(theta)^2*b-2*diff(X,2)*cos(theta);
ode3= diff(X,2) == 2*lambda*sin(theta)+c*u*cos(theta)-2*K*X;
[V] = odeToVectorField(ode1,ode2,ode3);
M = matlabFunction(V,'vars', {'t','Y','I','alpha','b','m','B','J','c','cr','K'})
M = function_handle with value:
@(t,Y,I,alpha,b,m,B,J,c,cr,K)[Y(2);(I.*K.*Y(1).*-2.0-J.*K.*Y(1).*2.0-K.*b.^2.*m.*Y(1).*2.0+I.*c.*cos(Y(3)).*Y(5)+J.*c.*cos(Y(3)).*Y(5)-b.*cr.*m.*sin(Y(3)).*Y(4).*2.0+I.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+J.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+b.^2.*c.*m.*cos(Y(3)).*Y(5)+B.*J.*alpha.^2.*b.*m.*sin(Y(3)).*sin(alpha.*t).*2.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);Y(4);-(cr.*Y(4)-B.*J.*alpha.^2.*sin(alpha.*t)+cr.*m.*sin(Y(3)).^2.*Y(4).*4.0+b.*m.*Y(4).*Y(5)+K.*b.*m.*sin(Y(3)).*Y(1).*4.0-B.*J.*alpha.^2.*m.*sin(Y(3)).^2.*sin(alpha.*t).*4.0-b.*c.*m.*cos(Y(3)).*sin(Y(3)).*Y(5).*2.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);-(-b.^3.*m.^2.*Y(4).^2+I.*c.*Y(5)+J.*c.*Y(5)-I.*b.*m.*Y(4).^2-J.*b.*m.*Y(4).^2+b.^2.*c.*m.*Y(5)-K.*b.^2.*m.^2.*cos(Y(3)).*Y(1).*4.0-I.*K.*m.*cos(Y(3)).*Y(1).*4.0-J.*K.*m.*cos(Y(3)).*Y(1).*4.0-I.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0-J.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0+b.^2.*c.*m.^2.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+J.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+J.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+I.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0+J.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0-b.*cr.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*4.0+B.*J.*alpha.^2.*b.*m.^2.*cos(Y(3)).*sin(Y(3)).*sin(alpha.*t).*4.0)./(m.*(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0))]
IC = [0 0 0 1 1]; % Init conds for u , theta, thetadot, X, Xdot;
tspan_solve=0:0.1:100;
tspan_plot=[0 100];
sol = ode45(M,tspan_solve,IC,1,1,1,1,1,1,1,1,1,1) % Parameters for I, alpha, b, m, B, J, c, cr, K
sol = struct with fields:
solver: 'ode45' extdata: [1×1 struct] x: [0 2.0095e-04 0.0012 0.0062 0.0313 0.1539 0.3730 0.6942 1.1139 1.7977 2.4751 3.1526 3.7802 4.3105 4.9130 5.5156 6.0510 6.5580 7.1590 7.7309 8.4067 8.7822 9.1577 9.4928 9.8279 10.2876 10.6589 11.2264 11.8542 12.4819 13.0872 13.6235 … ] y: [5×248 double] stats: [1×1 struct] idata: [1×1 struct]
Cris LaPierre
Cris LaPierre on 30 Nov 2022
Edited: Cris LaPierre on 30 Nov 2022
You do not need to add an extra parameter. You do need to be aware of the expected inputs. I think your 'extra' parameter is being interpretted as the options input, as I pointed out previously.
Sticking with the syntax you are using, your inputs should be
sol = ode45(M, tspan_solve,IC,options,I,alpha,b,m,B,J,c,cr,K)
syms m alpha theta(t) b u(t) I B J x(t) y(t) D c cr K X(t)%J=Ir
phi=B*sin(alpha*t);
lambda= m*(I+J)*(-2*diff(X,2)*sin(theta)+u*diff(theta)-(b*(J*diff(phi,2)+cr*diff(theta))/(I + J)))/(I+J+m*b^2);
ode1= diff(theta,2) == -(lambda*b+J*diff(phi,2)+cr*diff(theta))/(I+J);
ode2= diff(u) == -c*u/m+diff(theta)^2*b-2*diff(X,2)*cos(theta);
ode3= diff(X,2) == 2*lambda*sin(theta)+c*u*cos(theta)-2*K*X;
[V] = odeToVectorField(ode1,ode2,ode3);
M = matlabFunction(V,'vars', {'t','Y','I','alpha','b','m','B','J','c','cr','K'})
M = function_handle with value:
@(t,Y,I,alpha,b,m,B,J,c,cr,K)[Y(2);(I.*K.*Y(1).*-2.0-J.*K.*Y(1).*2.0-K.*b.^2.*m.*Y(1).*2.0+I.*c.*cos(Y(3)).*Y(5)+J.*c.*cos(Y(3)).*Y(5)-b.*cr.*m.*sin(Y(3)).*Y(4).*2.0+I.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+J.*m.*sin(Y(3)).*Y(4).*Y(5).*2.0+b.^2.*c.*m.*cos(Y(3)).*Y(5)+B.*J.*alpha.^2.*b.*m.*sin(Y(3)).*sin(alpha.*t).*2.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);Y(4);-(cr.*Y(4)-B.*J.*alpha.^2.*sin(alpha.*t)+cr.*m.*sin(Y(3)).^2.*Y(4).*4.0+b.*m.*Y(4).*Y(5)+K.*b.*m.*sin(Y(3)).*Y(1).*4.0-B.*J.*alpha.^2.*m.*sin(Y(3)).^2.*sin(alpha.*t).*4.0-b.*c.*m.*cos(Y(3)).*sin(Y(3)).*Y(5).*2.0)./(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0);-(-b.^3.*m.^2.*Y(4).^2+I.*c.*Y(5)+J.*c.*Y(5)-I.*b.*m.*Y(4).^2-J.*b.*m.*Y(4).^2+b.^2.*c.*m.*Y(5)-K.*b.^2.*m.^2.*cos(Y(3)).*Y(1).*4.0-I.*K.*m.*cos(Y(3)).*Y(1).*4.0-J.*K.*m.*cos(Y(3)).*Y(1).*4.0-I.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0-J.*b.*m.^2.*sin(Y(3)).^2.*Y(4).^2.*4.0+b.^2.*c.*m.^2.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+J.*c.*m.*cos(Y(3)).^2.*Y(5).*2.0+I.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+J.*c.*m.*sin(Y(3)).^2.*Y(5).*4.0+I.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0+J.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*Y(5).*4.0-b.*cr.*m.^2.*cos(Y(3)).*sin(Y(3)).*Y(4).*4.0+B.*J.*alpha.^2.*b.*m.^2.*cos(Y(3)).*sin(Y(3)).*sin(alpha.*t).*4.0)./(m.*(I+J+b.^2.*m+I.*m.*sin(Y(3)).^2.*4.0+J.*m.*sin(Y(3)).^2.*4.0))]
opts = [];
IC = [0 0 0 1 1]; % Init conds for u , theta, thetadot, X, Xdot;
tspan_solve=0:0.1:100;
tspan_plot=[0 100];
sol = ode45(M,tspan_solve,IC,opts,1,1,1,1,1,1,1,1,1); % Parameters for I, alpha, b, m, B, J, c, cr, K
plot(sol.x,sol.y(1,:))

Sign in to comment.


Steven Lord
Steven Lord on 30 Nov 2022
That syntax, where you pass additional input arguments after the options structure, is an older syntax that is no longer documented and is intended for backwards compatibility.
Instead I recommend using one of the techniques described in the Parameterizing Functions link in the description of the odefun input argument on the ode45 documentation page. There's also an example on the ode45 documentation page that demonstrates the technique; see "Pass Extra Parameters to ODE Function" on that page.

Walter Roberson
Walter Roberson on 30 Nov 2022
Change
M = matlabFunction(V,'vars', {'t','Y','A','I','alpha','b','m','B','J','n','c','cr'})
to
M = matlabFunction(V, 'vars', {[t Y A I alpha b m B J n c cr]})
  1 Comment
ali mohseni
ali mohseni on 30 Nov 2022
How that works?
Do you mean I pass my input to parameters in the matlabFunction instead of doing that in ode45?

Sign in to comment.

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!