matrix_t matrix_t::solve(matrix_t const &rhs) const { stack::fe_asserter dummy{}; // it appears as if dgesv works only for square matrices Oo // --> if the matrix was rectangular, then they system would be over/under determined // and we would need least squares instead (LAPACKE_dgels) stack_assert(get_rows() == get_cols()); stack_assert(this->get_rows() == rhs.get_rows()); // TODO assert that this matrix is not singular matrix_t A = this->clone(); // will be overwritten by LU factorization matrix_t b = rhs.clone(); // thes solution is overwritten in b vector_ll_t ipiv{A.get_rows()}; stack_assert(0 == LAPACKE_dgesv(LAPACK_COL_MAJOR, A.get_rows(), rhs.get_cols()/*nrhs*/, A.get_data(), A.ld(), ipiv.get_data(), b.get_data(), b.ld())); return b; }
matrix_t operator+(matrix_t const & X, diag_t const & D) { stack::fe_asserter fe{}; stack_assert(X.get_rows() == D.get_rows()); stack_assert(X.get_cols() == D.get_cols()); matrix_t ret = X.clone(); vector_t Xdiag = vector_t{ ret.get_data(), ret.get_rows()/*it's a square matrix*/, ret.get_rows() + 1, // diagonal entries of a square matrix }; Xdiag += diag_clone(D); return ret; }
// mult X * D matrix_t diag_t::left_mult(matrix_t const &X) const { stack::fe_asserter fe{}; stack_assert(diagonal.get_len() == X.get_cols()); matrix_t ret = X.clone(); if(ret.get_rows() < ret.get_cols()) for(size_t r = 0; r < ret.get_rows(); r++) ret[r] *= diagonal; else for(size_t c = 0; c < ret.get_cols(); c++) ret.get_col(c) *= diagonal[c]; return ret; }