1######################################################################## 2## 3## Copyright (C) 2003-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {} isdefinite (@var{A}) 28## @deftypefnx {} {} isdefinite (@var{A}, @var{tol}) 29## Return true if @var{A} is symmetric positive definite matrix within the 30## tolerance specified by @var{tol}. 31## 32## If @var{tol} is omitted, use a tolerance of 33## @code{100 * eps * norm (@var{A}, "fro")}. 34## 35## Background: A positive definite matrix has eigenvalues which are all 36## greater than zero. A positive semi-definite matrix has eigenvalues which 37## are all greater than or equal to zero. The matrix @var{A} is very likely to 38## be positive semi-definite if the following two conditions hold for a 39## suitably small tolerance @var{tol}. 40## 41## @example 42## @group 43## isdefinite (@var{A}) @result{} 0 44## isdefinite (@var{A} + 5*@var{tol}, @var{tol}) @result{} 1 45## @end group 46## @end example 47## @seealso{issymmetric, ishermitian} 48## @end deftypefn 49 50function retval = isdefinite (A, tol) 51 52 if (nargin < 1 || nargin > 2) 53 print_usage (); 54 endif 55 56 ## Validate inputs 57 retval = false; 58 if (! isnumeric (A)) 59 return; 60 endif 61 62 if (! isfloat (A)) 63 A = double (A); 64 endif 65 66 if (nargin == 1) 67 tol = 100 * eps (class (A)) * norm (A, "fro"); 68 elseif (! (isnumeric (tol) && isscalar (tol) && tol >= 0)) 69 error ("isdefinite: TOL must be a scalar >= 0"); 70 endif 71 72 if (! ishermitian (A, tol)) 73 return; 74 endif 75 76 e = tol * eye (rows (A)); 77 [~, p] = chol (A - e); 78 if (p == 0) 79 retval = true; 80 endif 81 82endfunction 83 84 85%!test 86%! A = [-1, 0; 0, -1]; 87%! assert (isdefinite (A), false); 88 89%!test 90%! A = [1, 0; 0, 1]; 91%! assert (isdefinite (A), true); 92 93%!test 94%! A = [2, -1, 0; -1, 2, -1; 0, -1, 2]; 95%! assert (isdefinite (A), true); 96 97## Test for positive semi-definite matrix 98%!test 99%! A = [1, 0; 0, 0]; 100%! assert (isdefinite (A), false); 101%! tol = 100*eps; 102%! assert (isdefinite (A+5*tol, tol), true); 103 104%!assert (! isdefinite (magic (3))) 105 106%!error isdefinite () 107%!error isdefinite (1,2,3) 108%!error <TOL must be a scalar .= 0> isdefinite (1, {1}) 109%!error <TOL must be a scalar .= 0> isdefinite (1, [1 1]) 110%!error <TOL must be a scalar .= 0> isdefinite (1, -1) 111