How can I plot amplitude of transfer function in three dimension (for instance to check poles and zeros on graph) ?
Suppose this is my transfer function:
My code:
b = [6 -10 2];
a = [1 -3 2];
[x, y] = meshgrid(-3:0.1:3);
z = x+y*j;
res = (polyval(b, z))./(polyval(a,z));
surf(x,y, abs(res));
Is it correct? I'd also like to know is it possible to mark unit circle on plot?
I think it's correct. However, you're computing H(z^-1), not H(z). Is that you want to do? For H(z), just reverse the entries in a from left to right (with fliplr), and do the same to b:
res = (polyval(fliplr(b), z))./(polyval(fliplr(a),z));
To plot the unit circle you can use rectangle. Seriously :-) It has a 'Curvature' property which can be set to generate a circle.
It's best if you use imagesc instead of surf to make the circle clearly visible. You will get a view from above, where color represents height (value of abs(H)):
imagesc(-3:0.1:3,-3:0.1:3, abs(res));
hold on
rectangle('curvature', [1 1], 'position', [-1 -1 2 2], 'edgecolor', 'w');
axis equal
I have never in my whole life heard of a 3D transfer function, it doesn't make sense. I think you are completely wrong: z does not represent a complex number, but the fact that your transfer function is a discrete one, rather than a continuous one (see the Z transform for more details).
The correct way to do this in MATLAB is to use the tf function, which requires the Control System Toolbox (note that I have assumed your discrete sample time to be 0.1s, adjust as required):
>> b = [6 -10 2];
a = [1 -3 2];
>> sys = tf(b,a,0.1,'variable','z^-1')
sys =
6 - 10 z^-1 + 2 z^-2
--------------------
1 - 3 z^-1 + 2 z^-2
Sample time: 0.1 seconds
Discrete-time transfer function.
To plot the transfer function, use the bode or bodeplot function:
bode(sys)
For the poles and zeros, simply use the pole and zero functions.
Related
Given scatter data, or a matrix, I would like to generate a nice plot such as the one shown below, with all 3 histograms and a colored matrix. I'm specifically interested in the diagonal histogram, which ideally, would correspond to the diagonals of a matrix:
Source figure: www.med.upenn.edu/mulab/jpst.html
The existing command scatterhist is not that powerful to generate this type of graph. Any ideas?
Thanks!
EDIT:
Following #Cris Luengo's hints, I came up with the following code which does some first work at the inclined histogram: WORK IN PROGRESS (HELP WELCOME)!!
b = [0 1 2 3 4 5 6 7 8 9 10];
h = [0.33477 0.40166 0.20134 0.053451 0.008112 0.000643 2.7e-05 0 0 0 0];
wid = 0.25; bb = sort([b-wid b-wid b+wid b+wid]);
kk = [zeros(numel(h),1) h(:) h(:) zeros(numel(h),1)];
kk = reshape(kk',[1,numel(kk)]);
pp=patch(bb,kk,'b');axis([-.5 5 0 .5])
set(gca,'CameraUpVector',[-1,.08,0]);axis square
EDIT 2: Using rotation
phi = pi/4;
R = [cos(phi),-sin(phi);sin(phi),cos(phi)];
rr = [bb' kk'] * R;
bb = rr(:,1); kk = rr(:,2);
patch(bb,kk,'b'); axis([-.5 3 -4 .5])
Here is a recipe to plot the diagonal histogram, if you can do that I’m sure you can figure out the rest too.
Compute the histogram, the bin counts are h, the bin centers are b.
Build a coordinate matrix, attaching the coordinates of a point on the x-axis at the left and right ends of the histogram:
coords = [b(:),h(:)];
coords = [coord;b(end),0;b(1),0];
Using patch you can now plot the histogram as follows:
patch(coords(1,:),coords(2,:));
To plot a rotated histogram you can simply multiply the coords matrix with a rotation matrix, before using patch:
phi = pi/4;
R = [cos(phi),-sin(phi);sin(phi),cos(phi)];
coords = R * coords;
You might need to shift the plot to place it at the right location w.r.t. the other elements.
I recommend that you place all these graphic elements in the same axes object; you can set the axes’ visibility to 'off' so that it works only as a canvas for the other elements.
It will be a bit of work to get everything placed as in the plot you show, but none of it is difficult. Use the low-level image, line,patch and text to place those types of elements, don’t try to use the higher-level plotting functions such as plot, they don’t provide any benefits over the low-level ones in this case.
I am trying to get solutions of a equation and then plot the result on a graph in MATLAB. Suppose, if a equation is,
R=A*sin(theta)
Where, A is a variable, say from 0 to 5 (which will be plotted on x-axis) and theta is from 0 to 3. The resultant values of R, for continous range of A i.e. 0 to 5, will be plotted on y-axis.
I would like to ask that, in MATLAB, how can I get a continous range of variable A, (and that of theta as well), so that I can plot the values on a graph with respective continous-values (or resultant values) of R?
you can use ezplot(fun, [xmin xmax]):
theta = pi;
R =#(A) A*sin(theta);
ezplot(R,[0 5]);
EDIT:
In case you want theta range as well you can use the 3D equivalent: ezsurf or fsurf(fun, [xmin xmax ymin ymax]), like that:
R = #(theta,A) A*sin(theta);
ARange = [0 5];
thetaRange = [0 3];
fsurf(R,[thetaRange ARange]);
xlabel('\theta')
ylabel('A')
title('A\cdotsin(\theta)')
Suppose we have five vertices:
X = [0 1;
2 1;
4 1;
1 0;
3 0];
a triangulation:
T = [1 4 2;
4 5 2;
5 3 2];
and function values defined on the vertices:
Fx = [1;
2;
3;
4;
-5];
then we can easily compute the function value for any point inside the triangle by using the barycentric coordinates. For point P = [1 .5], which lies in the first triangle, the barycentric coordinates are B = [.25 .5 .25], so the function evaluates to Fxi = 1/4 + 4/2 + 2/4 = 2.75.
However, I have difficulty to see how one would extrapolate this surface. We could find the closest triangle and extrapolate from that. The problem is that this results in a discontinuous function. Consider e.g. point P = [2 2]. According to triangle 1, its value would be -0.5, whereas according to triangle 3 its value would be 9.5.
Is there a "standard" or generally accepted approach to extrapolate from piecewise linear functions? Any pointers to existing material also greatly appreciated.
A possibility is Shepard's method:
https://en.wikipedia.org/wiki/Inverse_distance_weighting
The resulting function interpolates the input values defined at the vertices and is non-linear but continuous everywhere else.
The choice p=2 usually gives decent results.
Another technique to look for are "Barycentric coordinates for non-convex polygons".
The following publication shows (page 8 etc.) how the weight functions behave outside the polygons
https://www.in.tu-clausthal.de/fileadmin/homes/techreports/ifi0505hormann.pdf
However, even this solution does not behave piecewise-linear on your given triangulation.
I am trying to plot step responses in MATLAB and cannot figure it out for anything, I have graphed a Bode plot for 3 different k values for the following differential equation in time domain:
d^2y(t)/dt + (v/m)dy(t)/dt + (k/m)y(t) = (k/m)x(t)
in frequency the equation is:
H(jw)=((k/m))/((〖jw)〗^2+(v/m)(jw)+(k/m) )=k/(m(〖jw)〗^2+v(jw)+k)
the values of k are 1, 0.09, 4
The equations to solve for v is as follows:
v=sqrt(2)*sqrt(k*m) where m=1
I now must do the same for step, but am trying to no avail. Can anyone provide any suggestions?
Here is the code for my Bode plot and my attempted but failed step plots:
w=logspace(-2,2,100);
%Creating different vectors based upon K value
%then calculating the frequencey response based upon
%these values
b1=[1];
a1=[1 2^(.5) 1];
H1=freqs(b1,a1,w);
b2=[.09];
a2=[1 (2^.5)*(.09^.5) .09];
H2=freqs(b2,a2,w);
b3=[4];
a3=[1 2*(2^.5) 4];
H3=freqs(b3,a3,w);
%Ploting frequency response on top plot
%with loglog scale
subplot(2,1,1)
loglog(H1,w,'r')
axis([.04 10 .01 10])
hold on
loglog(H2,w,'g')
loglog(H3,w,'c')
xlabel('Omega')
ylabel('Frequency Response')
title('Bode plot with various K values')
legend('H1, K=1','H2, K=.09','H3, K=4')
hold off
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%creating transfer function, how the functions
%respond in time
h1=tf(b1,a1);
h2=tf(b2,a2);
h3=tf(b3,a3);
t=linspace(0,30);
[y1,t1]=step(h1,t);
[y2,t2]=step(h2,t);
[y3,t3]=step(h3,t);
%Ploting step response on bottom plot
%with respect to time
subplot(2,1,2)
plot(t1,abs(y1),'r')
hold on
plot(t2,abs(y2),'g')
plot(t3,abs(y3),'c')
legend('h1, K=1','h2, K=.09','h3, K=4')
xlabel('time(s)')
ylabel('Amplitude')
title('Step response with various K values')
Have you tried using the step function? You already have the coefficients defined in your code above for each of the TFs. step takes in a TF object and gives you the step response in the time domain.
First, take those coefficients and create TF objects. After, run a step response. Using the code you already provided above, do something like this:
b=[1];
a=[1 2^(.5) 1];
% I would personally do: a = [1 sqrt(2) 1];
H1=tf(b, a); % Transfer Function #1
b=[.09];
a=[1 (2^.5)*(.09^.5) .09];
% I would personally do a = [1 sqrt(2*0.09) 0.09];
H2=tf(b, a); % Transfer Function #2
b=[4];
a=[1 2*(2^.5) 4];
% I would personally do a = [1 2*sqrt(2) 4];
H3=tf(b, a); % Transfer Function #3
% Plot the step responses for all three
% Going from 0 to 5 seconds in intervals of 0.01
[y1,t1] = step(H1, 0:0.01:5);
[y2,t2] = step(H2, 0:0.01:5);
[y3,t3] = step(H3, 0:0.01:5);
% Plot the responses
plot(t1, y1, t1, y2, t3, y3)
legend('H1(s)', 'H2(s)', 'H3(s)');
xlabel('Time (s)');
ylabel('Amplitude');
This is the figure I get:
FYI, powering anything to the half is the same as sqrt(). You should consider using that instead to make your code less obfuscated. Judging from your code, it looks like you are trying to modify the frequency of natural oscillations in each second-order underdamped model you are trying to generate while keeping the damping ratio the same. As you increase k, the system should get faster and the steady-state value should also become larger and closer towards 1 - ensuring that you compensate for the DC gain of course. (I'm a former instructor on automatic control systems).
I want to draw some plots in Matlab.
Details: For class 1, p(x|c1) is uniform for x between [2, 4] with the parameters a = 1 and b = 4. For class 2, p(x|c2) is exponential with parameter lambda = 1. Besides p(c1) = p(c2) = 0.5 I would like to draw a sketch of the two class densities multiplied by P(c1) and P(c2) respectively, as
a function of x, clearly showing the optimal decision boundary (or boundaries).
I have the solution for this problem, this is what the writer did (and I want to get), but there's no Matlab code, so I want to do it all by myself.
And this is what I drew.
And this is the MATLAB code I wrote.
x=0:1:8;
pc1 = 0.5;
px_given_c1 = exppdf(x,1);
px_given_c2 = unifpdf(x,2,4);
figure;
plot(x,px_given_c1,'g','linewidth',3);
hold on;
plot(x,px_given_c2,'r','linewidth',3);
axis([0 8 0 0.5]);
legend('P(x|c_1)','P(x|c_2)');
figure;
plot(x,px_given_c1.*pc1,'g','linewidth',3);
hold on;
plot(x,px_given_c2.*(1-pc1),'r','linewidth',3);
axis([0 8 0 0.5]);
legend('P(x|c_1)P(c_1)','P(x|c_2)P(c_2)');
As you can see, they are almost smiliar, but I am having problem with this uniform distribution, which is drawn in red. How can I change it?
You should probably change x=0:1:8; to something like x=0:1e-3:8; or even x=linspace(0,8,1000); to have finer plotting. This increases number of points in vectors (and therefore line segments) Matlab will use to plot.
Explanation: Matlab works with line segments when it does plotting!
By writing x=0:1:8; you create vector [0 1 2 3 4 5 6 7 8] that is of length 9, and by applying exppdf and unifpdf respectively you create two vectors of the same length derived from original vector. So basically you get vectors [exppdf(0) exppdf(1) ... exppdf(8)] and [unifpdf(0) unifpdf(1) ... unifpdf(8)].
When you issue plot command afterwards Matlab plots only line segments (8 of them in this case because there are 9 points):
from (x(1), px_given_c1(1)) to (x(2), px_given_c1(2)),
...
from (x(8), px_given_c1(8)) to (x(9), px_given_c1(9)).