Interpolation within ode45 - matlab

I have a vector with discrete values that I need to pass into my ODE system and I want to use ode45 command. This vector needs to be interpolated within the solver when I use it. Is there a way this can be done?
I have a coupled system of linear ODEs.
dxdt = f(t)*x + g(t)*y
dydt = g(t)*x + h(t)*y
I have three vectors f(t), g(t) and h(t) as a function of t. I need to pass them into the the solver.
I can code up a Runge-Kutta solver in C or C++. I was suggested that doing it in Matlab would be quicker. Can someone suggest a way to do this?

Sure, you can use interp1. Suppose you have vectors fvec, gvec and tvec containing respectively the values of f, g, and the time points at which these values are taken, you can define your derivative function as:
dxydt = #(t,x) [interp1(tvec, fvec, t) * x(1) + interp1(tvec, gvec, t) * x(2)
interp1(tvec, gvec, t) * x(1) + interp1(tvec, hvec, t) * x(2)];
and use it in ode45:
[T,Y] = ode45(dxydt, tspan, [x0; y0]);

Related

How to solve coupled differential equation in matlab using ode45

I have two differential equations: da/dt=a(.3/a^3+.7)^1/2 and dτ/dt=1/a. The initial conditions are t=0; a=1 and τ=0, respectively. How can I solve the equations in Matlab? I need to calculate different values of a, t and τ also plot τ vs a. Thanks.
That's quite easy.
First write a function to implement your differential equation and save it with a filename corresponding to the function name:
function dy = my_ode(t,y)
dy(1) = y(1)*(0.3/y(1)^3 + 0.)^(1/2); % a
dy(2) = 1/dy(1); % tau
Then in MATLAB, call the ode45 solver with your function
[t,y] = ode45(#my_ode,[0 10],[1; 0]);
This is the result:

How to solve a coupled nonlinear first order differential equation?

I have a problem in the form of 2 equations and known initial conditions. The equations are:
dx/dt = (-a1*sin(y) + a2 + a3*sin(y-x)) / ((dy/dt)*a4*cos(y-x))
dy/dt = (a1*sin(x) -a5 + a6*x + a7*sin(y-x)) / ((dx/dt)*a8*cos(y-x))
where a1 to a8 are variables.
I am trying to plot x vs t and y vs t on MATLAB, but I am not sure how to solve this numerically or analytically. Any help would be appreciated!!
The ODE of your problem cannot be written as dy/dt=f(t,y) nor M(t,y)dy/dt=f(t,y). That means it is a Differential Algebraic Equation which has to be solved numerically in the form:
f(t, y, dy/dt)=0
In matlab this can be done with the command ode15i.
Therefore, the first step is to write the function in a proper way, in this case, one option is:
function f = cp_ode(t,y,yp,a)
f1 = (-a(1)*sin(y(2))+a(2)+a(3)*sin(y(2)-y(1)))/yp(2)*a(4)*cos(y(2)-y(1)) - yp(1);
f2 = (a(1)*sin(y(1))-a(5)+a(6)*y(1)+a(7)*sin(y(2)-y(1)))/yp(1)*a(8)*cos(y(2)-y(1)) - yp(2);
f = [f1 ; f2] ;
end
Then, the initial conditions and integration timespan can be set in order to call ode15i:
tspan = [0 10];
y0 = [1; 1] ;
yp0 = fsolve(#(yp)cp_ode(0,y0,yp,a),<yp0_guess>);
a = ones(1,8) ;
[t,y] = ode15i(#(t,y,yp)cp_ode(t,y,yp,a), tspan, y0, yp0);
It has to be noted that the initial conditions t, y, yp should fulfill the equation f(t, y, yp)=0. Here an fsolve is used to satisfy this condition.
The use of annonymus functions is to define the function with the parameters as inputs and then execute the ODE solver having defined the parameters in the main code.

How to solve a differential equation with non-constant coefficient?

I have an equation like this:
dy/dx = a(x)*y + b
where a(x) is a non-constant (a=1/x) and b is a vector (10000 rows).
How can I solve this equation?
Let me assume you would like to write a generic numerical solver for dy/dx = a(x)*y + b. Then you can pass the function a(x) as an argument to the right-hand side function of one of the ODE solvers. e.g.
a = #(x) 1/x;
xdomain = [1 10];
b = rand(10000,1);
y0 = ones(10000,1);
[x,y] = ode45(#(x,y,a,b)a(x)*y + b,xdomain,y0,[],a,b);
plot(x,y)
Here, I've specified the domain of x as xdomain, and the value of y at the bottom limit of x as y0.
From my comments, you can solve this without MATLAB. Assuming non-zero x, you can use an integrating factor to get a 10000-by-1 solution y(x)
y_i(x) = b_i*x*ln(x) + c_i*x
with 10000-by-1 vector of constants c, where y_i(x), b_i and c_i are the i-th entries of y(x), b and c respectively. The constant vector c can be determined at some point x0 as
c_i = y_i(x0)/x_0 - b_i*ln(x0)

Get coefficients of symbolic polynomial in Matlab

I have a Matlab function that returns a polynomial of the form:
poly = ax^2 + bx*y + cy^2
where a, b, and c are constants, and x and y are symbolic (class sym).
I want to get the coefficients of the polynomial in the form [a b c], but I'm running into the following problem. If the function returns poly = y^2, then coeffs(poly) = 1. I don't want this – I want it to return [0 0 1].
How can I create a function that will give me the coefficients of a symbolic polynomial in the form that I want?
You can use sym2poly if your polynomial is a function of a single variable like your example y^2:
syms y
p = 2*y^2+3*y+4;
c = sym2poly(p)
which returns
c =
2 3 4
Use fliplr(c) if you really want the coefficients in the other order. If you're going to be working with polynomials it would probably also be a good idea not to create a variable called poly, which is the name of a function you might want to use.
If you actually need to handle polynomials in multiple variables, you can use MuPAD functions from within Matlab. Here is how you can use MuPAD's coeff to get the coefficients in terms of the order of variable they precede (x or y):
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
c = eval(feval(symengine,'coeff',p,v))
If you want to extract all of the information from the polynomial, the poly2list function is quite helpful:
syms x y
p = 2*x^2+3*x*y+4*y;
v = symvar(p);
m = eval(feval(symengine,'poly2list',p,v));
c = m(:,1); % Coefficients
degs = m(:,2:end); % Degree of each variable in each term
The polynomial can then be reconstructed via:
sum(c.*prod(repmat(v,[size(m,1) 1]).^degs,2))
By the way, good choice on where you go to school. :-)
There is also an alternative to this problem. For a given degree, this function returns a polynomial of that degree and its coefficients altogether.
function [polynomial, coefficeint] = makePoly(degree)
syms x y
previous = 0 ;
for i=0:degree
current = expand((x+y)^i);
previous= current + previous ;
end
[~,poly] = coeffs(previous);
for j= 1:length(poly)
coefficeint(j) = sym(strcat('a', int2str(j)) );
end
polynomial = fliplr(coefficeint)* poly.' ;
end
Hope this helps.

How do you plot nonlinear differential equations in matlab

Dx=y
Dy=-k*y-x^3+9.8*cos(t)
inits=('x(0)=0,y(0)=0')
these are the differential equations that I wanted to plot.
first, I tried to solve the differential equation and then plot the graph.
Dsolve('Dx=y','Dy=-k*y-x^3+9.8*cos(t)', inits)
like this, however, there was no explicit solution for this system.
now i am stuck :(
how can you plot this system without solving the equations?
First define the differential equation you want to solve. It needs to be a function that takes two arguments - the current time t and the current position x, and return a column vector. Instead of x and y, we'll use x(1) and x(2).
k = 1;
f = #(t,x) [x(2); -k * x(2) - x(1)^3 + 9.8 * cos(t)];
Define the timespan you want to solve over, and the initial condition:
tspan = [0, 10];
xinit = [0, 0];
Now solve the equation numerically using ode45:
ode45(f, tspan, xinit)
which results in this plot:
If you want to get the values of the solution at points in time, then just ask for some output arguments:
[t, y] = ode45(f, tspan, xinit);
You can plot the phase portrait x against y by doing
plot(y(:,1), y(:,2)), xlabel('x'), ylabel('y'), grid
which results in the following plot