How do I get the values of y and y' for specific values of t from ode45 in Matlab? - matlab

I have to solve a second-degree differential equation and I specifically need the value of the first derivative of y at the final time point. My code is the following:
[T Y]=ode45(#(t y)vdp4(t,y,0.3),[0 1],[0.3/4,((3*0.3)^0.5)/2]);
I know the output will contain the values at which ode45 evaluated the function. To get the y values at specific time value at have it has been advised to give more than two time points in the MATLAB documentation. I did that too.
tspan=[0:0.01:1]
[T Y]=ode45(#(t y)vdp4(t,y,0.3),tspan,[0.3/4,((3*0.3)^0.5)/2]);
The T vector still does not have all the values from 0 to 1 (The last value is 0.39). This happens especially after multiple executions of ode45 function. I found something else in the MATLAB documentation: using "sol" structure to deval the values for specific t values. Is that the right way to go?
For reference, my differential equation is in the following function.
function dy = vdp4(t,y,k)
dy = zeros(2,1); % a column vector
dy(1)=y(2);
dy(2)=(y(2)^2-2*t*y(2)+2*y(1))/k+2;
end
Edit: I provided the parameter value. It should now be executable.

Try to plot your solution, you will find the answer

Related

Plotting the sum of series

I use this code and i don't know what it needs to work for my problem:
syms x k t
for t=0:10
num=((-1)^k)/k
t1=sin(8*3.1415*k*t)
S1=symsum((num*t1),k,1,2);
x=0.5-((1/3.1415)*S1);
end
Plot(x)
On the x axis I show time and on the y axis I show the function over four periods.
When I try to run the code I get the following error:
Undefined function 'symsum' for input arguments of type 'double'.
Maybe I can't use symsum with my argument type, but is there another function I can use? Sum also didn't work:
Error using sum Dimension argument must be a positive integer scalar within indexing range.
Since you want to plot x(t), you need to use plot(t,x) where t and x are vectors.
Instead of using for t=0:10, just let t=0:10 and calculate the corresponding x.
Also, the symbolic variable is just k.
syms k
t=0:10;
num=((-1)^k)/k;
t1=sin(8*3.1415*k*t);
S1=symsum((num*t1),k,1,2);
x=0.5-((1/3.1415)*S1);
plot(t,x)
It is noted that if you let t=0:10, then the sin(8*k*pi*t) will always be 0 since t is a vector of the integer from 0 to 10. The result of x(t) will be 5:
Output when t=0:10:
As you can see, the value of x(t) is very close to each other. Theoretically, they should all be 5. But there is some numerical approximation which leads to the small error.
You probably want non-integer t. Here is a output when t=0:0.1:10

Interpolate on scattered data in MATLAB

I have some series of data (y axis) vs time (x axis) relationship. I want to find specific time value of a specific "y value" by interpolating. I tried to use interp1 command. But the problem is, the curve passes that "y value" at several time values. interp1 command only gives the first time value. is there any way of performing interpolation so that i can find every time value?
thanks!
this is not a smart answer.
essentially you are trying to solve
y(t)=c
this can be written as
f(t)=y(t)-c = 0
then it remains to find the zero-crossings of function f(t) i guess there are functions to detect zero crossings or find roots of a dataset in matlab like fzero fnzero or crossing. but here is a home-made one to find points where value of a sine function is 0.5
t=1:50;
y=sind(4*pi.*t);
plot(t,y);
hold on;
t1=1:0.02:50;
y1=interp1(t,y,t1,'spline');
plot(t1,y1,'k');
c=0.5;
f=y1-c;
nn=length(y1);
k=0;
for i=1:nn-1
if f(i)*f(i+1) < 0
k=k+1;
allzeros(k)=i;
end
end
plot(t1(allzeros),y1(allzeros),'+');

How to retrieve accelerations from ode

As the title says I'd like to know how to retrieve the 2nd order derivative from a Matlab ode.
The system i'm trying to simulate is described by 12 1st order differential equations.
Let's explain:
...
[T,Y] = ode113(#sixdofsolver,time,Y0,options,settings);
T = 1700x1 vector
Y = 1700x12 matrix
Now if i do:
[dY] = sixdofsolver(T,Y,settings)
dY = 12x1 vector
I'd have expected to have a same-size matrix like Y.
What am I doing wrong?
You're on the right track. Your integration function sixdofsolver is likely designed first for used by Matlab's ODE solvers. These functions evaluate the function at one point in time (and a single state value) rather than across a range of times.
You either need to rewrite your sixdofsolver function so that it can handle more than a single time or your need to create a new function based on it that does that. In other words you need to vectorize the integration function. You probably have variable like y(1), y(2), ..., y(12). Well, now the input state vector is a matrix so you need to use something likey(:,1),y(:,2), ..., y(:,12). You may need to do other things like switch to element-wise operators. I can't help you more from what you've provided.

ODE System, IVP with differential initial condition

I am trying to model a system of three differential equations. This is a droplet model, parametrized vs the arc length, s.
The equations are:
dx/ds=cos(theta)
dz/ds=sin(theta)
(theta)/ds=2*b+c*z-sin(theta)/x
The initial conditions are that x,z, and theta are all 0 at s=0. To avoid the singularity on d(theta)/ds, I also have the condition that, at s=0, d(theta)/ds=b. I have already written this code:
[s,x]=ode23(#(s,x)drpivp(s,x,p),sspan,x0);
%where p contains two parameters and x0 contains initial angle theta, x, z values.
%droplet ODE function:
function drpivp = drpivp(s,x,p);
%x(1)=theta
%x(2)=x
%x(3)=z
%b is curvature at apex
%c is capillarity constant
b=p(1);
c=p(2);
drpivp=[2/p(1)+p(2)*x(3)-sin(x(1))/x(2); cos(x(1)); sin(x(1))];
Which yields a solution that spirals out. Instead of creating one droplet profile, it creates many. Of course, here I have not initialized the equation properly, because I am not certain how to use a different equation for theta at s=0.
So the question is: How do I include the initial condition that d(theta)/ds=b instead of it's usual at s=0? Is this possible using the built-in solvers on matlab?
Thanks.
There are several ways of doing this, the easiest is to simply add an if statement into your equation:
function drpivp = drpivp(s,x,p);
%x(1)=theta
%x(2)=x
%x(3)=z
%b is curvature at apex
%c is capillarity constant
b=p(1);
c=p(2);
if (s == 0)
drpivp=[b; cos(x(1)); sin(x(1))];
else
drpivp=[2/p(1)+p(2)*x(3)-sin(x(1))/x(2); cos(x(1)); sin(x(1))];
end

ODE45 and time interval

ODE45 function in matlab takes argument:
(function,[tinitial tfinal],yinitial)
But here, I believe, the span of time is predetermined. How can I assign a vector for it? I mean how do I solve the ODE for the domain 1:0.1:5?
Thank You.
If you need the values at specified points in time, simply go:
tspan = 1:0.1:5
[T Y] = ode45(odefun, tspan, y0)
T should be the same as tspan, and Y will be the corresponding values for each point in time.
You can assign the following vector for time span,and this way, you are saying to ode45 that you want the solution at specific time points (here , every 0.001)
tspan = ti:0.001:tf;
Output vectors ( T, X ) will have as many steps as the tspan vector has.
(But if you mean that you want the solver to take predetermined and constant steps for solving the equation , you can't do that.)