Interpolation in Matlab - matlab

I've done an interpolation but I don't know if it's possible to save the data. For example. This is my code:
load ab1.txt
x= ab1(:,2);
y= ab1(:,3);
z= 399.25:1:2179.5;
yi= interp1(x,y,z);
plot(x,y,'o',z,yi)
I have a lot of values like 352.4, 352.5 354.3... and I want to get, with the interpolation, only one value from every number.For example, for the value 352 I want to get the value of the interpolation. Is that possible? Or I will have to do something different like mediums or something like that?

y352 = interp1(X,Y,352)
gives you the interpolated value at 352.
8 AUGUST 2012 EDIT: Then OP comments
Thanks mwengler! But the problem is I need to find missing values with interpolation. For example. I have 350, 351, 353, 354 (x) with their values (y). And I need that Matlab identify that the number 352 is missed and to find their value with interpolation. Is that possible? Thanks a lot! :) – user1578688 yesterday
From your other comment, you consider an integer number N to be missing if there are no true samples in X that are in range N<=x<N+1. So the answer to your question is:
1) find missing numbers and make an array of them
2) interpolate values of those numbers only.
X = sort(X); % make sure our X go from least to most in order
XasInt = floor(X); % the integer X at each X value
XasIntFullRange = (X(1):X(end))'; % all X including "missing" values
XasIntMissing = setdiff(XasIntFullRange,XasInt); % just the missing ones
YasIntMissing = interp1(X,Y,XasIntMissing); % interpolated values of the missing

Related

MATLAB - Create Array Variable in For Loop and Plot

I will preface this post with the obvious fact that I'm not very experienced in MATLAB and this post may be somewhat confusing. Any help is appreciated!
I need to store data inside two parameters but unsure on how to do it. The number of "x" values is known but it is a user inputted value, so it's not something that can be hard coded. Same as the "y" values. Here's a simplified example of what I think I need (numbers are hard coded here for the sake of the example).
Then, the final figure should have multiple plots on it. Each "x" variable is its own "output" that needs to be plotted. In the end I need "x" number of plots with "z" and "y" being the (X,Y) coordinates for each "x" plot, respectively.
EDIT: Updated example code.
list = [.0025, .005, .0075];
x = input('How many? ');
y = linspace(2.4*10^9, 5.0*10^9, 1000);
z = zeros(x, length(y));
for i = x
time = list(i)/(3*10^8);
for j = y
z(i,j) = (time * j);
end
end
for i = x
plot(z(i,j));
end
I get the following error:
Requested 3x2400000000 (53.6GB) array exceeds maximum array size preference. Creation of arrays greater
than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or
preference panel for more information.
The example that I provided could be totally wrong but I hope I have explained enough for someone to provide feedback.
Create the z-Array beforehand to your needs: https://uk.mathworks.com/help/matlab/ref/zeros.html
Then you can fill it with z[x,y] = x+y
HTH

Wrong dendrogram generated

I have 31 data, but dendrogram is missing one data. Here is my code:
A = csvread('similarityNoGrpS2.csv',1,1) % 31x31 double
Z = linkage(A, 'average') % 30x3 double
H = dendrogram(Z,'Orientation','left','ColorThreshold','default') %29x1 line
My input file can be found here.
Here is my dendrogram:
According to Z, (24,30) and (27,31) should be clustered, but in dendrogram pic, we can see there is no 31 and 27 is getting clustered with 30 which is wrong!
Can anyone help me in this matter?
P.S. I'm using MATLAB R2016a.
You need to modify the last line of your code to this:
H = dendrogram(Z, 0, 'Orientation', 'left', 'ColorThreshold', 'default');
which for the given data gives:
Explanation
Your original data set (A) has more than 30 points but you did not specify the value of P. It is mentioned in the documentation:
If you do not specify P then dendrogram uses 30 as the maximum number of leaf nodes. To display the complete tree, set P equal to 0.
So you need to put P=0 in this syntax:
dendrogram(tree,P,Name,Value)

Sampling and DTFT in Matlab

I need to produce a signal x=-2*cos(100*pi*n)+2*cos(140*pi*n)+cos(200*pi*n)
So I put it like this :
N=1024;
for n=1:N
x=-2*cos(100*pi*n)+2*cos(140*pi*n)+cos(200*pi*n);
end
But What I get is that the result keeps giving out 1
I tried to test each values according to each n, and I get the same results for any n
For example -2*cos(100*pi*n) with n=1 has to be -1.393310473. Instead of that, Matlab gave the result -2 for it and it always gave -2 for any n
I don't know how to fix it, so I hope someone could help me out! Thank you!
Not sure where you get the idea that -2*cos(100*pi) should be anything other than -2. Maybe you are not aware that Matlab works in radians?
Look at your expression. Each term can be factored to contain 2*pi*(an integer). And you should know that cos(2*pi*(an integer)) = 1.
So the results are exactly as expected.
What you are seeing is basically what happens when you under-sample a waveform. You may know that the Nyquist criterion says that you need to have a sampling rate that is at least two times greater than the highest frequency component present; but in your case, you are sampling one point every 50, 70, 100 complete cycles. So you are "far beyond Nyquist". And that can only be solved by sampling more closely.
For example, you could do:
t = linspace(0, 1, 1024); % sample the waveform 1024 times between 0 and 1
f1 = 50;
f2 = 70;
f3 = 100;
signal = -2*cos(2*pi*f1*t) + 2*cos(2*pi*f2*t) + cos(2*pi*f3*t);
figure; plot(t, signal)
I think you are using degrees when you are doing your calculations, so do this:
n = 1:1024
x=-2*cosd(100*pi*n)+2*cosd(140*pi*n)+cosd(200*pi*n);
cosd uses degrees instead of radians. Radians is the default for cos so matlab has a separate function when degree input is used. For me this gave:
-2*cosd(100*pi*1) = -1.3933
The first term that I got using:
x=-2*cosd(100*pi*1)+2*cosd(140*pi*1)+cosd(200*pi*1)
x = -1.0693
Also notice that I defined n as n = 1:1024; this will give all integers from 1,2,...,1024,
there is no need to use a for loop since many of Matlab's built in functions are vectorized. Meaning you can just input a vector and it will calculate the function for every element in the vector.

