Warning: Matrix is singular to working precision

2 views (last 30 days)
fafz1203
fafz1203 on 16 Oct 2016
Commented: Aaina on 7 Aug 2018
i am experiencing the above warning while running this code
sigma = eye(10);
mu = repelem(zeros,10);
xTrain = mvnrnd (mu,sigma,1000,10);
t = transpose (xTrain);
xTest = transpose (mvnrnd (mu,sigma,1000,10));
yTrain = randn(1000,1);
x = inv(t*xTrain);

Answers (2)

Walter Roberson
Walter Roberson on 16 Oct 2016
You are doing inv(xTrain.'*xTrain) but rank(xTrain) is only 1
This is related to your passing in the undocumented fourth parameter to mvnrnd, which you give as 10. The third and fourth parameter together do not give an output size: the output size is determined by the third parameter (a size) and the length of the diagonal of the second parameter.
The undocumented fourth parameter is:
% R = MVNRND(MU,SIGMA,N,T) supplies the Cholesky factor T of
% SIGMA, so that SIGMA(:,:,J) == T(:,:,J)'*T(:,:,J) if SIGMA is a 3D array or SIGMA
% == T'*T if SIGMA is a matrix. No error checking is done on T.
You encounter the line
r = randn(n,size(T,1),'like',outtype) * T + mu;
where n is 1000 (your third parameter) and T is 10 so size(T,1) is 1 and mu is the vector of zeros you passed in as your first parameter, replicated to have n rows, so 1000 x 10 of zeros. This is then a 1000 x 1 vector plus a 1000 x 10 array of zeros.
If you were running R2016a or earlier you would have received an error, but in R2016b or later the operation is equivalent to
bsxfun(@plus, randn(n,size(T,1),'like',outtype) * T, mu)
so the 1000 x 1 vector is replicated to 1000 x 10 and the 1000 x 10 array of zeros is added. This gives you a 1000 x 10 matrix in which all of the rows are identical, and the rank of that is going to be 1. Multiply it by its transpose and the rank of the result cannot be greater than 1 so you cannot inv() it.

Aaina
Aaina on 5 Apr 2018
Edited: Walter Roberson on 7 Apr 2018
I also have the warning
Warning: Matrix is singular to working precision.
> In NormalizePopulation>FindHyperplaneIntercepts at 41
In NormalizePopulation at 31
the matlab code goes like this:
function [pop, params] = NormalizePopulation(pop, params)
params.zmin = UpdateIdealPoint(pop, params.zmin);
fp = [pop.Cost] - repmat(params.zmin, 1, numel(pop));
params = PerformScalarizing(fp, params);
a = FindHyperplaneIntercepts(params.zmax);
for i = 1:numel(pop)
pop(i).NormalizedCost = fp(:,i)./a;
end
end
function a = FindHyperplaneIntercepts(zmax)
w = ones(1, size(zmax,2))/zmax;
a = (1./w)';
end
What is the problem?
  2 Comments
Walter Roberson
Walter Roberson on 7 Apr 2018
Your params.zmax is not a scalar, so ones(1, size(zmax,2))/zmax uses the mrdivide operator / and wants to do approximately
ones(1, size(zmax,2)) * inv(zmax)
but your zmax matrix is singular.
The code does seem to be expecting zmax to be an array -- otherwise it probably would not use size(zmax, 2)
In short: your matrix zmax is not linearly independent so the matrix division is not working properly.
Aaina
Aaina on 7 Aug 2018
Thank you so much.... u solved my problem

Sign in to comment.

Categories

Find more on Operating on Diagonal Matrices in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!