Warning: Matrix is singular to working precision

2 次查看(过去 30 天)
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);

回答(2 个)

Walter Roberson
Walter Roberson 2016-10-16
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 2018-4-5
编辑:Walter Roberson 2018-4-7
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 个评论
Walter Roberson
Walter Roberson 2018-4-7
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by