Error in MATLAB: first input subs must contain positive integer - matlab

Is there any operation in MATLAB that removes zeros from number
150.0000 150.0000 0.0000
143.0000 148.0000 0.0000
152.0000 152.0000 0.0000
152.0000 144.0000 0.0000
146.0000 150.0000 0.0000
149.0000 145.0000 0.0000
148.0000 152.0000 0.0000
152.0000 157.0000 0.0000
157.0000 164.0000 0.0000
160.0000 155.0000 0.0000
154.0000 154.0000 0.0000
The reason I ask is because I want to use them in function called accumarray and I keep getting the error
First input SUBS must contain positive integer subscripts.
Thanks
Update: Eventually I would like to use as follows
[X] = round(x)
[Y] = round(y)
data = [X,Y,Z];
plotdata = accumarray(data(:,1:2),data(:,3));
surface(plotdata)
colorbar

[X] = round(x-min(x))+1;
[Y] = round(y-min(y))+1;
data = [X,Y,Z];
plotdata = accumarray(data(:,1:2),data(:,3));
surface(unique(x),unique(y),plotdata)
colorbar
min() moves your array to the upper-left corner of your matrix, basically removing leading zero rows and columns. The +1 ensures it does not end up at zero, which gives the error in accumarray.

Related

Mistakes with this MATLAB code

I have written this script to test the secant method in MATLAB
%Test of the Secant Method
function secantm1(x0,x1)
tol=10^-6; % tolerance
itmax=1000; % max number of iterations
itnum=0; % iterations counter
disp([itnum,x0,x1])
x2=x1-f1(x1)*((x1-x0)/f1(x1)-f1(x0));
itnum=itnum+1;
disp([itnum,x1,abs((x0-x1)/x0)])
while abs((x1-x2)/x1)>tol && itnum<itmax
x0=x1; % I think here is mistake
x1=x2;
x2=x1-f1(x1)*((x1-x0)/f1(x1)-f1(x0));
itnum=itnum+1;
disp([itnum,x1,abs((x1-x2)/x1),x2])
end
end
function y=f1(x)
y=x^3+x-3;
end
function y=f2(x)
y=x-tan(x);
end
But the thing is that it doesn't run, I have pointed out where I think is the mistake, but I am not quite sure if I am right and how can I fix it.
Can someone help me with this mistake please?
The thing is that when I input f1 I expect to get like 1.23... but the method doesn't converge, with the other function I expect not convergence
when I run it it gives me the following:
secantm1(1,2)
0 1 2
1 2 1
1.0e+03 *
0.0020 -0.0060 0.2612 -1.5730
1.0e+11 *
0.0000 -0.0000 0.0056 8.7573
1.0e+45 *
0.0000 0.0000 0.0000 -2.6139
1.0e+172 *
0.0000 -0.0000 0.0000 -1.1995
1.0e+172 *
0.0000 -1.1995 Inf Inf
7 Inf NaN NaN
Thanks in advance.
The problem was you were missing a set of parentheses in the denominator of your iteration update.
i.e
x2=x1-f1(x1)*((x1-x0)/f1(x1)-f1(x0));
should be
x2=x1-f1(x1)*((x1-x0)/( f1(x1)-f1(x0) ));
The corrected secant code should be:
function secantm1(x0,x1)
tol=10^-6; % tolerance
itmax=1000; % max number of iterations
itnum=0; % iterations counter
disp([itnum,x0,x1])
x2=x1-f1(x1)*((x1-x0)/ ( f1(x1)-f1(x0) ));
itnum=itnum+1;
disp([itnum,x1,abs((x0-x1)/x0)])
while abs((x1-x2)/x1)>tol && itnum<itmax
x0=x1; % This was OK
x1=x2;
x2=x1-f1(x1)*((x1-x0)/( f1(x1)-f1(x0) ));
itnum=itnum+1;
disp([itnum,x1,abs((x1-x2)/x1),x2])
end
end
This will converge to a result now:
secantm1(1,2)
0 1 2
1 2 1
2.0000 1.1250 0.0471 1.1780
3.0000 1.1780 0.0320 1.2156
4.0000 1.2156 0.0019 1.2134
5.0000 1.2134 0.0000 1.2134
6.0000 1.2134 0.0000 1.2134

MATLAB : Block diagonalize a complex antisymmetric matrix

I am using the following function to block diagonalize antisymmetric matrices.
function [R, RI , S ] = Matrix_block (A)
[U,D]= schur (A);
E=ordeig(double(D)) ;
[R, S]= ordschur (U,D, abs(E)<1000*eps ) ;
RI=R';
The code works perfectly fine for real antisymmetric matrices but fails for complex antisymmetric matrices as follows :-
a = rand(6); a = a-a'; [r,ri,s] = Matrix_block(a);
b = rand(6)+1i*rand(6); b= b-conj(b)'; [r,ri,s] = Matrix_block(b);
How can I correct my code for it to work also for complex matrices ? I want a block-diagonal matrix (of the following form) as the output for both real and complex matrices.
0 e1 -0.0000 -0.0000 0.0000 -0.0000
-e1 0 0.0000 0.0000 -0.0000 0.0000
0 0 -0.0000 e2 0.0000 -0.0000
0 0 -e2 -0.0000 0.0000 -0.0000
0 0 0 0 -0.0000 e3
0 0 0 0 -e3 -0.0000
You need a different algorithm for the complex case. The Matlab documentation says:
If A is complex, schur returns the complex Schur form in matrix T. The complex Schur form is upper triangular with the eigenvalues of A on the diagonal.
Also, I could notice that you cast your matrix D into double(D). This has no real effects since D is already double. Nevertheless I have seen that the ordeig return different values for the eigenvalues depending if you input D or double(D) even for the real case. It is something to dig more deeply.

