diff --git a/numerical_methods/lu_decompose.cpp b/numerical_methods/lu_decompose.cpp index a0a2d00ab..2ce5fb653 100644 --- a/numerical_methods/lu_decompose.cpp +++ b/numerical_methods/lu_decompose.cpp @@ -7,73 +7,15 @@ #include #include #include -#include -#ifdef _OPENMP -#include -#endif -/** Perform LU decomposition on matrix - * \param[in] A matrix to decompose - * \param[out] L output L matrix - * \param[out] U output U matrix - * \returns 0 if no errors - * \returns negative if error occurred - */ -int lu_decomposition(const std::vector> &A, - std::vector> *L, - std::vector> *U) { - int row, col, j; - int mat_size = A.size(); - - if (mat_size != A[0].size()) { - // check matrix is a square matrix - std::cerr << "Not a square matrix!\n"; - return -1; - } - - // regularize each row - for (row = 0; row < mat_size; row++) { - // Upper triangular matrix -#ifdef _OPENMP -#pragma omp for -#endif - for (col = row; col < mat_size; col++) { - // Summation of L[i,j] * U[j,k] - double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][row][j] * U[0][j][col]; - - // Evaluate U[i,k] - U[0][row][col] = A[row][col] - lu_sum; - } - - // Lower triangular matrix -#ifdef _OPENMP -#pragma omp for -#endif - for (col = row; col < mat_size; col++) { - if (row == col) { - L[0][row][col] = 1.; - continue; - } - - // Summation of L[i,j] * U[j,k] - double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][col][j] * U[0][j][row]; - - // Evaluate U[i,k] - L[0][col][row] = (A[col][row] - lu_sum) / U[0][row][row]; - } - } - - return 0; -} +#include "./lu_decomposition.h" /** * operator to print a matrix */ template std::ostream &operator<<(std::ostream &out, - std::vector> const &v) { + std::vector> const &v) { const int width = 10; const char separator = ' '; @@ -99,14 +41,14 @@ int main(int argc, char **argv) { std::srand(std::time(NULL)); // random number initializer /* Create a square matrix with random values */ - std::vector> A(mat_size); - std::vector> L(mat_size); // output - std::vector> U(mat_size); // output + std::vector> A(mat_size, + std::valarray(mat_size)); + std::vector> L( + mat_size, std::valarray(mat_size)); // output + std::vector> U( + mat_size, std::valarray(mat_size)); // output for (int i = 0; i < mat_size; i++) { // calloc so that all valeus are '0' by default - A[i] = std::vector(mat_size); - L[i] = std::vector(mat_size); - U[i] = std::vector(mat_size); for (int j = 0; j < mat_size; j++) /* create random values in the limits [-range2, range-1] */ A[i][j] = static_cast(std::rand() % range - range2); diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h new file mode 100644 index 000000000..9cb881ba9 --- /dev/null +++ b/numerical_methods/lu_decomposition.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#ifdef _OPENMP +#include +#endif + +/** Perform LU decomposition on matrix + * \param[in] A matrix to decompose + * \param[out] L output L matrix + * \param[out] U output U matrix + * \returns 0 if no errors + * \returns negative if error occurred + */ +template +int lu_decomposition(const std::vector> &A, + std::vector> *L, + std::vector> *U) { + int row, col, j; + int mat_size = A.size(); + + if (mat_size != A[0].size()) { + // check matrix is a square matrix + std::cerr << "Not a square matrix!\n"; + return -1; + } + + // regularize each row + for (row = 0; row < mat_size; row++) { + // Upper triangular matrix +#ifdef _OPENMP +#pragma omp for +#endif + for (col = row; col < mat_size; col++) { + // Summation of L[i,j] * U[j,k] + double lu_sum = 0.; + for (j = 0; j < row; j++) lu_sum += L[0][row][j] * U[0][j][col]; + + // Evaluate U[i,k] + U[0][row][col] = A[row][col] - lu_sum; + } + + // Lower triangular matrix +#ifdef _OPENMP +#pragma omp for +#endif + for (col = row; col < mat_size; col++) { + if (row == col) { + L[0][row][col] = 1.; + continue; + } + + // Summation of L[i,j] * U[j,k] + double lu_sum = 0.; + for (j = 0; j < row; j++) lu_sum += L[0][col][j] * U[0][j][row]; + + // Evaluate U[i,k] + L[0][col][row] = (A[col][row] - lu_sum) / U[0][row][row]; + } + } + + return 0; +}