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

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!

Related

How to plot inequality equations associated with a linear programming function

I'm fairly new to Matlab, but have some basic understanding of programming principles.
I would like to plot the two variables, H (x-axis) vs. C (y-axis) following these two inequality equations: 4H+C<=20 and H+3C<=10, given: NB=H+2C (linear objective function vector), which are solved using the linprog function tool in Matlab (x=linprog(f,A,b);)
I know how to input the linprog programming (note here negative values for f are because I want to maximize, and not minimize my objective function):
f=[-1,-2];
A=[4 1; 1 3];
b=[20;10];
[x,fval,exitflag,output,lambda] = linprog(f,A,b);
which gives the optimal solution at x = (4.5455, 1.8182)
I would like to show this graphically, i.e. plot both inequality equations on a graph with both axis scales going from 0 to 10 using intervals of 1, but I cannot seem to make this work.
Here is what I have:
[H,C] = meshgrid((0:1:10),(0:1:10));
figure, hold on
xlabel('H, Hydropower')
ylabel('C, Crops')
The first problem is that it plots from 0-1 using intervals of 0.1 (??)
And of course, there are no lines representing the inequalities. But how to create the inequality lines?
Any help would be very much appreciated!
Urs
The trick is generating the whole NB and then deleting the parts that do not fill the conditions. Here you have a piece of code that does that (plus some fancy plotting). Remember, to plot the lines where the condition is in the "boundary" you neet to delete de inequality and put an equality (see code).
clear;clc
%Generate data
[H,C] = meshgrid(0:0.1:10);
NB=H+2*C;
% Get True where condition aplies, false where not.
cond1=4*H+C<=20;
cond2=H+3*C<=10;
% Get boundaries of the condition
Cp1=20-4*H(1,:);
Cp2=(10-H(1,:))/3;
%Delete Areas whereCondition does not apply;
NB(~cond1)=NaN;
NB(~cond2)=NaN;
%% Plot
[C,h]=contourf(H,C,NB,20);
clabel(C,h,'LabelSpacing',100) % optional
hold on
plot(H(1,:),Cp1,'r')
text(H(1,45),Cp1(45), '\leftarrow Cond1'); %arbitrary location
plot(H(1,:),Cp2,'k')
text(H(1,75),Cp2(75), '\leftarrow Cond2'); %arbitrary location
axis([0 10 0 10])
xlabel('H, Hydropower')
ylabel('C, Crops')

Dividing matlab plot into grids

I have two different functions of time x(t) and y(t). I want to plot x(t) vs y(t) in Matlab . The plot needs to be divided into a 40x40 grid stretching from min and max values of signal in each direction. I then need to calculate the number of grid boxes occupied in the plot. Please suggest a convenient way to implement this in Matlab.
I've tried the following code (neglect the upper and lower limits of axis):
NrGrid = 20; % Number Of Grids
x = linspace(0, 100, NrGrid+1);
[X,Y] = meshgrid(x);
figure(1)
plot(X,Y,'k')
hold on
plot(Y,X,'k')
hold off
set(gca, 'Box','off', 'XTick',[], 'YTick',[])
axis square
In my understanding, the code only divides the plot into grids. how do I count the number of grids that are occupied?
Reference: I basically need to implement the algorithm in this paper:
http://www.fhv.at/media/pdf/forschung/prozess-und-produktengineering/working-papers/working-papers-2005/detecting-ventricular
Sounds like you want to create a 40x40 matrix and then use a Bresenham line drawing algorithm to connect each of the points (after appropriate scaling) in x(t)/y(t) correspondence in that matrix.
You can then use nnz to count the number of non-zero elements in the matrix.
I managed to get a much simpler solution than the one mentioned by Dave Durbin by quantizing the signal into 40 levels and then comparing it with its shifted region. The code is attached for reference:
function TD=TimeDelay(val,fs)
n=40;
jump=( max(val) + abs(min(val)))/40;
level=zeros(n,1);
level(1)=min(val) + jump;
for i=2:n
level(i)=level(i-1)+jump;
end
level(n)=level(n)+1;
ScaledECG=zeros(size(val));
ScaledECG(val <= level(1))=1;
for j=2:n
ScaledECG( val<=level(j) & val>level(j-1))=j;
end
tau=fs*.5;
N=zeros(n,n);
for k=tau+1:1:length(val)
N(ScaledECG(k-tau),ScaledECG(k))=N(ScaledECG(k-tau),ScaledECG(k)) + 1;
end
N(N>5)=0;
N(N<=5)=1;
TD=sum(sum(N));

Plotting differentiation error in 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).

Histogram (hist) not starting (and ending) in zero

I'm using the Matlab function "hist" to estimate the probability density function of a realization of a random process I have.
I'm actually:
1) taking the histogram of h0
2) normalizing its area in order to get 1
3) plotting the normalized curve.
The problem is that, no matter how many bins I use, the histogram never start from 0 and never go back to 0 whereas I would really like that kind of behavior.
The code I use is the following:
Nbin = 36;
[n,x0] = hist(h0,Nbin);
edge = find(n~=0,1,'last');
Step = x0(edge)/Nbin;
Scale_factor = sum(Step*n);
PDF_h0 = n/Scale_factor;
hist(h0 ,Nbin) %plot the histogram
figure;
plot(a1,p_rice); %plot the theoretical curve in blue
hold on;
plot(x0, PDF_h0,'red'); %plot the normalized curve obtained from the histogram
And the plots I get are:
If your problem is that the plotted red curve does not go to zero: you can solve that adding initial and final points with y-axis value 0. It seems from your code that the x-axis separation is Step, so it would be:
plot([x0(1)-Step x0 x0(end)+Step], [0 PDF_h0 0], 'red')

