SimpleMatrix::SimpleMatrix(const SiconosMatrix &m): SiconosMatrix(m.getNum()), _isPLUFactorized(), _isQRFactorized(false), _isPLUInversed(false) { // num is set in SiconosMatrix constructor with m.getNum() ... must be changed if m is Block unsigned int numM = m.getNum(); _isPLUFactorized= m.isPLUFactorized(); _isPLUInversed= m.isPLUInversed(); if (m.ipiv()) _ipiv.reset(new VInt(*(m.ipiv()))); if (numM == 0) // ie if m is Block, this matrix is set to a dense. { const BlockMatrix& mB = static_cast<const BlockMatrix&>(m); num = 1; // get number of blocks in a row/col of m. mat.Dense = new DenseMat(m.size(0), m.size(1)); ConstBlocksIterator1 it; ConstBlocksIterator2 it2; unsigned int posRow = 0; unsigned int posCol = 0; for (it = mB._mat->begin1(); it != mB._mat->end1(); ++it) { for (it2 = it.begin(); it2 != it.end(); ++it2) { setBlock(posRow, posCol, **it2); posCol += (*it2)->size(1); } posRow += (*it)->size(0); posCol = 0; } } else if (num == 1) { mat.Dense = new DenseMat(m.size(0), m.size(1)); noalias(*mat.Dense) = (*m.dense()); } else if (num == 2) mat.Triang = new TriangMat(*m.triang()); else if (num == 3) mat.Sym = new SymMat(*m.sym()); else if (num == 4) mat.Sparse = new SparseMat(*m.sparse()); else if (num == 5) mat.Banded = new BandedMat(*m.banded()); else if (num == 6) mat.Zero = new ZeroMat(m.size(0), m.size(1)); else // if(num == 7) mat.Identity = new IdentityMat(m.size(0), m.size(1)); }
SimpleMatrix& SimpleMatrix::operator = (const SiconosMatrix& m) { if (&m == this) return *this; // auto-assignment. unsigned int numM = m.getNum(); if (size(0) != m.size(0) || size(1) != m.size(1)) { resize(m.size(0), m.size(1)); } // SiconosMatrixException::selfThrow("SimpleMatrix::operator = failed. Inconsistent sizes."); if (numM == 6) // m = zero matrix { zero(); return *this; } if (numM == 7) // m = identity matrix { eye(); return *this; } if (numM == 0) // if m is a BlockMatrix { const BlockMatrix& mB = static_cast<const BlockMatrix&>(m); ConstBlocksIterator1 it; ConstBlocksIterator2 it2; unsigned int posRow = 0; unsigned int posCol = 0; for (it = mB._mat->begin1(); it != mB._mat->end1(); ++it) { for (it2 = it.begin(); it2 != it.end(); ++it2) { setBlock(posRow, posCol, **it2); posCol += (*it2)->size(1); } posRow += (*it)->size(0); posCol = 0; } } else { switch (num) { case 1: switch (numM) { case 1: noalias(*(mat.Dense)) = *m.dense(); break; case 2: noalias(*(mat.Dense)) = *m.triang(); break; case 3: noalias(*(mat.Dense)) = *m.sym(); break; case 4: noalias(*(mat.Dense)) = *m.sparse(); break; case 5: noalias(*(mat.Dense)) = *m.banded(); break; default: SiconosMatrixException::selfThrow("SimpleMatrix::op= (const SimpleMatrix): invalid type of matrix"); break; } break; case 2: switch (numM) { case 2: noalias(*(mat.Triang)) = *m.triang(); break; default: SiconosMatrixException::selfThrow("SimpleMatrix::assignment of a bad type of matrix into a triangular one."); break; } break; case 3: if (numM == 3) noalias(*(mat.Sym)) = *m.sym(); else SiconosMatrixException::selfThrow("SimpleMatrix::bad assignment of matrix (symetric one = dense or ...)"); break; case 4: switch (numM) { case 2: noalias(*(mat.Sparse)) = *m.triang(); break; case 3: noalias(*(mat.Sparse)) = *m.sym(); break; case 4: noalias(*(mat.Sparse)) = *m.sparse(); break; case 5: noalias(*(mat.Sparse)) = *m.banded(); break; default: SiconosMatrixException::selfThrow("SimpleMatrix::op= (const SimpleMatrix): invalid type of matrix"); break; } break; case 5: switch (numM) { case 5: noalias(*(mat.Banded)) = *m.banded(); break; default: SiconosMatrixException::selfThrow("SimpleMatrix::op= (const SimpleMatrix): invalid type of matrix"); break; } break; default: SiconosMatrixException::selfThrow("SimpleMatrix::op= (const SimpleMatrix): invalid type of matrix"); break; } resetLU(); } return *this; }