00001
00002
00003
00004
00005 #define WANT_MATH
00006
00007
00008 #include "include.h"
00009
00010 #include "newmat.h"
00011 #include "newmatrm.h"
00012
00013 #ifdef use_namespace
00014 namespace NEWMAT {
00015 #endif
00016
00017 #ifdef DO_REPORT
00018 #define REPORT { static ExeCounter ExeCount(__LINE__,14); ++ExeCount; }
00019 #else
00020 #define REPORT {}
00021 #endif
00022
00023
00024
00025
00026
00027
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
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 void UpdateCholesky(UpperTriangularMatrix &chol, RowVector r1Modification)
00096 {
00097 int nc = chol.Nrows();
00098 ColumnVector cGivens(nc); cGivens = 0.0;
00099 ColumnVector sGivens(nc); sGivens = 0.0;
00100
00101 for(int j = 1; j <= nc; ++j)
00102 {
00103
00104 for(int k = 1; k < j; ++k)
00105 GivensRotation(cGivens(k), sGivens(k), chol(k,j), r1Modification(j));
00106
00107
00108 pythag(chol(j,j), r1Modification(j), cGivens(j), sGivens(j));
00109
00110
00111 {
00112 Real tmp0 = cGivens(j) * chol(j,j) + sGivens(j) * r1Modification(j);
00113 chol(j,j) = tmp0; r1Modification(j) = 0.0;
00114 }
00115
00116 }
00117
00118 }
00119
00120
00121
00122 void DowndateCholesky(UpperTriangularMatrix &chol, RowVector x)
00123 {
00124 int nRC = chol.Nrows();
00125
00126
00127 LowerTriangularMatrix L = chol.t();
00128 ColumnVector a(nRC); a = 0.0;
00129 int i, j;
00130
00131 for (i = 1; i <= nRC; ++i)
00132 {
00133
00134 Real subtrsum = 0.0;
00135 for(int k = 1; k < i; ++k) subtrsum += a(k) * L(i,k);
00136
00137 a(i) = (x(i) - subtrsum) / L(i,i);
00138 }
00139
00140
00141 Real squareNormA = a.SumSquare();
00142 if (squareNormA >= 1.0)
00143 Throw(ProgramException("DowndateCholesky() fails", chol));
00144
00145 Real alpha = sqrt(1.0 - squareNormA);
00146
00147
00148 ColumnVector cGivens(nRC); cGivens = 0.0;
00149 ColumnVector sGivens(nRC); sGivens = 0.0;
00150 for(i = nRC; i >= 1; i--)
00151 alpha = pythag(alpha, a(i), cGivens(i), sGivens(i));
00152
00153
00154 ColumnVector xtilde(nRC); xtilde = 0.0;
00155 for(j = nRC; j >= 1; j--)
00156 {
00157
00158 for(int k = j; k >= 1; k--)
00159 GivensRotation(cGivens(k), -sGivens(k), chol(k,j), xtilde(j));
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 void RightCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
00170 {
00171 int nRC = chol.Nrows();
00172 int i, j;
00173
00174
00175 Matrix cholCopy = chol;
00176
00177 ColumnVector columnL = cholCopy.Column(l);
00178
00179 for(j = l-1; j >= k; --j)
00180 cholCopy.Column(j+1) = cholCopy.Column(j);
00181
00182 cholCopy.Column(k) = 0.0;
00183 for(i = 1; i < k; ++i) cholCopy(i,k) = columnL(i);
00184
00185
00186 int nGivens = l-k;
00187 ColumnVector cGivens(nGivens); cGivens = 0.0;
00188 ColumnVector sGivens(nGivens); sGivens = 0.0;
00189 for(i = l; i > k; i--)
00190 {
00191 int givensIndex = l-i+1;
00192 columnL(i-1) = pythag(columnL(i-1), columnL(i),
00193 cGivens(givensIndex), sGivens(givensIndex));
00194 columnL(i) = 0.0;
00195 }
00196
00197 cholCopy(k,k) = columnL(k);
00198
00199
00200
00201 for(j = k+1; j <= nRC; ++j)
00202 {
00203 ColumnVector columnJ = cholCopy.Column(j);
00204 int imin = nGivens - (j-k) + 1; if (imin < 1) imin = 1;
00205 for(int gIndex = imin; gIndex <= nGivens; ++gIndex)
00206 {
00207
00208 int topRowIndex = k + nGivens - gIndex;
00209 GivensRotationR(cGivens(gIndex), sGivens(gIndex),
00210 columnJ(topRowIndex), columnJ(topRowIndex+1));
00211 }
00212 cholCopy.Column(j) = columnJ;
00213 }
00214
00215 chol << cholCopy;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 void LeftCircularUpdateCholesky(UpperTriangularMatrix &chol, int k, int l)
00225 {
00226 int nRC = chol.Nrows();
00227 int i, j;
00228
00229
00230 Matrix cholCopy = chol;
00231
00232 ColumnVector columnK = cholCopy.Column(k);
00233
00234 for(j = k+1; j <= l; ++j)
00235 cholCopy.Column(j-1) = cholCopy.Column(j);
00236
00237 cholCopy.Column(l) = 0.0;
00238 for(i = 1; i <= k; ++i)
00239 cholCopy(i,l) = columnK(i);
00240
00241
00242 int nGivens = l-k;
00243 ColumnVector cGivens(nGivens); cGivens = 0.0;
00244 ColumnVector sGivens(nGivens); sGivens = 0.0;
00245 for(j = k; j <= nRC; ++j)
00246 {
00247 ColumnVector columnJ = cholCopy.Column(j);
00248
00249
00250 int imax = j - k; if (imax > nGivens) imax = nGivens;
00251 for(int i = 1; i <= imax; ++i)
00252 {
00253 int gIndex = i;
00254 int topRowIndex = k + i - 1;
00255 GivensRotationR(cGivens(gIndex), sGivens(gIndex),
00256 columnJ(topRowIndex), columnJ(topRowIndex+1));
00257 }
00258
00259
00260 if(j < l)
00261 {
00262 int gIndex = j-k+1;
00263 columnJ(j) = pythag(columnJ(j), columnJ(j+1), cGivens(gIndex), sGivens(gIndex));
00264 columnJ(j+1) = 0.0;
00265 }
00266
00267 cholCopy.Column(j) = columnJ;
00268 }
00269
00270 chol << cholCopy;
00271
00272 }
00273
00274
00275
00276
00277 #ifdef use_namespace
00278 }
00279 #endif
00280