1function result = spsym (A, quick) %#ok 2%SPSYM determine if a sparse matrix is symmetric, Hermitian, or skew-symmetric. 3% If so, also determine if its diagonal has all positive real entries. 4% A must be sparse. 5% 6% Example: 7% result = spsym (A) ; 8% result = spsym (A,quick) ; 9% 10% If quick = 0, or is not present, then this routine returns: 11% 12% 1: if A is rectangular 13% 2: if A is unsymmetric 14% 3: if A is symmetric, but with one or more A(j,j) <= 0 15% 4: if A is Hermitian, but with one or more A(j,j) <= 0 or with 16% nonzero imaginary part 17% 5: if A is skew symmetric (and thus the diagonal is all zero as well) 18% 6: if A is symmetric with real positive diagonal 19% 7: if A is Hermitian with real positive diagonal 20% 21% If quick is nonzero, then the function can return more quickly, as soon as 22% it finds a diagonal entry that is <= 0 or with a nonzero imaginary part. 23% In this case, it returns 2 for a square matrix, even if the matrix might 24% otherwise be symmetric or Hermitian. 25% 26% Regardless of the value of "quick", this function returns 6 or 7 if A is 27% a candidate for sparse Cholesky. 28% 29% For an MATLAB M-file function that computes the same thing as this 30% mexFunction (but much slower), see the get_symmetry function by typing 31% "type spsym". 32% 33% This spsym function does not compute the transpose of A, nor does it need 34% to examine the entire matrix if it is unsymmetric. It uses very little 35% memory as well (just size-n workspace, where n = size (A,1)). 36% 37% Examples: 38% load west0479 39% A = west0479 ; 40% spsym (A) 41% spsym (A+A') 42% spsym (A-A') 43% spsym (A+A'+3*speye(size(A,1))) 44% 45% See also mldivide. 46 47% function result = get_symmetry (A,quick) 48% %GET_SYMMETRY: does the same thing as the spsym mexFunction. 49% % It's just a lot slower and uses much more memory. This function 50% % is meant for testing and documentation only. 51% [m n] = size (A) ; 52% if (m ~= n) 53% result = 1 ; % rectangular 54% return 55% end 56% if (nargin < 2) 57% quick = 0 ; 58% end 59% d = diag (A) ; 60% posdiag = all (real (d) > 0) & all (imag (d) == 0) ; 61% if (quick & ~posdiag) 62% result = 2 ; % Not a candidate for sparse Cholesky. 63% elseif (~isreal (A) & nnz (A-A') == 0) 64% if (posdiag) 65% result = 7 ; % complex Hermitian, with positive diagonal 66% else 67% result = 4 ; % complex Hermitian, nonpositive diagonal 68% end 69% elseif (nnz (A-A.') == 0) 70% if (posdiag) 71% result = 6 ; % symmetric with positive diagonal 72% else 73% result = 3 ; % symmetric, nonpositive diagonal 74% end 75% elseif (nnz (A+A.') == 0) 76% result = 5 ; % skew symmetric 77% else 78% result = 2 ; % unsymmetric 79% end 80 81% With additional outputs, spsym computes the following for square matrices: 82% (in this case "quick" is ignored, and set to zero): 83% 84% [result xmatched pmatched nzoffdiag nnzdiag] = spsym(A) 85% 86% xmatched is the number of nonzero entries for which A(i,j) = conj(A(j,i)). 87% pmatched is the number of entries (i,j) for which A(i,j) and A(j,i) are 88% both in the pattern of A (the value doesn't matter). nzoffdiag is the 89% total number of off-diagonal entries in the pattern. nzdiag is the number 90% of diagonal entries in the pattern. If the matrix is rectangular, 91% xmatched, pmatched, nzoffdiag, and nzdiag are not computed (all of them are 92% returned as zero). Note that a matched pair, A(i,j) and A(j,i) for i != j, 93% is counted twice (once per entry). 94 95% Copyright 2006-2007, Timothy A. Davis, http://www.suitesparse.com 96 97error ('spsym mexFunction not found') ; 98