MatLab ode45 explanation - matlab

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.

Related

MATLAB: Issue with Simulink "does not support code generation"

I have something similar to the following block diagram on Simulink, which looks rather messy especially with an increasing number of blocks.
I want to replace a 3-point summing block with a function block, while keeping the same output.
First I started by placing the code inside the function block:
function y = fcn(u)
sys1 = tf(0.5,[1 0 0 4]);
sys2 = tf([3 0.5],[1 0 15]);
sys3 = tf(1,[1 1]);
y = sys1 + sys2 + sys3;
However I was greeted with an error saying that Simulink does not support code generation.
"The 'tf' class does not support code generation."
I then came across a similar problem here: https://nl.mathworks.com/matlabcentral/answers/74770-is-there-any-way-to-disable-code-generation-in-simulink
I am trying to implement an extrinsic function or 'wrapper function' with some difficulty. I created a new script called myWrapper.m, containing the same code:
function y = myWrapper(u)
sys1 = tf(0.5,[1 0 0 0 4]);
sys2 = tf([3 5],[1 0 15]);
sys3 = tf(1,[1 1]);
y = sys1 + sys2 + sys3;
and the MATLAB Function edited to:
function y1 = fcn(u1)
y1 = myWrapper(u1);
The error persists.
I somehow want to access myWrapper.m file from the MATLAB Function block. Any pointers on how this should be done? Following the previous link given and the official docs I am ending up with something like this in my MATLAB Function block:
function y1 = fcn(u1)coder.extrinsic('myWrapper')
y1 = myWrapper(u1);
The last code above is syntactically incorrect and I am at a loss on how it should be done. MATLAB automaticaly corrects the above code to:
function y1 = fcn(u1,coder,extrinsic, myWrapper )
y1 = myWrapper(u1);
which is not what I want.
Any tips and/or suggestions on how this could be done would be appreciated.
A similar question was asked on the MathWorks forum here, two years ago, with no response.
I was going about tackling this problem completely wrong. Thanks to several helpful comments I realized that in order to replace the summing block, one must NOT remove the Transfer Function blocks which feed into the summing block.
A MATLAB Function does not support code generation (and rightly so) such that a transfer function may be implemented inside it. That is why the blocks simply feed into the MATLAB Function as follows.
The script would very simply be:
function y1 = fcn(u1, u2, u3)
x = (u1 + u2 +u3);
y1 = x;
end

How to write many functions depending on each other in matlab

I have some functions are depending on each ther , the functions are from this book page 136 http://www.cs.helsinki.fi/u/ahyvarin/papers/bookfinal_ICA.pdf .. I functions are presented below , How to write following functions in matlab ??
y(t) = W(t-1)*x(t)
h(t) = P(t-1)*y(t)
P(t)=(1/B)*Tri[P(t-1)-m(t)*h^T(t)]
m(t) = h(t)/(B+y^T(t))*h(t))
e(t) = x(t)-W^T(t-1)*y(t)
W(t) = W(t-1) + m(t)*e^T(t)
It is solving the weight matrix W(t) iteratively .. I tried to do like this in matlab but I did not work so may be you can advice to correct the code :
for i=1:10
e=randn(3,5000);
A=[1 0 0;-0.5 0.5 0;0.3 0.1 0.1];
x=A*e;
y(t) = W(t-1)*x(t)
h(t) = P(t-1)*y(t)
P(t)=(1/B)*Tri[P(t-1)-m(t)*h^T(t)]
m(t) = h(t)/(B+y^T(t))*h(t))
e(t) = x(t)-W^T(t-1)*y(t)
W(t) = W(t-1) + m(t)*e^T(t)
end
Thanks
Ok. I can't really understand what you want, but your code shows that you don't understand some moments. I will try to clarify some moments to you:
for i = 2:10
x = rand(3);
y = W(:,:,i-1)*x;
h = P(:,:,i-1)*y;
m=h/(1+y'*h);
P(:,:,i)=P(:,:,i-1)*m*h';
e=x-W(:,:,i-1)'*y;
W(:,:,i)=W(:,:,i-1)+m*e';
end
You must go something like this: 1. you calculate x and use it to calculate other functions.
2. all of them are matrices. So you need to define it first. For example y = ones(3) etc. 3.Thats not y^T or e^T. Its transposing. If you do not feel difference it's early for you to solve this task :)
And the last: Tri function will create a some kind of problems to you, but it's defined at 136 page.
P.S. i missed beta becouse of don't know what is it :)

Simulating nonlinear differential quation in 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

MATLAB Symbolic coeffs issues

I'm working with MATLAB's symbolic toolbox, and I'm having some issues pulling out the coefficients of derivatives. Maybe MATLAB can't do what I am looking for. Anyway, code that reproduces the issue I'm having is shown below:
clear ; close all; clc;
syms a b t
x = sym('x(t)');
y = sym('y(t)');
syms a b;
ra = a*cos(x);
radot = diff(ra, t);
xdot = diff(x,t);
ydot = diff(y,t);
% This one works as expected
works = coeffs(radot(1), xdot)
% This doesn't work as expected
fails = coeffs(radot(1), ydot)
Comments in the above code sections highlight what works and what does not work as expected. Specifically, the outputs are:
radot =
-a*sin(x(t))*diff(x(t), t)
works =
-a*sin(x(t))
fails =
-a*sin(x(t))*diff(x(t), t)
Does anyone know why this happens or whether I'm doing something wrong?
The result of the last line is constant with respect to ydot, and therefore the whole expression is seen as a single coefficient (a constant).
What is your expected result for coeffs(radot(1), ydot)?
It looks like you may be using coeffs for something that it wasn't meant for. Look at the help. It's designed to give the coefficients of a polynomial, not wether a differential equation is a function of one variable or another.
If you happen to be trying to take the derivative with respect to xdot and ydot, you can do this
syms z; % Subsitution variable for diff(x(t), t) and diff(y(t), t)
diff(subs(radot(1),xdot,z),z)
diff(subs(radot(1),ydot,z),z)
which returns
ans =
-a*sin(x(t))
ans =
0

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).