00001
00002
00003
00004
00005 #ifndef WANT_MATH
00006 #define WANT_MATH
00007 #endif
00008
00009
00010 #include "include.h"
00011
00012 #include "newmat.h"
00013 #include "newmatrm.h"
00014
00015 #ifdef use_namespace
00016 namespace NEWMAT {
00017 #endif
00018
00019 #ifdef DO_REPORT
00020 #define REPORT { static ExeCounter ExeCount(__LINE__,14); ++ExeCount; }
00021 #else
00022 #define REPORT {}
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00031 ReturnMatrix Cholesky(const SymmetricMatrix& S)
00032 {
00033 REPORT
00034 Tracer trace("Cholesky");
00035 int nr = S.Nrows();
00036 LowerTriangularMatrix T(nr);
00037 Real* s = S.Store(); Real* t = T.Store(); Real* ti = t;
00038 for (int i=0; i<nr; i++)
00039 {
00040 Real* tj = t; Real sum; int k;
00041 for (int j=0; j<i; j++)
00042 {
00043 Real* tk = ti; sum = 0.0; k = j;
00044 while (k--) { sum += *tj++ * *tk++; }
00045 *tk = (*s++ - sum) / *tj++;
00046 }
00047 sum = 0.0; k = i;
00048 while (k--) { sum += square(*ti++); }
00049 Real d = *s++ - sum;
00050 if (d<=0.0) Throw(NPDException(S));
00051 *ti++ = sqrt(d);
00052 }
00053 T.Release(); return T.ForReturn();
00054 }
00055
00056 ReturnMatrix Cholesky(const SymmetricBandMatrix& S)
00057 {
00058 REPORT
00059 Tracer trace("Band-Cholesky");
00060 int nr = S.Nrows(); int m = S.lower;
00061 LowerBandMatrix T(nr,m);
00062 Real* s = S.Store(); Real* t = T.Store(); Real* ti = t;
00063
00064 for (int i=0; i<nr; i++)
00065 {
00066 Real* tj = t; Real sum; int l;
00067 if (i<m) { REPORT l = m-i; s += l; ti += l; l = i; }
00068 else { REPORT t += (m+1); l = m; }
00069
00070 for (int j=0; j<l; j++)
00071 {
00072 Real* tk = ti; sum = 0.0; int k = j; tj += (m-j);
00073 while (k--) { sum += *tj++ * *tk++; }
00074 *tk = (*s++ - sum) / *tj++;
00075 }
00076 sum = 0.0;
00077 while (l--) { sum += square(*ti++); }
00078 Real d = *s++ - sum;
00079 if (d<=0.0) Throw(NPDException(S));
00080 *ti++ = sqrt(d);
00081 }
00082
00083 T.Release(); return T.ForReturn();
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 void UpdateCholesky(UpperTriangularMatrix &chol, RowVector r1Modification)
00098 {
00099 int nc = chol.Nrows();
00100 ColumnVector cGivens(nc); cGivens = 0.0;
00101 ColumnVector sGivens(nc); sGivens = 0.0;
00102
00103 for(int j = 1; j <= nc; ++j)
00104 {
00105
00106 for(int k = 1; k < j; ++k)
00107 GivensRotation(cGivens(k), sGivens(k), chol(k,j), r1Modification(j));
00108
00109
00110 pythag(chol(j,j), r1Modification(j), cGivens(j), sGivens(j));
00111
00112
00113 {
00114 Real tmp0 = cGivens(j) * chol(j,j) + sGivens(j) * r1Modification(j);
00115 chol(j,j) = tmp0; r1Modification(j) = 0.0;
00116 }
00117
00118 }
00119
00120 }
00121
00122
00123
00124 void DowndateCholesky(UpperTriangularMatrix &chol, RowVector x)
00125 {
00126 int nRC = chol.Nrows();
00127
00128
00129 LowerTriangularMatrix L = chol.t();
00130 ColumnVector a(nRC); a = 0.0;
00131 int i, j;
00132
00133 for (i = 1; i <= nRC; ++i)
00134 {
00135
00136 Real subtrsum = 0.0;
00137 for(int k = 1; k < i; ++k) subtrsum += a(k) * L(i,k);
00138
00139 a(i) = (x(i) - subtrsum) / L(i,i);
00140 }
00141
00142
00143 Real squareNormA = a.SumSquare();
00144 if (squareNormA >= 1.0)
00145 Throw(ProgramException("DowndateCholesky() fails", chol));
00146
00147 Real alpha = sqrt(1.0 - squareNormA);
00148
00149
00150 ColumnVector cGivens(nRC); cGivens = 0.0;
00151 ColumnVector sGivens(nRC); sGivens = 0.0;
00152 for(i = nRC; i >= 1; i--)
00153 alpha = pythag(alpha, a(i), cGivens(i), sGivens(i));
00154
00155
00156 ColumnVector xtilde(nRC); xtilde = 0.0;
00157 for(j = nRC; j >= 1; j--)
00158 {
00159
00160 for(int k = j; k >= 1; k--)
00161 GivensRotation(cGivens(k), -sGivens(k), chol(k,j), xtilde(j));
00162 }
00163 }
00164
00165
00166
00167
00168
00169
00170
00171 void RightCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
00172 {
00173 int nRC = chol.Nrows();
00174 int i, j;
00175
00176
00177 Matrix cholCopy = chol;
00178
00179 ColumnVector columnL = cholCopy.Column(l);
00180
00181 for(j = l-1; j >= k; --j)
00182 cholCopy.Column(j+1) = cholCopy.Column(j);
00183
00184 cholCopy.Column(k) = 0.0;
00185 for(i = 1; i < k; ++i) cholCopy(i,k) = columnL(i);
00186
00187
00188 int nGivens = l-k;
00189 ColumnVector cGivens(nGivens); cGivens = 0.0;
00190 ColumnVector sGivens(nGivens); sGivens = 0.0;
00191 for(i = l; i > k; i--)
00192 {
00193 int givensIndex = l-i+1;
00194 columnL(i-1) = pythag(columnL(i-1), columnL(i),
00195 cGivens(givensIndex), sGivens(givensIndex));
00196 columnL(i) = 0.0;
00197 }
00198
00199 cholCopy(k,k) = columnL(k);
00200
00201
00202
00203 for(j = k+1; j <= nRC; ++j)
00204 {
00205 ColumnVector columnJ = cholCopy.Column(j);
00206 int imin = nGivens - (j-k) + 1; if (imin < 1) imin = 1;
00207 for(int gIndex = imin; gIndex <= nGivens; ++gIndex)
00208 {
00209
00210 int topRowIndex = k + nGivens - gIndex;
00211 GivensRotationR(cGivens(gIndex), sGivens(gIndex),
00212 columnJ(topRowIndex), columnJ(topRowIndex+1));
00213 }
00214 cholCopy.Column(j) = columnJ;
00215 }
00216
00217 chol << cholCopy;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 void LeftCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
00227 {
00228 int nRC = chol.Nrows();
00229 int i, j;
00230
00231
00232 Matrix cholCopy = chol;
00233
00234 ColumnVector columnK = cholCopy.Column(k);
00235
00236 for(j = k+1; j <= l; ++j)
00237 cholCopy.Column(j-1) = cholCopy.Column(j);
00238
00239 cholCopy.Column(l) = 0.0;
00240 for(i = 1; i <= k; ++i)
00241 cholCopy(i,l) = columnK(i);
00242
00243
00244 int nGivens = l-k;
00245 ColumnVector cGivens(nGivens); cGivens = 0.0;
00246 ColumnVector sGivens(nGivens); sGivens = 0.0;
00247 for(j = k; j <= nRC; ++j)
00248 {
00249 ColumnVector columnJ = cholCopy.Column(j);
00250
00251
00252 int imax = j - k; if (imax > nGivens) imax = nGivens;
00253 for(int i = 1; i <= imax; ++i)
00254 {
00255 int gIndex = i;
00256 int topRowIndex = k + i - 1;
00257 GivensRotationR(cGivens(gIndex), sGivens(gIndex),
00258 columnJ(topRowIndex), columnJ(topRowIndex+1));
00259 }
00260
00261
00262 if(j < l)
00263 {
00264 int gIndex = j-k+1;
00265 columnJ(j) = pythag(columnJ(j), columnJ(j+1), cGivens(gIndex), sGivens(gIndex));
00266 columnJ(j+1) = 0.0;
00267 }
00268
00269 cholCopy.Column(j) = columnJ;
00270 }
00271
00272 chol << cholCopy;
00273
00274 }
00275
00276
00277
00278
00279 #ifdef use_namespace
00280 }
00281 #endif
00282