File: superlu.m

package info (click to toggle)
superlu 5.3.0%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 11,976 kB
  • sloc: ansic: 59,420; makefile: 405; fortran: 185; csh: 141
file content (155 lines) | stat: -rw-r--r-- 5,499 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
function [L,U,prow,pcol] = superlu(A,psparse)
% SUPERLU : Supernodal LU factorization
% 
%  Executive summary:
%
%  [L,U,p] = superlu(A)          is like [L,U,P] = lu(A), but faster.
%  [L,U,prow,pcol] = superlu(A)  preorders the columns of A by min degree,
%                                    yielding A(prow,pcol) = L*U.
%
%  Details and options:
%
%  With one input and two or three outputs, SUPERLU has the same effect as LU,
%  except that the pivoting permutation is returned as a vector, not a matrix:
%
%  [L,U,p] = superlu(A) returns unit lower triangular L, upper triangular U,
%            and permutation vector p with A(p,:) = L*U.
%  [L,U] = superlu(A) returns permuted triangular L and upper triangular U
%            with A = L*U.
%
%  With a second input, the columns of A are permuted before factoring:
%
%  [L,U,prow] = superlu(A,psparse) returns triangular L and U and permutation 
%            prow with A(prow,psparse) = L*U.
%  [L,U] = superlu(A,psparse) returns permuted triangular L and triangular U 
%            with A(:,psparse) = L*U.
%  Here psparse will normally be a user-supplied permutation matrix or vector
%  to be applied to the columns of A for sparsity.  COLAMD is one way to get
%  such a permutation; see below to make SUPERLU compute it automatically.
%  (If psparse is a permutation matrix, the matrix factored is A*psparse'.)
%
%  With a fourth output, a column permutation is computed and applied:
%
%  [L,U,prow,pcol] = superlu(A,psparse)  returns triangular L and U and
%            permutations prow and pcol with A(prow,pcol) = L*U.
%            Here psparse is a user-supplied column permutation for sparsity,
%            and the matrix factored is A(:,psparse) (or A*psparse' if the
%            input is a permutation matrix).  Output pcol is a permutation
%            that first performs psparse, then postorders the etree of the 
%            column intersection graph of A.  The postorder does not affect 
%            sparsity, but makes supernodes in L consecutive.
%  [L,U,prow,pcol] = superlu(A,0) is the same as ... = superlu(A,I); it does
%            not permute for sparsity but it does postorder the etree.
%  [L,U,prow,pcol] = superlu(A) is the same as ... = superlu(A,colamd(A));
%            it uses column minimum degree to permute columns for sparsity,
%            then postorders the etree and factors.
%
%  This m-file calls the mex-file MEXSUPERLU to do the work.
%
% See also COLAMD, LUSOLVE.
%
% John Gilbert, 6 April 1995.
% Copyright (c) 1995 by Xerox Corporation.  All rights reserved.
% HELP COPYRIGHT for complete copyright and licensing notice.

% Note on permutation matrices and vectors:
%
% Names beginning with p are permutation vectors; 
% names beginning with P are the corresponding permutation matrices.
%
% Thus  A(pfoo,pbar) is the same as Pfoo*A*Pbar'.
%
% We don't actually form any permutation matrices except Psparse,
% but matrix notation is easier to untangle in the comments.


[m,n] = size(A);
if m ~= n 
    error('matrix must be square.'); 
end;
if n == 0
    L = []; U = []; prow = []; pcol = [];
    return;
end;

% If necessary, compute the column sparsity permutation.
if nargin < 2 
    if nargout >= 4
        psparse = colamd(A);
    else
        psparse = 1:n;
    end;
end;
if max(size(psparse)) <= 1
    psparse = 1:n;
end;

% Compute the permutation-matrix version of psparse,
% which fits the internal data structures of mexsuperlu.
if min(size(psparse)) == 1
    Psparse = sparse(1:n,psparse,1,n,n);
else
    Psparse = psparse;
    psparse = Psparse*[1:n]';
end;

% Make sure the matrices are sparse.
if ~issparse(A)
    A = sparse(A);
end;
if ~issparse(Psparse)
    Psparse = sparse(Psparse);
end;


% The output permutations from the mex-file are dense permutation vectors.
[L,U,prowInv,pcolInv] = mexsuperlu(A,Psparse);
prow = zeros(1,n);
prow(prowInv) = 1:n;
pcol = zeros(1,n);
pcol(pcolInv) = 1:n;

% -- Added 12/14/2011 --
% The row indices of L & U matrices are not sorted from SuperLU, but 
% Matlab requires the matrices to be sorted.
% Now, we do double-transpose to achieve sorting. This acts like bucket sort,
% should be faster than find / sparse combination, which probably uses
% quicksort.
% [i,j,s] = find(L); L = sparse(i,j,s,m,n);

L1 = L'; L = L1';
U1 = U'; U = U1';
% ----

% We now have
%
%    Prow*A*Psparse'*Post' = L*U   (1)
%    Pcol' = Psparse'*Post'         
%
% (though we actually have the vectors, not the matrices, and
% we haven't computed Post explicitly from Pcol and Psparse).
% Now we figure out what the user really wanted returned,
% and rewrite (1) accordingly.

if nargout == 4  
    % Return both row and column permutations.  
    % This is what we've already got.
    % (1) becomes  Prow*A*Pcol' = L*U. 
elseif nargout == 3
    % Return row permutation only.  Fold the postorder perm 
    % but not the sparsity perm into it, and into L and U.
    % This preserves triangularity of L and U.
    % (1) becomes (Post'*Prow) * A * Psparse' = (Post'*L*Post) * (Post'*U*Post).
    postInv = pcolInv(psparse);
    prow = prow(postInv);
    L = L(postInv,postInv);
    U = U(postInv,postInv);
else % nargout <= 2
    % Return no permutations.  Fold the postorder perm but
    % not the sparsity perm into L and U.  Fold the pivoting
    % perm into L, which destroys its triangularity.
    % (1) becomes A * Psparse' = (Prow'*L*Post) * (Post'*U*Post).
    postInv = pcolInv(psparse);
    L = L(prowInv,postInv);
    U = U(postInv,postInv);
end;