Ok guys. I have the following problem:
I have the data of the following plot.
So the data file of this plot contains three columns.
The 2nd and 3rd ones the x,y points. And the 1st one is to which system those points belong.
In this case the red ones are for the system of 20 years. The blue ones for the 30 years.
What I want to find is the curve at 25 years. So if I plot it it should be between the red and blue curves.
I have no idea how interpolate the data in order to obtain what I want. Actually I want to have for 21,22,...29 years, I guess if we can find it for a time in between these two, then the method should work for any time between 20 and 30.
PS: I guess the interpolation for each curve (in this case red or blue one) is quite easy. Just using interp1(x,y,xx) will work. But what happened with the other "dimension" (M)
The data.
20.0000 3.4076 0
20.0000 3.4226 99.5405
20.0000 3.4701 196.3360
20.0000 3.5592 287.0781
20.0000 3.6248 328.8516
20.0000 3.6643 348.3373
20.0000 3.7091 367.2823
20.0000 3.7591 385.4784
20.0000 3.8077 402.7170
20.0000 3.8957 437.5221
20.0000 4.0314 506.9907
30.0000 3.6335 0
30.0000 3.6373 49.8884
30.0000 3.6488 99.5405
30.0000 3.6685 148.5936
30.0000 3.7363 243.2204
30.0000 3.7876 287.7398
30.0000 3.8537 329.6097
30.0000 3.8935 349.9452
30.0000 3.9384 368.9776
30.0000 3.9892 387.2576
30.0000 4.0410 404.5759
30.0000 4.1350 439.5416
30.0000 4.2153 474.2420
30.0000 4.2813 509.3309
Actually, by looking at the Matlab documentation I found a simpler way. You can use the function griddata. (The doc in matlab help shows visual example). The resampling on a common grid and the interpolation is embedded in the function.
%// First separate (and name your column to identify them better)
t = d(:,1) ;
x = d(:,2) ;
y = d(:,3) ;
%// use the function 'griddata'
[TI,YI] = meshgrid( 20:30 , 0:20:500 ) ; %// change these values to change the grid limits
XI = griddata(t,y,x,TI,YI) ;
%// show result in 3D ... but could be projected in X-Y plane if necessary
plot3(TI,YI,XI , 'Marker','o' )
xlabel('Time') ; ylabel('Y') ; zlabel('X')
The last line of the code shows this plot:
All your interpolated data are in the XI matrix. The way to retrieve them depends on how you want to organize them ultimately.
EDIT:
To place all the interpolated data in a single table InterpData organized the same way of your original table, use the following:
nLine = numel(XI) ;
InterpData = [ reshape(TI,nLine,[]) reshape(XI,nLine,[]) reshape(YI,nLine,[]) ] ;
Regarding the NaNs. They will come to bother you every time you ask to do an interpolation outside of the initially known values.
For example, if your time in the original data is in the [20 to 30] interval, matlab will gladly interpolate anything within that interval, but will return NaN if you ask to return a value for time = 19 for example. Same goes for Y, the grid on which to interpolate has to be within the initial range. (as in this implementation we use a base grid formed by Time (column 1) and Y(column 3), to interpolate the X column).
Try this code, which implements #Hoki 's comment:
m20=[3.4076 0; 3.4226 99.5405; 3.4701 196.3360; 3.5592 287.0781; 3.6248 328.8516; 3.6643 348.3373; 3.7091 367.2823; 3.7591 385.4784; 3.8077 402.7170; 3.8957 437.5221; 4.0314 506.9907];
m30=[3.6335 0; 3.6373 49.8884; 3.6488 99.5405; 3.6685148.5936; 3.7363 243.2204; 3.7876 287.7398; 3.8537 329.6097; 3.8935 349.9452; 3.9384 368.9776; 3.9892 387.2576; 4.0410 404.5759; 4.1350 439.5416; 4.2153 474.2420; 4.2813 509.3309];
yy = [0:50:500];
xx20 = interp1(m20(:,2),m20(:,1),yy);
xx30 = interp1(m30(:,2),m30(:,1),yy);
for m = 1:9
mm(:,m) = xx20 + (xx30-xx20)*(m/(30-20));
end
plot(m20(:,1),m20(:,2),xx20,yy,xx30,yy,m30(:,1),m30(:,2),mm,yy)
You interpolate the given M vectors to find the x coordinate of a set of y values - these are the interp1 lines. Then, you linearly interpolate as a function of m between the interpolated x-coordinates.
Related
Let's say f(x) = (4x^2-9)/(2x-3). The function f(x) is undefined at x=3/2. Note that the function can be factored to yield f(x)=2x+3 but let's examine the first equation. In the following script when x=1.5, the function f(x=1.5)=4.0
clear all
clc
x = 0:0.3:2;
for i = 1:length(x)
if x(i) == 1.5 % this line for some reasons is ignored.
y(i) = 6;
else
y(i) = (4*x(i)^2-9)/(2*x(i)-3);
end
end
x
y
The output of the preceding script is
x = 0 0.3000 0.6000 0.9000 1.2000 1.5000 1.8000
y = 3.0000 3.6000 4.2000 4.8000 5.4000 4.0000 6.6000
Why y=4.0000 when x=1.5000? Now let's run the code without for-loop,
clear all
clc
x = 0:0.3:2
y = (4*x.^2-9)/(2*x-3)
The result of the above code is
x = 0 0.3000 0.6000 0.9000 1.2000 1.5000 1.8000
y = 3.6000
There is only one value for f(x). Can any one explain what is going on?
As for your first question, yes, you are running into a floating point precision error. You can check this by checking the difference between the x value that it's supposed to be a 1.5 and a 1.5.
x(6)-1.5
%ans=
% -2.2204e-16
Specifically in your case it comes from using 0.3 to construct the vector x since that value cannot be precisely saved into binary, see here for a deeper explanation
Any of the following should solve your problem
x=0:3:20; %Create the vector based on values that can be represented
x=x/10;
x=[0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]; %Directly input the values
abs(x(i)-1.5) < tol %Instead of directly comparing values, compare the difference to a determined tolerance (very small compared to the values at hand)
As for your second question #Phill already gave you the answer, you are using / matrix division, and you want ./ element wise division.
When I run your first example with the for loop in Octave, I do not see a problem with the x=1.5 if statement being ignored. Perhaps this is a subtle difference between Matlab and Octave for this although I would be surprised.
For the array notation second example
clear all
clc
x = 0:0.3:2
y = (4*x.^2-9)/(2*x-3)
You have chosen the matrix division operator / instead of the element by element division operator ./
I have a data set on the form of 3 spatial coordinates x,y,z and an amplitude, here is a small crop of the data:
[ 0 2.9373 0.4646 2.9926
0.8384 1.5338 1.0000 1.0016
0 0.7619 0.5051 1.0033
1.0000 3.5288 0.6667 2.9894
0 0.5013 0.4343 1.0037
1.0000 2.8070 0.4848 2.9935
0.7980 4.0000 0.8586 2.9872
1.0000 0.1404 0.0707 1.0043
1.0000 1.7845 0.1818 1.0007
0.9798 3.1679 1.0000 2.9913]
What I would like is a 2D contour plot, where the interface is represented by the contour levels within, say, 2.0 +/- 0.05.
First I start by making the data 2D and thus choose the values z within +/- 0.01. Then I am only left with x,y,amplitude.
Then I used this for extracting the data sets that satisfy data(:,4) is within 2.0 +/- 0.05.
However, what remains now is actually making the contour plot. I tried contour but that requires the data to have a format of meshgrid, which it does not. So my question is, what is the easiest way to make a contour plot of the extracted data?
You should be able to create an interpolation function for your scattered data like this:
F_interp = scatteredInterpolant(x,y,amplitude);
Then setup a gridded mesh of interpolation points (using limits and sizes that could be based on the original data):
xMin = min(x);
xMax = max(x);
yMin = min(y);
yMax = max(y);
Nx = 2*length(x);
Ny = 2*length(y);
xpts = linspace(xMin,xMax,Nx);
ypts = linspace(yMin,yMax,Ny);
[X,Y] = meshgrid(xpts,ypts);
Interpolate the data at those gridded points:
A = F_interp(X,Y);
Now pass the interpolated data to the MATLAB contour function:
contour(X,Y,A);
Using the code for plot_pz([poles],[zeros])
function plot_pz(b,a)
b_roots = roots(b);
a_roots = roots(a);
plot(b_roots,'x black');
plot(a_roots,'o blue');
axis equal;
I can get my b_roots to plot properly, but my a_roots continually plot on the 1+0i axis (or x=1). For example, the Z-Transform H(z) = [[1 2 2],[0 1 .8]] gives the following poles and zeros (per matlab):
poles =
-1.0000 + 1.0000i
-1.0000 - 1.0000i
zeros =
-0.8000
It should look like this
but instead what I get is
Where my zeros are at -1+1i and -1-1i, and my poles seem to be at 1-.8i, but should instead be at -.8+0i
I'm sure it's something simple that I'm missing, but I can't figure it out. I think it only happens when I have a single pole or a single zero.
Does plot(X) always default to plotting 1+xi?
Fixed by being more clear with real() and imag()
plot(real(b_roots),imag(b_roots),'o blue');
plot(real(a_roots),imag(a_roots),'x red');
I'm trying to do an algorithm in Matlab to try to calculate a received power in dBm of a logarithmic model of a wireless telecommunication system..
My algorithm calculate the received power for a number of distances in km that the user specified in the input and stores it in a vector
vector_distances = { 1, 5, 10, 50, 75 }
vector_Prx = { 131.5266 145.5060 151.5266 165.5060 169.0278 }
The thing is that I almost have everything that I need, but for graphics purposes I need to plot a graph in where on the x axys I have my vector of receiver power but on the y axys I want to show the same received power but with the most complete logarithmic model (the one that have also the noise - with Log-normal distribution on the formula - but for this thing in particular for every distance in my vector I need to choose 50 numbers with 0.5 distance between them (like a matrix) and then for every new point in the same distance calculate the logarithmic model to later plot in the same graph the two functions, one with the model with no noise (a straight line) and one with the noise.. like this picture
!http://imgur.com/gLSrKor
My question is, is there a way to choose 50 numbers with 0.5 distance between them for an existing number?
I know for example, if you have a vector
EDU>> m = zeros(1,5)
m =
0 0 0 0 0
EDU>> v = 5 %this is the starter distance%
v =
5
EDU>> m(1) = 5
m =
5 0 0 0 0
% I want to create a vector with 5 numbers with 0.5 distance between them %
EDU>> for i=2:5
m(i) = m(i-1) + 0.5
end
EDU>> m
m =
5.0000 5.5000 6.0000 6.5000 7.0000
But I have two problems, the firs one is, could this be more simplex? I am new on Matlab..and the other one, could I create a vector like this (with the initial number in the center)
EDU>> m
m =
4.0000 4.5000 **5.0000** 5.5000 6.0000
Sorry for my english, and thank you so much for helping me
In MATLAB, if you want to create a vector from a number n to a number m, you use the format
A = 5:10;
% A = [5,6,7,8,9,10]
You can also specify the step of the vector by including a third argument between the other two, like so:
A = 5:0.5:10;
% A = [5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10]
You can also use this to count backwards:
A = 10:-1:5
% A = [10,9,8,7,6,5]
I have the following results :
v =
7.8053 959.5985
6.1820 481.3263
4.9794 242.2347
4.0829 122.7578
3.4079 63.1224
2.8962 33.4578
2.5118 18.8560
2.2380 11.9084
2.0725 8.9597
2.0086 8.0952
2.0001 8.0012
2.0000 8.0000
2.0000 8.0000
Which I got them after I ran a function called newton_system for calculating , and I ran the input vector [10,3] on the follwoing f(x,y) :
y(1) = x(1)^3 - 5*x(1)^4 + x(2)^2 + 8;
y(2) = 2*x(1)^3 - x(2)^2 + 5*x(1)^2 + 5*x(2) - 12;
I ran 13 iterations , and now I want to plot a graph of the approximations as a function of the iterations (from 1 to 13) , can someone please explain how to do that ?
FYI please notice that as I progress with the iterations , we converge to 2.0000 8.0000
Here's a solution using the plot command:
plot(v(:,1),v(:,2),'-o') %# plot the line with circles for the x,y values
hold on,plot(2,8,'+r') %# add a red cross for the solution
xlim([0 8]) %# modify x-axes limits so that the plot looks a bit better
Use the zoom button on the figure menu to zoom into the area around the solution.