#ifndef HPC_ULMLAPACK_GETF2_H #define HPC_ULMLAPACK_GETF2_H 1 #include <algorithm> #include <hpc/matvec/r.h> #include <hpc/matvec/iamax.h> #include <hpc/matvec/scal.h> #include <hpc/matvec/swap.h> #include <hpc/ulmblas/ger.h> #include <hpc/ulmblas/iamax.h> #include <hpc/ulmblas/scal.h> #include <hpc/ulmblas/swap.h> namespace hpc { namespace ulmlapack { template <typename Index, typename TA, typename TP> Index getf2(Index m, Index n, TA *A, Index incRowA, Index incColA, TP *p, Index incP) { Index mn = std::min(m,n); for (Index j=0; j<mn; ++j) { Index i = j+ulmblas::iamax(m-j, &A[j*(incRowA+incColA)], incRowA); if (i!=j) { ulmblas::swap(n, &A[i*incRowA], incColA, &A[j*incRowA], incColA); } p[j*incP] = i; if (A[j*(incRowA+incColA)]==TA(0)) { return j; } ulmblas::scal(m-1-j, TA(1)/A[j*(incRowA+incColA)], &A[j*(incRowA+incColA)+incRowA], incRowA); ulmblas::ger(m-1-j, n-1-j, TA(-1), &A[j*(incRowA+incColA)+incRowA], incRowA, &A[j*(incRowA+incColA)+incColA], incColA, &A[(j+1)*(incRowA+incColA)], incRowA, incColA); } return -1; } template <typename MA, typename VP> typename std::enable_if<hpc::matvec::IsGeMatrix<MA>::value && hpc::matvec::IsDenseVector<VP>::value, typename std::remove_reference<MA>::type::Index>::type tf2(MA &&A, VP &&p) { typedef typename std::remove_reference<MA>::type MatrixA; typedef typename MatrixA::ElementType T; typedef typename MatrixA::Index Index; using namespace hpc::matvec; Index m = A.numRows; Index n = A.numCols; for (Index j=0; m>0 && n>0; ++j, --m, --n) { auto Ajj = A(j, j, m, n); Index i = j+iamax(Ajj.col(0)); if (i!=j) { swap(A.row(i), A.row(j)); } p(j) = i; if (A(j,j)==T(0)) { return j; } if (m==1 || n==1) { break; } auto a01 = Ajj.row(0)(1,n-1); auto a10 = Ajj.col(0)(1,m-1); auto A11 = Ajj(1, 1, m-1, n-1); scal(T(1)/A(j,j), a10); r(T(-1), a10, a01, A11); } return -1; } } } // namespace ulmblas, hpc #endif // HPC_ULMLAPACK_GETF2_H |