Go to the documentation of this file.00001
00002
00003
00004
00005 #define WANT_MATH
00006
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
00023
00024
00025
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