Not sure how the hist function in MATLAB works

I am not very sure how the hist function in MATLAB works. I seem to have few problems with it.
Bascially, in the code below, i am trying to run the rotation invariant Uniform Local Binary Pattern(LBP) code. I have no problem with the LBP code but the problem is with hist function(indicated in the code below).
The problem is that the range i should get is from 0:9 but when i apply the histogram function i get values greater than 9 such as 35, 27 and even values such as 178114.Not very sure how to correct it.
I2 = imread('test.png');
RIUniformHist=[];
m=size(I2,1);
n=size(I2,2);
for i=1:10:m
for j=1:10:n
for k=i+1:i+8
for l=j+1:j+8
J0=I2(k,l);
I3(k-1,l-1)=I2(k-1,l-1)>J0;
I3(k-1,l)=I2(k-1,l)>J0;
I3(k-1,l+1)=I2(k-1,l+1)>J0;
I3(k,l+1)=I2(k,l+1)>J0;
I3(k+1,l+1)=I2(k+1,l+1)>J0;
I3(k+1,l)=I2(k+1,l)>J0;
I3(k+1,l-1)=I2(k+1,l-1)>J0;
I3(k,l-1)=I2(k,l-1)>J0;
LBP=I3(k-1,l-1)*2^7+I3(k-1,l)*2^6+I3(k-1,l+1)*2^5+I3(k,l+1)*2^4+I3(k+1,l+1)*2^3+I3(k+1,l)*2^2+I3(k+1,l-1)*2^1+I3(k,l-1)*2^0;
bits = bitand(LBP, 2.^(7:-1:0))>0;
if nnz(diff(bits([1:end, 1]))) <= 2
RIULBP(k,l)=abs(I3(k-1,l-1)-I3(k-1,l))+ abs(I3(k-1,l)-I3(k-1,l+1))+ abs(I3(k-1,l+1)-I3(k,l+1))+ abs(I3(k,l+1)-I3(k+1,l+1))+abs(I3(k+1,l+1)-I3(k+1,l))+abs(I3(k+1,l)-I3(k+1,l-1))+abs(I3(k+1,l-1)-I3(k,l-1));
else
RIULBP(k,l)=9;
end
end
end
RIULBP=uint8(RIULBP);
RIULBPv=reshape(RIULBP,1,size(RIULBP,1)*size(RIULBP,2));
RIUHist=hist(RIULBPv,0:9); % problem
RIUniformHist = [RIUniformHist RIUHist];
end
end
The vector returned by
RIUHist=hist(data, bins)
is the count of how many elements of data are nearest the point identified by the bins vector. So if you have a value of 178114, that juts means that there were 178114 elements of data that were nearest to the matching index in bins.
You can use
[RIUHist, binsOut] = hist(data)
to let Matlab choose the bins (I believe it uses 20 bins) or
[RIUHist, binsOut] = hist(data, binCount)
To let Matlab choose the bins, but force a certain number of bins (I often use 100 or 200).

Matlab "interp2" problem regarding NaN at edges

I am a bit stuck on a simple exercise and would appreciate some help.
I am trying to do some simple 2D interpolation using the "interp2" function in Matlab for a variable 'tmin' of dimension [15x12]:
lat = 15:1.5:32;
lon = 70:1.5:92;
lat_interp = 15:1:32;
lon_interp = 70:1:92;
[X,Y] = meshgrid(lat,lon);
[Xi,Yi] = meshgrid(lat_interp,lon_interp);
tmin_interp = zeros(length(lon_interp),length(lat_interp),Num_Days);
tmin_interp(:,:) = interp2(X,Y,tmin(:,:),Xi,Yi,'linear');
This code results in the last row and last column of tmin_interp to be NaNs, i.e.:
tmin_interp(23,1:18) ==> NaN
tmin_interp(1:23,18) ==> NaN
Does anyone know what I might be doing wrong? Am I making a simple mistake with regards to the interpolation setup? Thank you for your time.
The reason they are nans is that there is no data before and after your grid to interpolate to. Linear interpolation uses the gradient of the field at the Xi,Yi, in order to estimate the value at that point. If there is nothing either side, it can't.
You can use extrapval parameter to extrapolate outside the X,Y you specify. Just add the parameter 0 after 'linear':
interp2(X,Y,tmin(:,:),Xi,Yi,'linear', 0);
This will put zero for the points 'on the edge'. However, it is likely that for points outside, they may fall off to some default value, like zero. To do this, you can add zeros before and after tmin:
tmin_padded = [ zeros(1,size(tmin,2)+2)
zeros(size(tmin,1),1) tmin zeros(size(tmin,1),1)
zeros(1,size(tmin,2)+2) ];
(haven't checked this but you get the idea.) you will also need to add some pre- and post-values to X and Y.
Use some other value, if that's the 'outside' or 'default' value of tmin.
PS why are you creating tmin_interp as 3-dimensional?
Or just try:
interp2(X,Y,tmin(:,:),Xi,Yi,'spline');
to avoid imposing the 0 value.
HTH!