Homepage Demos Overview Downloads Tutorials Reference
Credits

hholder.cpp

Go to the documentation of this file.
00001 //$$ hholder.cpp                                   QR 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 "newmatap.h"
00011 
00012 #ifdef use_namespace
00013 namespace NEWMAT {
00014 #endif
00015 
00016 #ifdef DO_REPORT
00017 #define REPORT { static ExeCounter ExeCount(__LINE__,16); ++ExeCount; }
00018 #else
00019 #define REPORT {}
00020 #endif
00021 
00022 
00023 /*************************** QR decompositions ***************************/
00024 
00025 inline Real square(Real x) { return x*x; }
00026 
00027 void QRZT(Matrix& X, LowerTriangularMatrix& L)
00028 {
00029    REPORT
00030    Tracer et("QRZT(1)");
00031    int n = X.Ncols(); int s = X.Nrows(); L.ReSize(s);
00032    if (n == 0 || s == 0) { L = 0.0; return; }
00033    Real* xi = X.Store(); int k;
00034    for (int i=0; i<s; i++)
00035    {
00036       Real sum = 0.0;
00037       Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
00038       sum = sqrt(sum);
00039       if (sum == 0.0)
00040       {
00041          REPORT
00042          k=n; while(k--) { *xi0++ = 0.0; }
00043          for (int j=i; j<s; j++) L.element(j,i) = 0.0;
00044       }
00045       else
00046       {
00047          L.element(i,i) = sum;
00048          Real* xj0=xi0; k=n; while(k--) { *xj0++ /= sum; }
00049          for (int j=i+1; j<s; j++)
00050          {
00051             sum=0.0;
00052             xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
00053             xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
00054             L.element(j,i) = sum;
00055          }
00056       }
00057    }
00058 }
00059 
00060 void QRZT(const Matrix& X, Matrix& Y, Matrix& M)
00061 {
00062    REPORT
00063    Tracer et("QRZT(2)");
00064    int n = X.Ncols(); int s = X.Nrows(); int t = Y.Nrows();
00065    if (Y.Ncols() != n)
00066       { Throw(ProgramException("Unequal row lengths",X,Y)); }
00067    M.ReSize(t,s);
00068    Real* xi = X.Store(); int k;
00069    for (int i=0; i<s; i++)
00070    {
00071       Real* xj0 = Y.Store(); Real* xi0 = xi;
00072       for (int j=0; j<t; j++)
00073       {
00074          Real sum=0.0;
00075          xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
00076          xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
00077          M.element(j,i) = sum;
00078       }
00079    }
00080 }
00081 
00082 /*
00083 void QRZ(Matrix& X, UpperTriangularMatrix& U)
00084 {
00085   Tracer et("QRZ(1)");
00086   int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s);
00087   Real* xi0 = X.Store(); int k;
00088   for (int i=0; i<s; i++)
00089   {
00090     Real sum = 0.0;
00091     Real* xi = xi0; k=n; while(k--) { sum += square(*xi); xi+=s; }
00092     sum = sqrt(sum);
00093     U.element(i,i) = sum;
00094     if (sum==0.0) Throw(SingularException(U));
00095     Real* xj0=xi0; k=n; while(k--) { *xj0 /= sum; xj0+=s; }
00096     xj0 = xi0;
00097     for (int j=i+1; j<s; j++)
00098     {
00099       sum=0.0;
00100       xi=xi0; k=n; xj0++; Real* xj=xj0;
00101       while(k--) { sum += *xi * *xj; xi+=s; xj+=s; }
00102       xi=xi0; k=n; xj=xj0;
00103       while(k--) { *xj -= sum * *xi; xj+=s; xi+=s; }
00104       U.element(i,j) = sum;
00105     }
00106     xi0++;
00107   }
00108 }
00109 */
00110 
00111 void QRZ(Matrix& X, UpperTriangularMatrix& U)
00112 {
00113    REPORT
00114    Tracer et("QRZ(1)");
00115    int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); U = 0.0;
00116    if (n == 0 || s == 0) return;
00117    Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
00118    int j, k; int J = s; int i = s;
00119    while (i--)
00120    {
00121       Real* xj0 = xi0; Real* xi = xi0; k = n;
00122       if (k) for (;;)
00123       {
00124          u = u0; Real Xi = *xi; Real* xj = xj0;
00125          j = J; while(j--) *u++ += Xi * *xj++;
00126          if (!(--k)) break;
00127          xi += s; xj0 += s;
00128       }
00129 
00130       Real sum = sqrt(*u0); *u0 = sum; u = u0+1;
00131       if (sum == 0.0)
00132       {
00133          REPORT
00134          j = J - 1; while(j--) *u++ = 0.0;
00135 
00136          xj0 = xi0++; k = n;
00137          if (k) for (;;)
00138          {
00139             *xj0 = 0.0;
00140             if (!(--k)) break;
00141             xj0 += s;
00142          }
00143          u0 += J--;
00144       }
00145       else
00146       {
00147          int J1 = J-1; j = J1; while(j--) *u++ /= sum;
00148 
00149          xj0 = xi0; xi = xi0++; k = n;
00150          if (k) for (;;)
00151          {
00152             u = u0+1; Real Xi = *xi; Real* xj = xj0;
00153             Xi /= sum; *xj++ = Xi;
00154             j = J1; while(j--) *xj++ -= *u++ * Xi;
00155             if (!(--k)) break;
00156             xi += s; xj0 += s;
00157          }
00158          u0 += J--;
00159       }
00160    }
00161 }
00162 
00163 void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
00164 {
00165    REPORT
00166    Tracer et("QRZ(2)");
00167    int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
00168    if (Y.Nrows() != n)
00169       { Throw(ProgramException("Unequal column lengths",X,Y)); }
00170    M.ReSize(s,t); M = 0;Real* m0 = M.Store(); Real* m;
00171    Real* xi0 = X.Store();
00172    int j, k; int i = s;
00173    while (i--)
00174    {
00175       Real* xj0 = Y.Store(); Real* xi = xi0; k = n;
00176       if (k) for (;;)
00177       {
00178          m = m0; Real Xi = *xi; Real* xj = xj0;
00179          j = t; while(j--) *m++ += Xi * *xj++;
00180          if (!(--k)) break;
00181          xi += s; xj0 += t;
00182       }
00183 
00184       xj0 = Y.Store(); xi = xi0++; k = n;
00185       if (k) for (;;)
00186       {
00187          m = m0; Real Xi = *xi; Real* xj = xj0;
00188          j = t; while(j--) *xj++ -= *m++ * Xi;
00189          if (!(--k)) break;
00190          xi += s; xj0 += t;
00191       }
00192       m0 += t;
00193    }
00194 }
00195 
00196 /*
00197 
00198 void QRZ(const Matrix& X, Matrix& Y, Matrix& M)
00199 {
00200   Tracer et("QRZ(2)");
00201   int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols();
00202   if (Y.Nrows() != n)
00203   { Throw(ProgramException("Unequal column lengths",X,Y)); }
00204   M.ReSize(s,t);
00205   Real* xi0 = X.Store(); int k;
00206   for (int i=0; i<s; i++)
00207   {
00208     Real* xj0 = Y.Store();
00209     for (int j=0; j<t; j++)
00210     {
00211       Real sum=0.0;
00212       Real* xi=xi0; Real* xj=xj0; k=n;
00213       while(k--) { sum += *xi * *xj; xi+=s; xj+=t; }
00214       xi=xi0; k=n; xj=xj0++;
00215       while(k--) { *xj -= sum * *xi; xj+=t; xi+=s; }
00216       M.element(i,j) = sum;
00217     }
00218     xi0++;
00219   }
00220 }
00221 */
00222 
00223 void UpdateQRZT(Matrix& X, LowerTriangularMatrix& L)
00224 {
00225    REPORT
00226    Tracer et("UpdateQRZT");
00227    int n = X.Ncols(); int s = X.Nrows();
00228    if (s != L.Nrows())
00229       Throw(ProgramException("Incompatible dimensions",X,L)); 
00230    if (n == 0 || s == 0) return;
00231    Real* xi = X.Store(); int k;
00232    for (int i=0; i<s; i++)
00233    {
00234       Real r = L.element(i,i); 
00235       Real sum = 0.0;
00236       Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); }
00237       sum = sqrt(sum + square(r));
00238       if (sum == 0.0)
00239       {
00240          REPORT
00241          k=n; while(k--) { *xi0++ = 0.0; }
00242          for (int j=i; j<s; j++) L.element(j,i) = 0.0;
00243       }
00244       else
00245       {
00246          Real frs = fabs(r) + sum;
00247          Real a0 = sqrt(frs / sum); Real alpha = a0 / frs;
00248          if (r <= 0) { REPORT L.element(i,i) = sum; alpha = -alpha; }
00249          else { REPORT L.element(i,i) = -sum; }
00250          Real* xj0=xi0; k=n; while(k--) { *xj0++ *= alpha; }
00251          for (int j=i+1; j<s; j++)
00252          {
00253             sum = 0.0;
00254             xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; }
00255             sum += a0 * L.element(j,i);
00256             xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; }
00257             L.element(j,i) -= sum * a0;
00258          }
00259       }
00260    }
00261 }
00262 
00263 void UpdateQRZ(Matrix& X, UpperTriangularMatrix& U)
00264 {
00265    REPORT
00266    Tracer et("UpdateQRZ");
00267    int n = X.Nrows(); int s = X.Ncols();
00268    if (s != U.Ncols())
00269       Throw(ProgramException("Incompatible dimensions",X,U));
00270    if (n == 0 || s == 0) return; 
00271    Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u;
00272    RowVector V(s); Real* v0 = V.Store(); Real* v; V = 0.0;
00273    int j, k; int J = s; int i = s;
00274    while (i--)
00275    {
00276       Real* xj0 = xi0; Real* xi = xi0; k = n;
00277       if (k) for (;;)
00278       {
00279          v = v0; Real Xi = *xi; Real* xj = xj0;
00280          j = J; while(j--) *v++ += Xi * *xj++;
00281          if (!(--k)) break;
00282          xi += s; xj0 += s;
00283       }
00284 
00285       Real r = *u0;
00286       Real sum = sqrt(*v0 + square(r));
00287       
00288       if (sum == 0.0)
00289       {
00290          REPORT
00291          u = u0; v = v0;
00292          j = J; while(j--) { *u++ = 0.0; *v++ = 0.0; }
00293          xj0 = xi0++; k = n;
00294          if (k) for (;;)
00295          {
00296             *xj0 = 0.0;
00297             if (!(--k)) break;
00298             xj0 += s;
00299          }
00300          u0 += J--;
00301       }
00302       else
00303       {
00304          Real frs = fabs(r) + sum;
00305          Real a0 = sqrt(frs / sum); Real alpha = a0 / frs;
00306          if (r <= 0) { REPORT alpha = -alpha; *u0 = sum; }
00307          else { REPORT *u0 = -sum; }
00308       
00309          j = J - 1; v = v0 + 1; u = u0 + 1;     
00310          while (j--)
00311             { *v = a0 * *u + alpha * *v; *u -= a0 * *v; ++v; ++u; }
00312 
00313          xj0 = xi0; xi = xi0++; k = n;
00314          if (k) for (;;)
00315          {
00316             v = v0 + 1; Real Xi = *xi; Real* xj = xj0;
00317             Xi *= alpha; *xj++ = Xi;
00318             j = J - 1; while(j--) *xj++ -= *v++ * Xi;
00319             if (!(--k)) break;
00320             xi += s; xj0 += s;
00321          }
00322          
00323          j = J; v = v0;
00324          while (j--) *v++ = 0.0;
00325          
00326          u0 += J--;
00327       }
00328    }
00329 }
00330 
00331 
00332 #ifdef use_namespace
00333 }
00334 #endif
00335 

newmat11b
Generated Tue Nov 23 16:35:39 2004 by Doxygen 1.3.9.1