I've been trying to run this code, for a non linear pendulum, but i get the following errors:
for the function----
Not enough input arguments.
Error in pend_l (line 4)
xdot = [x(2); -wsq*x(1)-C*x(2)];
for the script:
Error using feval
Unrecognized function or variable 'pend_n'.
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 pend_solve (line 10)
[t2,y] = ode45('pend_n',tspan,y0);
THE CODE
function xdot = pend_l(t1,x)
wsq = 13.56;
C = 0.1;
xdot = [x(2); -wsq*x(1)-C*x(2)];
% clf;
tspan = 0:0.01:50;
x0 = [1 ; 0];
y0 = [1 ; 0];
[t1,x] = ode45('pend_l',tspan,x0);
[t2,y] = ode45('pend_n',tspan,y0);
X1 = x(:,1);
X2 = x(:,2);
Y1 = y(:,1);
Y2 = y(:,2);
a = 2400;
% n = numel(t1);
n = 8000;
% plot(t1(a:n),0.69*X1(a:n),'linewidth',3);
% hold on;
% grid on;
%
% plot(t2(a:n)-1.81,Y1(a:n),'r','linewidth',3);
%
% legend('Linear', 'Nonlinear')
% hold off;
%
% figure(2);
% clf; % energies are scaled to 10% of its actual values
L = 1*20e-2*20e-2*Y2.*Y2 - 1*9.81*20e-2*(1-cos(Y1)); %lagrangian
E = 1*20e-2*20e-2*Y2.*Y2 + 1*9.81*20e-2*(1-cos(Y1)); %Total energy
D = 0.1*Y2.*Y2; %dissipated energy
% plot(t2,L,'linewidth',3);
% hold on;
% grid on;
% plot(t2,E,'r','linewidth',3);
% plot(t2,D,'g','linewidth',3);
% plot(t2,E-D,'k','linewidth',3); %net energy
b = 1;
f = 2;
figure(3);
clf;
plot(t1,1*20e-2*20e-2*Y2.*Y2,'linewidth',3);
hold on;
plot(t1,1*9.81*20e-2.*(1-cos(Y1)),'r','linewidth',3);
plot(t1,E,'c','linewidth',3);
% plot(t1,X1-b,'linewidth',3);
hold on;
grid on;
plot(t2,Y1-b,'r','linewidth',3);
plot(t2,L+f,'linewidth',3);
plot(t2,D+f,'g','linewidth',3);
plot(t2,(E-D)+f,'k','linewidth',3); %net energy
plot(t1,Y1*0-b-0.3,'k','linewidth',1);
plot(t1,Y1*0-b+0.3,'k','linewidth',1);
plot(t1*0+24,3.5*Y1+1,'k','linewidth',1);
text(30,-b+0.4,'\downarrow Linear Range');
% text(12,0,'\leftarrow Time instant @ which non-linear to linear');
% text(12,-0.5,'transition takes place');
% % legend('Linear', 'Nonlinear')
legend('T','V','Total Energy','Linear', 'Nonlinear','Lagrangian','Dissipated Energy','Net Energy');
figure(4);
clf;
ED = E-D;
[pks,locs] = findpeaks(L);
[pks1,locs1] = findpeaks(ED);
[pks2,locs2] = findpeaks(D);
TF = islocalmin(L);
TF1 = islocalmin(ED);
TF2 = islocalmin(D);
plot(locs*0.01,pks,'b');
hold on;
plot(locs1*0.01,pks1,'r');
plot(locs2*0.01,pks2,'k');
grid on;
plot(t1(TF),L(TF),'b')
plot(locs1*0.01,pks1,'r');
plot(t1(TF1),ED(TF1),'r');
plot(t1(TF2),D(TF2),'k');
plot(t1*0+24,1*Y1+0,'k','linewidth',1);
legend('Lagrangian','Net Energy','Dissipated Energy');
------------------------------------------------------------------------------------------------------
Any idea why it isn't working? thanks guys

 采纳的回答

