51 lines
1.6 KiB
Matlab
51 lines
1.6 KiB
Matlab
function [test, penalty] = ispd(A)
|
||
|
||
% Test if the square matrix A is positive definite.
|
||
%
|
||
% INPUTS
|
||
% - A [double] n×n matrix.
|
||
%
|
||
% OUTPUTS
|
||
% - test [logical] scalar, true if and only if matrix A is positive definite (and symmetric...)
|
||
% - penalty [double] scalar, absolute value of the uum of the negative eigenvalues of A. This output argument is optional.
|
||
|
||
% Copyright © 2007-2024 Dynare Team
|
||
%
|
||
% This file is part of Dynare.
|
||
%
|
||
% Dynare is free software: you can redistribute it and/or modify
|
||
% it under the terms of the GNU General Public License as published by
|
||
% the Free Software Foundation, either version 3 of the License, or
|
||
% (at your option) any later version.
|
||
%
|
||
% Dynare is distributed in the hope that it will be useful,
|
||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
% GNU General Public License for more details.
|
||
%
|
||
% You should have received a copy of the GNU General Public License
|
||
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
if ~isquare(A)
|
||
error(['ispd:: Input argument ' inputname(1) ' has to be a square matrix!'])
|
||
end
|
||
|
||
[~, info] = chol(A);
|
||
test = ~info;
|
||
|
||
if nargout>1
|
||
penalty = 0;
|
||
if info
|
||
if isoctave && any(any(~isfinite(A))) % workaround for https://savannah.gnu.org/bugs/index.php?63082
|
||
penalty = 1;
|
||
else
|
||
% TODO: the penalty is only concerned with negative eigenvalues, we should also consider the case of non symmetric matrix A.
|
||
a = diag(eig(A));
|
||
k = find(a<0);
|
||
if k > 0
|
||
penalty = sum(-a(k));
|
||
end
|
||
end
|
||
end
|
||
end
|