Dynamic Time Warping for geology time series, Matlab

Background:
Basically I'm using a dynamic time warping algorithm like used in speech recognition to try to warp geological data (filter out noise from environmental conditions) The main difference between these two problems is that dtw prints a warping function that allows both vectors that are input to be warped, whereas for the problem I'm trying to solve I need to keep one reference vector constant while stretching and shrinking the test variable vector to fit.
here is dtw in matlab:
function [Dist,D,k,w]=dtw()
%Dynamic Time Warping Algorithm
%Dist is unnormalized distance between t and r
%D is the accumulated distance matrix
%k is the normalizing factor
%w is the optimal path
%t is the vector you are testing against
%r is the vector you are testing
[t,r,x1,x2]=randomtestdata();
[rows,N]=size(t);
[rows,M]=size(r);
%for n=1:N
% for m=1:M
% d(n,m)=(t(n)-r(m))^2;
% end
%end
d=(repmat(t(:),1,M)-repmat(r(:)',N,1)).^2; %this replaces the nested for loops from above Thanks Georg Schmitz
D=zeros(size(d));
D(1,1)=d(1,1);
for n=2:N
D(n,1)=d(n,1)+D(n-1,1);
end
for m=2:M
D(1,m)=d(1,m)+D(1,m-1);
end
for n=2:N
for m=2:M
D(n,m)=d(n,m)+min([D(n-1,m),D(n-1,m-1),D(n,m-1)]);
end
end
Dist=D(N,M);
n=N;
m=M;
k=1;
w=[];
w(1,:)=[N,M];
while ((n+m)~=2)
if (n-1)==0
m=m-1;
elseif (m-1)==0
n=n-1;
else
[values,number]=min([D(n-1,m),D(n,m-1),D(n-1,m-1)]);
switch number
case 1
n=n-1;
case 2
m=m-1;
case 3
n=n-1;
m=m-1;
end
end
k=k+1;
w=cat(1,w,[n,m]);
end
w=flipud(w)
%w is a matrix that looks like this:
% 1 1
% 1 2
% 2 2
% 3 3
% 3 4
% 3 5
% 4 5
% 5 6
% 6 6
so what this is saying is that the both the first and second points of the second vector should be mapped to the first point of the first vector. i.e. 1 1
1 2
and that the fifth and sixth points on the first vector should be mapped to the second vector at point six. etc. so w contains the x coordinates of the warped data.
Normally I would be able to say
X1=w(:,1);
X2=w(:,2);
for i=1:numel(reference vector)
Y1(i)=reference vector(X1(i));
Y2(i)=test vector(X2(i));
end
but I need not to stretch the reference vector so I need to use the repeats in X1 to know how to shrink Y2 and the repeats in X2 to know how to stretch Y2 rather than using repeats in X1 to stretch Y1 and repeats in X2 to stretch Y2.
I tried using a find method to find the repeats in both X1 and X2 and then average(shrink) or interpolate linearly(stretch) as needed but the code became very complicated and difficult to debug.
Was this really unclear? I had a hard time explaining this problem, but I just need to know how to take w and create a Y2 that is stretched and shrunk accordingly.
First, here's DTW in Matlab translated from the pseudocode on wikipedia:
t = 0:.1:2*pi;
x0 = sin(t) + rand(size(t)) * .1;
x1 = sin(.9*t) + rand(size(t)) * .1;
figure
plot(t, x0, t, x1);
hold on
DTW = zeros(length(x0), length(x1));
DTW(1,:) = inf;
DTW(:,1) = inf;
DTW(1,1) = 0;
for i0 = 2:length(x0)
for i1 = 2:length(x1)
cost = abs(x0(i0) - x1(i1));
DTW(i0, i1) = cost + min( [DTW(i0-1, i1) DTW(i0, i1-1) DTW(i0-1, i1-1)] );
end
end
Whether you are warping x_0 onto x_1, x_1 onto x_0, or warping them onto each other, you can get your answer out of the matrix DTW. In your case:
[cost, path] = min(DTW, [], 2);
plot(t, x1(path));
legend({'x_0', 'x_1', 'x_1 warped to x_0'});
I don't have an answer but I have been playing with the code of #tokkot implemented from the pseudocode in the Wikipedia article. It works, but I think it lacks three requeriments of DTW:
The first and last points of both sequences must be a match, with the use of min(), some (or many) of the first and ending points of one of the sequences are lost.
The output sequence is not monotonically increasing. I have used x1(sort(path)) instead, but I don't believe it is the real minimum distance.
Additionally, for a reason I haven't found yet, some intermediate points of the warped sequences are lost, which I believe is not compatible with DTW.
I'm still searching for an algorithm like DTW in which one of the sequences is fixed (not warped). I need to compare a time series of equally spaced temperature measurements with another sequence. The first one cannot be time shifted, it does not make sense.