Change transfer function in loop - simulink - matlab

I started to use Simulink and I have a question about changing a transfer function using matlab for loop.
Let say I have the following problem:
And my goal is that "system" will be equal to:
Basically I want to run 5 Simulink simulations from time = 0 to time = 10 for 5 different transfer functions.
Any help is appreciated.
Thank you.

Unless I misunderstood your question, I don't think you need to use Simulink for something like this. The following is my understanding of what you're trying to do, it can be done in plain MATLAB (with the control system toolbox):
t = 0:1e-3:10;
u = ones(size(t));
y = zeros(5,length(t));
for k=1:5
H = (1 + tf('s')*5/k)^k; % system transfer function
CL = 1/((tf('s'))^2*(1-H)); % closed-loop transfer function
y(k,:) = (lsim(CL,u,t))';
end
plot(t,y)
legend('#1','#2','#3','#4','#5','Location','NorthWest')
grid on
xlabel('Time [s]')
ylabel('Output')
which produces the following plot (in Octave). Only the first 2 iterations give a non-zero output:

Related

matlab plot vectors must be the same lengths

I am writing a program regarding solving the following boundary value problem using shooting-bisection method:
y''-y+x=0, y(0)=y(1)=0.
I first convert this to a system of first order equations, set
y'=z
then I let dydt represent the vector (y',z'), and come up with the script file:
function dydt=shoot(t,y)
dydt=[y(2);y(1)-t]
end
With this, I then came up with the following code:
clear
clc
a=0;
b=1;
alpha=0;
beta=0;
s(1)=(beta-alpha)/(b-a);
s(2)=-1
[G,Y]=ode113('shoot',[a b],[alpha;s(1)]);
[G,Z]=ode113('shoot',[a b],[alpha;s(2)])
hold
tol=1e-4
u=s(1);
v=s(2);
while abs(u-v)>tol;
s(3)=(u+v)/2;
[G,W]=ode113('shoot',[a b],[alpha;s(3)]);
if W(end,1)>0
u=s(3);
else
v=s(3);
end
end
[G,W]=ode113('shoot',[a b],[alpha;s(3)])
plot(G,Y(:,1),'-o', G,Z(:,1),'-o',G,W(:,1),'-o')
Then I run the program, MATLAB said I'm using the plot argument incorrectly, where plot vectors must be the same lengths. I have no idea how to fix this problem. Any help is appreciated.
Your Y, Z and W outputs are from different runs of ode113. The output independents variables, G from each run are different because ode113 is an adaptive solver. There are two ways you can fix this. You can save your G outputs as separate variables:
...
[Gy,Y]=ode113('shoot',[a b],[alpha;s(1)]);
[Gz,Z]=ode113('shoot',[a b],[alpha;s(2)]);
...
[Gw,W]=ode113('shoot',[a b],[alpha;s(3)]);
plot(Gy,Y(:,1),'-o', Gz,Z(:,1),'-o',Gw,W(:,1),'-o');
Or you could specify a fixed set of output points by specifying more than two points for tspan (second argument to ode113):
...
tspan = linspace(a,b,50);
[G,Y]=ode113('shoot',tspan,[alpha;s(1)]);
[G,Z]=ode113('shoot',tspan,[alpha;s(2)]);
...
[G,W]=ode113('shoot',tspan,[alpha;s(3)]);
plot(G,Y(:,1),'-o', G,Z(:,1),'-o',G,W(:,1),'-o');
Unless your version of Matlab is more than 10 years old, you should also specify your integration function, shoot, via a function handle, not a string, i.e.:
[Gw,W]=ode113(#shoot,[a b],[alpha;s(3)]);

LTI System and Output Signal in matlab

I have 2 systems [H]: y(n) = x(2n), [G]: y(n)=x(n).x(n-1).x(n-2) – 2y(n-1)
1. How can i check if whether 2 systems above is LTI or not? i can't use num,den, and filter function for those function.
2. How can i simulate the output signal with input x(n) = (0.5).^ .*u(n) ?
Thank you for helping me.
And how can i simulate the impulse response of G and H ?
Please explain "." in G and ".^.*" in x. It is not really clear.
1.Question: See https://ccrma.stanford.edu/~jos/fp/Showing_Linearity_Time_Invariance.html
2.Question: The simulation is not difficult, because it is normal algebra. Firstly, the input signal is created:
u=rand(1,50); % 50 random values between 0 and 1
Then, x can be calculated.
x = 0.5.^u;
For H, the command is very simple:
y = x(1:2:end);
For G it is a little bit more difficult. The simplest solution would be a loop (or a function). An idea would be:
y2=zeros(1,length(x));
for n=3:length(x)
y2(n)=x(n)*x(n-1)*x(n-2)-2*y2(n-1);
end
An alternative solution would be with a Simulink model.

how to make this function periodic in 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

How to get a transfer function from a Simulink model into Matlab

I would like to plot a transfer function from a Simulnik file model.mdl where I used blocks From Workspace (simin) and To Workspace (simou) to start a simulation from Matlab.
And now comes the problem. I simply can't find a way to run this Simulink model in Matlab.
Here is my code;
sim('model');
h=simout/simin;
[H,omega]=freqz(h);
%plot
I get this errors;
Error evaluating parameter 'VariableName' in 'model/From
Workspace'
Caused by:
Error using sigma (line 8)
Undefined function or variable 'simin'.
What am I doing wrong?
This is my model:
Thank you so much.
Do you actually know the transfer function? Is implemented correctly in Simulink? Then the error suggests that you haven't assigned the correct variable name to your from workspace block, you just kept the default VariableName. For the frequency response you need to define your transfer function outside Simulink with tf, then use bodeplot to plot it.
(Look at the end of these answer)
But it appears to me, that you have some inputdata and some outputdata and you'd like to estimate the transfer function and finally get the frequency response of that transfer function. There is no need for Simulink to do that. Once you found your transfer function you could implement it into Simulink using the Transfer function block, feed the simulation with the From Workspace Block and display the results with Scope. But first you need the transfer function.
Assuming you have the variables inputdata and outputdata you first need to create a transfer function dataset:
% prepare data for tftest, 100 is a random chosen sampling time
tfdata = iddata(data(:,1),data(:,2),100);
then you can use tfest to estimate the transfer function with a chosen number of poles:
N = 5; % Number of poles
sys = tfest(tfdata,N);
The frequency response you get e.g. with bodeplot:
bodeplot(sys)
The function FREQZ you intended to use is just for digital filters, not for transfer functions.
Finally you can test your model with Simulink:
where the numerator of the Transfer Fcn Block is sys.num{1} and the denominator sys.den{1} (for my example).
If the graph displayed in Scope (be aware that you should disable "Limit Data points to last 5000" in the scope Settings) is similar to your outputdata the estimation was successful.
I made a testrun for your model: (fixed step solver, no continuous states, 0.0001 steptime).
Then the following code:
tfdata = iddata(inputdata,outputdata,0.0001);
N = 5;
sys = tfest(tfdata,N);
bodeplot(sys)
returning:
sys =
From input "u1" to output "y1":
-2068 s^4 + 2.89e06 s^3 + 7.017e10 s^2 + 5.205e13 s - 8.931e15
-------------------------------------------------------
s^5 + 1.034e04 s^4 + 4.552e07 s^3 + 1.114e11 s^2 + 8.337e13 s + 8.931e15
and:
or convert it to discrete:
sysd = c2d(sys,0.0001)
sysd =
From input "u1" to output "y1":
-0.0995 z^-1 + 0.4644 z^-2 - 0.7491 z^-3 + 0.5061 z^-4 - 0.1219 z^-5
-------------------------------------------------------
1 - 4.042 z^-1 + 6.554 z^-2 - 5.332 z^-3 + 2.176 z^-4 - 0.3556 z^-5
I can't help you more, and it's a homework anyway, right? So the rest is up to you. And honestly, calculate it by hand! It will be much more exact!
Well, the error message should be self-explanatory: you haven't defined your variable simin in the base workspace. Define it (as a function of time) and then your model will run.
BTW, a much better way to obtain the transfer function from your Simulink model is use dlinmod, as other people have already pointed out, or linearize if you have Simulink Control Design. Your approach is prone to noise and not very robust. It also relies on your input having all the frequency components of interest, which is unlikely. Simulink Control Design also provides frestimate to estimate the frequency response function of your model.
Take a look at dlinmod: Extract discrete-time linear state-space model around operating point (from a Simulink model).
The following code helps me:
[A B C D]=linmod2('FileNameWithoutExtension');
tf_you_want_to_get=tf(minreal(ss(A,B,C,D)))

Matlab integral function & function handles in a loop

'Outliers.m' is called from a higher level .m file. The variables are all defined in the higher level file, and set as globals for access by Outliers.m. The purpose of the code is to identify outliers using Chauvenets Criterion, and for this, I have to calculate the integral of the guassian distribution, using the Integral function and function handles. The code works and gives sensible values when I enter specific variables as a test, but I cannot get it to work in a loop. My data set is comprised of 7 individual samples, each 1x30, all of which need to be analyzed. I have had various errors, read through the guidance on Integral and function handles, but cannot seem to find the solution...Any help or guidance would be very much appreciated.... Here is my code:
n = 7
for x = 1:n
for y = 1:30
z(x,y) = abs((cc(x,y) - mastercc(1,y))/masterccstd(1,y));
xmax(x,y) = mastercc(1,y)+z(x,y)*masterccstd(1,y);
xmin(x,y) = mastercc(1,y)-z(x,y)*masterccstd(1,y);
p(x,y) = 1/(masterccstd(1,y)*(sqrt(2*pi)));
fun(x,y)= #(x,y,z) (exp(-1/2)*z(x,y).^2);
q(x,y) = integral(fun(x,y),xmin(x,y),xmax(x,y),'ArrayValued',true);
pq(x,y) = p(x,y)*q(x,y); % probability
value(x,y) = n*(1/pq(x,y));
count(x,y) = logical(value(x,y) <0.5);
badbins(x)=sum(count(x,:));
end
end
It seems like your error is caused by an invald function definition.
If you try it like this it should work:
fun = #(x,y,z) (exp(-1/2)*z(x,y).^2)
Now it can be called like this for example:
fun(1,2,magic(4))
Solution to the loop problem, courtesy Andrei Bobrov via Matlab Central, link below:
http://www.mathworks.com/matlabcentral/answers/103958#comment_177000
NB: Please note the code is not complete for the purpose I explained in the problem description, but it does solve the Loop error.