Not able to solve ODE using ODE45 solver - matlab

This is my original code.
function dydt = Biogearsmcdaniel(t,y)
SP= 0.60;
kPT=3.7*10^4;
thetaP =1.35*10^-4;
kPTB= 3.1;
kPTMT=6.3*10^-3;
kPTNT=6.1*10^-4;
SMT=2.6*10^-2;
Mv=0.3;
kMT=6.43*10^-5;
kMTB=36.0;
SNT=7.0*10^-7;
Nv =1*10^8;
kNTB=36.0;
kNTMT=0.16;
kNT=6.1*10^-2;
SB =4.6*10^-2;
kBPT=26.0;
kBR= 0.14;
kBNT=4.0*10^-8;
kPBNA=5.8;
xPN= 0.5;
kPS =6.9*10^3;
xPS=1.3*10^4;
kMP=1.01;
xMP =-37.5;
kMD=5.0*10^-2;
xMD = 0.75;
xMTNF=0.4;
kM6=0.1;
xM6 =1.0;
xM10 =0.297;
kMR=0.05;
SM= 1.0;
kMA=0.2;
kNP= 33.75;
xNP=56.25;
kND= 0.05;
xND =0.4;
kNTNF= 0.2;
xENOSP =1.015;
k10MA=0.1;
xNTNF= 2.0;
kENOS= 4.0;
k10TNF= 1.485;
kN6 =1.5;
kNO3= 0.46;
x10TNF=0.05;
xN6 =1.0;
kNOMN= 2.0;
k106= 5.1*10^-2;
xN10= 0.2;
kTNFN =2.97;
x106 =8.0*10^-2;
kNR=0.05;
kTNFM=0.1;
k10R= 0.1;
SN =1.0;
xTNF10= 7.9*10^-2;
x1012=1.0*10^-2;
kNA=0.5;
xTNF6= 5.9*10^-2;
k10= 0.35;
kINOSN =1.5;
kTNF= 1.4;
S10= 1.0*10^-2;
kINOSM =0.1;
k6N= 0.2;
k12M= 0.303;
kINOSEC= 0.1;
k6M= 3.03;
x1210= 0.2525;
xINOSTNF =0.05;
k6TNF= 1.0;
k12= 5.0*10^-2;
kINOSd= 0.05;
x6TNF= 0.1;
kD= 0.15;
kINOS6= 2.0;
k6NO= 2.97;
kD6= 0.125;
xINOS6 =0.1;
x6NO= 0.4;
xD6= 0.85;
xINOS10= 0.1;
x610= 0.1782;
xDNO= 0.5;
xINOSNO= 0.3;
x66= 0.5;
kINOS= 0.101;
k6= 0.7;
kENOSEC= 0.05;
xENOSTNF= 0.4;
k10N=0.1;
S6= 1.0*10^-3;
dydt=zeros(19,1);%DAEs
function f=HU1(x,n,h)
f=x^h/1+(x/n)^h;
end
function g=HU2(x,n,h)
g=x^h/(x^h+n^h);
end
function r=HUD(x,n,h)
r=1/1+(x/n)^h;
end
R=1;
dydt(1)=(SP/kPT)*y(1)*(1-y(1))-(thetaP*y(1)/1+kPTB*y(1))-(kPTMT*y(2)*y(1))-kPTNT*y(3)*y(1);
dydt(2)=SMT*y(3)*Mv/1+kMTB*y(4)-kMT*y(2);
dydt(3)=SNT*R*Nv/((1+kNTB*y(4))*(1+kNTMT*y(2)))-kNT*y(3);
dydt(4)=(SB/1+kBPT)*y(4)*(1-y(4))-kBR*R*y(4)-kBNT*y(3)*y(4);
dydt(5)=SP*y(5)+thetaP*y(1)/1+kPTB*y(1)-kPS*y(5)/xPS+y(5)-kPBNA*y(9)*HU2(y(5),xPN,2);
dydt(6)=(-(kMP*HU2(y(5),xMP,2)+kMD*HU2(1-y(18),xMD,4)*(HU2(y(14),xMTNF,2)+kM6*HU2(y(15),xM6,2)))*HUD(y(16),xM10,2)*y(6)-kMR*(y(6)-SM));
dydt(7)=(kMP*HU2(y(5),xMP,2)+kMD*HU2(1-y(18),xMD,4))*(HU2(y(14),xMTNF,2)+kM6*HU2(y(15),xM6,2))*HUD(y(16),xM10,2)*y(6)-kMA*y(7);
dydt(8)=-((kNP*HU2(y(5),xNP,1))+kND*HU1(1-y(18),xND,2)+kNTNF*HU1(y(14),xNTNF,1)+kN6*HU1(y(15),xN6,2))*HUD(y(16),xN10,2)*y(8)-kNR*(y(8)-SN);
dydt(9)=(kNP*HU2(y(5),xNP,1))+kND*HU1(1-
y(18),xND,2)+kNTNF*HU1(y(14),xNTNF,1)+kN6*HU1(y(15),xN6,2)*HUD(y(16),xN10,2)*y(8)-kNA*y(9);
dydt(10=(kINOSN*y(9)+kINOSM*y(7)+kINOSEC*HU1(y(14),xINOSTNF,2)+kINOS6*HU1(y(15),xINOS6,2))*HUD(y(16),xINOS10,2)*HUD(y(19),xINOSNO,4)-kINOSd*y(10);
dydt(11)=kINOS*(y(10)-y(11));
dydt(12)=kENOSEC*HUD(y(14),xENOSTNF,1)*HUD(y(5),xENOSP,1)-kENOS*y(12);
dydt(13)=kNO3*(y(19)-y(13));
dydt(14)=(kTNFN*y(9)+kTNFM*y(7))*HUD(y(16),xTNF10,2)*HUD(y(15),xTNF6,3)-kTNF*y(14);
dydt(15)=(k6N*y(9)+y(7))*(k6M+k6TNF*HU2(y(14),x6TNF,2)+k6NO*HU2(y(19),x6NO,2))*HUD(y(16),x610,2)*HUD(y(16),x66,1)-k6*(y(15)-S6);
dydt(16)=(k10N*y(9)+y(7))*(k10MA+k10TNF*HU2(y(14),x10TNF,4)+k106*HU2(y(15),x106,4))*((1-k10R)*HUD(y(17),x1012,4)+k10R)-k10*(y(16)-S10);
dydt(17)=k12M*y(7)*HUD(y(16),x1210,2)-k12*y(17);
dydt(18)=kD*(1-y(18))*(y(18)-0.05)-(y(18)-0.05)*kD6*HU2(y(15),xD6,6)*(1/xDNO^2+y(19)^2);
dydt(19)=y(11)*(1+kNOMN*(y(7)+y(9)))+y(12);
end
The below code is the syntax used by me to write for the solver of the code.
tspan = 0:120;
yo=[1 1000 1000 0 0 1000 0 1000 0 0 0 0 0 1.1 1.02 1.05 1.2 0 0];
[t,y]=ode15s(#(t,y)Biogearsmcdaniel,tspan,yo);
for i=1:19
figure(i)
plot(t,y(:,i))
hold on
end
I am getting the following error when I run the above file
Not enough input arguments.
Error in Biogearsmcdaniel (line 109)
dydt(1)=(SP/kPT)y(1)(1-y(1))-(thetaPy(1)/1+kPTBy(1))-(kPTMT*y(2)y(1))-kPTNTy(3)*y(1);
Error in untitled148>#(t,y)Biogearsmcdaniel (line 3)
[t,y]=ode15s(#(t,y)Biogearsmcdaniel,tspan,yo);
Error in odearguments (line 92) f0 = ode(t0,y0,args{:}); % ODE15I
sets args{1} to yp0.
Error in ode15s (line 153)
odearguments(odeIsFuncHandle, odeTreatAsMFile, solver_name, ode, tspan, y0, options, varargin);
Error in untitled148 (line 3)
[t,y]=ode15s(#(t,y)Biogearsmcdaniel,tspan,yo);
Please help me out.

this is John BG jgb2012#sky.com
I patched your start script to run without errors.
However, not sure if the obtained result is what you are looking for
steps done to get your script up and running:
1.- you were not feeding ode15s correctly, on telling the name of the function, one has to define the inputs of such function.
2.- I have put each function in a different file
3.- I have made global the large amount parameters, it may not be necessary outside the main support function, but you can take if from here
4.- here's the code of the main support function that doesn't crash
function dydt = Biogearsmcdaniel(t,y)
global SP
global kPT
global thetaP
global kPTB
global kPTMT
global kPTNT
global SMT
global Mv
global kMT
global kMTB
global SNT
global Nv
global kNTB
global kNTMT
global kNT
global SB
global kBPT
global kBR
global kBNT
global kPBNA
global xPN
global kPS
global xPS
global kMP
global xMP
global kMD
global xMD
global xMTNF
global kM6
global xM6
global xM10
global kMR
global SM
global kMA
global kNP
global xNP
global kND
global xND
global kNTNF
global xENOSP
global k10MA
global xNTNF
global kENOS
global k10TNF
global kN6global
global kNO3
global x10TNF
global xN6global
global kNOMN
global k106
global xN10
global kTNFNglobal
global x106global
global kNR
global kTNFM
global k10R
global SN
global xTNF10
global x1012
global kNA
global xTNF6
global k10
global kINOSN
global kTNF
global S10
global kINOSM
global k6N
global k12M
global kINOSEC
global k6M
global x1210
global xINOSTNF
global k6TNF
global k12
global kINOSd
global x6TNF
global kD
global kINOS6
global k6NO
global kD6
global xINOS6
global x6NO
global xD6
global xINOS10
global x610
global xDNO
global xINOSNO
global x66
global kINOS
global k6
global kENOSEC
global xENOSTNF
global k10N
global S6
SP= 0.60;
kPT=3.7*10^4;
thetaP =1.35*10^-4;
kPTB= 3.1;
kPTMT=6.3*10^-3;
kPTNT=6.1*10^-4;
SMT=2.6*10^-2;
Mv=0.3;
kMT=6.43*10^-5;
kMTB=36.0;
SNT=7.0*10^-7;
Nv =1*10^8;
kNTB=36.0;
kNTMT=0.16;
kNT=6.1*10^-2;
SB =4.6*10^-2;
kBPT=26.0;
kBR= 0.14;
kBNT=4.0*10^-8;
kPBNA=5.8;
xPN= 0.5;
kPS =6.9*10^3;
xPS=1.3*10^4;
kMP=1.01;
xMP =-37.5;
kMD=5.0*10^-2;
xMD = 0.75;
xMTNF=0.4;
kM6=0.1;
xM6 =1.0;
xM10 =0.297;
kMR=0.05;
SM= 1.0;
kMA=0.2;
kNP= 33.75;
xNP=56.25;
kND= 0.05;
xND =0.4;
kNTNF= 0.2;
xENOSP =1.015;
k10MA=0.1;
xNTNF= 2.0;
kENOS= 4.0;
k10TNF= 1.485;
kN6 =1.5;
kNO3= 0.46;
x10TNF=0.05;
xN6 =1.0;
kNOMN= 2.0;
k106= 5.1*10^-2;
xN10= 0.2;
kTNFN =2.97;
x106 =8.0*10^-2;
kNR=0.05;
kTNFM=0.1;
k10R= 0.1;
SN =1.0;
xTNF10= 7.9*10^-2;
x1012=1.0*10^-2;
kNA=0.5;
xTNF6= 5.9*10^-2;
k10= 0.35;
kINOSN =1.5;
kTNF= 1.4;
S10= 1.0*10^-2;
kINOSM =0.1;
k6N= 0.2;
k12M= 0.303;
kINOSEC= 0.1;
k6M= 3.03;
x1210= 0.2525;
xINOSTNF =0.05;
k6TNF= 1.0;
k12= 5.0*10^-2;
kINOSd= 0.05;
x6TNF= 0.1;
kD= 0.15;
kINOS6= 2.0;
k6NO= 2.97;
kD6= 0.125;
xINOS6 =0.1;
x6NO= 0.4;
xD6= 0.85;
xINOS10= 0.1;
x610= 0.1782;
xDNO= 0.5;
xINOSNO= 0.3;
x66= 0.5;
kINOS= 0.101;
k6= 0.7;
kENOSEC= 0.05;
xENOSTNF= 0.4;
k10N=0.1;
S6= 1.0*10^-3;
dydt=zeros(19,1);%DAEs
% function f=HU1(x,n,h)
% these functions in separate files
% f=x^h/1+(x/n)^h;
%
% end
% function g=HU2(x,n,h)
%
% g=x^h/(x^h+n^h);
%
% end
% function r=HUD(x,n,h)
%
% r=1/1+(x/n)^h;
%
% end
R=1;
dydt(1)=(SP/kPT)*y(1)*(1-y(1))-(thetaP*y(1)/1+kPTB*y(1))-(kPTMT*y(2)*y(1))-kPTNT*y(3)*y(1);
dydt(2)=SMT*y(3)*Mv/1+kMTB*y(4)-kMT*y(2);
dydt(3)=SNT*R*Nv/((1+kNTB*y(4))*(1+kNTMT*y(2)))-kNT*y(3);
dydt(4)=(SB/1+kBPT)*y(4)*(1-y(4))-kBR*R*y(4)-kBNT*y(3)*y(4);
dydt(5)=SP*y(5)+thetaP*y(1)/1+kPTB*y(1)-kPS*y(5)/xPS+y(5)-kPBNA*y(9)*HU2(y(5),xPN,2);
dydt(6)=(-(kMP*HU2(y(5),xMP,2)+kMD*HU2(1-y(18),xMD,4)*(HU2(y(14),xMTNF,2)+kM6*HU2(y(15),xM6,2)))*HUD(y(16),xM10,2)*y(6)-kMR*(y(6)-SM));
dydt(7)=(kMP*HU2(y(5),xMP,2)+kMD*HU2(1-y(18),xMD,4))*(HU2(y(14),xMTNF,2)+kM6*HU2(y(15),xM6,2))*HUD(y(16),xM10,2)*y(6)-kMA*y(7);
dydt(8)=-((kNP*HU2(y(5),xNP,1))+kND*HU1(1-y(18),xND,2)+kNTNF*HU1(y(14),xNTNF,1)+kN6*HU1(y(15),xN6,2))*HUD(y(16),xN10,2)*y(8)-kNR*(y(8)-SN);
dydt(9)=(kNP*HU2(y(5),xNP,1))+kND*HU1(1-y(18),xND,2)+kNTNF*HU1(y(14),xNTNF,1)+kN6*HU1(y(15),xN6,2)*HUD(y(16),xN10,2)*y(8)-kNA*y(9);
dydt(10)=(kINOSN*y(9)+kINOSM*y(7)+kINOSEC*HU1(y(14),xINOSTNF,2)+kINOS6*HU1(y(15),xINOS6,2))*HUD(y(16),xINOS10,2)*HUD(y(19),xINOSNO,4)-kINOSd*y(10);
dydt(11)=kINOS*(y(10)-y(11));
dydt(12)=kENOSEC*HUD(y(14),xENOSTNF,1)*HUD(y(5),xENOSP,1)-kENOS*y(12);
dydt(13)=kNO3*(y(19)-y(13));
dydt(14)=(kTNFN*y(9)+kTNFM*y(7))*HUD(y(16),xTNF10,2)*HUD(y(15),xTNF6,3)-kTNF*y(14);
dydt(15)=(k6N*y(9)+y(7))*(k6M+k6TNF*HU2(y(14),x6TNF,2)+k6NO*HU2(y(19),x6NO,2))*HUD(y(16),x610,2)*HUD(y(16),x66,1)-k6*(y(15)-S6);
dydt(16)=(k10N*y(9)+y(7))*(k10MA+k10TNF*HU2(y(14),x10TNF,4)+k106*HU2(y(15),x106,4))*((1-k10R)*HUD(y(17),x1012,4)+k10R)-k10*(y(16)-S10);
dydt(17)=k12M*y(7)*HUD(y(16),x1210,2)-k12*y(17);
dydt(18)=kD*(1-y(18))*(y(18)-0.05)-(y(18)-0.05)*kD6*HU2(y(15),xD6,6)*(1/xDNO^2+y(19)^2);
dydt(19)=y(11)*(1+kNOMN*(y(7)+y(9)))+y(12);
end
5.- and here is the caller
clear all;clc;close all
global SP
global kPT
global thetaP
global kPTB
global kPTMT
global kPTNT
global SMT
global Mv
global kMT
global kMTB
global SNT
global Nv
global kNTB
global kNTMT
global kNT
global SB
global kBPT
global kBR
global kBNT
global kPBNA
global xPN
global kPS
global xPS
global kMP
global xMP
global kMD
global xMD
global xMTNF
global kM6
global xM6
global xM10
global kMR
global SM
global kMA
global kNP
global xNP
global kND
global xND
global kNTNF
global xENOSP
global k10MA
global xNTNF
global kENOS
global k10TNF
global kN6global
global kNO3
global x10TNF
global xN6global
global kNOMN
global k106
global xN10
global kTNFNglobal
global x106global
global kNR
global kTNFM
global k10R
global SN
global xTNF10
global x1012
global kNA
global xTNF6
global k10
global kINOSN
global kTNF
global S10
global kINOSM
global k6N
global k12M
global kINOSEC
global k6M
global x1210
global xINOSTNF
global k6TNF
global k12
global kINOSd
global x6TNF
global kD
global kINOS6
global k6NO
global kD6
global xINOS6
global x6NO
global xD6
global xINOS10
global x610
global xDNO
global xINOSNO
global x66
global kINOS
global k6
global kENOSEC
global xENOSTNF
global k10N
global S6
SP= 0.60;
kPT=3.7*10^4;
thetaP =1.35*10^-4;
kPTB= 3.1;
kPTMT=6.3*10^-3;
kPTNT=6.1*10^-4;
SMT=2.6*10^-2;
Mv=0.3;
kMT=6.43*10^-5;
kMTB=36.0;
SNT=7.0*10^-7;
Nv =1*10^8;
kNTB=36.0;
kNTMT=0.16;
kNT=6.1*10^-2;
SB =4.6*10^-2;
kBPT=26.0;
kBR= 0.14;
kBNT=4.0*10^-8;
kPBNA=5.8;
xPN= 0.5;
kPS =6.9*10^3;
xPS=1.3*10^4;
kMP=1.01;
xMP =-37.5;
kMD=5.0*10^-2;
xMD = 0.75;
xMTNF=0.4;
kM6=0.1;
xM6 =1.0;
xM10 =0.297;
kMR=0.05;
SM= 1.0;
kMA=0.2;
kNP= 33.75;
xNP=56.25;
kND= 0.05;
xND =0.4;
kNTNF= 0.2;
xENOSP =1.015;
k10MA=0.1;
xNTNF= 2.0;
kENOS= 4.0;
k10TNF= 1.485;
kN6 =1.5;
kNO3= 0.46;
x10TNF=0.05;
xN6 =1.0;
kNOMN= 2.0;
k106= 5.1*10^-2;
xN10= 0.2;
kTNFN =2.97;
x106 =8.0*10^-2;
kNR=0.05;
kTNFM=0.1;
k10R= 0.1;
SN =1.0;
xTNF10= 7.9*10^-2;
x1012=1.0*10^-2;
kNA=0.5;
xTNF6= 5.9*10^-2;
k10= 0.35;
kINOSN =1.5;
kTNF= 1.4;
S10= 1.0*10^-2;
kINOSM =0.1;
k6N= 0.2;
k12M= 0.303;
kINOSEC= 0.1;
k6M= 3.03;
x1210= 0.2525;
xINOSTNF =0.05;
k6TNF= 1.0;
k12= 5.0*10^-2;
kINOSd= 0.05;
x6TNF= 0.1;
kD= 0.15;
kINOS6= 2.0;
k6NO= 2.97;
kD6= 0.125;
xINOS6 =0.1;
x6NO= 0.4;
xD6= 0.85;
xINOS10= 0.1;
x610= 0.1782;
xDNO= 0.5;
xINOSNO= 0.3;
x66= 0.5;
kINOS= 0.101;
k6= 0.7;
kENOSEC= 0.05;
xENOSTNF= 0.4;
k10N=0.1;
S6= 1.0*10^-3;
tspan = [0:120];
yo=[1 1000 1000 0 0 1000 0 1000 0 0 0 0 0 1.1 1.02 1.05 1.2 0 0];
figure(1)
hold all
for i=1:19
% figure(i)
[t,y]=ode15s(#(t,y) Biogearsmcdaniel(t,yo),tspan,yo);
plot(t,y(:,i))
hold on
end
grid on
6.- there's no need to repeat the hold on inside the for loop, just overlap each resulting plot
yes, all repeated, too many lines, but it's good practice to post as soon as the script is working; overworking scripts often go back to errors initially solved.
Hope it helps
John BG
jgb2012#sky.com

Related

Not Sure How to Fix Errors Using 'ODE45' Command

I am having trouble figuring out how to fix my script, specifically using the ODE45 command.
This is what I have so far:
clc; clear all;
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40 IC
I11 = 160;
I22 = 400;
I33 = 400;
Mx = 0;
My = 0;
Mz = 45;
w10 = 2;
w20 = -1;
w30 = 1;
eps10 = 0;
eps20 = 0;
eps30 = 0;
eps40 = 1;
IC = [w10 w20 w30 eps10 eps20 eps30 eps40];
function soln = DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40
w1 = y(1);
w2 = y(2);
w3 = y(3);
eps1 = y(4);
eps2 = y(5);
eps3 = y(6);
eps4 = y(7);
w1_dot = Mx - w2*w3*(I33-I22)/I11;
w2_dot = My - w1*w3*(I11-I33)/I22;
w3_dot = Mz - w1*w2*(I22-I11)/I33;
eps1_dot = .5*(w1*eps4-w2*eps3+w3*eps2);
eps2_dot = .5*(w1*eps3+w2*eps4-w3*eps1);
eps3_dot = .5*(-w1*eps2+w2*eps1+w3*eps4);
eps4_dot = -.5*(w1*eps1+w2*eps2+w3*eps3);
soln = [w1_dot; w2_dot; w3_dot; eps1_dot; eps2_dot; eps3_dot; eps4_dot];
end
I recently though the issues was with my variables, which is why I defined them all as global.
When I try to run the following in the command window:
[t, y] = ode45(#(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);
I get these errors:
>> [t, y] = ode45(#(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);
Undefined function or variable 'DynEqn1'.
Error in #(t,y)DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)
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);
I've tried researching it on Mathworks and other websites, but couldn't figure out what is the issue.
I'm not too familiar using the 'ODE45' function as well.
Any help is appreciated. Thank you.
Are you defining a local function inside a script file? If so, bear in mind that "Local functions are only visible within the file where they are defined. They are not visible to functions in other files, and cannot be called from the Command Window." (Ref.)
You need to either call ode45(...DynEqn1...) from the script file, rather than the command line, or create a separate file to make the function visible to the outside world.

Boundary value problem in MATLAB, issue with fsolve

I am trying to solve and ODE with boundary conditions at 0 and end, ws.mat can be downloaded at https://gofile.io/?c=RYzPsO
clear all
clc
global omega eta_max_ode eta F T Tp
eta_max_ode = 10;
omega=0.76;
load('ws','T','Tp','F','eta')
IC=[0,1];
opt = optimset('Display','off','TolFun',1E-20);
FI = fsolve(#(FI) eval_boundary_UVWTI(FI),IC,opt)
[eta_ode_i, fg_ode_i] = solve_UVWTI(FI);
sol_i = [fg_ode_i];
eta_i = eta_ode_i;
plot(eta_i,sol_i(:,1))
function [dfi]=UVWTI(t,fi)
global omega eta_max_ode eta F T Tp
for i=1:length(eta)
if eta(i)<t
else
inde=i;
break
end
end
A11=0;
A12=1;
A21=0;
A22=-(T(inde)^(1-omega))*F(inde)-omega*Tp(inde)/T(inde)+Tp(inde)/T(inde);
dfi=zeros(2,1);
dfi(1)=A11*fi(1)+A12*fi(2);
dfi(2)=A21*fi(1)+A22*fi(2);
end
function [eta_ode_i, fg_ode_i] = solve_UVWTI(FI)
global eta_max_ode eta
options = odeset('RelTol',1e-9,'AbsTol',1e-9);
[eta_ode_i, fg_ode_i] = ode45(#UVWTI,eta,FI,options);
size(fg_ode_i);
end
function [gi] = eval_boundary_UVWTI(FI)
% Get the solution to the ODE with inital condition F
[eta_ode_i, fg_ode_i] = solve_UVWTI(FI);
% Get the function values (for BCs) at the starting/end points
w_start = fg_ode_i(1,1); %w(0) = 0
w_end = fg_ode_i(end,1); %w(inf) = 0
% Evaluate the boundary function
gi = [
w_start
w_end - 1
];
end
I obtained the correct behaviour this is the solution tending to a constant. However, I should get sol_i(:,1) tending to 1 and fsolve does not seem to calculate the correct initial condition so that this happen. What's wrong in the code? eval_boundary_UVWTI() seems to be correct

How to write function correctly

I'm making a Matlab program for cell growth,
I have a problem with some function in main.m and I found some functions that I thought are written wrong way:
function y = f(c)
y = 0.5*(1-tanh(4*c-2));
function y = h(c)
y = 0.5*f(c);
function y = g(c)
global beta
y = beta*exp(beta*c);
%y=1+0.2*c;
main.m
%%main program
clear; clc;
global alpha beta gamma
%set parameter values
alpha = 0.9; beta = 0.5; gamma = 10;
dx = 1; X = 210; dt = 0.04; T = 16;
c0 = 1;
%set up arrays
x = [dx:dx:X]; Nx = round(X/dx); Nt = round(T/dt);
p = zeros(1,Nx); nextp = zeros(1,Nx);
q = zeros(1,Nx); nextq = zeros(1,Nx);
n = zeros(1,Nx); nextn = zeros(1,Nx);
u = zeros(1,Nx); v = zeros(1,Nx); r = zeros(1,Nx); c = zeros(1,Nx);
P = zeros(Nt,Nx); Q = zeros(Nt,Nx); N = zeros(Nt,Nx);
%set initial values
p = exp(-0.1.*x);
function y = f(c)
y = 0.5*(1-tanh(4*c-2));
function y = h(c)
y = 0.5*f(c);
function y = g(c)
global beta
y = beta*exp(beta*c);
%y=1+0.2*c;
%start FDM time-stepping
for k=1:Nt
r = p + q;
c = (c0.*gamma./(gamma+p)).*(1-alpha.*(p+q+n));
for i=2:Nx-1
u(i)=((p(i+1)-p(i-1))*r(i)*(r(i+1)-r(i-1))+ 4*p(i)*r(i)*...
(r(i+1)-2*r(i)+r(i-1))-p(i)*(r(i+1)-r(i-1))^2)/(2*...
(dx*r(i))^2);
v(i)=((q(i+1)-q(i-1))*r(i)*(r(i+1)-r(i-1))+ 4*q(i)*r(i)*...
(r(i+1)-2*r(i)+r(i-1))-q(i)*(r(i+1)-r(i-1))^2)/(2*...
(dx*r(i))^2);
end
nextp=p+dt.*(u+g(c).*p.*(1-(p+q+n))-f(c).*p);
nextq=q+dt.*(v+f(c).*p-h(c).*q);
nextn=n+dt.*(h(c).*q);
p=nextp;
q=nextq;
n=nextn;
P(k,:)=p; Q(k,:)=q; N(k,:)=n;
end
figure(1)
for n=1:500:Nt
plot(P(n,:),'LineWidth',1.2); hold on;
end
axis([0 270 0 0.6]);
figure(2)
for n=1:500:Nt
plot(Q(n,:),'LineWidth',1.2); hold on;
end
axis([0 270 0 0.6]);
figure(3)
for n=1:500:Nt
plot(N(n,:),'LineWidth',1.2); hold on;
end
axis([0 270 0 1]);
animation.m
%create image for cells
rand('state', sum(100*clock));
prefix='t';
Nm=0;
figure(1)
for n=1:250:Nt
Nm=Nm+1;
for i=1:Nx
tP=round(P(n,i)),tQ=round(Q(n,i)),tN=round(N(n,i));
for m=1:tP
theta=2*pi*rand();
plot(i*sin(theta),i*cos(theta),'b.'); hold on;
end
for m=1:tQ
theta=2*pi*rand();
plot(i*sin(theta),i*cos(theta),'r.'); hold on;
end
for m=1:tN
theta=2*pi*rand();
plot(i*sin(theta),i*cos(theta),'k.'); hold on;
end
axis square
axis([-300 300 -300 300])
end
print('-djpeg','-r100',sprintf('%s_%s',prefix,num2str(Nm)));
end
clear MM
for i=1:Nm
[XX,map]=imread(sprintf('%s_%s',prefix,num2str(i)),'jpeg');
imagesc(XX);
MM(i)=getframe;
pause(0.1);
end
Please help me solve this problem..
You're main.m is a script, not a function (it doesn't start with the word function), see function and Scripts vs. Functions).
In short: function declaration is not allowed in command-line or scripts only in function files.
Do as oro777 advises,
create a seperate file for each function.
Another way is to turn your main.m into a function too, by starting it with function main. Then decleration of additional functions is allowed in the same file, but these are all local functions which means they will only be available from within that file. You can not call them from outside the file they were declared in.
You should write the output error so we can see which function is badly written. At first view, I would say you should use longer function names because with only one letter, it may easily shadow with a variable name and I would advise not to use global variables.
I see that your functions are defined in the same file as the main program, I would advise to create one function per file. For example a f_function m-file with the following code.
function y = f_function(c)
y = 0.5*(1-tanh(4*c-2));
Do the same for your two other functions and place your newly created m-files in the same folder as your main program.

Pass extra variable parameters to ode15s function (MATLAB)

I'm trying to solve a system of ordinary differential equations in MATLAB.
I have a simple equation:
dy = -k/M *x - c/M *y+ F/M.
This is defined in my ode function test2.m, dependant on the values X and t. I want to trig 'F' with a signal, generated by my custom function squaresignal.m. The output hereof, is the variable u, spanding from 0 to 1, as it is a smooth heaviside function. - Think square wave. The inputs in squaresignal.m, is t and f.
u=squaresignal(t,f)
These values are to be used inside my function test2, in order to enable or disable variable 'F' with the value u==1 (enable). Disable for all other values.
My ode function test2.m reads:
function dX = test2(t ,X, u)
x = X (1) ;
y = X (2) ;
M = 10;
k = 50;
c = 10;
F = 300;
if u == 1
F = F;
else
F = 0,
end
dx = y ;
dy = -k/M *x - c/M *y+ F/M ;
dX = [ dx dy ]';
end
And my runscript reads:
clc
clear all
tstart = 0;
tend = 10;
tsteps = 0.01;
tspan = [0 10];
t = [tstart:tsteps:tend];
f = 2;
u = squaresignal(t,f)
for ii = 1:length(u)
options=odeset('maxstep',tsteps,'outputfcn',#odeplot);
[t,X]=ode15s(#(t,X)test2(t,X,u(ii)),[tstart tend],[0 0],u);
end
figure (1);
plot(t,X(:,1))
figure (2);
plot(t,X(:,2));
However, the for-loop does not seem to do it's magic. I still only get F=0, instead of F=F, at times when u==1. And i know, that u is equal to one at some times, because the output of squaresignal.m is visible to me.
So the real question is this. How do i properly pass my variable u, to my function test2.m, and use it there to trig F? Is it possible that the squaresignal.m should be inside the odefunction test2.m instead?
Here's an example where I pass a variable coeff to the differential equation:
function [T,Q] = main()
t_span = [0 10];
q0 = [0.1; 0.2]; % initial state
ode_options = odeset(); % currently no options... You could add some here
coeff = 0.3; % The parameter we wish to pass to the differential eq.
[T,Q] = ode15s(#(t,q)diffeq(t,q,coeff),t_span,q0, ode_options);
end
function dq = diffeq(t,q,coeff)
% Preallocate vector dq
dq = zeros(length(q),1);
% Update dq:
dq(1) = q(2);
dq(2) = -coeff*sin(q(1));
end
EDIT:
Could this be the problem?
tstart = 0;
tend = 10;
tsteps = 0.01;
tspan = [0 10];
t = [tstart:tsteps:tend];
f = 2;
u = squaresignal(t,f)
Here you create a time vector t which has nothing to do with the time vector returned by the ODE solver! This means that at first we have t[2]=0.01 but once you ran your ODE solver, t[2] can be anything. So yes, if you want to load an external signal source depending on time, then you need to call your squaresignal.m from within the differential equation and pass the solver's current time t! Your code should look like this (note that I'm passing f now as an additional argument to the diffeq):
function dX = test2(t ,X, f)
x = X (1) ;
y = X (2) ;
M = 10;
k = 50;
c = 10;
F = 300;
u = squaresignal(t,f)
if u == 1
F = F;
else
F = 0,
end
dx = y ;
dy = -k/M *x - c/M *y+ F/M ;
dX = [ dx dy ]';
end
Note however that matlab's ODE solvers do not like at all what you're doing here. You are drastically (i.e. non-smoothly) changing the dynamics of your system. What you should do is to use one of the following:
a) events if you want to trigger some behaviour (like termination) depending on the integrated variable x or
b) If you want to trigger the behaviour based on the time t, you should segment your integration into different parts where the differential equation does not vary during one segment. You can then resume your integration by using the current state and time as x0 and t0 for the next run of ode15s. Of course this only works of you're external signal source u is something simple like a step funcion or square wave. In case of the square wave you would only integrate for a timespan during which the wave does not jump. And then exactly at the time of the jump you start another integration with altered differential equations.

How to store variables in MATLAB workspace

I have a MATLAB function, when I try to run it, it does not store the output variables in the workspace. Please let me know the proper solution such that the variables in the function are stored in the workspace.
I have a following code in which I have to store values of variables T and Y in workspace.
function him1
k0 = ones(1,5);
exp=[0.2;0.12;0.24;0.2]; %//experimental data
time=[0;1;2;3]; %//time span
%// initial values of state variables
x01=1;
x02=1;
x03=1;
x04=1;
x0 = [x01,x02,x03,x04];
tspan = [min(time),max(time)];
k_opt = fminsearch(#minimize, k0)
function e = minimize(k0)
[~,y_hat] = ode45(#unit2, tspan, x0,[], k0);
% size(y_hat)
% y_hat = deval(sol, time(end)); % // evaluate solution at given times
e = sum((y_hat(end,:)' - exp).^2) % // compute squarederror '
end
% // plot with optimal parameter
[T,Y] = ode45(#unit2, tspan, [x01,x02,x03,x04], [], k_opt);
figure
subplot(1,2,1)
plot(time(end), exp, '*', 'markersize',15)
hold on
plot(T,Y, 'linewidth', 2)
end
function dx = unit2(t, x, k)
dx = zeros(4,1);
dx(1)=-k(1)*x(1)*7 + k(2)*x(2);
dx(2)=k(1)*x(1)*7 - k(2)*x(2) -k(3)*x(2)*x(2) + k(4)*x(3);
dx(3)=k(3)*x(2)*x(2) - k(4)*x(3)-k(5)*x(4);
dx(4)=k(5)*x(4);
end
It is a characateristic of functions, that only variables which are defined in the declatation are handed over to the workspace. (If you ignore more complex concepts like global variables and assignin)
If your main target is to get the calculation done and the variables in the workspace, than I suggest to convert it to an m-script instead of a function.
See: http://de.mathworks.com/help/matlab/matlab_prog/scripts-and-functions.html
You can try to identify your variables as global.