spectral clustering

First off I must say that I'm new to matlab (and to this site...) , so please excuse my ignorance.
I'm trying to write a function in matlab that will use Spectral Clustering to split a set of points into two clusters.
my code is as follows
function Groups = TrySpectralClustering(data)
dist_mat = squareform(pdist(data));
W= zeros(length(data),length(data));
for i=1:length(data),
for j=(i+1):length(data),
W(i,j)=10^(-dist_mat(i,j));
W(j,i)=W(i,j);
end
end
D = zeros(length(data),length(data));
for i=1:length(W),
D(i,i)=sum(W(i,:));
end
L=D-W;
L=D^(-0.5)*L*D^(-0.5);
[ V E ] = eig(L);
disp ('V:');
disp (V);
If I understand correctly, then by using the second smallest eigenvector I should be able to perform a partition of the data into two clusters - If the ith member of the 2nd eigenvector is positive, the ith data point would be in the one cluster, otherwise it would be in the other cluster.
However, when I try the following
f=[1,1;0,0;1,0;0,1;100,100;100,101;101,101;101,100]
TrySpectralClustering(f)
I would expect that the first four points would form one cluster, and the last four would form another.
However, I receive
V:
-0.0000 -0.5000 0.0000 -0.5777 0.0000 0.4078 -0.0000 0.5000
-0.0000 -0.5000 0.0000 0.5777 0.0000 -0.4078 -0.0000 0.5000
-0.0000 -0.5000 0.0000 0.4078 0.0000 0.5777 -0.0000 -0.5000
-0.0000 -0.5000 0.0000 -0.4078 0.0000 -0.5777 -0.0000 -0.5000
-0.5000 -0.0000 -0.0000 -0.0000 -0.7071 -0.0000 0.5000 -0.0000
-0.5000 -0.0000 0.7071 0.0000 -0.0000 -0.0000 -0.5000 -0.0000
-0.5000 0.0000 -0.0000 0.0000 0.7071 0.0000 0.5000 0.0000
-0.5000 0 -0.7071 0 0 0 -0.5000 0
Taking the 2nd eigenvector
-0.0000 -0.5000 0.0000 0.5777 0.0000 -0.4078 -0.0000 0.5000
I find the one cluster includes the points 1,0;0,1;100,100;101,100
and the other cluster is made from the points 1,1;0,0;100,101;101,101
I wonder what am I doing wrong.
Note: I am working on the above as a part of a homework project.
Thanks in advance!
What you are getting is correct. Let U be the matrix containing the eigenvectors as shown above and let them be arranged such that the 1st column corresponds to the smallest eigenvalue and progressive columns correspond to the ascending eigenvalues. Then, take a subset of columns of U by retaining the eigenvectors corresponding to the smaller eigenvalues. Now, read these columns row-wise into a new set of vectors, call it Y. Cluster Y to get the spectral clusters. So, let us assume our subset is only the first column. We clearly see that if u were to cluster the first column, u would get the first 4 into 1 cluster and the next 4 into another cluster, which is what you want.
Take a look at the implementation on Prof. J. Shi's webpage. Pay close attention to discretisation.m function.
Moreover, your code is very inefficient. You need to take more advantage of Matlab's vectorization:
W = 10.^( - dist_mat ); % single liner of nested loop for comuting W
% computing the symmetric laplacian
d = sum( W, 2 ); % sum each row
d( d == 0 ) = 1; % avoid division by zero
d_half = 1./sqrt( d );
L = eye( n ) - bsxfun( #times, bsxfun( #times, W, d_half' ), d_half );
Two observations:
L=D-W; L=D^(-0.5)*L*D^(-0.5);
Why do you let him calculate the identity matrix? Just use the identity matrix eye(n) and substract D^(-0.5) * W * D^(-0.5) from that to calculate the Laplacian L
eig returns the eigenvectors as columns, why do you take the row? Did you check the values of the corresponding eigenvalues in E, so you can be sure you are looking at a eigenvec corresponding to the 2nd smallest eigenval?

How to represent e^(-t^2) in MATLAB?

I am a beginner in MATLAB, and I need to represent e(-t2).
I know that, for example, to represent ex I use exp(x), and I have tried the following
1) tp=t^2; / tp=t*t;
x=exp(-tp);
2) x=exp(-t^2);
3) x=exp(-(t*t));
4) x=exp(-t)*exp(-t);
What is the correct way to do it?
If t is a matrix, you need to use the element-wise multiplication or exponentiation. Note the dot.
x = exp( -t.^2 )
or
x = exp( -t.*t )
All the 3 first ways are identical. You have make sure that if t is a matrix you add . before using multiplication or the power.
for matrix:
t= [1 2 3;2 3 4;3 4 5];
tp=t.*t;
x=exp(-(t.^2));
y=exp(-(t.*t));
z=exp(-(tp));
gives the results:
x =
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
y =
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
z=
0.3679 0.0183 0.0001
0.0183 0.0001 0.0000
0.0001 0.0000 0.0000
And using a scalar:
p=3;
pp=p^2;
x=exp(-(p^2));
y=exp(-(p*p));
z=exp(-pp);
gives the results:
x =
1.2341e-004
y =
1.2341e-004
z =
1.2341e-004

how to Display data in matrix with with more than 4 decimals

He,
My question is about this matlab
output:
>>model3.Mu
ans =
0.7677 -1.1755 -0.8956
-0.0100 0.0883 0.0235
0.0001 -0.0010 -0.0003
-0.0000 0.0000 0.0000
How to display this data in a 4x3 matrix with more than 4 decimals?
type at the matlab prompt:
>> help format
I think what you want to do is issue the command "FORMAT LONG" before you execute your script.
You can also print the matrix out to arbitrary precision using fprintf in a loop.