void Print(const UpperTriangularMatrix& X) { ++PCN; cout << "\nMatrix type: " << X.Type().Value() << " ("; cout << X.Nrows() << ", "; cout << X.Ncols() << ")\n\n"; if (X.IsZero()) { cout << "All elements are zero\n" << flush; return; } int nr=X.Nrows(); int nc=X.Ncols(); for (int i=1; i<=nr; i++) { int j; for (j=1; j<i; j++) cout << "\t"; for (j=i; j<=nc; j++) cout << X(i,j) << "\t"; cout << "\n"; } cout << flush; ++PCZ; }
void updateQRZ(UpperTriangularMatrix& X, UpperTriangularMatrix& U) { REPORT Tracer et("updateQRZ(3)"); int s = X.Ncols(); if (s != U.Ncols()) Throw(ProgramException("Incompatible dimensions",X,U)); if (s == 0) return; Real* xi0 = X.data(); Real* u = U.data(); for (int i=1; i<=s; ++i) { Real r = *u; Real sum = 0.0; { Real* xi=xi0; int k=i; int l=s; while(k--) { sum += square(*xi); xi+= --l;} } sum = sqrt(sum + square(r)); if (sum == 0.0) { REPORT X.column(i) = 0.0; *u = 0.0; } else { Real frs = fabs(r) + sum; Real a0 = sqrt(frs / sum); Real alpha = a0 / frs; if (r <= 0) { REPORT *u = sum; alpha = -alpha; } else { REPORT *u = -sum; } { Real* xj0=xi0; int k=i; int l=s; while(k--) { *xj0 *= alpha; --l; xj0 += l;} } Real* xj0=xi0; Real* uj=u; for (int j=i+1; j<=s; ++j) { Real sum = 0.0; ++xj0; ++uj; Real* xi=xi0; Real* xj=xj0; int k=i; int l=s; while(k--) { sum += *xi * *xj; --l; xi += l; xj += l; } sum += a0 * *uj; xi=xi0; xj=xj0; k=i; l=s; while(k--) { *xj -= sum * *xi; --l; xi += l; xj += l; } *uj -= sum * a0; } } ++xi0; u += s-i+1; } }
void updateQRZ(const UpperTriangularMatrix& X, Matrix& MX, Matrix& MU) { REPORT Tracer et("updateQRZ(4)"); int s = X.Ncols(); if (s != MX.Nrows()) Throw(ProgramException("Incompatible dimensions",X,MX)); if (s != MU.Nrows()) Throw(ProgramException("Incompatible dimensions",X,MU)); int t = MX.Ncols(); if (t != MU.Ncols()) Throw(ProgramException("Incompatible dimensions",MX,MU)); if (s == 0) return; const Real* xi0 = X.data(); Real* mx = MX.data(); Real* muj = MU.data(); for (int i=1; i<=s; ++i) { Real sum = 0.0; { const Real* xi=xi0; int k=i; int l=s; while(k--) { sum += square(*xi); xi+= --l;} } Real a0 = sqrt(2.0 - sum); Real* mxj0 = mx; for (int j=1; j<=t; ++j) { Real sum = 0.0; const Real* xi=xi0; Real* mxj=mxj0; int k=i; int l=s; while(--k) { sum += *xi * *mxj; --l; xi += l; mxj += t; } sum += *xi * *mxj; // last line of loop sum += a0 * *muj; xi=xi0; mxj=mxj0; k=i; l=s; while(--k) { *mxj -= sum * *xi; --l; xi += l; mxj += t; } *mxj -= sum * *xi; // last line of loop *muj -= sum * a0; ++mxj0; ++muj; } ++xi0; } }
void updateQRZ(Matrix& X, UpperTriangularMatrix& U) { REPORT Tracer et("updateQRZ"); int n = X.Nrows(); int s = X.Ncols(); if (s != U.Ncols()) Throw(ProgramException("Incompatible dimensions",X,U)); if (n == 0 || s == 0) return; Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u; RowVector V(s); Real* v0 = V.Store(); Real* v; V = 0.0; int j, k; int J = s; int i = s; while (i--) { Real* xj0 = xi0; Real* xi = xi0; k = n; if (k) for (;;) { v = v0; Real Xi = *xi; Real* xj = xj0; j = J; while(j--) *v++ += Xi * *xj++; if (!(--k)) break; xi += s; xj0 += s; } Real r = *u0; Real sum = sqrt(*v0 + square(r)); if (sum == 0.0) { REPORT u = u0; v = v0; j = J; while(j--) { *u++ = 0.0; *v++ = 0.0; } xj0 = xi0++; k = n; if (k) for (;;) { *xj0 = 0.0; if (!(--k)) break; xj0 += s; } u0 += J--; } else { Real frs = fabs(r) + sum; Real a0 = sqrt(frs / sum); Real alpha = a0 / frs; if (r <= 0) { REPORT alpha = -alpha; *u0 = sum; } else { REPORT *u0 = -sum; } j = J - 1; v = v0 + 1; u = u0 + 1; while (j--) { *v = a0 * *u + alpha * *v; *u -= a0 * *v; ++v; ++u; } xj0 = xi0; xi = xi0++; k = n; if (k) for (;;) { v = v0 + 1; Real Xi = *xi; Real* xj = xj0; Xi *= alpha; *xj++ = Xi; j = J - 1; while(j--) *xj++ -= *v++ * Xi; if (!(--k)) break; xi += s; xj0 += s; } j = J; v = v0; while (j--) *v++ = 0.0; u0 += J--; } } }