Simulating nonlinear differential quation in MATLAB? - matlab

I was assigned a program where I have to create a MATLAB model for the equation and figure as follows-- http://i.stack.imgur.com/wV0ro.png. Unfortunately, I've been stuck for quite a while.
or dh/dt = (-r^2*sqrt(2*g*h))/(0.5r+htan(phi))^2
where
g=386.4 in/s^2
h = 2+(34/64) in
r = 1/10 in
angle=30.519612098961595 degrees
I calculated for dh/dt, which is -0.185963075319895 in/s and time to empty t=13.611573134321043 s, which I did by t=h/-c1_solution.
My x and y range are:
t1_span = [0 t]
y1_span = [0 ; h]
My function is like this so far:
function hvt1 = leak(r,h,angle, g)
c1_solution_1 = (-(r(y1_span))^2 * sqrt(2*g*h(y1_span))) ;
c1_solution_2 = (0.5*r(t1_span)+h(t1_span)*tand(angle))^2 ;
c1_solution = c1_solution_1(1)/c1_solution_2(1) ;
hvt1 = c1_solution ;
So, this definitely needs work. I'm very inexperienced with this type of thing. I'm wondering how I can model how the container drains as a function of time. I'm guessing I'll have to use ode45. I know how to format ode45 in my program, but I'm having trouble with creating the functions.
Thanks in advance. :)

