//===================== // matrices comparison //===================== bool isComparableTo(const SiconosMatrix& m1, const SiconosMatrix& m2) { // return: // - true if one of the matrices is a Simple and if they have the same dimensions. // - true if both are block but with blocks which are facing each other of the same size. // - false in other cases if ((!m1.isBlock() || !m2.isBlock()) && (m1.size(0) == m2.size(0)) && (m1.size(1) == m2.size(1))) return true; const SP::Index I1R = m1.tabRow(); const SP::Index I2R = m2.tabRow(); const SP::Index I1C = m1.tabCol(); const SP::Index I2C = m2.tabCol(); return ((*I1R == *I2R) && (*I1C == *I2C)); }
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::SolveByLeastSquares(SiconosMatrix &B) { if (B.isBlock()) SiconosMatrixException::selfThrow("SimpleMatrix::SolveByLeastSquares(Siconos Matrix &B) failed. Not yet implemented for M being a BlockMatrix."); int info = 0; #ifdef USE_OPTIMAL_WORKSPACE info += lapack::gels(*mat.Dense, *(B.dense()), lapack::optimal_workspace()); #endif #ifdef USE_MINIMAL_WORKSPACE info += lapack::gels(*mat.Dense, *(B.dense()), lapack::minimal_workspace()); #endif if (info != 0) SiconosMatrixException::selfThrow("SimpleMatrix::SolveByLeastSquares failed."); }
void private_addprod(const SiconosMatrix& A, unsigned int startRow, unsigned int startCol, const BlockVector& x, SiconosVector& y) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); assert(!A.isBlock() && "private_addprod(A,start,x,y) error: not yet implemented for block matrix."); VectorOfVectors::const_iterator it; unsigned int startColBis = startCol; for (it = x.begin(); it != x.end(); ++it) { private_addprod(A, startRow, startColBis, **it, y); startColBis += (*it)->size(); } }
void private_addprod(const SiconosMatrix& A, unsigned startRow, unsigned int startCol, const SiconosVector& x, SiconosVector& y) { assert(!(A.isPLUFactorized()) && "A is PLUFactorized in prod !!"); assert(!A.isBlock() && "private_addprod(A,start,x,y) error: not yet implemented for block matrix."); // we take a submatrix subA of A, starting from row startRow to row (startRow+sizeY) and between columns startCol and (startCol+sizeX). // Then computation of y = subA*x + y. unsigned int numA = A.getNum(); unsigned int numY = y.getNum(); unsigned int numX = x.getNum(); unsigned int sizeX = x.size(); unsigned int sizeY = y.size(); assert(numX == numY && "private_addprod(A,start,x,y) error: not yet implemented for x and y of different types."); if (numY == 1 && numX == 1) { assert(y.dense() != x.dense()); if (numA == 1) noalias(*y.dense()) += prod(ublas::subrange(*A.dense(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 2) noalias(*y.dense()) += prod(ublas::subrange(*A.triang(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 3) noalias(*y.dense()) += prod(ublas::subrange(*A.sym(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else if (numA == 4) noalias(*y.dense()) += prod(ublas::subrange(*A.sparse(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); else //if(numA==5) noalias(*y.dense()) += prod(ublas::subrange(*A.banded(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.dense()); } else // x and y sparse { if (numA == 4) *y.sparse() += prod(ublas::subrange(*A.sparse(), startRow, startRow + sizeY, startCol, startCol + sizeX), *x.sparse()); else SiconosMatrixException::selfThrow("private_addprod(A,start,x,y) error: not yet implemented for x, y sparse and A not sparse."); } }
bool write(const std::string& fileName, const std::string& mode, const SiconosMatrix& m, const std::string& outputType) { // Open file and various checks std::ofstream outfile; if (mode == "ascii") outfile.open(fileName.c_str(), std::ofstream::out); else if (mode == "binary") outfile.open(fileName.c_str(), std::ofstream::binary); else SiconosMatrixException::selfThrow("ioMatrix::write Incorrect mode for writing"); if (!outfile.good()) SiconosMatrixException::selfThrow("ioMatrix:: write error : Fail to open \"" + fileName + "\""); if (m.isBlock()) SiconosMatrixException::selfThrow("ioMatrix:: write error : not yet implemented for BlockMatrix"); outfile.precision(15); outfile.setf(std::ios::scientific); // Writing if (outputType != "noDim") outfile << m.size(0) << " " << m.size(1) << std::endl; if (m.getNum() == 1) { // DenseMat * p = m.dense(); DenseMat::iterator1 row; DenseMat::iterator2 col; double tmp; for (unsigned int i = 0; i < m.size(0); i++) { for (unsigned int j = 0; j < m.size(1); j++) { tmp = m(i, j); if (fabs(tmp) < std::numeric_limits<double>::min()) tmp = 0.0; outfile << tmp << " " ; assert(outfile.good()); } outfile << std::endl; } } else if (m.getNum() == 2) { TriangMat * p = m.triang(); TriangMat::iterator1 row; for (row = p->begin1(); row != p->end1() ; ++row) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(outfile, " ")); outfile << std::endl; } } else if (m.getNum() == 3) { SymMat * p = m.sym(); SymMat::iterator1 row; for (row = p->begin1(); row != p->end1() ; ++row) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(outfile, " ")); outfile << std::endl; } } else if (m.getNum() == 4) { SparseMat * p = m.sparse(); SparseMat::iterator1 row; for (row = p->begin1(); row != p->end1() ; ++row) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(outfile, " ")); outfile << std::endl; } } else { BandedMat * p = m.banded(); BandedMat::iterator1 row; for (row = p->begin1(); row != p->end1() ; ++row) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(outfile, " ")); outfile << std::endl; } } outfile.close(); return true; }
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."); }