Wrong dendrogram generated - matlab

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)

Related

random process modeling in signal processing

i would like to understand one thing and please help me to clarify it,sometimes it is necessary to represent given data by sum of complex exponentials with additive white noise,let us consider following model using sinusoidal model
clear all;
A1=24;
A2=23;
A3=23;
A4=23;
A5=10;
f1=11.01;
f2=11.005;
f3= 10;
f4=10.9
phi=2*pi*(rand(1,4)-0.5);
t=0:0.01:2.93;
k=1:1:294;
x=rand([1,length(t)]);
y(k)=A1.*sin(2*pi*f1*t+phi(1))+A2.*cos(2*pi*f2*t+phi(2))+A3.*sin(2*pi*f3*t+phi(3))+A4.*cos(2*pi*f4*t+phi(4))+A5.*x;
[pxx,f]=periodogram(y,[],[],100);
plot(f,pxx)
there phases are distributed uniformly in range of [-pi pi],but my main question is related following fact.to represent data as linear combination of complex exponentials with phases uniformly distributed in [-pi pi] interval, should we generate these phases outside of sampling or at each sampling process we should generate new list of phases?please help me to clarify this things
As I stated in the my comment, I don't really understand what you're asking. But, I will answer this as if you had asked it on codereview.
The following is not good practice in MATLAB:
A1=24;
A2=23;
A3=23;
A4=23;
A5=10;
There are very few cases (if any), where you actually need such variable names. Instead, the following would be much better:
A = [24 23 23 23 10];
Now, if you want to use A1, you do A(1) instead.
These two lines:
t=0:0.01:2.93;
k=1:1:294;
They are of course the same size (1x294), but when you do it that way, it's easy to get it wrong. You will of course get errors later on if they're not the same size, so it's nice to make sure that you have it correct on the first try, thus using linspace might be a good idea. The following line will give you the same t as the line above. This way it's easier to be sure you have exactly 294 elements, not 293, 295 or 2940 (it is sometimes easy to miss).
t = linspace(0,2.93,294);
Not really important, but k = 1:1:294 can be simplified to k = 1:294, as the default step size is 1.
The syntax .*, is used for element-wise operations. That is, if you want to multiply each element of a vector (or matrix) with the corresponding element in another one. Using it when multiplying vectors with scalars is therefore unnecessary, * is enough.
Again, not an important point, but x=rand([1,length(t)]); is simpler written x=rand(1, length(t)); (without brackets).
You don't need the index k in y(k) = ..., as k is continuous, starting at 1, with increments of 1. This is the default behavior in MATLAB, thus y = ... is enough. If, however, you only wanted to fill in every other number between 1 and 100, you could do y(1:2:100).
This is far from perfect, but in my opinion big step in the right direction:
A = [24 23 23 23 10];
f = [11.01 11.005 10 10.9]; % You might want to use , as a separator here
phi = 2*pi*(rand(1,4)-0.5);
t = linspace(0,2.93,294);
x = rand(1, length(t));
w = 2*pi*f; % For simplicity
y = A(1)*sin(w(1)*t+phi(1)) + A(2)*cos(w(2)*t+phi(2)) + ...
A(3)*sin(w(3)*t+phi(3)) + A(4)*cos(w(4)*t+phi(4))+A(5)*x;
Another option would be:
z = [sin(w(1)*t+phi(1)); cos(w(2)*t+phi(2)); sin(w(3)*t+phi(3)); ...
cos(w(4)*t+phi(4)); x];
y = A.*z;
This will give you the same y as the first one. Having the same w, t and phi as above, the following will also give you the same results:
c = bsxfun(#times,w,t') + kron(phi,ones(294,1));
y = sum(bsxfun(#times,A,[sin(c(:,1)), cos(c(:,2)), sin(c(:,3)), cos(c(:,4)), x']),2)';
I hope something in here might help you some in your further work. And maybe I actually answered your question. =)

Interpolation in 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

MATLAB XYZ to Grid

I have a tab separated XYZ file which contains 3 columns, e.g.
586231.8 2525785.4 15.11
586215.1 2525785.8 14.6
586164.7 2525941 14.58
586199.4 2525857.8 15.22
586219.8 2525731 14.6
586242.2 2525829.2 14.41
Columns 1 and 2 are the X and Y coordinates (in UTM meters) and column 3 is the associated Z value at the point X,Y; e.g. the elevation (z) at a point is given as z(x,y)
I can read in this file using dlmread() to get 3 variables in the workspace, e.g. X = 41322x1 double, but I would like to create a surface of size (m x n) using these variables. How would I go about this?
Following from the comments below, I tried using TriScatteredInterp (see commands below). I keep getting the result shown below (it appears to be getting some of my surface though):
Any ideas what is going on to cause this result? I think the problem lies with themeshgrid command, though I'm not sure where (or why). I am currently putting in the following set of commands to calculate the above figure (my X and Y columns are in meters, and I know my grid size is 8m, hence ti/tj going up in 8s):
F = TriScatteredInterp(x,y,z,'nearest');
ti = ((min(x)):8:(max(x)));
tj = ((min(y)):8:(max(y)));
[qx,qy] = meshgrid(ti,tj);
qz = F(qx,qy);
imagesc(qz) %produces the above figure^
I think you want the griddata function. See Interpolating Scattered Data in MATLAB help.
Griddata and tirscattteredinterp are extremely slow. Use the utm2deg function on the file exchange and from there a combination of both vec2mtx to make a regular grid and then imbedm to fit the data to the grid.
I.E.
for i = 1:length(X)
[Lat,Lon ] = utm2deg(Easting ,Northing ,Zone);
end
[Grid, R] = vec2mtx(Lat, Lon, gridsize);
Grid= imbedm(Lat, Lon,z, Grid, R);
Maybe you are looking for the function "ndgrid(x,y)" or "meshgrid(x,y)"

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, graphing functions

I have a homework problem, I think I did it correctly but need to make sure 100%. Can anyone check for me, before I hand it in?
Thank you.
Question:
Plot the function given by f (x) = 2 sin(2x) − 3 cos(x/2) over the in-
terval [0, 2π] using steps of length .001 (How?). Use the commands max and min to estimate the maximum and minimum points. Include the maximum and minimum points as tick marks on the x-axis and the maximum and minimum values as tick marks on the y-axis.
My code:
x=linspace(0,2*pi,6280);
f=#(x)...
2.*sin(2.*x)-3.*cos(x./2);
%f = #(x)2.*sin(2.*x)-3.*cos(x./2)
g=#(x)...
-1*(2.*sin(2.*x)-3.*cos(x./2));
%g = #(x)-1*(2.*sin(2.*x)-3.*cos(x./2))
[x3,y5]=fminbnd(g,0,2*pi);
%x3 = 4.0968
%y3 = -3.2647
[x2,y4]=fminbnd(f,0,2*pi);
%x2 =2.1864
%y2 = -3.2647
y2=max(f(x));
y3=min(f(x));
plot(x,f(x));
set(gca,'XTick',[x2 x3]);
set(gca,'YTick',[y2 y3]);
(*after I paste this code here, it appeared not as nice as I had it in my program, don't know why)
To create a vector with certain step do
x=0:0.001:2*pi;
Why do you have g(x) function and why are you using fminbind? Use MIN and MAX, return index of those values and find related x values.
[ymin, minindex] = min(f(x));
xmin = x(minindex);
For general case if you have multiple min/max values, index will contain only the first occurrence. Instead you can do:
minindex = find(y==ymin);
Or for real values to avoid precision error:
minindex = find(abs(y-ymin)<=eps);
Also your last statement returns error Values must be monotonically increasing. To avoid it sort your tick values.
set(gca,'XTick',sort([xmin xmax]));
set(gca,'YTick',sort([ymin ymax]));