Weird behavior of a sparse Matrix under MATLAB - matlab

I have been given this 63521x63521 real sparse symmetric matrix in MATLAB and for some reason it seems to be behaving weirdly for some commands.
I am not sure if there is a 'defect' in the matrix file or in the way I am using
MATLAB's commands.
Consider the following script. I have indicated the output of each of the steps.
% Gives sparsity shown as expected, so this works fine
spy(rYbus)
% I want the top 3 singular values of rYbus. But this line Returns empty matrix! Why/
S = svds(rYbus,3);
% Set exact answer and rhs and solve the linear system with iterative and direct method
b_exact = ones(size(Ybus,1),1);
rhs = rYbus*b_exact ;
% Following line gives Warning: Matrix is singular, close to singular or badly scaled.
% Results may be inaccurate. RCOND = NaN.
% > In Ybustest at 14.
b_numerical_1 = rYbus\rhs;
% Even for a single GMRES iteration b_numerical_2 is a vector of Nans. Why?
b_numerical_2 = gmres(rYbus,rhs,[],[],1);
Can anyone point out what may have gone wrong?
I have already used the "isnan" function to verify that the matrix rYbus
does not have any nans. The size of the matrix is 63521 x 63521

Have you checked if your input sparse matrix rYbus has any NaNs? If I remember correctly, svds can give you an empty matrix instead of an error.
Another possible error is the size of rYbus. What is the size of it?

Related

Very small numerical issues with hessian symmetry and sparse command

I am using IPOPT in MATLAB to run an optimization and I am running into some issues where it says:
Hessian must be an n x n sparse, symmetric and lower triangular matrix
with row indices in increasing order, where n is the number of variables.
After looking at my Hessian Matrix, I found that the non-symmetric elements it is complaining about are very close, here is an example:
H(k,j) = 2.956404205984938
H(j,k) = 2.956404205984939
Obviously these elements are close enough and there are some numerical round-off issues or something of the like. Also, when I call MATLABs issymmetric function with H as an input, I get false. Is there a way to forget about these very small differences in symmetry?
A little more info:
I am using an optimized matlabFunction to actually calculate the entire hessian (H), then I did some postprocessing before passing it to IPOPT:
H = tril(H);
H = sparse(H);
The tril command generates a lower triangular matrix, so these numeral differences should not come into play. So, the issue might be that it is complaining that the sparse command passes back increasing column indices and not increasing row indices. Is there a way to change this so that it passes back the sparse matrix in increasing row indices?
If H is very close to symmetric but not quite, and you need to force it to be exactly symmetric, a standard way to do this would be to say H = (H+H')./2.

How to multiply matrix of nxm with matrix nxmxp different dimensions in matlab

In my current analysis, I am trying to multiply a matrix (flm), of dimension nxm, with the inverse of a matrix nxmxp, and then use this result to multiply it by the inverse of the matrix (flm).
I was trying using the following code:
flm = repmat(Data.fm.flm(chan,:),[1 1 morder]); %chan -> is a vector 1by3
A = (flm(:,:,:)/A_inv(:,:,:))/flm(:,:,:);
However. due to the problem of dimensions, I am getting the following error message:
Error using ==> mrdivide
Inputs must be 2-D, or at least one
input must be scalar.
To compute elementwise RDIVIDE, use
RDIVIDE (./) instead.
I have no idea on how to proceed without using a for loop, so anyone as any suggestion?
I think you are looking for a way to conveniently multiply matrices when one is of higher dimensionality than the other. In that case you can use bxsfun to automatically 'expand' the smaller matrix.
x = rand(3,4);
y = rand(3,4,5);
bsxfun(#times,x,y)
It is quite simple, and very efficient.
Make sure to check out doc bsxfun for more examples.

Matlab Stats Svm error in testing

I am using the Matlab 2012 svm included in the stats package. I have a binary classification problem where I train a set of vectors and test another set of vectors as the following matlab code shows:
%set the maximum number of iterations
optSVM = statset('MaxIter', 1000000);
%train the classifier with a set of feature vectors
SVMtrainModel = svmtrain(training_vectors_matrix(:,2:end), training_vectors_matrix(:,1), 'kernel_function' , 'linear', 'options', optSVM, 'tolkkt', 0.01);
%read the test vectors
TestV = csvread(test_file);
%Test the feature vectors in the built classifier
TestAttribBin = svmclassify(SVMtrainModel, TestV(:,2:end))
It' s a quite simple code and would run normally. The training runs ok, but when I test the following error happens:
Subscript indices must either be real positive integers or logicals.
Error in svmclassify (line 140)
outclass= glevels(outclass(~unClassified),:);
So, are my feature vectors with any problem? If I run this same code in different feature vectors (training and testing vectors) the code runs ok. I already checked the feature vectors and there are no NaNs. What should be the cause of this problem?
This should be solvable keeping my generic solution to this problem in mind.
1) Run the code with dbstop if error
It will now stop at the line that you provided:
outclass= glevels(outclass(~unClassified),:);
2) Check the possible solutions.
In this case I assume that glevels and outclass are both
variables. The next thing to do would be to carefully examine
everything that could be an index.
Starting inside out:
The first index is ~unClassified, as the ~ operation did not fail, it is safe to say that this is now a logical vector.
The second and lastindex is outclass(~unClassified), this one is most likely not consisting of only numbers like 1,2,3,... or true,false values.
The test whether the values are all valid is quite simple, one of these two should hold:
To confirm that the values in x are logical: class(x) should return 'logical'
To confirm that the values in x are real positive integers: isequal(x, max(1,round(abs(x)))) should return 'true'.
This problem can be solve if you remove your NaN rows or data:
Features(~any(~isnan(Features), 2),:)=[];
maybe you have complex numbers too, then use this code:
Features3(any(isnan(Features3),2),:)=0;
Features3 =real(Features3);
first line, make all NaN values turn to zero and the second line turns all complex numbers to be real.

