cholesky.cc
Go to the documentation of this file.
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 


rl_agent
Author(s): Todd Hester
autogenerated on Thu Jun 6 2019 22:00:13