how to make this function periodic in MATLAB? - matlab

I have wrote this code in MATLAB editor and want this function to be periodic (period = 0.8s)
HR=75;
E_max=2.0;
E_min=0.06;
t_c=60/HR;
T_max=0.2+0.15*t_c;
t=0:0.0001:t_c;
t_n=t/T_max;
E_n=1.55*(((t_n/0.7).^1.9)./(1+(t_n/0.7).^1.9)).*(1./(1+(t_n/1.17).^21.9));
E=(E_max-E_min)*E_n+E_min;
plot(t,E)
I want to use the function in simulink as a voltage source. so i do not need a point but the whole function. so I need a function that takes the overall time (for example 20 secs) and gives the output CONTINUSELY (like a Sin function).
the function and it's shape is:
http://tinypic.com/r/2641a1s/8

Create your data in the MATLAB base workspace by running your code in MATLAB before running your Simulink model. Then use the Repeating Sequence Block. Use your variable t as the Time Values and E as the Output Values. You'll also need to make sure that the maximum step size that the solver takes is min(diff(t)), which in the case of your data is 0.0001.

Well you are confusing the Matlab vector and a function
The function gives a value for any query in the domain of the function.
i.e. if the domain is [-1,2] then f(x) where x in [-1,2] should give and only give one value. such as y = 3x + 2.
If you want The function then you should make the script into a function.
cardiac.m
function y = cardiac(x,cropPeriod,period)
t_n = mod(x*cropPeriod/period,cropPeriod);
y=1.55*(((t_n/0.7).^1.9)./(1+(t_n/0.7).^1.9)).*(1./(1+(t_n/1.17).^21.9));
end
Then, save the file as cardiac.m and will give you the function.
And call the function as cardiac(x,0.8) then this will give you the value you want
demo.m
t = 0:0.01:10; % choose arbitrary range.
p = 0.8; % period
cropPeriod = 4; % explained below
y = cardiac(t,cropPeriod,p);
plot(t,y);
It is clear that the equation given in http://tinypic.com/view.php?pic=j75jzk&s=8#.U7iH43VdXJ8 is different from the plot on the image. Since I don't know the period of the function, you can simply choose appropriate number cropPeriod until you are satisfied.
Example Plot
If you just want to make it to have period p
MATLAB plot is nothing but a series of data point. when you call plot(t,E), MATLAB plots a points in position (t(1),E(1)) and (t(2),E(2)) ... Thus, if you want to scale it just type
plot(p * t,E);
xlabel('sec(s)'); % Give x axis label
ylabel('E(t)')
where p = 0.8

Related

How to set initial condition t=0 for Simulink integrator loop

I have a differential equation: dx/dt = a * x. Using Matlab Simulink, I need to solve this equation and output it using Scope block.
The problem is, I don't know how to specify an initial condition value t = 0.
So far I have managed to create a solution that looks like this:
I know that inside integrator, there is a possiblity to set "Initial condition" but I can't figure out how that affects the final result. How can I simply set the value of x at t = 0; e.i. x(0) = 6?
Let's work this problem through analytically first so we know if the model is correct.
dx/dt = a*x % Seperable differential equation
=> (1/x) dx = a dt % Now we can integrate
=> ln(x) = a*t + c % We can determine c using the initial condition x(0)
=> ln(x0) = a*0 + c
=> ln(x0) = c
=> x = exp(a*t + ln(x0)) % Subbing into 3rd line and taking exp of both sides
=> x = x0 * exp(a*t)
So now we have an idea. Let's look at this for t = 0 .. 1, x0 = 6, a = 5:
% Plot x vs t using plain MATLAB
x0 = 6; a = 5;
t = 0:1e-2:1; x = x0*exp(a*t);
plot(t,x)
Now let's make a Simulink model which acts as a numerical integrator. We don't actually need the Integrator block for this application, we simply want to add the change at each time step!
To run this, we must first set a couple of things up. In Simulation > Model Configuration Parameters, we must set the time step to match the time step we've used to switch between dx/dt and dx (2nd Gain block).
Lastly, we must set the initial condition for x0, this can be done in the Memory block
Setting the end time to 1s and running the model, we see the expected result in the Scope. Because it matches our analytical solution, we know it is correct.
Now we understand what's going on, we can re-introduce the integration block to make the model more flexible. Using the integrator means that dt is automatically calculated, and we don't need to micro-manage the Gain block, in fact we can get rid of it. We still need a Memory block though. We now also need intial conditions in both the integrator, and the memory block. Put scopes in different locations and just complete the first few time steps to work out why!
Note that the initial conditions are less clear when using the integrator block.
The way to think about the integrator blocks is either completely in the Laplace picture, or as representing the equivalent integral equation for the IVP
y'(t)=f(t,y(t)), y(0) = y_0
is equivalent to
y(t) = y_0 + int(s=0 to t) f(s,y(s)) ds
The feed-back loop in the block diagram realizes almost literally this fixed-point equation for the solution function.
So there is no need for complicated constructions and extra blocks.

