Home > General-Functions > external > sparse_inverse > sparseinv > sparseinv.m

sparseinv

PURPOSE ^

SPARSEINV computes the sparse inverse subset of a real sparse square matrix A.

SYNOPSIS ^

function [Z, Zpattern, L, D, U, P, Q, stats] = sparseinv (A)

DESCRIPTION ^

SPARSEINV computes the sparse inverse subset of a real sparse square matrix A.
 This function is typically much faster than computing all of inv(A).

 [Z, Zpattern, L, D, U, P, Q, stats] = sparseinv (A)

 Z is a subset of the inverse a sparse matrix A of full rank.  On output, if
 Zpattern(i,j)=1, it means that Z(i,j) has been computed.  That is, the norm
 of (Zpattern .* (Z - inv (A))) will be small.

 Method: The permuted matrix C = P*A*Q is first factorized into C =
 (L+I)*D*(U+I) where D is diagonal, L+I is lower triangular with unit
 diagonal, and U+I is upper triangular with unit diagonal (I = speye (n)).  If
 A is symmetric and positive definite, then a Cholesky factorization is used
 (in which case P=Q' and L=U', and Z will include all diagonal entries of
 inv(A)).  Next, the entries in the inverse of C that correspond to nonzero
 values in Zpattern are found via Takahashi's method.  Zpattern is the
 symbolic Cholesky factorization of C+C', so it includes all entries in L+U
 and its transpose.

 stats is an optional struct containing statistics on the factorization.

 Example:
   load west0479
   A = west0479 ;
   [Z, Zpattern] = sparseinv (A) ;
   S = inv (A) ;
   err = norm (Zpattern .* (Z - S), 1) / norm (S, 1)

 See also inv, lu, chol.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [Z, Zpattern, L, D, U, P, Q, stats] = sparseinv (A)
0002 %SPARSEINV computes the sparse inverse subset of a real sparse square matrix A.
0003 % This function is typically much faster than computing all of inv(A).
0004 %
0005 % [Z, Zpattern, L, D, U, P, Q, stats] = sparseinv (A)
0006 %
0007 % Z is a subset of the inverse a sparse matrix A of full rank.  On output, if
0008 % Zpattern(i,j)=1, it means that Z(i,j) has been computed.  That is, the norm
0009 % of (Zpattern .* (Z - inv (A))) will be small.
0010 %
0011 % Method: The permuted matrix C = P*A*Q is first factorized into C =
0012 % (L+I)*D*(U+I) where D is diagonal, L+I is lower triangular with unit
0013 % diagonal, and U+I is upper triangular with unit diagonal (I = speye (n)).  If
0014 % A is symmetric and positive definite, then a Cholesky factorization is used
0015 % (in which case P=Q' and L=U', and Z will include all diagonal entries of
0016 % inv(A)).  Next, the entries in the inverse of C that correspond to nonzero
0017 % values in Zpattern are found via Takahashi's method.  Zpattern is the
0018 % symbolic Cholesky factorization of C+C', so it includes all entries in L+U
0019 % and its transpose.
0020 %
0021 % stats is an optional struct containing statistics on the factorization.
0022 %
0023 % Example:
0024 %   load west0479
0025 %   A = west0479 ;
0026 %   [Z, Zpattern] = sparseinv (A) ;
0027 %   S = inv (A) ;
0028 %   err = norm (Zpattern .* (Z - S), 1) / norm (S, 1)
0029 %
0030 % See also inv, lu, chol.
0031 
0032 % Copyright 2011, Timothy A. Davis, http://www.suitesparse.com
0033 
0034 get_stats = (nargout > 7) ;
0035 if (get_stats)
0036     t1 = tic ;
0037 end
0038 
0039 % check inputs
0040 if (~issparse (A))
0041     error ('A must be sparse') ;
0042 end
0043 [m n] = size (A) ;
0044 if (m ~= n)
0045     error ('A must be square') ;
0046 end
0047 if (~isreal (A))
0048     error ('complex matrices not supported') ;
0049 end
0050 
0051 % construct the factorization: C = P*A*Q = (L+I)*D*(U+I)
0052 p = 1 ;
0053 if (all (diag (A)) > 0 && nnz (A-A') == 0)
0054     [L,p,Q] = chol (A, 'lower') ;
0055 end
0056 if (p == 0)
0057     % Cholesky worked.
0058     P = Q' ;
0059     d = diag (L) ;
0060     L = tril (L / diag (d), -1) ;
0061     U = L' ;
0062     d = d.^2 ;
0063     D = diag (d) ;
0064 else
0065     % Cholesky failed, or wasn't attempted.  Use LU instead.
0066     [L,U,P,Q] = lu (A) ;
0067     d = diag (U) ;
0068     if (any (d == 0))
0069         error ('A must be full-rank') ;
0070     end
0071     D = diag (d) ;
0072     U = triu (D \ U, 1) ;
0073     L = tril (L, -1) ;
0074 end
0075 d = full (d) ;
0076 
0077 % find the symbolic Cholesky of C+C'
0078 S = spones (P*A*Q) ;
0079 [c,h,pa,po,R] = symbfact (S+S') ;
0080 clear h pa po
0081 Zpattern = spones (R+R') ;
0082 clear R S
0083 
0084 if (get_stats)
0085     t1 = toc (t1) ;
0086     t2 = tic ;
0087 end
0088 
0089 % compute the sparse inverse subset
0090 [Z takflops] = sparseinv_mex (L, d, U', Zpattern) ;
0091 if (p == 0)
0092     % Force Z to be symmetric.  This is because sparseinv_mex does not
0093     % exploit the symmetry in the factorization, but computes both upper and
0094     % lower triangular parts of Z separately.  The work for the Takahashi
0095     % equations could be cut in half as a result.
0096     Z = (Z + Z') / 2 ;
0097 end
0098 
0099 % permute the result
0100 Z = Q*Z*P ;
0101 Zpattern = Q*Zpattern*P ;
0102 
0103 % return stats, if requested
0104 if (nargout > 7)
0105     t2 = toc (t2) ;
0106     if (p == 0)
0107         stats.kind = 'Cholesky' ;
0108         fl = 2*n + sum (c.^2) ;
0109         stats.nnz_factors = sum (c) ;
0110     else
0111         stats.kind = 'LU' ;
0112         Lnz = full (sum (spones (L))) ;            % off diagonal nz in cols of L
0113         Unz = full (sum (spones (U')))' ;    % off diagonal nz in rows of U
0114         fl = n + 2*Lnz*Unz + sum (Lnz) ;
0115         stats.nnz_factors = nnz (L) + nnz (U) + n ;
0116     end
0117     stats.flops_factorization = fl ;
0118     stats.flops_Takahashi = takflops ;
0119     stats.time_factorization = t1 ;
0120     stats.time_Takahashi = t2 ;
0121 end
0122

Generated on Sat 21-Jul-2018 20:56:10 by m2html © 2005