MOOS 0.2375
|
00001 //$$ hholder.cpp QR decomposition 00002 00003 // Copyright (C) 1991,2,3,4: R B Davies 00004 00005 #define WANT_MATH 00006 00007 #include "include.h" 00008 00009 #include "newmatap.h" 00010 00011 #ifdef use_namespace 00012 namespace NEWMAT { 00013 #endif 00014 00015 #ifdef DO_REPORT 00016 #define REPORT { static ExeCounter ExeCount(__LINE__,16); ++ExeCount; } 00017 #else 00018 #define REPORT {} 00019 #endif 00020 00021 00022 /*************************** QR decompositions ***************************/ 00023 00024 inline Real square(Real x) { return x*x; } 00025 00026 void QRZT(Matrix& X, LowerTriangularMatrix& L) 00027 { 00028 REPORT 00029 Tracer et("QZT(1)"); 00030 int n = X.Ncols(); int s = X.Nrows(); L.ReSize(s); 00031 Real* xi = X.Store(); int k; 00032 for (int i=0; i<s; i++) 00033 { 00034 Real sum = 0.0; 00035 Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); } 00036 sum = sqrt(sum); 00037 L.element(i,i) = sum; 00038 if (sum==0.0) Throw(SingularException(L)); 00039 Real* xj0=xi0; k=n; while(k--) { *xj0++ /= sum; } 00040 for (int j=i+1; j<s; j++) 00041 { 00042 sum=0.0; 00043 xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; } 00044 xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; } 00045 L.element(j,i) = sum; 00046 } 00047 } 00048 } 00049 00050 void QRZT(const Matrix& X, Matrix& Y, Matrix& M) 00051 { 00052 REPORT 00053 Tracer et("QRZT(2)"); 00054 int n = X.Ncols(); int s = X.Nrows(); int t = Y.Nrows(); 00055 if (Y.Ncols() != n) 00056 { Throw(ProgramException("Unequal row lengths",X,Y)); } 00057 M.ReSize(t,s); 00058 Real* xi = X.Store(); int k; 00059 for (int i=0; i<s; i++) 00060 { 00061 Real* xj0 = Y.Store(); Real* xi0 = xi; 00062 for (int j=0; j<t; j++) 00063 { 00064 Real sum=0.0; 00065 xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; } 00066 xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; } 00067 M.element(j,i) = sum; 00068 } 00069 } 00070 } 00071 00072 /* 00073 void QRZ(Matrix& X, UpperTriangularMatrix& U) 00074 { 00075 Tracer et("QRZ(1)"); 00076 int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); 00077 Real* xi0 = X.Store(); int k; 00078 for (int i=0; i<s; i++) 00079 { 00080 Real sum = 0.0; 00081 Real* xi = xi0; k=n; while(k--) { sum += square(*xi); xi+=s; } 00082 sum = sqrt(sum); 00083 U.element(i,i) = sum; 00084 if (sum==0.0) Throw(SingularException(U)); 00085 Real* xj0=xi0; k=n; while(k--) { *xj0 /= sum; xj0+=s; } 00086 xj0 = xi0; 00087 for (int j=i+1; j<s; j++) 00088 { 00089 sum=0.0; 00090 xi=xi0; k=n; xj0++; Real* xj=xj0; 00091 while(k--) { sum += *xi * *xj; xi+=s; xj+=s; } 00092 xi=xi0; k=n; xj=xj0; 00093 while(k--) { *xj -= sum * *xi; xj+=s; xi+=s; } 00094 U.element(i,j) = sum; 00095 } 00096 xi0++; 00097 } 00098 } 00099 */ 00100 00101 void QRZ(Matrix& X, UpperTriangularMatrix& U) 00102 { 00103 REPORT 00104 Tracer et("QRZ(1)"); 00105 int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); U = 0.0; 00106 Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u; 00107 int j, k; int J = s; int i = s; 00108 while (i--) 00109 { 00110 Real* xj0 = xi0; Real* xi = xi0; k = n; 00111 if (k) for (;;) 00112 { 00113 u = u0; Real Xi = *xi; Real* xj = xj0; 00114 j = J; while(j--) *u++ += Xi * *xj++; 00115 if (!(--k)) break; 00116 xi += s; xj0 += s; 00117 } 00118 00119 Real sum = sqrt(*u0); *u0 = sum; u = u0+1; 00120 if (sum == 0.0) Throw(SingularException(U)); 00121 int J1 = J-1; j = J1; while(j--) *u++ /= sum; 00122 00123 xj0 = xi0; xi = xi0++; k = n; 00124 if (k) for (;;) 00125 { 00126 u = u0+1; Real Xi = *xi; Real* xj = xj0; 00127 Xi /= sum; *xj++ = Xi; 00128 j = J1; while(j--) *xj++ -= *u++ * Xi; 00129 if (!(--k)) break; 00130 xi += s; xj0 += s; 00131 } 00132 u0 += J--; 00133 } 00134 } 00135 00136 void QRZ(const Matrix& X, Matrix& Y, Matrix& M) 00137 { 00138 REPORT 00139 Tracer et("QRZ(2)"); 00140 int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols(); 00141 if (Y.Nrows() != n) 00142 { Throw(ProgramException("Unequal column lengths",X,Y)); } 00143 M.ReSize(s,t); M = 0;Real* m0 = M.Store(); Real* m; 00144 Real* xi0 = X.Store(); 00145 int j, k; int i = s; 00146 while (i--) 00147 { 00148 Real* xj0 = Y.Store(); Real* xi = xi0; k = n; 00149 if (k) for (;;) 00150 { 00151 m = m0; Real Xi = *xi; Real* xj = xj0; 00152 j = t; while(j--) *m++ += Xi * *xj++; 00153 if (!(--k)) break; 00154 xi += s; xj0 += t; 00155 } 00156 00157 xj0 = Y.Store(); xi = xi0++; k = n; 00158 if (k) for (;;) 00159 { 00160 m = m0; Real Xi = *xi; Real* xj = xj0; 00161 j = t; while(j--) *xj++ -= *m++ * Xi; 00162 if (!(--k)) break; 00163 xi += s; xj0 += t; 00164 } 00165 m0 += t; 00166 } 00167 } 00168 00169 /* 00170 00171 void QRZ(const Matrix& X, Matrix& Y, Matrix& M) 00172 { 00173 Tracer et("QRZ(2)"); 00174 int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols(); 00175 if (Y.Nrows() != n) 00176 { Throw(ProgramException("Unequal column lengths",X,Y)); } 00177 M.ReSize(s,t); 00178 Real* xi0 = X.Store(); int k; 00179 for (int i=0; i<s; i++) 00180 { 00181 Real* xj0 = Y.Store(); 00182 for (int j=0; j<t; j++) 00183 { 00184 Real sum=0.0; 00185 Real* xi=xi0; Real* xj=xj0; k=n; 00186 while(k--) { sum += *xi * *xj; xi+=s; xj+=t; } 00187 xi=xi0; k=n; xj=xj0++; 00188 while(k--) { *xj -= sum * *xi; xj+=t; xi+=s; } 00189 M.element(i,j) = sum; 00190 } 00191 xi0++; 00192 } 00193 } 00194 */ 00195 00196 #ifdef use_namespace 00197 } 00198 #endif 00199