Warning: Matrix is singular to working precision
2 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Risposte (2)
Walter Roberson
il 16 Ott 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 Commenti
Aaina
il 5 Apr 2018
Modificato: Walter Roberson
il 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 Commenti
Walter Roberson
il 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.
Vedere anche
Categorie
Scopri di più su Logical in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!