Пример #1
0
Файл: LU.cpp Проект: DikBSD/STE
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];
			}
		}
	}
}
Пример #2
0
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);
            }
         }
      }
   }