double Simplex::getDeterminant(const std::vector<double>& amat) const { double res = 1; size_t nSquare = amat.size(); int n = (int) std::sqrt( (double) nSquare ); std::vector<double> mat(amat); // make a copy // LU decomposition std::vector<int> ipiv((size_t) n); int err = 0; _GETRF_(&n, &n, &mat.front(), &n, &ipiv.front(), &err); // no error checking // compute the determinant for (size_t i = 0; i < (size_t)n; ++i) { double aii = mat[i + (size_t)n*i]; // ipiv holds the fortran indices if (ipiv[i] != (int)i + 1) { res *= -aii; } else { res *= aii; } } return res; }
int solveLinearEquationLU(dmatrix a, const dmatrix &b, dmatrix &out_x) { assert(a.rows() == a.cols() && a.cols() == b.rows() ); out_x = b; const int n = (int)a.rows(); const int nrhs = (int)b.cols(); int info; std::vector<int> ipiv(n); #ifndef USE_CLAPACK_INTERFACE int lda = n; int ldb = n; dgesv_(&n, &nrhs, &(a(0,0)), &lda, &(ipiv[0]), &(out_x(0,0)), &ldb, &info); #else info = clapack_dgesv(CblasColMajor, n, nrhs, &(a(0,0)), n, &(ipiv[0]), &(out_x(0,0)), n); #endif assert(info == 0); return info; }
Array<T> solveLU(const Array<T> &A, const Array<int> &pivot, const Array<T> &b, const af_mat_prop options) { if(OpenCLCPUOffload()) { return cpu::solveLU(A, pivot, b, options); } int N = A.dims()[0]; int NRHS = b.dims()[1]; std::vector<int> ipiv(N); copyData(&ipiv[0], pivot); Array< T > B = copyArray<T>(b); const cl::Buffer *A_buf = A.get(); cl::Buffer *B_buf = B.get(); int info = 0; magma_getrs_gpu<T>(MagmaNoTrans, N, NRHS, (*A_buf)(), A.getOffset(), A.strides()[1], &ipiv[0], (*B_buf)(), B.getOffset(), B.strides()[1], getQueue()(), &info); return B; }
/* * Solve Ax = b. Vector b is overwritten on exit with x. */ int SquareMatrix::solve(doublereal * b) { if (useQR_) { return solveQR(b); } int info=0; /* * Check to see whether the matrix has been factored. */ if (!m_factored) { int retn = factor(); if (retn) { return retn; } } /* * Solve the factored system */ ct_dgetrs(ctlapack::NoTranspose, static_cast<int>(nRows()), 1, &(*(begin())), static_cast<int>(nRows()), DATA_PTR(ipiv()), b, static_cast<int>(nColumns()), info); if (info != 0) { if (m_printLevel) { writelogf("SquareMatrix::solve(): DGETRS returned INFO = %d\n", info); } if (! m_useReturnErrorCode) { throw CELapackError("SquareMatrix::solve()", "DGETRS returned INFO = " + int2str(info)); } } return info; }
auto inverse(const tensor_base<ET, tensor_shape<ST, MT, NT>, T> &A, bool *succeed = nullptr) { assert(A.cols() == A.rows()); blas_int n = (blas_int)A.rows(); assert(n > 0); blas_int lda = n; auto Adata = A.t().eval(); std::vector<blas_int> ipiv(n); blas_int info = 0; // lu factorization lapack::getrf(&n, &n, Adata.ptr(), &lda, ipiv.data(), &info); if (succeed) { *succeed = info == 0; } if (info == 0) { blas_int lwork = n; vecx_<ET> work(make_shape(lwork)); // inverse lapack::getri(&n, Adata.ptr(), &lda, ipiv.data(), work.ptr(), &lwork, &info); if (succeed) { *succeed = info == 0; } } return std::move(Adata).t(); }
Array<T> generalSolve(const Array<T> &a, const Array<T> &b) { dim4 iDims = a.dims(); int M = iDims[0]; int N = iDims[1]; int MN = std::min(M, N); std::vector<int> ipiv(MN); Array<T> A = copyArray<T>(a); Array<T> B = copyArray<T>(b); cl::Buffer *A_buf = A.get(); int info = 0; magma_getrf_gpu<T>(M, N, (*A_buf)(), A.getOffset(), A.strides()[1], &ipiv[0], getQueue()(), &info); cl::Buffer *B_buf = B.get(); int K = B.dims()[1]; magma_getrs_gpu<T>(MagmaNoTrans, M, K, (*A_buf)(), A.getOffset(), A.strides()[1], &ipiv[0], (*B_buf)(), B.getOffset(), B.strides()[1], getQueue()(), &info); return B; }
void trisolve(Teuchos::RCP<Teuchos::LAPACK<int,Real> > lapack, const std::vector<Real>& a, const std::vector<Real>& b, const std::vector<Real>& c, const std::vector<Real>& r, std::vector<Real>& x ) { const char TRANS = 'N'; const int N = b.size(); const int NRHS = 1; int info; std::vector<Real> dl(a); std::vector<Real> d(b); std::vector<Real> du(c); std::vector<Real> du2(N-2,0.0); std::vector<int> ipiv(N); // Do matrix factorization, overwriting the LU bands lapack->GTTRF(N,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&info); x = r; // Solve the system using the banded LU factors lapack->GTTRS(TRANS,N,NRHS,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&x[0],N,&info); }
// DGESV uses the LU factorization to compute solution // to a real system of linear equations, A * X = B, // where A is square (N,N) and X, B are (N,NRHS). // // If the system is over or under-determined, // (i.e. A is not square), then pass the problem // to the Least-squares solver (DGELSS) below. //--------------------------------------------------------- void umSOLVE(const DMat& mat, const DMat& B, DMat& X) //--------------------------------------------------------- { if (!mat.ok()) {umWARNING("umSOLVE()", "system is empty"); return;} if (!mat.is_square()) { umSOLVE_LS(mat, B, X); // return a least-squares solution. return; } DMat A(mat); // work with copy of input X = B; // initialize result with RHS int rows=A.num_rows(), LDA=A.num_rows(), cols=A.num_cols(); int LDB=B.num_rows(), NRHS=B.num_cols(), info=0; if (rows<1) {umWARNING("umSOLVE()", "system is empty"); return;} IVec ipiv(rows); // Solve the system. GESV(rows, NRHS, A.data(), LDA, ipiv.data(), X.data(), LDB, info); if (info < 0) { X = 0.0; umERROR("umSOLVE(A,B, X)", "Error in input argument (%d)\nNo solution computed.", -info); } else if (info > 0) { X = 0.0; umERROR("umSOLVE(A,B, X)", "\nINFO = %d. U(%d,%d) was exactly zero." "\nThe factorization has been completed, but the factor U is " "\nexactly singular, so the solution could not be computed.", info, info, info); } }
//--- Calculation of determinamt --- double det(const dmatrix &_a) { assert( _a.cols() == _a.rows() ); typedef dmatrix mlapack; mlapack a = _a; // <- int info; int n = (int)a.cols(); int lda = n; std::vector<int> ipiv(n); #ifdef USE_CLAPACK_INTERFACE info = clapack_dgetrf(CblasColMajor, n, n, &(a(0,0)), lda, &(ipiv[0])); #else dgetrf_(&n, &n, &a(0,0), &lda, &(ipiv[0]), &info); #endif double det=1.0; for(int i=0; i < n-1; i++) if(ipiv[i] != i+1) det = -det; for(int i=0; i < n; i++) det *= a(i,i); assert(info == 0); return det; }
static inline void compute(BM& A, BM& B, const typename BM::value_type& ts = 0.) { BoostMatrixTraits<int>::BoostVecType ipiv(A.size1()); //pivoting //! use adaptor boost::numeric::ublas::symmetric_adaptor<BM, UL> Adapt(A); //std::cout << Adapt.size1() << "\t" << Adapt.size2() << std::endl; boost::numeric::bindings::lapack::sysv(Adapt, ipiv, B); }
void inverse(std::vector<PetscScalar> & A, unsigned int n) { mooseAssert(n >= 1, "MatrixTools::inverse - n (leading dimension) needs to be positive"); mooseAssert(n <= std::numeric_limits<int>::max(), "MatrixTools::inverse - n (leading dimension) too large"); std::vector<PetscBLASInt> ipiv(n); std::vector<PetscScalar> buffer(n * 64); // Following does a LU decomposition of "square matrix A" // upon return "A = P*L*U" if return_value == 0 // Here I use quotes because A is actually an array of length n^2, not a matrix of size n-by-n int return_value; LAPACKgetrf_(reinterpret_cast<int *>(&n), reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &return_value); if (return_value != 0) throw MooseException( return_value < 0 ? "Argument " + Moose::stringify(-return_value) + " was invalid during LU factorization in MatrixTools::inverse." : "Matrix on-diagonal entry " + Moose::stringify(return_value) + " was exactly zero during LU factorization in MatrixTools::inverse."); // get the inverse of A int buffer_size = buffer.size(); #if PETSC_VERSION_LESS_THAN(3, 5, 0) FORTRAN_CALL(dgetri) (reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &buffer[0], &buffer_size, &return_value); #else LAPACKgetri_(reinterpret_cast<int *>(&n), &A[0], reinterpret_cast<int *>(&n), &ipiv[0], &buffer[0], &buffer_size, &return_value); #endif if (return_value != 0) throw MooseException(return_value < 0 ? "Argument " + Moose::stringify(-return_value) + " was invalid during invert in MatrixTools::inverse." : "Matrix on-diagonal entry " + Moose::stringify(return_value) + " was exactly zero during invert in MatrixTools::inverse."); }
void lapack_getrf<T>::operator()( clapack::integer m, clapack::integer n, T* a_ptr) throw(ecomp) { array<clapack::integer> ipiv(m); (*this)(m, n, a_ptr, ipiv.c_ptr()); }
int main(int argc, char** argv) { std::size_t n = 5; ublas::matrix<double> A (n, n); // fill matrix A std::vector<int> ipiv (n); // pivot vector atlas::lu_factor (A, ipiv); // alias for getrf() atlas::lu_invert (A, ipiv); // alias for getri() return 0; }
inline DCMatrix inv(const MatrixT &mat, double regularizationCoeff = 0.0) { BOOST_ASSERT(mat.size1() == mat.size2()); unsigned int n = mat.size1(); DCMatrix inv = mat; // copy data, as it will be modified below if (regularizationCoeff != 0.0) inv += regularizationCoeff * ublas::identity_matrix<double>(n); std::vector<int> ipiv(n); // pivot vector, is first filled by trf, then used by tri to inverse matrix lapack::getrf(inv,ipiv); // inv and ipiv will both be modified lapack::getri(inv,ipiv); // afterwards, "inv" is the inverse return inv; }
void MultiPlasticityLinearSystem::nrStep(const RankTwoTensor & stress, const std::vector<Real> & intnl_old, const std::vector<Real> & intnl, const std::vector<Real> & pm, const RankFourTensor & E_inv, const RankTwoTensor & delta_dp, RankTwoTensor & dstress, std::vector<Real> & dpm, std::vector<Real> & dintnl, const std::vector<bool> & active, std::vector<bool> & deactivated_due_to_ld) { // Calculate RHS and Jacobian std::vector<Real> rhs; calculateRHS(stress, intnl_old, intnl, pm, delta_dp, rhs, active, true, deactivated_due_to_ld); std::vector<std::vector<Real> > jac; calculateJacobian(stress, intnl, pm, E_inv, active, deactivated_due_to_ld, jac); // prepare for LAPACKgesv_ routine provided by PETSc int system_size = rhs.size(); std::vector<double> a(system_size*system_size); // Fill in the a "matrix" by going down columns unsigned ind = 0; for (int col = 0 ; col < system_size ; ++col) for (int row = 0 ; row < system_size ; ++row) a[ind++] = jac[row][col]; int nrhs = 1; std::vector<int> ipiv(system_size); int info; LAPACKgesv_(&system_size, &nrhs, &a[0], &system_size, &ipiv[0], &rhs[0], &system_size, &info); if (info != 0) mooseError("In solving the linear system in a Newton-Raphson process, the PETSC LAPACK gsev routine returned with error code " << info); // Extract the results back to dstress, dpm and dintnl std::vector<bool> active_not_deact(_num_surfaces); for (unsigned surface = 0 ; surface < _num_surfaces ; ++surface) active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]); unsigned int dim = 3; ind = 0; for (unsigned i = 0 ; i < dim ; ++i) for (unsigned j = 0 ; j <= i ; ++j) dstress(i, j) = dstress(j, i) = rhs[ind++]; dpm.assign(_num_surfaces, 0); for (unsigned surface = 0 ; surface < _num_surfaces ; ++surface) if (active_not_deact[surface]) dpm[surface] = rhs[ind++]; dintnl.assign(_num_models, 0); for (unsigned model = 0 ; model < _num_models ; ++model) if (anyActiveSurfaces(model, active_not_deact)) dintnl[model] = rhs[ind++]; mooseAssert(static_cast<int>(ind) == system_size, "Incorrect extracting of changes from NR solution in nrStep"); }
inline DCMatrix invSym(const MatrixT &mat, double regularizationCoeff = 0.0) { BOOST_ASSERT(mat.size1() == mat.size2()); unsigned int n = mat.size1(); DCMatrix inv = mat; // copy data, as it will be modified below if (regularizationCoeff != 0.0) inv += regularizationCoeff * ublas::identity_matrix<double>(n); std::vector<int> ipiv(n); // pivot vector, is first filled by trf, then used by tri to inverse matrix // TODO (9): use "po..." (po=positive definite matrix) instead if "sy..." (symmetric indefinite matrix) to make it faster lapack::sytrf('U',inv,ipiv); // inv and ipiv will both be modified lapack::sytri('U',inv,ipiv); // afterwards, "inv" is the real inverse, but only the upper elements are valid!!! ublas::symmetric_adaptor<DCMatrix, ublas::upper> iSym(inv); return iSym; // copies upper matrix to lower }
/** * Factor A. A is overwritten with the LU decomposition of A. */ int SquareMatrix::factor() { integer n = static_cast<int>(nRows()); int info=0; m_factored = true; ct_dgetrf(n, n, &(*(begin())), static_cast<int>(nRows()), DATA_PTR(ipiv()), info); if (info != 0) { cout << "Singular matrix, info = " << info << endl; throw CanteraError("invert", "DGETRF returned INFO="+int2str(info)); } return 0; }
double lu_determinant(MatrixType a) { // factorize const size_t n = linalg::num_rows(a); std::vector<int> ipiv(n, 0); int info = getrf(a, ipiv); if (info) throw std::runtime_error("getrf failed in lu_determinant" + std::to_string(info)); return getrfdet(a, ipiv); }
inline int gesv (MatrA& a, MatrB& b) { // with 'internal' pivot vector // gesv() errors: // if (info == 0), successful // if (info < 0), the -info argument had an illegal value // -- we will use -101 if allocation fails // if (info > 0), U(i-1,i-1) is exactly zero int info = -101; traits::detail::array<int> ipiv (traits::matrix_size1 (a)); if (ipiv.valid()) info = gesv (a, ipiv, b); return info; }
void gaussj(matrix_t & a, matrix_t & b) { int i,icol,irow,j,k,l,ll; double big,dum,pivinv; int n=a.size(); int m=b[0].size(); vector_t indxc(n),indxr(n),ipiv(n); for (j=0;j<n;j++) ipiv[j]=0; for (i=0;i<n;i++) { big=0.0; for (j=0;j<n;j++) if (ipiv[j] != 1) for (k=0;k<n;k++) { if (ipiv[k] == 0) { if (fabs(a[j][k]) >= big) { big=fabs(a[j][k]); irow=j; icol=k; } } } ++(ipiv[icol]); if (irow != icol) { for (l=0;l<n;l++) SWAP(a[irow][l],a[icol][l]); for (l=0;l<m;l++) SWAP(b[irow][l],b[icol][l]); } indxr[i]=irow; indxc[i]=icol; if (a[icol][icol] == 0.0) error("gaussj: Singular Matrix"); pivinv=1.0/a[icol][icol]; a[icol][icol]=1.0; for (l=0;l<n;l++) a[icol][l] *= pivinv; for (l=0;l<m;l++) b[icol][l] *= pivinv; for (ll=0;ll<n;ll++) if (ll != icol) { dum=a[ll][icol]; a[ll][icol]=0.0; for (l=0;l<n;l++) a[ll][l] -= a[icol][l]*dum; for (l=0;l<m;l++) b[ll][l] -= b[icol][l]*dum; } } for (l=n-1;l>=0;l--) { if (indxr[l] != indxc[l]) for (k=0;k<n;k++) SWAP(a[k][(int)indxr[l]],a[k][(int)indxc[l]]); } }
int BandMatrix::solve(int n, doublereal* b) { int info = 0; if (!m_factored) info = factor(); if (info == 0) ct_dgbtrs(ctlapack::NoTranspose, columns(), nSubDiagonals(), nSuperDiagonals(), 1, DATA_PTR(ludata), ldim(), DATA_PTR(ipiv()), b, columns(), info); // error handling if (info != 0) { ofstream fout("bandmatrix.csv"); fout << *this << endl; fout.close(); } return info; }
void test_getrf_getrs(matrix_type& lu, matrix_type& x) { typedef typename matrix_type::value_type value_type ; numerics::matrix< value_type > a( lu ) ; // tmp to verify result numerics::matrix< value_type > b( x ) ; // tmp to verify result std::vector< int > ipiv( x.size1() ) ; boost::numeric::bindings::lapack::getrf( lu, ipiv ) ; matrix_type ia( lu ); boost::numeric::bindings::lapack::getrs( 'N', lu, ipiv, x ) ; boost::numeric::bindings::lapack::getri( ia, ipiv ) ; std::cout << prod(a,x) - b << std::endl ; std::cout << prod(a,ia) << std::endl ; }
void InterfaceRBF::updateRBF(void) { int i,j,n; n = centers.size(); TNT::Matrix<double> A(n + 4, n + 4); TNT::Vector<int> ipiv(n + 4); TNT::Vector<double> h(n + 4); for(i=0; i < n; i++) { for(j=0; j < n; j++) { // A[i][j] = (*this)[j].phi(convert((*this)[i].c)); A[i][j] = _phiFunction->phi(centers[j].c - centers[i].c); } A[n][i] = 1.0; A[i][n] = 1.0; for(j=0; j < 3; j++) { A[n + 1 + j][i] = centers[i].c[j]; A[i][n + 1 + j] = centers[i].c[j]; } } for(i = 0; i < n; i++) h[i] = centers[i].h; h[n] = 0.0; h[n + 1] = 0.0; h[n + 2] = 0.0; h[n + 3] = 0.0; int singularTest = TNT::LU_factor(A,ipiv); // if the matrix is singular, this call will break the program [TK 3.05] if(singularTest != 0) return; // the system is singular, and cannot be solved. That would crash the program immediately. TNT::LU_solve(A,ipiv,h); for(i = 0; i < n; i++) centers[i].w = h[i]; m_p[0] = h[n]; m_p[1] = h[n+1]; m_p[2] = h[n+2]; m_p[3] = h[n+3]; }
VectorType lu_solve(MatrixType a, const VectorType& y) { const size_t n = linalg::size(y); MatrixType y1(n, 1, 0); column(y1, 0) = y; std::vector<int> ipiv(n, 0); int info = getrf(a, ipiv); if (info != 0) { throw std::runtime_error("getrf failed in lu_solve " + std::to_string(info)); } getrs(a, ipiv, y1); return linalg::column(y1, 0); }
int BandMatrix::factor() { int info=0; ludata = data; ct_dgbtrf(nRows(), nColumns(), nSubDiagonals(), nSuperDiagonals(), ludata.data(), ldim(), ipiv().data(), info); // if info = 0, LU decomp succeeded. if (info == 0) { m_factored = true; } else { m_factored = false; ofstream fout("bandmatrix.csv"); fout << *this << endl; } return info; }
/** * Perform an LU decomposition. LAPACK routine DGBTRF is used. * The factorization is saved in ludata. */ int BandMatrix::factor() { int info=0; copy(data.begin(), data.end(), ludata.begin()); ct_dgbtrf(rows(), columns(), nSubDiagonals(), nSuperDiagonals(), DATA_PTR(ludata), ldim(), DATA_PTR(ipiv()), info); // if info = 0, LU decomp succeeded. if (info == 0) { m_factored = true; } else { m_factored = false; ofstream fout("bandmatrix.csv"); fout << *this << endl; fout.close(); } return info; }
int sipg_sem_1d<FLOAT_TYPE>::solve() { stiffness_matrix_generation.start(); // start timer compute_stiffness_matrix(); stiffness_matrix_generation.stop(); // stop timer compute_rhs_vector(); #ifdef USE_LAPACK std::vector<int> ipiv(_vec_size,0); // pivot _u = _rhs; linear_system_solution.start(); // start timer int info = lapacke_gesv( LAPACK_ROW_MAJOR, _vec_size, 1, _A.data(), _vec_size, ipiv.data(), _u.data(), 1 ); #else ConjugateGradient<Eigen::SparseMatrix<FLOAT_TYPE> > cg; cg.compute(_A); _u = cg.solve(_rhs); #endif linear_system_solution.stop(); // stop timer compute_err_norms(); return info; }
/* * Factor A. A is overwritten with the LU decomposition of A. */ int SquareMatrix::factor() { if (useQR_) { return factorQR(); } a1norm_ = ct_dlange('1', m_nrows, m_nrows, &(*(begin())), m_nrows, DATA_PTR(work)); integer n = static_cast<int>(nRows()); int info=0; m_factored = 1; ct_dgetrf(n, n, &(*(begin())), static_cast<int>(nRows()), DATA_PTR(ipiv()), info); if (info != 0) { if (m_printLevel) { writelogf("SquareMatrix::factor(): DGETRS returned INFO = %d\n", info); } if (! m_useReturnErrorCode) { throw CELapackError("SquareMatrix::factor()", "DGETRS returned INFO = "+int2str(info)); } } return info; }
// DGESV computes the solution to a real system of linear // equations, A*x = b, where A is an N-by-N matrix, and // x and b are N-by-1 vectors. The LU decomposition // with partial pivoting and row interchanges is used to // factor A as A = P*L*U, where P is a permutation matrix, // L is unit lower triangular, and U is upper triangular. // The system is solved using this factored form of A. //--------------------------------------------------------- void umSOLVE(const DMat& mat, const DVec& b, DVec& x) //--------------------------------------------------------- { // Work with copies of input arrays. DMat A(mat); x = b; int NRHS = 1; int LDA = A.num_rows(); int rows = A.num_rows(); int cols = A.num_cols(); int info = 0; if (rows != cols) { umERROR("umSOLVE(DMat, DVec)", "Matrix A (%d,%d) is not square.\n" "For a Least-Squares solution, see umSOLVE_LS(A,B).", rows, cols); } if (rows < 1) { umLOG(1, "Empty system passed into umSOLVE().\n"); return; } IVec ipiv(rows, 0); GESV (rows, NRHS, A.data(), LDA, ipiv.data(), x.data(), rows, info); if (info < 0) { x = 0.0; umERROR("umSOLVE(DMat&, DVec&)", "Error in input argument (%d)\nNo solution computed.", -info); } else if (info > 0) { x = 0.0; umERROR("umSOLVE(DMat&, DVec&)", "\nINFO = %d. U(%d,%d) was exactly zero." "\nThe factorization has been completed, but the factor U is " "\nexactly singular, so the solution could not be computed.", info, info, info); } }
MatrixType lu_invert(MatrixType a) { const size_t n = linalg::num_rows(a); std::vector<int> ipiv(n, 0); int info = getrf(a, ipiv); if (info) { throw std::runtime_error("getrf failed in lu_invert " + std::to_string(info)); } info = getri(a, ipiv); if (info != 0) { throw std::runtime_error("getri failed in lu_invert " + std::to_string(info)); } return a; }