Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lu.h
1 /*
2 This file is distributed as part of the BIAS library (Basic ImageAlgorithmS)
3 but it has not been developed by the authors of BIAS.
4 
5 For copyright, author and license information see below.
6 */
7 
8 
9 /*
10 *
11 * Template Numerical Toolkit (TNT): Linear Algebra Module
12 *
13 * Mathematical and Computational Sciences Division
14 * National Institute of Technology,
15 * Gaithersburg, MD USA
16 *
17 *
18 * This software was developed at the National Institute of Standards and
19 * Technology (NIST) by employees of the Federal Government in the course
20 * of their official duties. Pursuant to title 17 Section 105 of the
21 * United States Code, this software is not subject to copyright protection
22 * and is in the public domain. The Template Numerical Toolkit (TNT) is
23 * an experimental system. NIST assumes no responsibility whatsoever for
24 * its use by other parties, and makes no guarantees, expressed or implied,
25 * about its quality, reliability, or any other characteristic.
26 *
27 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
28 * see http://math.nist.gov/tnt for latest updates.
29 *
30 */
31 
32 
33 
34 #ifndef LU_H
35 #define LU_H
36 
37 // Solve system of linear equations Ax = b.
38 //
39 // Typical usage:
40 //
41 // Matrix(double) A;
42 // Vector(Subscript) ipiv;
43 // Vector(double) b;
44 //
45 // 1) LU_Factor(A,ipiv);
46 // 2) LU_Solve(A,ipiv,b);
47 //
48 // Now b has the solution x. Note that both A and b
49 // are overwritten. If these values need to be preserved,
50 // one can make temporary copies, as in
51 //
52 // O) Matrix(double) T = A;
53 // 1) LU_Factor(T,ipiv);
54 // 1a) Vector(double) x=b;
55 // 2) LU_Solve(T,ipiv,x);
56 //
57 // See details below.
58 //
59 
60 
61 // for fabs()
62 //
63 #include <cmath>
64 
65 // right-looking LU factorization algorithm (unblocked)
66 //
67 // Factors matrix A into lower and upper triangular matrices
68 // (L and U respectively) in solving the linear equation Ax=b.
69 //
70 //
71 // Args:
72 //
73 // A (input/output) Matrix(1:n, 1:n) In input, matrix to be
74 // factored. On output, overwritten with lower and
75 // upper triangular factors.
76 //
77 // indx (output) Vector(1:n) Pivot vector. Describes how
78 // the rows of A were reordered to increase
79 // numerical stability.
80 //
81 // Return value:
82 //
83 // int (0 if successful, 1 otherwise)
84 //
85 //
86 
87 
88 namespace TNT
89 {
90 
91  template <class MaTRiX, class VecToRSubscript>
92  int LU_factor( MaTRiX &A, VecToRSubscript &indx)
93  {
94  BIASASSERT(A.lbound() == 1); // currently for 1-offset
95  BIASASSERT(indx.lbound() == 1); // vectors and matrices
96 
97  Subscript M = A.num_rows();
98  Subscript N = A.num_cols();
99 
100  if (M == 0 || N==0) return 0;
101  if (indx.dim() != M)
102  indx.newsize(M);
103 
104  Subscript i=0,j=0,k=0;
105  Subscript jp=0;
106 
107  typename MaTRiX::element_type t;
108 
109  Subscript minMN = (M < N ? M : N) ; // min(M,N);
110 
111  for (j=1; j<= minMN; j++)
112  {
113 
114  // find pivot in column j and test for singularity.
115 
116  jp = j;
117  t = fabs(A(j,j));
118  for (i=j+1; i<=M; i++)
119  if ( fabs(A(i,j)) > t)
120  {
121  jp = i;
122  t = fabs(A(i,j));
123  }
124 
125  indx(j) = jp;
126 
127  // jp now has the index of maximum element
128  // of column j, below the diagonal
129 
130  if ( A(jp,j) == 0 )
131  return 1; // factorization failed because of zero pivot
132 
133 
134  if (jp != j) // swap rows j and jp
135  for (k=1; k<=N; k++)
136  {
137  t = A(j,k);
138  A(j,k) = A(jp,k);
139  A(jp,k) =t;
140  }
141 
142  if (j<M) // compute elements j+1:M of jth column
143  {
144  // note A(j,j), was A(jp,p) previously which was
145  // guarranteed not to be zero (Label #1)
146  //
147  typename MaTRiX::element_type recp = 1.0 / A(j,j);
148 
149  for (k=j+1; k<=M; k++)
150  A(k,j) *= recp;
151  }
152 
153 
154  if (j < minMN)
155  {
156  // rank-1 update to trailing submatrix: E = E - x*y;
157  //
158  // E is the region A(j+1:M, j+1:N)
159  // x is the column vector A(j+1:M,j)
160  // y is row vector A(j,j+1:N)
161 
162  Subscript ii,jj;
163 
164  for (ii=j+1; ii<=M; ii++)
165  for (jj=j+1; jj<=N; jj++)
166  A(ii,jj) -= A(ii,j)*A(j,jj);
167  }
168  }
169 
170  return 0;
171  }
172 
173 
174 
175 
176  template <class MaTRiX, class VecToR, class VecToRSubscripts>
177  int LU_solve(const MaTRiX &A, const VecToRSubscripts &indx, VecToR &b)
178  {
179  BIASASSERT(A.lbound() == 1); // currently for 1-offset
180  BIASASSERT(indx.lbound() == 1); // vectors and matrices
181  BIASASSERT(b.lbound() == 1);
182 
183  Subscript i,ii=0,ip,j;
184  Subscript n = b.dim();
185  typename MaTRiX::element_type sum = 0.0;
186 
187  for (i=1;i<=n;i++)
188  {
189  ip=indx(i);
190  sum=b(ip);
191  b(ip)=b(i);
192  if (ii)
193  for (j=ii;j<=i-1;j++)
194  sum -= A(i,j)*b(j);
195  else if (sum) ii=i;
196  b(i)=sum;
197  }
198  for (i=n;i>=1;i--)
199  {
200  sum=b(i);
201  for (j=i+1;j<=n;j++)
202  sum -= A(i,j)*b(j);
203  b(i)=sum/A(i,i);
204  }
205 
206  return 0;
207  }
208 
209 } // namespace TNT
210 
211 #endif
212 // LU_H
TNT_SUBSCRIPT_TYPE Subscript
Definition: subscript.h:55
int LU_factor(MaTRiX &A, VecToRSubscript &indx)
Definition: lu.h:92
int LU_solve(const MaTRiX &A, const VecToRSubscripts &indx, VecToR &b)
Definition: lu.h:177