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