I am setting up a function that can solve the following differential equation for a laser system with the listed parameters. Whenever I run my code though, I keep getting errors that there are not enough input arguments for the equation (dydt). I am unsure where the fault in the code is occurring, but I believe it may have something to do with how I defined y. I expect to get a gaussian distribution in a plot, but the code keeps stopping at dydt. It does not process the variables. Thank you!
function dydt = 4_Lasers(t,y)
beta=1;
p0=10;
tau2=1e-7;
t = 1;
taupulse=tau2*100000;
taup=tau2/100;
p=p0*exp(-(t/taupulse)^2);
dydt = [(1/tau2)*(p-y(1)-y(1)*y(2)); (y(2)/taup)*
(y(1)-1)+beta*y(1)/tau2];
end
clear; close all;
[t,y] = ode45(#4_Lasers,[0 1e-6],[0; 0]);
plot(t,y(:,1),'r',t,y(:,2),'b')
title('p0=10,taupulse/tau2=1.5,tau2/taup=100');
xlabel('Time t');
ylabel('Amplitude');
legend('Photodensity','population inversion')
Cannot reproduce with this code:
clear; close all;
[t,y] = ode45(#Lasers,[0 1e-6],[0 0]);
plot(t,y(:,1),'r',t,y(:,2),'b')
title('p0=10,taupulse/tau2=1.5,tau2/taup=100');
xlabel('Time t');
ylabel('Amplitude');
legend('Photodensity','population inversion')
function dydt = Lasers(t,y)
beta=1;
p0=10;
tau2=1e-7;
t = 1;
taupulse=tau2*100000;
taup=tau2/100;
p=p0*exp(-(t/taupulse)^2);
dydt = [(1/tau2)*(p-y(1)-y(1)*y(2)); (y(2)/taup)*(y(1)-1)+beta*y(1)/tau2];
end
Related
I am trying to solve, using MATLAB, the time dependent Harmonic oscillator equation numerically. But I have no idea how to even get started as I have never learned this method in university:
X'' + w(t)^2 X = 0
with boundary conditions X_0 = 1, X_0' = 0 and Y_0 = 0, Y'_0 = 1
ode45 is a good start point.
Basic examples :
clear;close all;clc
tspan=[0 100]; % time
x_init=[5;0]; % known initial conditions
[t,y] = ode45(#vdp1,tspan,x_init);
figure(1)
plot(t,y(:,1),'r',t,y(:,2),'b')
grid on
title('Solution with ODE45');
xlabel('Time t');
ylabel('Solution y');
legend('y_1','y_2')
f=.5
[t,y] = ode45(#(t,y) vdp2(t,y,f),tspan,x_init);
figure(2)
plot(t,y(:,1),'r',t,y(:,2),'b')
grid on
title(['Solution with ODE45 and f = ' num2str(f)]);
xlabel('Time t');
ylabel('Solution y');
legend('y_1','y_2')
support functions:
function dydt = vdp1(t,y)
%
f=.1;
dydt = [y(2); sin(2*pi*f*t)*y(1)];
function dydt = vdp2(t,y,f)
%
dydt = [y(2); sin(2*pi*f*t)*y(1)];
This: https://uk.mathworks.com/matlabcentral/fileexchange/69951-runge-kutta-fixed-step-solvers?s_tid=srchtitle_harmonic%2520oscillator_81 among other examples has example1 solving damped and driven harmonic oscillators
And another harmonic oscillator solution with ODE solver:
https://uk.mathworks.com/matlabcentral/fileexchange/83233-matlab_program_solving_odes_harmonic_oscillators?s_tid=srchtitle_harmonic%20oscillator_9
You can also solve with symbolic expressions, this is Loren's post comparing symbolic and numerical solving
https://blogs.mathworks.com/loren/2010/04/08/odes-from-symbolic-to-numeric-code/?s_tid=srchtitle_harmonic%2520oscillator_105
I find the following concise introduction to ODE solving by Cleve Moler more useful than some full year university modules.
https://blogs.mathworks.com/cleve/2016/11/14/my-favorite-ode/?s_tid=srchtitle_harmonic%2520oscillator_131
When solving oscillators in polar coordinates you may need to have a look at
https://blogs.mathworks.com/cleve/2017/11/06/three-term-recurrence-relations-and-bessel-functions/?s_tid=srchtitle_harmonic%2520oscillator_140
In point 6 there's a wonderful introduction to Bessel functions and their zeros.
I try to save/see my variable m that is changed by an if loop during an ode45 differential equation solving process.
%Some parameter setting above
myfun=fprintf('m', num2str(m))
options = odeset('NonNegative',[1:3],'RelTol',1e-5,'AbsTol',1e-8, 'OutputFcn', #myfun);
[t,x] = ode45('myfunction', tspan, x0, options); %calculation
the if loop is in the equation file before all the other equations follows:
if x(1)>=threshold
m=1 ;
return
else
m=0 ;
end
I already took a look at the matlab description for the OutputFcn Option for ode45 and also read
https://de.mathworks.com/help/deeplearning/ug/customize-output-during-deep-learning-training.html
without understanding it properly. I am also open to other solutions to "see" which value m during the ode calculation has.
Create a separate file, and call this myOutputFcn.m, with the following code
function status = myOutputFcn(t,y,flag,threshold)
switch(flag)
case 'init' % code to run before integration
;
case '' % code to run after each integration step
% act on state
if y(1)>=threshold
m = 1;
else
m = 0;
end
% print m
fprintf('% 4.3f\t%i, t, m\n',t,m);
case 'done' % code to run when integation is finished
;
end
status = 0; % need to set status, otherwise integration will halt
end
Then to call this output function every iteration with the right threshold, you will have to do the following
threshold = 10; % idk, your threshold
options = odeset('NonNegative',[1:3],'RelTol',1e-5,'AbsTol',1e-8, 'OutputFcn', #(t,y,flag) myOutputFcn(t,y,flag,threshold));
[t,x] = ode45('myfunction', tspan, x0, options); %calculation
I'm trying to plot Exact VS FEM solution for this equation:
with boundary condition:
I followed this code for example: Example Code
It's fine for its case, but in my case I don't know about how to get the triangulation (for my case) for this line:
x(1)=0; x(2)=0.1; x(3)=0.3; x(4)=0.333; x(5)=0.5; x(6)=0.75;x(7)=1;
Here is my code:
clear all; close all;
x(1)=0*pi; x(2)=0.1*pi; x(3)=0.3*pi; x(4)=0.333*pi; x(5)=0.5*pi; x(6)=0.75*pi;x(7)=1*pi;
U = fem1d(x);
x2 = 0:0.01:pi; k2 = length(x2);
for i=1:k2,
u_exact(i) = soln(x2(i));
u_fem(i) = fem_soln(x,U,x2(i));
end
error = norm(u_fem-u_exact,inf)
plot(x2,u_fem,':',x2,u_exact)
hold; plot(x,U,'o')
xlabel('x'); ylabel('u(x) & u_{fem}(x)');
title('Solid line: Exact solution, Dotted line: FEM solution')
figure(2); plot(x2,u_fem-u_exact); title('Error plot')
xlabel('x'); ylabel('u-u_{fem}'); title('Error plot')
How to generate the triangulation values? Does anyone know?
Thank you
Let's suppose that we have the following solver for a system of first-order ODEs:
% func.m
function dydt = func(t,y)
dydt = [y(2); (1-y(1)^2)*y(2)-y(1)];
and the main code:
% solver.m
tspan=0:1:10;
[t,y] = ode45(#func,tspan,[2; 0]);
How to display in real-time the results, y1(t) and y2(t), for each time step t that the ode45 makes (t=0,1,2,...,10), without waiting for the whole code to finish?
The OutputFcn ode solver option should be used. For example, to plot the solution vs time, the built-in output function odeplot can be used:
options= odeset('OutputFcn',#odeplot);
[t,y] = ode45(#func,[0 200],[2; 0],options);
You can use your own output function. Here is an example:
myOutputFcn= #(t,y,flag)fprintf('t= %s y= %s\n',mat2str(t),mat2str(y))*0;
options= odeset('OutputFcn',myOutputFcn);
[t,y] = ode45(#f,0:1:10,[2; 0],options);
i want these two files to combine into one m.file, instead of using function to define the "monod" with passing parameters, i want to use anonymous functions passing the parameters. So to achieve in combining both two files.
%(file 1)
function dcdt = monod(t,c,k,ks,y,b)
dcdt = zeros(2,1);
dcdt(1) = -k*c(2)*c(1)/(ks+c(1));
dcdt(2) = y*k*c(2)*c(1)/(ks+c(1))-b*c(2);
% (file 2) ODE45
k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(#monod, [0,200],[200,1],options,k,ks,y,b);
% plot
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');
You can simply define a nested function within your file. Perfectly acceptable syntax. However, you will need to make File #2 an actual function as you can't define nested functions with a script file. To do this, just make it a function that accepts no inputs and returns nothing. :
function run_ode %// Change here
%// Include monod function here - watch the end keyword
function dcdt = monod(t,c,k,ks,y,b)
dcdt = zeros(2,1);
dcdt(1) = -k*c(2)*c(1)/(ks+c(1));
dcdt(2) = y*k*c(2)*c(1)/(ks+c(1))-b*c(2);
end %<----
%// Begin File #2
k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(#monod, [0,200],[200,1],options,k,ks,y,b);
% plot
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');
end %// Take note of this end too as we now have nested functions
Copy and paste the above code into a file called run_ode.m, then in the MATLAB Command Prompt, type in run_ode and push ENTER.
>> run_ode
You should get your desired results.
Alternatively, if you want to make use of anonymous functions as referenced in your question title, you can do this instead:
%// Change here
monod = #(t,c,k,ks,y,b) [-k*c(2)*c(1)/(ks+c(1)); y*k*c(2)*c(1)/(ks+c(1))-b*c(2)];
k = 3.7;ks=30;y=0.03;b=0.01;
options = odeset('Reltol',1.e-10,'AbsTol',1.e-10);
[t,c] = ode45(monod, [0,200],[200,1],options,k,ks,y,b); %// Change here too
% plot
C = c(:,1);
Xa = c(:,2);
figure(1);
grid on;
subplot(2,1,1);
plot(t,C);
title('Substrate aqueous concentration vs time(ODE45)');
xlabel('time');ylabel('Substrate aqueous concentration C')
subplot(2,1,2);
plot(t,Xa);
title('Active-cell concentration vs time');
xlabel('time');ylabel('Active-cell concentration Xa(ODE45)');
monod is now an anonymous function that takes in the 6 inputs, and outputs a two element column vector for use in ode45. Take note that ode45 is now changed so that the # is removed. monod is now already a handle to an anonymous function and so using # is not required.