Plotting differentiation error in matlab - matlab

I wrote a matlab code that approximates the derivative of cos(x) using the central difference.
meaning cos(x)'=(cos(x+h)-cos(x-h))/2h approximately.
as h goes from 0.1,0.01,0.001 and so on until 10^-8
This is my code
function [pos,neg,D]=shifted_cos(x)
for i=1:8
var=rand(1)*0.5*10^(-5);
pos(i)=cos(x+10^(-i))+var;
end
for j=1:8
var=rand(1)*0.5*10^(-5);
neg(j)=cos(x-10^(-j))+var;
end
D=pos-neg;
for k=1:8
D(k)=(D(k)/(2*10^(-k)));
end
end
Please note that the variable named var is just random noise that i added, since any "real" system has noise and its not 100% reliable, but i was given that the noise is no larger than 0.5*10^-5
Here is my problem: I am now trying to plot the error as a function of h.
By error i mean the real value of the derivative, minus the value in D (please note that D is a vector)
So I wrote the following lines in the console:
[p,n,d]=shifted_cos(1.2)
h=[0.1,0.01,0.001,0.0001,0.00001,0.000001,0.0000001,0.00000001]
plot(h,abs(-sin(1.2)-d))
and the output im getting is very weird. im seeing a graph, but its just a vertical line.
the values of d are
d =
Columns 1 through 3
-0.930475812604331 -0.932134403564042 -0.932748001778061
Columns 4 through 6
-0.944125866359780 -0.991297975178052 0.416450071288876
Columns 7 through 8
8.360791447226124 10.313974302400553
So it shouldnt be a vertical line...
Can someone shed some light on my problem?
Note: I was asked to plot the error as a function of h at the point x=1.2, and also note that the derivative of cos(x) is -sin(x)

I've run just the following code and that does not give me a vertical line. However since h is changing in orders of magnitude, a (double) logarithmic plot will give you much more insight.
d = [ -0.930475812604331 -0.932134403564042 -0.932748001778061 ...
-0.944125866359780 -0.991297975178052 0.416450071288876 ...
8.360791447226124 10.313974302400553 ];
h = 10.^-(1:8);
%// plot 1: your plot but with adjusted axes
subplot(1, 3, 1)
plot(h, abs(-sin(1.2)-d), '.-')
xlim([-.01, .2])
ylim([-1, 18])
%// plot 2: your data, just linearly plotted
subplot(1, 3, 2)
plot(abs(-sin(1.2)-d), '.-')
%// plot 3: double logarithmic plot
subplot(1, 3, 3)
loglog(abs(-sin(1.2)-d), '.-')
PS and not related to your question as such: Have a look here on how to avoid for loops in Matlab and make your code both faster and easier to read (And write).

Related

How to create Evenly-spaced and the unevenly-spaced grids

I am trying to create a function to test_Lagrange_interpolation().
I need to plot Lagrangian interpolant of (1) built on the grid (2) with N= 8 nodes and evaluated at x.
And
another plot Lagrangian interpolant of (1) built on the grid (3) withN= 8 nodes and evaluated at x.
So, in other words, to make evenly space grid we can use linspace(-1,1,9)
for unevely space grid what can we use?
Thankx
First, we have a Lagrange polynomials with type
even grid interpolation means we generate an even x to do interpolation.
uneven grid interpolation means the x is an uneven vector.
So, what is the benefit of an uneven interpolation? It is due to some shortage of even interpolation:Runge's phenomenon, which is a problem of oscillation at the edges of an interval that occurs when using polynomial interpolation with polynomials of a high degree over a set of equispaced interpolation points.
In other words, just look at the figure below. The left one is a LaGrange polynomial with even grid and the right one's grid is uneven(Chebyshev polynomials), and we could reckon that in this case, the performance of the right one (uneven grid) is better.
Codes:
clc; clear;
syms X
subplot(1,2,1)
ezplot('1/(1+25*x^2)',[-3 3])
Y=0;
xx=-3:0.5:3;
yy=1./(1+25*xx.^2);
for ii=1:length(xx)
tmp=1;
for jj=1:length(xx)
if (jj == ii)
continue;
end
tmp=tmp*(X-xx(jj))/(xx(ii)-xx(jj));
end
Y=Y+tmp*yy(ii);
end
hold on
ezplot(Y,[-3 3])
axis([-3 3 0 1.2])
title('even grid')
subplot(1,2,2)
ezplot('1/(1+25*x^2)',[-3 3])
Y2=0;
xx=-cos((0:12)/12*pi)*3;
yy=1./(1+25*xx.^2);
for ii=1:length(xx)
tmp=1;
for jj=1:length(xx)
if (jj == ii)
continue;
end
tmp=tmp*(X-xx(jj))/(xx(ii)-xx(jj));
end
Y2=Y2+tmp*yy(ii);
end
hold on
ezplot(Y2,[-3 3])
axis([-3 3 0 1.2])
title('uneven grid')
hope it helps!

