lu.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:4k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // Template Numerical Toolkit (TNT) for Linear Algebra
  2. //
  3. // BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
  4. // Please see http://math.nist.gov/tnt for updates
  5. //
  6. // R. Pozo
  7. // Mathematical and Computational Sciences Division
  8. // National Institute of Standards and Technology
  9. #ifndef LU_H
  10. #define LU_H
  11. // Solve system of linear equations Ax = b.
  12. //
  13. //  Typical usage:
  14. //
  15. //    Matrix(double) A;
  16. //    Vector(Subscript) ipiv;
  17. //    Vector(double) b;
  18. //
  19. //    1)  LU_Factor(A,ipiv);
  20. //    2)  LU_Solve(A,ipiv,b);
  21. //
  22. //   Now b has the solution x.  Note that both A and b
  23. //   are overwritten.  If these values need to be preserved, 
  24. //   one can make temporary copies, as in 
  25. //
  26. //    O)  Matrix(double) T = A;
  27. //    1)  LU_Factor(T,ipiv);
  28. //    1a) Vector(double) x=b;
  29. //    2)  LU_Solve(T,ipiv,x);
  30. //
  31. //   See details below.
  32. //
  33. // for abs() 
  34. //
  35. #include "tntmath.h"
  36. // right-looking LU factorization algorithm (unblocked)
  37. //
  38. //   Factors matrix A into lower and upper  triangular matrices 
  39. //   (L and U respectively) in solving the linear equation Ax=b.  
  40. //
  41. //
  42. // Args:
  43. //
  44. // A        (input/output) Matrix(1:n, 1:n)  In input, matrix to be
  45. //                  factored.  On output, overwritten with lower and 
  46. //                  upper triangular factors.
  47. //
  48. // indx     (output) Vector(1:n)    Pivot vector. Describes how
  49. //                  the rows of A were reordered to increase
  50. //                  numerical stability.
  51. //
  52. // Return value:
  53. //
  54. // int      (0 if successful, 1 otherwise)
  55. //
  56. //
  57. template <class Matrix, class VectorSubscript>
  58. int LU_factor( Matrix &A, VectorSubscript &indx)
  59. {
  60.     assert(A.lbound() == 1);                // currently for 1-offset
  61.     assert(indx.lbound() == 1);             // vectors and matrices
  62.     Subscript M = A.num_rows();
  63.     Subscript N = A.num_cols();
  64.     if (M == 0 || N==0) return 0;
  65.     if (indx.dim() != M)
  66.         indx.newsize(M);
  67.     Subscript i=0,j=0,k=0;
  68.     Subscript jp=0;
  69.     typename Matrix::element_type t;
  70.     Subscript minMN =  (M < N ? M : N) ;        // min(M,N);
  71.     for (j=1; j<= minMN; j++)
  72.     {
  73.         // find pivot in column j and  test for singularity.
  74.         jp = j;
  75.         t = abs(A(j,j));
  76.         for (i=j+1; i<=M; i++)
  77.             if ( abs(A(i,j)) > t)
  78.             {
  79.                 jp = i;
  80.                 t = abs(A(i,j));
  81.             }
  82.         indx(j) = jp;
  83.         // jp now has the index of maximum element 
  84.         // of column j, below the diagonal
  85.         if ( A(jp,j) == 0 )                 
  86.             return 1;       // factorization failed because of zero pivot
  87.         if (jp != j)            // swap rows j and jp
  88.             for (k=1; k<=N; k++)
  89.             {
  90.                 t = A(j,k);
  91.                 A(j,k) = A(jp,k);
  92.                 A(jp,k) =t;
  93.             }
  94.         if (j<M)                // compute elements j+1:M of jth column
  95.         {
  96.             // note A(j,j), was A(jp,p) previously which was
  97.             // guarranteed not to be zero (Label #1)
  98.             //
  99.             typename Matrix::element_type recp =  1.0 / A(j,j);
  100.             for (k=j+1; k<=M; k++)
  101.                 A(k,j) *= recp;
  102.         }
  103.         if (j < minMN)
  104.         {
  105.             // rank-1 update to trailing submatrix:   E = E - x*y;
  106.             //
  107.             // E is the region A(j+1:M, j+1:N)
  108.             // x is the column vector A(j+1:M,j)
  109.             // y is row vector A(j,j+1:N)
  110.             Subscript ii,jj;
  111.             for (ii=j+1; ii<=M; ii++)
  112.                 for (jj=j+1; jj<=N; jj++)
  113.                     A(ii,jj) -= A(ii,j)*A(j,jj);
  114.         }
  115.     }
  116.     return 0;
  117. }   
  118. template <class Matrix, class Vector, class VectorSubscripts>
  119. int LU_solve(const Matrix &A, const VectorSubscripts &indx, Vector &b)
  120. {
  121.     assert(A.lbound() == 1);                // currently for 1-offset
  122.     assert(indx.lbound() == 1);             // vectors and matrices
  123.     assert(b.lbound() == 1);
  124.     Subscript i,ii=0,ip,j;
  125.     Subscript n = b.dim();
  126.     typename Matrix::element_type sum = 0.0;
  127.     for (i=1;i<=n;i++) 
  128.     {
  129.         ip=indx(i);
  130.         sum=b(ip);
  131.         b(ip)=b(i);
  132.         if (ii)
  133.             for (j=ii;j<=i-1;j++) 
  134.                 sum -= A(i,j)*b(j);
  135.         else if (sum) ii=i;
  136.             b(i)=sum;
  137.     }
  138.     for (i=n;i>=1;i--) 
  139.     {
  140.         sum=b(i);
  141.         for (j=i+1;j<=n;j++) 
  142.             sum -= A(i,j)*b(j);
  143.         b(i)=sum/A(i,i);
  144.     }
  145.     return 0;
  146. }
  147. #endif
  148. // LU_H