You mixed up the functions and the calling code. Also there is no function for pend_n - to build a working code i just copied the same code as used for pend_l and used it as pend_n.
tspan = 0:0.01:50;
x0 = [1 ; 0];
y0 = [1 ; 0];
[t1,x] = ode45(@pend_l,tspan,x0);
[t2,y] = ode45(@pend_n,tspan,y0);
X1 = x(:,1);
X2 = x(:,2);
Y1 = y(:,1);
Y2 = y(:,2);
a = 2400;
% n = numel(t1);
n = 8000;
% plot(t1(a:n),0.69*X1(a:n),'linewidth',3);
% hold on;
% grid on;
%
% plot(t2(a:n)-1.81,Y1(a:n),'r','linewidth',3);
%
% legend('Linear', 'Nonlinear')
% hold off;
%
% figure(2);
% clf; % energies are scaled to 10% of its actual values
L = 1*20e-2*20e-2*Y2.*Y2 - 1*9.81*20e-2*(1-cos(Y1)); %lagrangian
E = 1*20e-2*20e-2*Y2.*Y2 + 1*9.81*20e-2*(1-cos(Y1)); %Total energy
D = 0.1*Y2.*Y2; %dissipated energy
% plot(t2,L,'linewidth',3);
% hold on;
% grid on;
% plot(t2,E,'r','linewidth',3);
% plot(t2,D,'g','linewidth',3);
% plot(t2,E-D,'k','linewidth',3); %net energy
b = 1;
f = 2;
figure(3);
clf;
plot(t1,1*20e-2*20e-2*Y2.*Y2,'linewidth',3);
hold on;
plot(t1,1*9.81*20e-2.*(1-cos(Y1)),'r','linewidth',3);
plot(t1,E,'c','linewidth',3);
% plot(t1,X1-b,'linewidth',3);
hold on;
grid on;
plot(t2,Y1-b,'r','linewidth',3);
plot(t2,L+f,'linewidth',3);
plot(t2,D+f,'g','linewidth',3);
plot(t2,(E-D)+f,'k','linewidth',3); %net energy
plot(t1,Y1*0-b-0.3,'k','linewidth',1);
plot(t1,Y1*0-b+0.3,'k','linewidth',1);
plot(t1*0+24,3.5*Y1+1,'k','linewidth',1);
text(30,-b+0.4,'\downarrow Linear Range');
% text(12,0,'\leftarrow Time instant @ which non-linear to linear');
% text(12,-0.5,'transition takes place');
% % legend('Linear', 'Nonlinear')
legend('T','V','Total Energy','Linear', 'Nonlinear','Lagrangian','Dissipated Energy','Net Energy');
figure(4);
clf;
ED = E-D;
[pks,locs] = findpeaks(L);
[pks1,locs1] = findpeaks(ED);
[pks2,locs2] = findpeaks(D);
TF = islocalmin(L);
TF1 = islocalmin(ED);
TF2 = islocalmin(D);
plot(locs*0.01,pks,'b');
hold on;
plot(locs1*0.01,pks1,'r');
plot(locs2*0.01,pks2,'k');
grid on;
plot(t1(TF),L(TF),'b')
plot(locs1*0.01,pks1,'r');
plot(t1(TF1),ED(TF1),'r');
plot(t1(TF2),D(TF2),'k');
plot(t1*0+24,1*Y1+0,'k','linewidth',1);
legend('Lagrangian','Net Energy','Dissipated Energy');
function xdot = pend_l(~,x)
wsq = 13.56;
C = 0.1;
xdot = [x(2); -wsq*x(1)-C*x(2)];
end
function xdot = pend_n(~,x)
wsq = 13.56;
C = 0.1;
xdot = [x(2); -wsq*x(1)-C*x(2)];
end
So this appears to work, bit you have to care for the correct pend_n code to get correct results!

5 个评论

Hi, can you please dumb it down a bit?
I've just started with matlab, and i ony know the bare basics. I don't understand how to save the code, where to save, or why exactly it in't running.
do i run the code in two different scripts? what do i save them as?
which part do i run how?
i'm really sorry about these simple questions, but i am yet to join a matlab class.
The part:
tspan = 0:0.01:50;
...
...
...
legend('Lagrangian','Net Energy','Dissipated Energy');
is the part where you call functions, caculate stuff and plot results.
The functions that are needed for the ode45 solver either have to be at the end of a matlab script or in seperate .m-files. In this case i put all code in one script in the correct order
function xdot = pend_l(~,x)
wsq = 13.56;
C = 0.1;
xdot = [x(2); -wsq*x(1)-C*x(2)];
end
function xdot = pend_n(~,x)
wsq = 13.56;
C = 0.1;
xdot = [x(2); -wsq*x(1)-C*x(2)];
end
What you did is mixing those parts into 1, which doesnt work properly.
Since you call ode45 2times with different functions (pend_l and pend_n), which means that you want to solve 2 different ode's you need to provide 2 functions at the end of the script.
Your code only provides 1 function, which will lead to an error when the script tries to run ode45 and tries calling the second function. As workaround i just copied the code from the first ode function and gave it the name of the second one.
Thus the code runs free of errors, but at least the second function has to be corrected to get meaningful results.
i tried the code you edited, and it worked. This is pend_solve.

请先登录,再进行评论。

更多回答(1 个)

0 个投票

10 个评论

The function part isnt displaying a plot now.
as in, pend_l isn't working.
also, can pend_n just be removed??
Stephan
Stephan 2020-11-4
编辑:Stephan 2020-11-4
pend_n could be removed if not needed, but then also remove all the code related to this function. So everything where y0, t2 and y appear (which are the results of pend_n) should be removed also.
Also both functions are written in a way that they are suitable for the ode45 solver. The solver calls them with the input arguments, so that they run without errors. What you do is calling a function that expects 2 inputs without an input, so it will throw this error above.
Ohhh okay.. I understand. Thank you so much!!!
Also, is there an online course you would recommend to a complete beginner? Or any way i could really understand the nitty gritty of MATLAB?
I'm done with mtlab onramp
Thanks Rik, will check out.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Numerical Integration and Differential Equations 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by