Exhibiting the correct axes values when making plot with density in Matlab

I'm trying to make a plot with density of the zeros of random quadratic monic polynomials in the complex plane. In fact, I am plotting! But there is just a little detail which is bugging me: the values of the axes are not matching with the points in the plot. Here is my code.
n=2;
p = [1 random('Uniform', -1, 1, [1,n])]
roots(p)
z = zeros(0);
n = 2;
for j=1:10000
p = [1 random('Uniform', -1, 1, [1,n])];
R = roots(p);
z = [ z, R.' ];
end
Re = real(z);
Im = imag(z);
[values, centers] = hist3([Im(:) Re(:)],[1000 1000]);
imagesc(centers{:}, values,[0,10]);
colorbar
axis equal
axis xy
cmap = summer(max(values(:)));
cmap(1:1,:) = 0;
colormap(cmap);
Now here is the plot generated by this code.
You can try this code and check max(Re) and max(Im), which correspond to the maximum values of the real part (x axis) and imaginary part (y axis). I have max(Re) = 1.6076 (it's always something close to 1.5) and max(Im) = 0.9993 (it's always something close to 1). These values doesn't match the plot, which seems to be the opposite.
If I try the scatter function (losing density and all the nice visual), I have the right values. The following command generates the figure below.
scatter(Re(1,:), Im(1,:),'.')
This clearly shows that the first plot is actually(not rotated as I was thinking first) correct, except for the axes values. I need a help to fix this. Thanks.
PS: The commands to make this plot I got in the answer here. Note the comments there. I explicitly asked for a solution for this problem and got one. The given solution actually worked in some cases but failed in this one, I don't know why.
I believe what you are looking for should be:
imagesc(centers{[2,1]}, values,[0,10]);
Incidently, you did not spot the problem in the other post is because the sample images all happen to be more or less square.

Implementing BPSK using MATLAB

I am trying to write some simple MATLAB code for plotting a BPSK but the code is not working. Here is the code:
t=0:(1/1000):3;
figure(1);
s0=sin( (2*pi)*t );
s1=sin( (2*pi)*t+(pi) );
sout=[s0 s1];
plot(t,sout);
grid on;
You can plot this code vectorized without having the need to use hold on as what Nematollah suggested. Simply place each data trace in a separate column. The t vector can be left alone. The reason why your code isn't working is because you placed s0 and s1 and concatenated them to be a single 1D array. t has 3001 elements while sout would have 3001 * 2 = 6002 elements. The dimensions are incompatible, which is why you're getting the error.
You can plot multiple signals using plot without a problem without the use of hold on. Just make sure that each trace is in a separate column. With your code setup, you just have to transpose s0 and s1 and this will work. As such:
t=0:(1/1000):3;
figure(1);
s0=sin( (2*pi)*t );
s1=sin( (2*pi)*t+(pi) );
sout=[s0.' s1.']; %// Change - transpose s0 and s1
plot(t,sout);
grid on;
This is what I get:
Notice that MATLAB automatically colour codes the traces for you, seeing as how each data trace is in a separate column.
Edit
You now want to concatenate these two signals together (which is actually what BPSK is supposed to do). We can easily do this by extending the time vector that you have and then tacking on the second signal when you're done like you did in your original post. You can easily do this in the following way:
t=0:(1/1000):3;
figure(1);
s0=sin( (2*pi)*t );
s1=sin( (2*pi)*t+(pi) );
sout = [s0 s1]; %// Note we are concatenating now
tvec = [t t(end) + t]; %// NEW
plot(tvec, sout); %// Plot 2 signals together as 1
Take a look at this statement:
tvec = [t t(end) + t];
I create a new vector which had the original time vector that goes between [0,3]. I then extend this vector so that we take the time vector from [0,3] and offset it by the last time value of the original signal, which is 3. As such, we would then add a vector of [3,6] at the end, as we will have two signals that are 3 seconds each - thus 6 seconds. This is what I get:
Looks like BPSK to me! :)
If you want to plot one symbol time, you should plot both signals on the same plot like this.
t = 0 : (1/1000) : 3;
s0 = sin((2*pi)*t);
s1=sin((2*pi)*t+pi);
plot(t, s0);
hold on
plot(t, s1, 'r');
grid

