void Print(const LowerTriangularMatrix& 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(); for (int i=1; i<=nr; i++) { for (int j=1; j<=i; j++) cout << X(i,j) << "\t"; cout << "\n"; } cout << flush; ++PCZ; }
/// /// /// Function to calculate the transformation matrix X ( p = X.f ) /// according to the Whiten Crusher Model described in /// the JKMRC monograph: /// Napier-Munn et al. /// "Mineral Comminution Circuits - Their Operation and Optimisation", /// JKMRC monograph 1996, /// p138ff /// void WhitenCrusherTransformationMatrix(const LowerTriangularMatrix& B, const DiagonalMatrix& C, Matrix& X) { int matrixSize = B.Nrows() ; IdentityMatrix I(matrixSize); /// do the matrix calculations X = (I - C) * (I - (B * C)).i() ; }
void updateQRZT(Matrix& X, LowerTriangularMatrix& L) { REPORT Tracer et("updateQRZT"); int n = X.Ncols(); int s = X.Nrows(); if (s != L.Nrows()) Throw(ProgramException("Incompatible dimensions",X,L)); if (n == 0 || s == 0) return; Real* xi = X.Store(); int k; for (int i=0; i<s; i++) { Real r = L.element(i,i); Real sum = 0.0; Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); } sum = sqrt(sum + square(r)); if (sum == 0.0) { REPORT k=n; while(k--) { *xi0++ = 0.0; } for (int j=i; j<s; j++) L.element(j,i) = 0.0; } else { Real frs = fabs(r) + sum; Real a0 = sqrt(frs / sum); Real alpha = a0 / frs; if (r <= 0) { REPORT L.element(i,i) = sum; alpha = -alpha; } else { REPORT L.element(i,i) = -sum; } Real* xj0=xi0; k=n; while(k--) { *xj0++ *= alpha; } for (int j=i+1; j<s; j++) { sum = 0.0; xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; } sum += a0 * L.element(j,i); xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; } L.element(j,i) -= sum * a0; } } } }