There is nothing mysterious or unclear about the documentation of ode45. As I said in comment, it's unclear what you are asking, and you should rewrite the differential equation in your post instead of linking to an external image...
In this example, you can replace solver by any matlab solver. r,g,phi are the constants defined by your problem, h0 is your initial state and tspan is the timespan in which you are considering your solution. Some solvers allow you to specify a timestep, others choose it dynamically.
[t,h] = solver( #dh_dt, tspan, h0 );
function dh = dh_dt(t,h)
dh = - r*r*sqrt(2*g*h);
dh = dh / (.5*r + h*tan(phi))^2;
end

Related

MATLAB want to convert explicit euler algorithm to implicit euler algorithm for SYSTEM of 1st order ODEs

Before anything, I can't use ANY built-in ODE solvers for this. I coded this system of ODEs with explicit euler's method but I need to instead rewrite it with implicit euler's. If I just switch the "i" to "i+1" (ex "y(1,i)" to "y(1,i+1)") then the answer comes out obscenely wrong.
A_init= 4;
B_init= 1.1;
C_init= 4;
y0 = [A_init; B_init; C_init];
h = 20/100;
n = 100;
t0 = 0;
tf = 20;
t = linspace(t0,tf,n);
y = zeros(numel(y0) , n);
y(:, 1) = y0(:);
dAdt= #(a,b) 7.27*(b-a*b+ a-(8.375*10^-5)*a^3);
dBdt= #(b,a,c)(-b-a*b+c)/77.27;
dCdt= #(c,a) 0.4*(a-c);
for i = 1:n-1
y(1,i+1) = y(1,i) +h*feval(dAdt,y(1,i),y(2,i));
y(3,i+1) = y(3,i) +h*feval(dCdt,y(3,i),y(1,i));
y(2,i+1) = y(2,i) +h*feval(dBdt,y(2,i),y(1,i),y(3,i));
end
Your idea is correct, but remember that if you change the i on the right-hand side to i+1, you will have y(1,i+1), y(2,i+1), y(3,i+1) appearing on both sides of the equation. This means that you actually have to solve for y(1,i+1), y(2,i+1) and y(3,i+1) at each step. Since your three equations are coupled, you have to solve a nonlinear system of equations at each time-step, using fsolve or fzero.
Read the answer to this question, which shows how to do this for the single equation case.

Solve a matrix valued differential equation in Matlab

I am trying to solve a particular system of ODE's dF/dt = A*F, F_initial = eye(9). Being a Matlab novice, I am trying to somehow use the implemented ode45 function, and I found useful advises online. However, all of them assume A to be constant, while in my case the matrix A is a function of t, in other words, A changes with each time step.
I have solved A separately and stored it in a 9x9xN array (because my grid is t = 0:dt:2, N=2/dt is the number of time-steps, and A(:,:,i) corresponds to it's value at the i-th time step). But I can't implement this array in ode45 to eventually solve my ODE.
Any help is welcomed, and please tell me if I have missed anything important while explaining my problem. Thank you
First of all, F must be a column vector when using ode45. You won't ever get a result by setting F_initial = eye(9), you'd need F = ones(9,1).
Also, ode45 (documentation here, check tspan section) doesn't necessarily evaluate your function at the timesteps that you give it, so you can't pre-compute the A matrix. Here I'm going to assume that F is a column vector and A is a matrix which acts on it, which can be computed each timestep. If this is the case, then we can just include A in the function passed to ode45, like so:
F_initial = ones(9,1);
dt = 0.01;
tspan = 0:2/dt:2;
[t, F] = ode45(#(t,F) foo(t, F, Ainput), tspan, F_initial);
function f = foo(t, F, Ainput)
A = calculate_A(t, Ainput);
f = A*F;
end
function A = calculate_A(t, Ainput)
%some logic, calculate A based on inputs and timestep
A = ones(9,9)*sqrt(t)*Ainput;
end
The #(x) f(x,y) basically creates a new anonymous function which allows you to treat y as a constant in the calculation.
Hope this is helpful, let me know if I've misunderstood something or if you have other questions.

MatLab ode45 explanation

For a project I need to understand a matlab code, but as I am quite new I dont really understand what is happening. I have a function file and a script file.
Function:
function dxdt = sniffer_ode(t,x,par,tu)
X = x(1);
R = x(2);
k1 = par(1);
k2 = par(2);
k3 = par(3);
k4 = par(4);
S = interp1(tu(:,1),tu(:,2),t);
dxdt(1) = k3*S-k4*X;
dxdt(2) = k1*S-k2*X*R;
dxdt = dxdt(:); %dxdt should be column
and the script file:
%sniffer
close all
%initial conditions:
X0=0; R0=0;
x0=[X0 R0];
%parameters:
k1=1; k2=1; k3=1; k4=1;
par=[k1 k2 k3 k4];
%input:
tu=[ 0 , 0
1 , 0
1.01, 1
20 , 1];
[t,x] = ode45(#sniffer_ode,[0 20],x0, [],par,tu);
plot(t,x);
So the question is: What is happening? I also need to plot S in the same figure as X and R. How do I do this?
I appreciate your help!
This is a really basic Matlab question. There is tons of information about your requested topic. I think these slides will help you on the right path.
However, a quick explanation; the first code you provide is the function which describes your ordinary differential equation. This function always has to be of the form x' = f(t,x,...). Herein t is the time and x is the state. After the state (on the place of the dots ...) you can define other input parameters, such as is being done in your ode function. Furthermore, the interp1 function interpolates the data provided.
The second code you provide is the code you start within Matlab. Parameters are defined, after which the ordinary differential equation is solved and plotted.
If you have any further questions I would recommend that you first try to find your answer using a search engine.

Finding unknown limit of integration in MATLAB

I have an equation of the form c = integral of f(t)dt limiting from a constant to a variable (I don't want to show the full equation because it is very long and complex). Is there any way to calculate in MATLAB what the value of that variable is (there are no other variables and the equation is too difficult to solve by hand)?
Assume your limit is from cons to t and g(t) as your function with variable t. Now,
syms t
f(t) = int(g(t),t);
This will give you the indefinite integral. Now f(t) will be
f(t) = f(t)+f(cons);
You have the value of f(t)=c. So just solve the equation
S = solve(f(t)==c,t,'Real',true);
eval(S) will give the answer i think
This is an extremely unclear question - if you do not want to post the full equation, post an example instead
I am assuming this is what you intend: you have an integrand f(x), which you know, and has been integrated to give some constant c which you know, over the limits of x = 0, to x = y, for example, where y may change, and you desire to find y
My advice would be to integrate f(x) manually, fill in the first limit, and subtract that portion from c. Next you could employ some technique such as the Newton-Ralphson method to iteratively search for the root to your equation, which should be in x only
You could use a function handle and the quad function for the integral
myFunc = #(t) exp(t*3); % or whatever
t0 = 0;
t1 = 3;
L = 50;
f = #(b) quad(#(t) myFunc(t,b),t0,t1);
bsolve = fzero(f,2);
Hope it help !

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).