void expm(SiconosMatrix& A, SiconosMatrix& Exp, bool computeAndAdd) { // Implemented only for dense matrices. // Note FP : Maybe it works for others but it has not been // tested here --> to be done // Do not work with sparse. A.resetLU(); Exp.resetLU(); assert(Exp.num() == 1 || A.num() == 1); if(computeAndAdd) *Exp.dense() += expm_pad(*A.dense()); else *Exp.dense() = expm_pad(*A.dense()); }
void SimpleMatrix::trans(const SiconosMatrix &m) { if (m.isBlock()) SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, not yet implemented for m being a BlockMatrix."); if (&m == this) trans();//SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, m = this, use this->trans()."); else { unsigned int numM = m.num(); switch (numM) { case 1: if (_num != 1) SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, try to transpose a dense matrix into another type."); noalias(*mat.Dense) = ublas::trans(*m.dense()); break; case 2: if (_num != 1) SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, try to transpose a triangular matrix into a non-dense one."); noalias(*mat.Dense) = ublas::trans(*m.triang()); break; case 3: *this = m; break; case 4: if (_num == 1) noalias(*mat.Dense) = ublas::trans(*m.sparse()); else if (_num == 4) noalias(*mat.Sparse) = ublas::trans(*m.sparse()); else SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, try to transpose a sparse matrix into a forbidden type (not dense nor sparse)."); break; case 5: if (_num == 1) noalias(*mat.Dense) = ublas::trans(*m.banded()); else if (_num == 5) noalias(*mat.Banded) = ublas::trans(*m.banded()); else SiconosMatrixException::selfThrow("SimpleMatrix::trans(m) failed, try to transpose a banded matrix into a forbidden type (not dense nor banded)."); break; case 6: *this = m; break; case 7: *this = m; } // unsigned int tmp = _dimRow; // _dimRow = _dimCol; // _dimCol = tmp; resetLU(); } }
void SimpleMatrix::PLUForwardBackwardInPlace(SiconosMatrix &B) { if (B.isBlock()) SiconosMatrixException::selfThrow("SimpleMatrix PLUForwardBackwardInPlace(B) failed at solving Ax = B. Not yet implemented for a BlockMatrix B."); int info = 0; if (_num == 1) { if (!_isPLUFactorized) // call gesv => LU-factorize+solve { // solve system: if (!_ipiv) _ipiv.reset(new VInt(size(0))); else _ipiv->resize(size(0)); info = lapack::gesv(*mat.Dense, *_ipiv, *(B.dense())); _isPLUFactorized = true; /* ublas::vector<double> S(std::max(size(0),size(1))); ublas::matrix<double, ublas::column_major> U(size(0),size(1)); ublas::matrix<double, ublas::column_major> VT(size(0),size(1)); int ierr = lapack::gesdd(*mat.Dense, S, U, VT); printf("info = %d, ierr = %d, emax = %f, emin = %f , cond = %f\n",info,ierr,S(0),S(2),S(0)/S(2)); */ // B now contains solution: } else // call getrs: only solve using previous lu-factorization if (B.num() == 1) info = lapack::getrs(*mat.Dense, *_ipiv, *(B.dense())); else SiconosMatrixException::selfThrow(" SimpleMatrix::PLUInverseInPlace: only implemented for dense matrices in RHS."); } else { if (!_isPLUFactorized) // call first PLUFactorizationInPlace { PLUFactorizationInPlace(); } // and then solve if (B.num() == 1) { inplace_solve(*sparse(), *(B.dense()), ublas::lower_tag()); inplace_solve(ublas::trans(*sparse()), *(B.dense()), ublas::upper_tag()); } else if (B.num() == 4) { inplace_solve(*sparse(), *(B.sparse()), ublas::lower_tag()); inplace_solve(ublas::trans(*sparse()), *(B.sparse()), ublas::upper_tag()); } else SiconosMatrixException::selfThrow(" SimpleMatrix::PLUInverseInPlace: only implemented for dense ans sparse matrices in RHS."); info = 0 ; } // SiconosMatrixException::selfThrow(" SimpleMatrix::PLUInverseInPlace: only implemented for dense matrices."); if (info != 0) SiconosMatrixException::selfThrow("SimpleMatrix::PLUForwardBackwardInPlace failed."); }
void SimpleMatrix::addBlock(unsigned int row_min, unsigned int col_min, const SiconosMatrix& m) { // add m to current matrix elements, starting from row row_min and column col_min, to the values of the matrix m. // m may be a BlockMatrix. if (_num == 6 || _num == 7) SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(pos,..., m) forbidden for zero or identity matrix."); if (&m == this) SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(pos,..., m): m = this."); if (row_min >= size(0)) SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(row,col): row is out of range"); if (col_min >= size(1)) SiconosMatrixException::selfThrow("SimpleMatrix::addBloc(row,col)k: col is out of range"); unsigned int row_max, col_max; row_max = m.size(0) + row_min; col_max = m.size(1) + col_min; if (row_max > size(0)) SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(row,col,m): m.row + row is out of range."); if (col_max > size(1)) SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(row,col,m): m.col + col is out of range."); unsigned int numM = m.num(); if (numM == 0) // if m is a block matrix ... { const BlockMatrix& mB = static_cast<const BlockMatrix&>(m); BlocksMat::const_iterator1 it; BlocksMat::const_iterator2 it2; unsigned int posRow = row_min; unsigned int posCol = col_min; for (it = mB._mat->begin1(); it != mB._mat->end1(); ++it) { for (it2 = it.begin(); it2 != it.end(); ++it2) { addBlock(posRow, posCol, **it2); posCol += (*it2)->size(1); } posRow += (*it)->size(0); posCol = 0; } } else if (numM == 6) // if m = 0 { // nothing to do ! } else // if m is a SimpleMatrix { if (_num == 1) { switch (numM) { case 1: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.dense()); break; case 2: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.triang()); break; case 3: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.sym()); break; case 4: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.sparse()); break; case 5: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.banded()); break; case 7: noalias(ublas::subrange(*mat.Dense, row_min, row_max, col_min, col_max)) += *(m.identity()); break; default: SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(...,m): wrong matrix type for m."); break; } } else SiconosMatrixException::selfThrow("SimpleMatrix::addBlock(...): implemeted only for dense matrices."); resetLU(); } }