Warning: Matrix is singular to working precision
2 views (last 30 days)
Show older comments
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);
0 Comments
Answers (2)
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.
0 Comments
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
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.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!