MOOS 0.2375
|
00001 //$$ cholesky.cpp cholesky decomposition 00002 00003 // Copyright (C) 1991,2,3,4: R B Davies 00004 00005 #define WANT_MATH 00006 //#define WANT_STREAM 00007 00008 #include "include.h" 00009 00010 #include "newmat.h" 00011 00012 #ifdef use_namespace 00013 namespace NEWMAT { 00014 #endif 00015 00016 #ifdef DO_REPORT 00017 #define REPORT { static ExeCounter ExeCount(__LINE__,14); ++ExeCount; } 00018 #else 00019 #define REPORT {} 00020 #endif 00021 00022 /********* Cholesky decomposition of a positive definite matrix *************/ 00023 00024 // Suppose S is symmetrix and positive definite. Then there exists a unique 00025 // lower triangular matrix L such that L L.t() = S; 00026 00027 inline Real square(Real x) { return x*x; } 00028 00029 ReturnMatrix Cholesky(const SymmetricMatrix& S) 00030 { 00031 REPORT 00032 Tracer trace("Cholesky"); 00033 int nr = S.Nrows(); 00034 LowerTriangularMatrix T(nr); 00035 Real* s = S.Store(); Real* t = T.Store(); Real* ti = t; 00036 for (int i=0; i<nr; i++) 00037 { 00038 Real* tj = t; Real sum; int k; 00039 for (int j=0; j<i; j++) 00040 { 00041 Real* tk = ti; sum = 0.0; k = j; 00042 while (k--) { sum += *tj++ * *tk++; } 00043 *tk = (*s++ - sum) / *tj++; 00044 } 00045 sum = 0.0; k = i; 00046 while (k--) { sum += square(*ti++); } 00047 Real d = *s++ - sum; 00048 if (d<=0.0) Throw(NPDException(S)); 00049 *ti++ = sqrt(d); 00050 } 00051 T.Release(); return T.ForReturn(); 00052 } 00053 00054 ReturnMatrix Cholesky(const SymmetricBandMatrix& S) 00055 { 00056 REPORT 00057 Tracer trace("Band-Cholesky"); 00058 int nr = S.Nrows(); int m = S.lower; 00059 LowerBandMatrix T(nr,m); 00060 Real* s = S.Store(); Real* t = T.Store(); Real* ti = t; 00061 00062 for (int i=0; i<nr; i++) 00063 { 00064 Real* tj = t; Real sum; int l; 00065 if (i<m) { REPORT l = m-i; s += l; ti += l; l = i; } 00066 else { REPORT t += (m+1); l = m; } 00067 00068 for (int j=0; j<l; j++) 00069 { 00070 Real* tk = ti; sum = 0.0; int k = j; tj += (m-j); 00071 while (k--) { sum += *tj++ * *tk++; } 00072 *tk = (*s++ - sum) / *tj++; 00073 } 00074 sum = 0.0; 00075 while (l--) { sum += square(*ti++); } 00076 Real d = *s++ - sum; 00077 if (d<=0.0) Throw(NPDException(S)); 00078 *ti++ = sqrt(d); 00079 } 00080 00081 T.Release(); return T.ForReturn(); 00082 } 00083 00084 00085 #ifdef use_namespace 00086 } 00087 #endif 00088