C:/programs/SCPPNT/src/include/cholesky.h

Go to the documentation of this file.
00001 /*! \file cholesky.h
00002  \brief Definition of function Cholesky_upper_factorization
00003 
00004  Contains modified version of the functions in cholesky.h from the
00005  Template Numerical Toolkit (TNT) using matrix iterators rather than
00006  matrix subscripting.
00007 
00008  */
00009 
00010 /*  
00011 
00012  Simple C++ Numerical Toolkit (SCPPNT)
00013  http://www.smallwaters.com/software/cpp/scppnt.html
00014  This release updates original work contributed by 
00015  Brad Hanson (http://www.b-a-h.com/) in 2001.
00016 
00017  */
00018 
00019 // Modified version of cholesky.h from:
00020 /*
00021  *
00022  * Template Numerical Toolkit (TNT): Linear Algebra Module
00023  *
00024  * Mathematical and Computational Sciences Division
00025  * National Institute of Technology,
00026  * Gaithersburg, MD USA
00027  *
00028  *
00029  * This software was developed at the National Institute of Standards and
00030  * Technology (NIST) by employees of the Federal Government in the course
00031  * of their official duties. Pursuant to title 17 Section 105 of the
00032  * United States Code, this software is not subject to copyright protection
00033  * and is in the public domain.  The Template Numerical Toolkit (TNT) is
00034  * an experimental system.  NIST assumes no responsibility whatsoever for
00035  * its use by other parties, and makes no guarantees, expressed or implied,
00036  * about its quality, reliability, or any other characteristic.
00037  *
00038  * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00039  * see http://math.nist.gov/tnt for latest updates.
00040  *
00041  */
00042 
00043 #ifndef SCPPNT_CHOLESKY_H
00044 #define SCPPNT_CHOLESKY_H
00045 
00046 #include <cmath> // for sqrt
00047 #ifdef BOOST_NO_STDC_NAMESPACE
00048 namespace std
00049 { using ::sqrt;}
00050 #endif
00051 
00052 #ifdef SCPPNT_NO_DIR_PREFIX
00053 #include "scppnt.h"
00054 #include "scppnt_error.h"
00055 #else
00056 #include "scppnt/scppnt.h"
00057 #include "scppnt/scppnt_error.h"
00058 #endif
00059 
00060 // index method
00061 
00062 namespace SCPPNT
00063 {
00064 
00065   /*! \brief Compute Cholesky factorization
00066    
00067    Modified version of Cholesky_upper_factorization from the Template
00068    Numerical Toolkit (TNT) using matrix iterators rather than matrix
00069    subscripting.
00070    
00071    Only upper part of A is used.  Cholesky factor is returned in lower
00072    part of L.  Returns 0 if successful, 1 otherwise.
00073    
00074    */
00075   template<class SPDMatrix, class SymmMatrix> int Cholesky_upper_factorization(SPDMatrix &A,
00076       SymmMatrix &L)
00077   {
00078     Subscript M = A.dim(1);
00079     Subscript N = A.dim(2);
00080 
00081     // assert(M == N);                 // make sure A is square
00082     if (M != N)
00083       throw BoundsError("Cholesky_upper_factorization");
00084 
00085     // readjust size of L, if necessary
00086 
00087     if (M != L.dim(1) || N != L.dim(2))
00088       L = SymmMatrix(N, N);
00089 
00090     Subscript i, j, k;
00091 
00092     typename SPDMatrix::element_type dot;
00093 
00094     typename SymmMatrix::diag_iterator diagL = L.begin_diagonal(1, 1);
00095     typename SPDMatrix::diag_iterator diagA = A.begin_diagonal(1, 1);
00096 
00097     for (j=1; j<=N; j++, ++diagL, ++diagA) // form column j of L
00098     {
00099       dot= 0;
00100 
00101       typename SymmMatrix::row_iterator irL = L.begin_row(j);
00102 
00103       for (i=1; i<j; i++) // for k= 1 TO j-1
00104       {
00105         dot += *irL * *irL; //dot = dot +  L(j,i)*L(j,i);
00106         ++irL;
00107       }
00108 
00109       *diagL = *diagA - dot; // L(j,j) = A(j,j) - dot;
00110 
00111       typename SymmMatrix::column_iterator icL = L.begin_column(j) + j;
00112       typename SPDMatrix::row_iterator irA = A.begin_row(j) + j;
00113 
00114       irL = L.begin_row(j);
00115 
00116       for (i=j+1; i<=N; i++, ++icL, ++irA)
00117       {
00118         dot = 0;
00119         typename SymmMatrix::row_iterator iL = L.begin_row(i);
00120         typename SymmMatrix::row_iterator jL =irL;
00121         for (k=1; k<j; k++, ++iL, ++jL)
00122           dot += *iL * *jL; // dot = dot +  L(i,k)*L(j,k);
00123         *icL = *irA - dot; // L(i,j) = A(j,i) - dot;
00124       }
00125 
00126       if (*diagL <= 0.0)
00127         return 1; // if (L(j,j) <= 0.0) return 1;
00128 
00129       *diagL = std::sqrt(*diagL); // L(j,j) = sqrt( L(j,j) );
00130 
00131       icL = L.begin_column(j) + j;
00132 
00133       for (i=j+1; i<=N; i++, ++icL)
00134         *icL /= *diagL; // L(i,j) = L(i,j) / L(j,j);
00135 
00136     }
00137     return 0;
00138   }
00139   
00140 } // namespace SCPPNT
00141 
00142 #endif
00143 // SCPPNT_CHOLESKY_H

Generated on Tue Dec 18 23:34:05 2007 for SCPPNT by  doxygen 1.5.4