Cryptic matlab error when computing eigs

I am trying to find the 2 eignevectors of the 2 smallest eigenvalues of a laplacian. I do this by
[v,c]=eigs(L,M,2,'SM');
Where L is the lapalcian and M is the mass matrix.
As a result I get the error
Error using eigs/checkInputs/LUfactorAminusSigmaB (line 1041)
The shifted operator is singular. The shift is an eigenvalue.
Try to use some other shift please.
Error in eigs/checkInputs (line 855)
[L,U,pp,qq,dgAsB] = LUfactorAminusSigmaB;
Error in eigs (line 94)
[A,Amatrix,isrealprob,issymA,n,B,classAB,k,eigs_sigma,whch, ...
Does this mean I am doing something wrong, or is this just matlab choosing a bad initial guess for its iteration process?
The matrices I am using should have a descent condition number...
I ran into the same problem while implementing normalized cuts segmentation. The condition number is actually infinite because the smallest eigenvalue is 0, and this is basically what MATLAB's error message is about. It's running LU decomposition first.
I just added a multiple of I, 10*eps*speye, to the normalized Laplacian to improve conditioning and that fixed it.
I had the same problem with the eigs function. So I went the long (and maybe stupid) way but it did the job for me as my problem is not that big: (I will try to keep your notation)
% Solve the eigenvalue problem using the full matrices
[v,c]=eig(full(L),full(M));
% Sort out the eigenvalues using the sort function (the "-" sign is because you want the smallest real eigenvalues in magnitude)
[E,P] = sort(real(c),'descend'); % Here I am assuming you know all the eigenvalues have` negative real parts
% Now P is a vector that contains (in order) the indices of the row permutation operated by the % function sort.
% In order to obtain the two eigenvectors corresponding to the 2 smallest eigenvalues:
for k = 1:2
index = P(k);
lambda(k) = c(index,index); % use this to check if c(index,index)=E(k,k)
eigvec(:,k) = v(:,index); % corresponding eigenvector
end
Hope this helps
G

Matlab inverse issue - fmri data - partial correlation algorithm

I'm using the following code To get a partial correlation matrix (original code from http://www.fmrib.ox.ac.uk/analysis/netsim/)
ic=-inv(cov(ts1)); % raw negative inverse covariance matrix
r=(ic ./ repmat(sqrt(diag(ic)),1,Nnodes)) ./ repmat(sqrt(diag(ic))',Nnodes,1); % use diagonal to get normalised coefficients
r=r+eye(Nnodes); % remove diagonal
My original matrix (ts1) is a brain activity over time course (X variable) in multiple voxels -volumetric pixel 3X3 (Y variable).
The problem is, I have more dependent variables(y -voxels ) than independent variables(x - time course).
I get the following Warning-
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 4.998365e-022.
Any thoughts on how to fix the code so I'll get the partial correlation between all of the voxels?
The warning is from Matlab having a problem inverting the covariance matrix.
One solution might be to try pinv()
http://www.mathworks.com/help/techdoc/ref/pinv.html