How to force dde23 function to generate output after fixed time step

I am solving a delay differential equation using MATLAB dde23 function. I want to use the output generated by the first dde23 function in the second dde23 function. Here is the code
tspan=[0:1:1440]';
x0=1.7;
%1st function
% options = ddeset('OutputFcn',#odeplot,'OutputSel',1);
sol = dde23(#dd,70,x0,tspan,options);
y_obs=sol.y;
tspan_new=sol.x;
%{2nd function
x1=[x0 ; 0.1; 0.01; 0.01];
final_sol = dde23(#ddc,70,x1,tspan,[],y_obs);
y_fit=final_sol.y;
tdata=final_sol.x;
%}
The time series I generated as an input to the first function is of size 1441 but the size of tspan_new and y_obs is 212 (generated from the dde23 output). I am unable to understand why the size is changing.
Is it possible to output y_obs at each time point provided in the input i.e. is it possible to obtain y_obs of length 1441 in this case ?
Since the size of output is different I am unable to use y_obs vector in my second function. The size of y_fit and tdata is again entirely different from y_obs and tspan.
Unlike the ODE Suite that implements a dense output routine as part of its time march, dde23 requires an explicit post-deval to accomplish what you're after:
tspan=[0:1:1440]';
x0=1.7;
%1st function
sol = dde23(#dd,70,x0,tspan([1,end]),options);
y_obs = deval(sol,tspan);
This function uses local Hermite cubic interpolation on the mesh generated by its dynamic time-stepping routine to approximate the y value at the requested t values.

No output while using "gmres" in Matlab

I want to solve a system of linear equalities of the type Ax = b+u, where A and b are known. I used a function in MATLAB like this:
x = #(u) gmres(A,b+u);
Then I used fmincon, where a value for u is given to this expression and x is computed. For example
J = #(u) (x(u)' * x(u) - x^*)^2
and
[J^*,u] = fmincon(J,...);
withe the dots as matrices and vectors for the equalities and inequalities.
My problem is, that MATLAB delivers always an output with information about the command gmres. But I have no idea, how I can stop this (it makes the Program much slower).
I hope you know an answer.
Patsch
It's a little hidden in the documentation, but it does say
No messages are displayed if the flag output is specified.
So you need to call gmres with at least two outputs. You can do this by making a wrapper function
function x = gmresnomsg(varargin)
[x,~] = gmres(varargin{:});
end
and use that for your handle creation
x = #(u) gmresnomsg(A,b+u);

How tick labels on one of the plot's axis can be multiplied in MATLAB?

I am currently trying to make 'nice looking' axis on my plot in Matlab. The values are samples where each is taken every 20ms. So on X axis I'd like to have time in ms. My general code for plotting data is very simple:
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
So far I've been able to correctly display sample numbers on this axis:
Code:
set(gca,'XTick',(1:size(data.matrix,1))*20);
Result (a):
In the given example the number of samples equals 184, that makes:
time = 184 * 20ms = 3680ms
Because changing the XTick value didn't do much of a change, I've tested XTickLabel property:
Code:
set(gca,'XTickLabel',ceil(linspace(0,size(data.matrix,1)*20,10)));
Result (b):
Code:
set(gca,'XTickLabel',0:ceil((size(data.matrix,1)*20)/10):size(data.matrix,1)*20);
Result (c):
As you may see, the results aren't the worst one. But this is not what I am trying to achieve. My goal is to have values like this:
So it simply first plot's (result a) X axis multiplied by 20.
Can someone please tell me how to achieve this?
when you use :
plot(1:size( data.matrix,1), data.matrix(:,1),'b');
The first parameter 1:size( data.matrix,1) create a vector of consecutive integers representing the indices of your data points. Two things are wrong with that:
1) You do not need to specify it. Matlab plot function called with only the Y data will create this vector automatically and use it to plot the data.
2) These indices represent the position of your data in an array, they have no physical meaning (like "time" for your case).
The solution is to create a proper 'time' vector and send it as the first parameter to the plot function. This way Matlab will take care of the tick management and you don't have to temper with the manual xtick settings.
Look at the two ways of doing it in the example below and everything will be clear:
%// build a simple index "X" vector (as you were doing)
x_index = 1:size(data.matrix,1) ;
%// build a properly scaled time vector
timeInterval = 20 ; % in milliseconds
x_time = ( 0:size(data.matrix,1)-1 ) * timeInterval ;
plot( x_index , data.matrix(:,1) ) %// this will do like in your example
plot( x_time , data.matrix(:,1) ) %// this will do what you want
Can you not just do?
set(gca,'XTickLabel',(1:size(data.matrix,1))*20*20);

Issue with reading data in text files and plotting a graph (Matlab)

I use the following code to collect data from two text files join them together and then plot them. For some reason, I appear to get two plots rather than 1, I am not sure why this is happening.
load MODES1.dat; % read data into the MODES1 matrix
x1 = MODES1(:,1); % copy first column of MODES1 into x1
y1 = MODES1(:,2); % and second column of MODES1 into y1
load MODES.dat; % read data into the MODES matrix
x = MODES(:,1); % copy first column of MODES into x
y = MODES(:,2); % and second column of MODES into y
% Joining the two sets of data
endx = [x1;x];
endy = [y1;y];
figure(1)
plot(endx,endy)
xlabel('Unique Threshold Strains','FontSize',12);
ylabel('Probabilities of occurrence','FontSize',12);
title('\it{Unique Values versus frequencies of occurrence}','FontSize',16);
Thanks
Your problem is quite a simple one. Matlab's plot command creates a point for each data point defined by the parameters and connects those points in the order they appeared in the first parameter. To get an idea of this behavior, try
x = [0;1;-1;2;-2;3;-3;4;-4;5];
plot(x,x.^2);
You won't get the quadratic function graph you might expect.
To fix this, you must sort you input arrays identically. Sorting one array is simple (sort(endx)), but you want to sort both in the same way. Matlab actually gives you a function to do this, but it only works on matrices, so you need to do some concatenating/seperating:
input = sortrows( [endx endy] );
endx = input(:,1);
endy = input(:,2);
This will sort the rows of the matrix built by putting endy right of endx with respect to the first column (endx). Now your inputs are correctly sorted and the resulting plot should only show one line. (More accurately, one line which does not at some point go back where it came from.)
Another way to achieve this, depending on you actual use case and data origin, would be to build the mean value of both parts of x, so instead of endx = [x1;x];, you'd build endx = mean([x1 x],2);.
Yet another way is to drop the line altogether and go with
plot(endx,endy,'.');
or
plot(endx,endy,'LineStyle','none');
But this is only useful if your data points are very close to each other.