LU::LU(int const m, int const n, double const* A) : m_LU(A, A + m * n), m_piv(m), m_pivSign(1), m_rows(m), m_cols(n) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. for (int i = 0; i < m; ++i) { m_piv[i] = i; } std::vector<double> LUcolj(m); // Outer loop. for (int j = 0; j < n; ++j) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; ++i) { LUcolj[i] = m_LU[i * n + j]; } // Apply previous transformations. for (int i = 0; i < m; ++i) { double* LUrowi = &m_LU[i * n]; // Most of the time is spent in the following dot product. int kmax = std::min(i, j); double s = 0.0; for (int k = 0; k < kmax; ++k) { s += LUrowi[k]*LUcolj[k]; } LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; ++i) { if (fabs(LUcolj[i]) > fabs(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { std::swap(m_LU[p * n + k], m_LU[j * n + k]); } std::swap(m_piv[p], m_piv[j]); m_pivSign = -m_pivSign; } // Compute multipliers. if (j < m && m_LU[j * n + j] != 0.0) { for (int i = j + 1; i < m; ++i) { m_LU[i * n + j] /= m_LU[j * n + j]; } } } }
LUDecomposition::LUDecomposition (const Matrix& A) { // Use a "left-looking", dot-product, Crout/Doolittle algorithm. LU = A; m = A.size1(); n = A.size2(); piv = PivotVector(m); for (int i = 0; i < m; i++) { piv(i) = i; } pivsign = 1; Vector LUcolj(m); // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; i++) { LUcolj(i) = LU(i,j); } // Apply previous transformations. for (int i = 0; i < m; i++) { matrix_row<Matrix> LUrowi(LU,i); // Most of the time is spent in the following dot product. int kmax = std::min(i,j); double s = 0.0; for (int k = 0; k < kmax; k++) { s += LUrowi(k)*LUcolj(k); } LUrowi(j) = LUcolj(i) -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j+1; i < m; i++) { if (std::abs(LUcolj(i)) > std::abs(LUcolj(p))) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { double t = LU(p,k); LU(p,k) = LU(j,k); LU(j,k) = t; } int k = piv(p); piv(p) = piv(j); piv(j) = k; pivsign = -pivsign; } // Compute multipliers. if (j < m && LU(j,j) != 0.0) { for (int i = j+1; i < m; i++) { LU(i,j) /= LU(j,j); } } } }