step plot function in matlab

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

maybe matrix plot!

for an implicit equation(name it "y") of lambda and beta-bar which is plotted with "ezplot" command, i know it is possible that by a root finding algorithm like "bisection method", i can find solutions of beta-bar for each increment of lambda. but how to build such an algorithm to obtain the lines correctly.
(i think solutions of beta-bar should lie in an n*m matrix)
would you in general show the methods of plotting such problem? thanks.
one of my reasons is discontinuity of "ezplot" command for my equation.
ok here is my pic:
alt text http://www.mojoimage.com/free-image-hosting-view-05.php?id=5039TE-beta-bar-L-n2-.png
or
http://www.mojoimage.com/free-image-hosting-05/5039TE-beta-bar-L-n2-.pngFree Image Hosting
and my code (in short):
h=ezplot('f1',[0.8,1.8,0.7,1.0]);
and in another m.file
function y=f1(lambda,betab)
n1=1.5; n2=1; z0=120*pi;
d1=1; d2=1; a=1;
k0=2*pi/lambda;
u= sqrt(n1^2-betab^2);
wb= sqrt(n2^2-betab^2);
uu=k0*u*d1;
wwb=k0*wb*d2 ;
z1=z0/u; z1_b=z1/z0;
a0_b=tan(wwb)/u+tan(uu)/wb;
b0_b=(1/u^2-1/wb^2)*tan(uu)*tan(wwb);
c0_b=1/(u*wb)*(tan(uu)/u+tan(wwb)/wb);
uu0= k0*u*a; m=0;
y=(a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*...
cos(2*uu0+m*pi)+b0_b*z1_b*sin(2*uu0+m*pi);
end
fzero cant find roots; it says "Function value must be real and finite".
anyway, is it possible to eliminate discontinuity and only plot real zeros of y?
heretofore,for another function (namely fTE), which is :
function y=fTE(lambda,betab,s)
m=s;
n1=1.5; n2=1;
d1=1; d2=1; a=1;
z0=120*pi;
k0=2*pi/lambda;
u = sqrt(n1^2-betab^2);
w = sqrt(betab^2-n2^2);
U = k0*u*d1;
W = k0*w*d2 ;
z1 = z0/u; z1_b = z1/z0;
a0_b = tanh(W)/u-tan(U)/w;
b0_b = (1/u^2+1/w^2)*tan(U)*tanh(W);
c0_b = -(tan(U)/u+tanh(W)/w)/(u*w);
U0 = k0*u*a;
y = (a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*cos(2*U0+m*pi)...
+ b0_b*z1_b*sin(2*U0+m*pi);
end
i'd plotted real zeros of "y" by these codes:
s=0; % s=0 for even modes and s=1 for odd modes.
lmin=0.8; lmax=1.8;
bmin=1; bmax=1.5;
lam=linspace(lmin,lmax,1000);
for n=1:length(lam)
increment=0.001; tolerence=1e-14; xstart=bmax-increment;
x=xstart;
dx=increment;
m=0;
while x > bmin
while dx/x >= tolerence
if fTE(lam(n),x,s)*fTE(lam(n),x-dx,s)<0
dx=dx/2;
else
x=x-dx;
end
end
if abs(real(fTE(lam(n),x,s))) < 1e-6 %because of discontinuity some answers are not correct.%
m=m+1;
r(n,m)=x;
end
dx=increment;
x=0.99*x;
end
end
figure
hold on,plot(lam,r(:,1),'k'),plot(lam,r(:,2),'c'),plot(lam,r(:,3),'m'),
xlim([lmin,lmax]);ylim([1,1.5]),
xlabel('\lambda(\mum)'),ylabel('\beta-bar')
you see i use matrix to save data for this plot.
![alt text][2]
because here lines start from left(axis) to rigth. but if the first line(upper) starts someplace from up to rigth(for the first figure and f1 function), then i dont know how to use matrix. lets improve this method.
[2]: http://www.mojoimage.com/free-image-hosting-05/2812untitled.pngFree Image Hosting
Sometimes EZPLOT will display discontinuities because there really are discontinuities or some form of complicated behavior of the function occurring there. You can see this by generating your plot in an alternative way using the CONTOUR function.
You should first modify your f1 function by replacing the arithmetic operators (*, /, and ^) with their element-wise equivalents (.*, ./, and .^) so that f1 can accept matrix inputs for lambda and betab. Then, run the code below:
lambda = linspace(0.8,1.8,500); %# Create a vector of 500 lambda values
betab = linspace(0.7,1,500); %# Create a vector of 500 betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
[c,h] = contour(L,B,y,[0 0]); %# Plot contour lines for the value 0
set(h,'Color','b'); %# Change the lines to blue
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
title('y = 0'); %# Add a title
And you should see the following plot:
Notice that there are now additional lines in the plot that did not appear when using EZPLOT, and these lines are very jagged. You can zoom in on the crossing at the top left and make a plot using SURF to get an idea of what's going on:
lambda = linspace(0.85,0.95,100); %# Some new lambda values
betab = linspace(0.95,1,100); %# Some new betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
surf(L,B,y); %# Make a 3-D surface plot of y
axis([0.85 0.95 0.95 1 -5000 5000]); %# Change the axes limits
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
zlabel('y'); %# Add a z label
Notice that there is a lot of high-frequency periodic activity going on along those additional lines, which is why they look so jagged in the contour plot. This is also why a very general utility like EZPLOT was displaying a break in the lines there, since it really isn't designed to handle specific cases of complicated and poorly behaved functions.
EDIT: (response to comments)
These additional lines may not be true zero crossings, although it is difficult to tell from the SURF plot. There may be a discontinuity at those lines, where the function shoots off to -Inf on one side of the line and Inf on the other side of the line. When rendering the surface or computing the contour, these points on either side of the line may be mistakenly connected, giving the false appearance of a zero crossing along the line.
If you want to find a zero crossing given a value of lambda, you can try using the function FZERO along with an anonymous function to turn your function of two variables f1 into a function of one variable fcn:
lambda_zero = 1.5; %# The value of lambda at the zero crossing
fcn = #(x) f1(lambda_zero,x); %# A function of one variable (lambda is fixed)
betab_zero = fzero(fcn,0.94); %# Find the value of betab at the zero crossing,
%# using 0.94 as an initial guess