2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
15 #include <Eigen/Sparse>
22 #include "tostring_common.hxx"
24 #include "matrixiterator.hxx"
25 #include "types_subtraction.hxx"
26 #include "types_addition.hxx"
27 #include "types_multiplication.hxx"
28 #include "configvariable.hxx"
29 #include "scilabWrite.hxx"
31 #include "sparseOp.hxx"
35 #include "elem_common.h"
40 /* used for debuging output
42 template<typename Os, typename In, typename Sz> Os& writeData(wchar_t const* title, In beg, Sz n, Os& os)
45 /* TODO: use tostring_common (with a kind of std::boolalpha for boolean output)
47 mycopy_n(beg, n, std::ostream_iterator<typename std::iterator_traits<In>::value_type, char>(os, L" "));
54 Printer (int precision) : p(precision)
58 std::wstring emptyName( /* */) const
64 std::wstring operator()(T const& t) const
67 std::wostringstream ostr;
76 std::wstring Printer::operator()(bool const& b) const
89 std::wstring Printer::operator()(double const& d) const
91 std::wostringstream ostr;
93 getDoubleFormat(d, &df);
94 addDoubleValue(&ostr, d, &df);
99 std::wstring Printer::operator()(std::complex<double > const& c) const
101 std::wostringstream ostr;
103 DoubleFormat dfR, dfI;
104 getComplexFormat(c.real(), c.imag(), &iLen, &dfR, &dfI);
105 addDoubleComplexValue(&ostr, c.real(), c.imag(), iLen, &dfR, &dfI);
110 std::wstring Printer::emptyName<bool>() const
116 template<typename T> std::wstring toString(T const& m, int precision)
118 std::wostringstream ostr;
122 getSignedIntFormat(m.rows(), &iWidthRows);
123 getSignedIntFormat(m.cols(), &iWidthCols);
126 addUnsignedIntValue<unsigned long long>(&ostr, m.rows(), iWidthRows);
128 addUnsignedIntValue<unsigned long long>(&ostr, m.cols(), iWidthCols);
131 Printer p(precision);
134 ostr << ( p.emptyName<typename Eigen::internal::traits<T>::Scalar>());
136 ostr << L" sparse matrix\n\n";
138 const typename Eigen::internal::traits<T>::Index* pIColPos = m.innerIndexPtr();
139 const typename Eigen::internal::traits<T>::Index* pINbItemByRow = m.outerIndexPtr();
143 for (size_t j = 1 ; j < m.rows() + 1 ; j++)
145 for (size_t i = pINbItemByRow[j - 1] ; i < pINbItemByRow[j] ; i++)
148 addUnsignedIntValue<unsigned long long>(&ostr, (int)j, iWidthRows);
150 addUnsignedIntValue<unsigned long long>(&ostr, pIColPos[iPos] + 1, iWidthCols);
151 ostr << L")\t" << p(m.valuePtr()[iPos]) << std::endl;
160 /** utility function to compare two Eigen::Sparse matrices to equality
162 template<typename T> bool equal(T const& s1, T const& s2)
165 // only compares elts when both inner iterators are "defined", so we assert that we compared all the non zero values
166 // i.e. the inner iterators where defined for the same values
167 std::size_t nbElts(0);
169 for (int k = 0; res && k != s1.outerSize(); ++k)
171 for (typename T::InnerIterator it1(s1, k), it2(s2, k); res && it1 && it2 ; ++it1, ++it2, ++nbElts)
173 res = (it1.value() == it2.value()
174 && it1.row() == it2.row()
175 && it1.col() == it2.col());
178 return res && (nbElts == s1.nonZeros()) && (nbElts == s2.nonZeros());
181 utility function to set non zero values of an Eigen::Sparse matrix to a fixed values
182 @param s : sparse matrix to modify
183 @param v : value to set (default to 1.)
185 template<typename T> bool setNonZero(T& s, typename Eigen::internal::traits<T>::Scalar v = 1.)
187 for (typename Eigen::internal::traits<T>::Index j = 0; j < s.outerSize(); ++j)
189 for (typename T::InnerIterator it(s, j); it; ++it)
199 template<typename Src, typename Sp>
200 void doAppend(Src SPARSE_CONST& src, int r, int c, Sp& dest)
202 typedef typename Eigen::internal::traits<Sp>::Scalar data_t;
203 mycopy_n(makeMatrixIterator<data_t>(src, makeNonZerosIterator(src)), nonZeros(src)
204 , makeMatrixIterator<data_t>(dest, makeTranslatedIterator(makeNonZerosIterator(src), Coords2D(r, c))));
207 template<typename Scalar1, typename Scalar2>
208 void doAppend(Eigen::SparseMatrix<Scalar1, Eigen::RowMajor> SPARSE_CONST& src, int r, int c, Eigen::SparseMatrix<Scalar2, Eigen::RowMajor>& dest)
210 typedef typename Eigen::SparseMatrix<Scalar1, Eigen::RowMajor>::InnerIterator srcIt_t;
211 for (std::size_t k = 0; k != src.outerSize(); ++k)
213 for (srcIt_t it(src, (int)k); it; ++it)
215 dest.insert( it.row() + r, it.col() + c) = it.value();
220 Sp is an Eigen::SparseMatrix
222 template<typename Sp, typename M>
223 void cwiseInPlaceProduct(Sp& sp, M SPARSE_CONST& m)
225 // should be a transform_n() over makeNonZerosIterator(src)
226 for (std::size_t k = 0; k != sp.outerSize(); ++k)
228 for (typename Sp::InnerIterator it(sp, k); it; ++it)
230 it.valueRef() *= get<typename Eigen::internal::traits<Sp>::Scalar >(m, it.row(), it.col());
239 template<typename T, typename Arg>
240 T* create_new(Arg const& a)
246 Double* create_new(double const& d)
248 Double* res(new Double(1, 1, false));
254 Double* create_new(std::complex<double>const& c)
256 Double* res(new Double(1, 1, true));
257 res->set(0, 0, c.real());
258 res->setImg(0, 0, c.imag());
263 Double* create_new(Sparse const& s)
265 Sparse& cs(const_cast<Sparse&>(s)); // inherited member functions are not const-correct
266 Double* res(new Double(cs.getRows(), cs.getCols(), cs.isComplex()));
267 const_cast<Sparse&>(s).fill(*res);
278 Sparse::Sparse( Sparse const& src) : GenericType(src)
279 , matrixReal(src.matrixReal ? new RealSparse_t(*src.matrixReal) : 0)
280 , matrixCplx(src.matrixCplx ? new CplxSparse_t(*src.matrixCplx) : 0)
284 m_piDims[0] = const_cast<Sparse*>(&src)->getRows();
285 m_piDims[1] = const_cast<Sparse*>(&src)->getCols();
288 Sparse::Sparse(int _iRows, int _iCols, bool cplx)
289 : matrixReal(cplx ? 0 : new RealSparse_t(_iRows, _iCols))
290 , matrixCplx(cplx ? new CplxSparse_t(_iRows, _iCols) : 0)
294 m_iSize = _iRows * _iCols;
296 m_piDims[0] = _iRows;
297 m_piDims[1] = _iCols;
300 Sparse::Sparse(Double SPARSE_CONST& src)
302 create(src.getRows(), src.getCols(), src, RowWiseFullIterator(src.getRows(), src.getCols()), src.getSize());
305 Sparse::Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx)
307 double SPARSE_CONST* const endOfRow(idx.getReal() + idx.getRows());
308 create( static_cast<int>(*std::max_element(idx.getReal(), endOfRow))
309 , static_cast<int>(*std::max_element(endOfRow, endOfRow + idx.getRows()))
310 , src, makeIteratorFromVar(idx), idx.getSize() / 2 );
313 Sparse::Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims)
315 create(static_cast<int>(dims.getReal(0, 0))
316 , static_cast<int>(dims.getReal(0, 1))
317 , src, makeIteratorFromVar(idx), idx.getSize() / 2);
320 Sparse::Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp): matrixReal(realSp), matrixCplx(cplxSp)
324 m_iCols = realSp->cols();
325 m_iRows = realSp->rows();
329 m_iCols = cplxSp->cols();
330 m_iRows = cplxSp->rows();
332 m_iSize = m_iCols * m_iRows;
334 m_piDims[0] = m_iRows;
335 m_piDims[1] = m_iCols;
338 Sparse::Sparse(Double SPARSE_CONST& xadj, Double SPARSE_CONST& adjncy, Double SPARSE_CONST& src, std::size_t r, std::size_t c)
340 Adjacency a(xadj.getReal(), adjncy.getReal());
341 create(static_cast<int>(r), static_cast<int>(c), src, makeIteratorFromVar(a), src.getSize());
344 template<typename DestIter>
345 void Sparse::create(int rows, int cols, Double SPARSE_CONST& src, DestIter o, std::size_t n)
349 m_iSize = cols * rows;
351 m_piDims[0] = m_iRows;
352 m_piDims[1] = m_iCols;
357 matrixCplx = new CplxSparse_t( rows, cols);
358 matrixCplx->reserve((int)n);
359 mycopy_n(makeMatrixIterator<std::complex<double> >(src, RowWiseFullIterator(src.getRows(), src.getCols())), n, makeMatrixIterator<std::complex<double> >(*matrixCplx, o));
363 matrixReal = new RealSparse_t(rows, cols);
364 matrixReal->reserve((int)n);
366 mycopy_n(makeMatrixIterator<double >(src, RowWiseFullIterator(src.getRows(), src.getCols())), n
367 , makeMatrixIterator<double>(*matrixReal, o));
372 void Sparse::fill(Double& dest, int r, int c) SPARSE_CONST
374 Sparse & cthis(const_cast<Sparse&>(*this));
377 mycopy_n(makeMatrixIterator<std::complex<double> >(*matrixCplx, RowWiseFullIterator(cthis.getRows(), cthis.getCols())), cthis.getSize()
378 , makeMatrixIterator<std::complex<double> >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
382 mycopy_n( makeMatrixIterator<double>(*matrixReal, RowWiseFullIterator(cthis.getRows(), cthis.getCols())), cthis.getSize()
383 , makeMatrixIterator<double >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
387 bool Sparse::set(int _iRows, int _iCols, std::complex<double> v, bool _bFinalize)
389 if (_iRows >= getRows() || _iCols >= getCols())
396 matrixReal->coeffRef(_iRows, _iCols) = v.real();
400 matrixCplx->coeffRef(_iRows, _iCols) = v;
410 bool Sparse::set(int _iRows, int _iCols, double _dblReal, bool _bFinalize)
412 if (_iRows >= getRows() || _iCols >= getCols())
419 matrixReal->coeffRef(_iRows, _iCols) = _dblReal;
423 matrixCplx->coeffRef(_iRows, _iCols) = std::complex<double>(_dblReal, 0);
434 void Sparse::finalize()
438 matrixCplx->prune(&keepForSparse<std::complex<double> >);
439 matrixCplx->finalize();
443 matrixReal->prune(&keepForSparse<double>);
444 matrixReal->finalize();
449 bool Sparse::neg(InternalType *& out)
451 SparseBool * _out = new SparseBool(getRows(), getCols());
452 type_traits::neg(getRows(), getCols(), matrixReal, _out->matrixBool);
459 bool Sparse::isComplex() const
461 return static_cast<bool>(matrixCplx != NULL);
464 // TODO: should have both a bounds checking and a non-checking interface to elt access
465 double Sparse::get(int _iRows, int _iCols) const
467 return getReal(_iRows, _iCols);
470 double Sparse::getReal(int _iRows, int _iCols) const
475 res = matrixReal->coeff(_iRows, _iCols);
479 res = matrixCplx->coeff(_iRows, _iCols).real();
484 std::complex<double> Sparse::getImg(int _iRows, int _iCols) const
486 std::complex<double> res;
489 res = matrixCplx->coeff(_iRows, _iCols);
493 res = std::complex<double>(matrixReal->coeff(_iRows, _iCols), 0.);
499 void Sparse::whoAmI() SPARSE_CONST
501 std::cout << "types::Sparse";
504 Sparse* Sparse::clone(void) const
506 return new Sparse(*this);
509 bool Sparse::zero_set()
513 matrixReal->setZero();
517 matrixCplx->setZero();
523 // TODO: handle precision and line length
524 bool Sparse::toString(std::wostringstream& ostr) const
526 int iPrecision = ConfigVariable::getFormatSize();
530 res = ::toString(*matrixReal, iPrecision);
534 res = ::toString(*matrixCplx, iPrecision);
541 bool Sparse::resize(int _iNewRows, int _iNewCols)
543 if (_iNewRows <= getRows() && _iNewCols <= getCols())
545 //nothing to do: hence we do NOT fail
555 size_t iNonZeros = nonZeros();
556 RealSparse_t *newReal = new RealSparse_t(_iNewRows, _iNewCols);
557 newReal->reserve((int)iNonZeros);
561 int* pRows = new int[iNonZeros * 2];
563 int* pCols = pRows + iNonZeros;
566 double* pNonZeroR = new double[iNonZeros];
567 double* pNonZeroI = new double[iNonZeros];
568 outputValues(pNonZeroR, pNonZeroI);
570 typedef Eigen::Triplet<double> triplet;
571 std::vector<triplet> tripletList;
573 for (size_t i = 0 ; i < iNonZeros ; i++)
575 tripletList.push_back(triplet((int)pRows[i] - 1, (int)pCols[i] - 1, pNonZeroR[i]));
578 newReal->setFromTriplets(tripletList.begin(), tripletList.end());
581 matrixReal = newReal;
589 size_t iNonZeros = nonZeros();
590 CplxSparse_t *newCplx = new CplxSparse_t(_iNewRows, _iNewCols);
591 newCplx->reserve((int)iNonZeros);
594 int* pRows = new int[iNonZeros * 2];
596 int* pCols = pRows + iNonZeros;
599 double* pNonZeroR = new double[iNonZeros];
600 double* pNonZeroI = new double[iNonZeros];
601 outputValues(pNonZeroR, pNonZeroI);
603 typedef Eigen::Triplet<std::complex<double> > triplet;
604 std::vector<triplet> tripletList;
606 for (size_t i = 0 ; i < iNonZeros ; i++)
608 tripletList.push_back(triplet((int)pRows[i] - 1, (int)pCols[i] - 1, std::complex<double>(pNonZeroR[i], pNonZeroI[i])));
611 newCplx->setFromTriplets(tripletList.begin(), tripletList.end());
615 matrixCplx = newCplx;
623 m_iSize = _iNewRows * _iNewCols;
624 m_piDims[0] = m_iRows;
625 m_piDims[1] = m_iCols;
635 // TODO decide if a complex matrix with 0 imag can be == to a real matrix
636 // not true for dense (cf double.cpp)
637 bool Sparse::operator==(const InternalType& it) SPARSE_CONST
639 Sparse* otherSparse = const_cast<Sparse*>(dynamic_cast<Sparse const*>(&it));/* types::GenericType is not const-correct :( */
640 Sparse & cthis (const_cast<Sparse&>(*this));
642 if (otherSparse == NULL)
647 if (otherSparse->getRows() != cthis.getRows())
652 if (otherSparse->getCols() != cthis.getCols())
657 if (otherSparse->isComplex() != isComplex())
664 return equal(*matrixCplx, *otherSparse->matrixCplx);
668 return equal(*matrixReal, *otherSparse->matrixReal);
672 bool Sparse::one_set()
676 return setNonZero(*matrixCplx);
680 return setNonZero(*matrixReal);
684 void Sparse::toComplex()
690 matrixCplx = new CplxSparse_t(matrixReal->cast<std::complex<double> >());
703 InternalType* Sparse::insertNew(typed_list* _pArgs, InternalType* _pSource)
706 InternalType *pOut = NULL;
707 Sparse* pSource = _pSource->getAs<Sparse>();
709 int iDims = (int)_pArgs->size();
710 int* piMaxDim = new int[iDims];
711 int* piCountDim = new int[iDims];
712 bool bComplex = pSource->isComplex();
713 bool bUndefine = false;
715 //evaluate each argument and replace by appropriate value and compute the count of combinations
716 int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
720 cleanIndexesArguments(_pArgs, &pArg);
721 return createEmptyDouble();
726 iSeqCount = -iSeqCount;
732 //manage : and $ in creation by insertion
734 int *piSourceDims = pSource->getDimsArray();
736 for (int i = 0 ; i < iDims ; i++)
741 if (pSource->isScalar())
748 piMaxDim[i] = piSourceDims[iSource];
749 piCountDim[i] = piSourceDims[iSource];
752 //replace pArg value by the new one
753 pArg[i] = createDoubleVector(piMaxDim[i]);
757 // piMaxDim[i] = piCountDim[i];
762 //remove last dimension at size 1
763 //remove last dimension if are == 1
764 for (int i = (iDims - 1) ; i >= 2 ; i--)
766 if (piMaxDim[i] == 1)
777 if (checkArgValidity(pArg) == false)
780 cleanIndexesArguments(_pArgs, &pArg);
781 //contain bad index, like <= 0, ...
787 if (pSource->getCols() == 1)
789 pOut = new Sparse(piCountDim[0], 1, bComplex);
794 pOut = new Sparse(1, piCountDim[0], bComplex);
799 pOut = new Sparse(piMaxDim[0], piMaxDim[1], bComplex);
800 //pOut = pSource->createEmpty(iDims, piMaxDim, bComplex);
803 //fill with null item
804 Sparse* pSpOut = pOut->getAs<Sparse>();
806 //insert values in new matrix
807 InternalType* pOut2 = pSpOut->insert(&pArg, pSource);
814 cleanIndexesArguments(_pArgs, &pArg);
819 Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
821 bool bNeedToResize = false;
822 int iDims = (int)_pArgs->size();
825 //sparse are only in 2 dims
837 Double* pSource = _pSource->getAs<Double>();
839 //evaluate each argument and replace by appropriate value and compute the count of combinations
840 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
844 cleanIndexesArguments(_pArgs, &pArg);
851 if (getRows() == 1 || getCols() == 1)
854 if (getSize() < piMaxDim[0])
856 bNeedToResize = true;
858 //need to enlarge sparse dimensions
859 if (getCols() == 1 || getSize() == 0)
862 iNewRows = piMaxDim[0];
865 else if (getRows() == 1)
869 iNewCols = piMaxDim[0];
873 else if (getSize() < piMaxDim[0])
876 cleanIndexesArguments(_pArgs, &pArg);
883 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
885 bNeedToResize = true;
886 iNewRows = std::max(getRows(), piMaxDim[0]);
887 iNewCols = std::max(getCols(), piMaxDim[1]);
891 //check number of insertion
892 if (pSource->isScalar() == false && pSource->getSize() != iSeqCount)
895 cleanIndexesArguments(_pArgs, &pArg);
899 //now you are sure to be able to insert values
902 if (resize(iNewRows, iNewCols) == false)
905 cleanIndexesArguments(_pArgs, &pArg);
911 if (pSource->isComplex() && isComplex() == false)
919 double* pIdx = pArg[0]->getAs<Double>()->get();
920 for (int i = 0 ; i < iSeqCount ; i++)
922 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
923 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
924 if (pSource->isScalar())
926 if (pSource->isComplex())
928 set(iRow, iCol, std::complex<double>(pSource->get(0), pSource->getImg(0)), false);
932 set(iRow, iCol, pSource->get(0), false);
937 if (pSource->isComplex())
939 set(iRow, iCol, std::complex<double>(pSource->get(i), pSource->getImg(i)), false);
943 set(iRow, iCol, pSource->get(i), false);
950 double* pIdxRow = pArg[0]->getAs<Double>()->get();
951 int iRowSize = pArg[0]->getAs<Double>()->getSize();
952 double* pIdxCol = pArg[1]->getAs<Double>()->get();
954 for (int i = 0 ; i < iSeqCount ; i++)
956 if (pSource->isScalar())
958 if (pSource->isComplex())
960 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, std::complex<double>(pSource->get(0), pSource->getImg(0)), false);
964 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(0), false);
969 int iRowOrig = i % pSource->getRows();
970 int iColOrig = i / pSource->getRows();
972 if (pSource->isComplex())
974 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, std::complex<double>(pSource->get(iRowOrig, iColOrig), pSource->getImg(iRowOrig, iColOrig)), false);
978 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(iRowOrig, iColOrig), false);
987 cleanIndexesArguments(_pArgs, &pArg);
992 Sparse* Sparse::insert(typed_list* _pArgs, Sparse* _pSource)
994 bool bNeedToResize = false;
995 int iDims = (int)_pArgs->size();
998 //sparse are only in 2 dims
1011 //evaluate each argument and replace by appropriate value and compute the count of combinations
1012 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1016 cleanIndexesArguments(_pArgs, &pArg);
1023 if (getRows() == 1 || getCols() == 1)
1026 bNeedToResize = true;
1027 if (getSize() < piMaxDim[0])
1029 //need to enlarge sparse dimensions
1030 if (getCols() == 1 || getSize() == 0)
1033 iNewRows = piMaxDim[0];
1036 else if (getRows() == 1)
1040 iNewCols = piMaxDim[0];
1044 else if (getSize() < piMaxDim[0])
1047 cleanIndexesArguments(_pArgs, &pArg);
1054 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
1056 bNeedToResize = true;
1057 iNewRows = std::max(getRows(), piMaxDim[0]);
1058 iNewCols = std::max(getCols(), piMaxDim[1]);
1062 //check number of insertion
1063 if (_pSource->isScalar() == false && _pSource->getSize() != iSeqCount)
1066 cleanIndexesArguments(_pArgs, &pArg);
1070 //now you are sure to be able to insert values
1073 if (resize(iNewRows, iNewCols) == false)
1076 cleanIndexesArguments(_pArgs, &pArg);
1082 if (_pSource->isComplex() && isComplex() == false)
1089 double* pIdx = pArg[0]->getAs<Double>()->get();
1090 for (int i = 0 ; i < iSeqCount ; i++)
1092 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
1093 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
1095 if (_pSource->isScalar())
1097 if (_pSource->isComplex())
1099 set(iRow, iCol, _pSource->getImg(0, 0), false);
1103 set(iRow, iCol, _pSource->get(0, 0), false);
1108 int iRowOrig = i % _pSource->getRows();
1109 int iColOrig = i / _pSource->getRows();
1110 if (_pSource->isComplex())
1112 set(iRow, iCol, _pSource->getImg(iRowOrig, iColOrig), false);
1116 set(iRow, iCol, _pSource->get(iRowOrig, iColOrig), false);
1123 double* pIdxRow = pArg[0]->getAs<Double>()->get();
1124 int iRowSize = pArg[0]->getAs<Double>()->getSize();
1125 double* pIdxCol = pArg[1]->getAs<Double>()->get();
1127 for (int i = 0 ; i < iSeqCount ; i++)
1129 if (_pSource->isScalar())
1131 if (_pSource->isComplex())
1133 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->getImg(0, 0), false);
1137 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(0, 0), false);
1142 int iRowOrig = i % _pSource->getRows();
1143 int iColOrig = i / _pSource->getRows();
1144 if (_pSource->isComplex())
1146 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->getImg(iRowOrig, iColOrig), false);
1150 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(iRowOrig, iColOrig), false);
1159 cleanIndexesArguments(_pArgs, &pArg);
1164 Sparse* Sparse::remove(typed_list* _pArgs)
1166 Sparse* pOut = NULL;
1167 int iDims = (int)_pArgs->size();
1170 //sparse are only in 2 dims
1179 //evaluate each argument and replace by appropriate value and compute the count of combinations
1180 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1184 cleanIndexesArguments(_pArgs, &pArg);
1188 bool* pbFull = new bool[iDims];
1189 //coord must represent all values on a dimension
1190 for (int i = 0 ; i < iDims ; i++)
1193 int iDimToCheck = getVarMaxDim(i, iDims);
1194 int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
1196 //we can have index more than once
1197 if (iIndexSize >= iDimToCheck)
1199 //size is good, now check datas
1200 double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
1201 for (int j = 0 ; j < iDimToCheck ; j++)
1204 for (int k = 0 ; k < iIndexSize ; k++)
1206 if ((int)pIndexes[k] == j + 1)
1217 //only one dims can be not full/entire
1218 bool bNotEntire = false;
1220 bool bTooMuchNotEntire = false;
1221 for (int i = 0 ; i < iDims ; i++)
1223 if (pbFull[i] == false)
1225 if (bNotEntire == false)
1232 bTooMuchNotEntire = true;
1238 if (bTooMuchNotEntire == true)
1241 cleanIndexesArguments(_pArgs, &pArg);
1247 //find index to keep
1248 int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
1249 double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
1250 int iKeepSize = getVarMaxDim(iNotEntire, iDims);
1251 bool* pbKeep = new bool[iKeepSize];
1253 //fill pbKeep with true value
1254 for (int i = 0 ; i < iKeepSize ; i++)
1259 for (int i = 0 ; i < iNotEntireSize ; i++)
1261 int idx = (int)piNotEntireIndex[i] - 1;
1263 //don't care of value out of bounds
1264 if (idx < iKeepSize)
1266 pbKeep[idx] = false;
1270 int iNewDimSize = 0;
1271 for (int i = 0 ; i < iKeepSize ; i++)
1273 if (pbKeep[i] == true)
1280 int* piNewDims = new int[iDims];
1281 for (int i = 0 ; i < iDims ; i++)
1283 if (i == iNotEntire)
1285 piNewDims[i] = iNewDimSize;
1289 piNewDims[i] = getVarMaxDim(i, iDims);
1293 //remove last dimension if are == 1
1294 int iOrigDims = iDims;
1295 for (int i = (iDims - 1) ; i >= 2 ; i--)
1297 if (piNewDims[i] == 1)
1309 if (iNewDimSize == 0)
1311 return new Sparse(0, 0);
1315 //two cases, depends of original matrix/vector
1316 if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
1318 //special case for row vector
1319 pOut = new Sparse(1, iNewDimSize, isComplex());
1320 //in this case we have to care of 2nd dimension
1325 pOut = new Sparse(iNewDimSize, 1, isComplex());
1331 pOut = new Sparse(piNewDims[0], piNewDims[0], isComplex());
1335 //find a way to copy existing data to new variable ...
1337 int* piIndexes = new int[iOrigDims];
1338 int* piViewDims = new int[iOrigDims];
1339 for (int i = 0 ; i < iOrigDims ; i++)
1341 piViewDims[i] = getVarMaxDim(i, iOrigDims);
1344 for (int i = 0 ; i < getSize() ; i++)
1346 bool bByPass = false;
1347 getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
1349 //check if piIndexes use removed indexes
1350 for (int j = 0 ; j < iNotEntireSize ; j++)
1352 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
1354 //by pass this value
1360 if (bByPass == false)
1365 pOut->set(iNewPos, getImg(i));
1369 pOut->set(iNewPos, get(i));
1375 //free allocated data
1376 for (int i = 0 ; i < iDims ; i++)
1378 if (pArg[i] != (*_pArgs)[i])
1385 delete[] piViewDims;
1388 cleanIndexesArguments(_pArgs, &pArg);
1393 bool Sparse::append(int r, int c, types::Sparse SPARSE_CONST* src)
1395 // std::wcerr << L"to a sparse of size"<<getRows() << L","<<getCols() << L" should append @"<<r << L","<<c<< "a sparse:"<< src->toString(32,80)<<std::endl;
1396 if (src->isComplex())
1402 if (src->isComplex())
1404 doAppend(*(src->matrixCplx), r, c, *matrixCplx);
1408 doAppend(*(src->matrixReal), r, c, *matrixCplx);
1413 doAppend(*(src->matrixReal), r, c, *matrixReal);
1418 return true; // realloc is meaningless for sparse matrices
1422 * create a new Sparse of dims according to resSize and fill it from currentSparse (along coords)
1424 InternalType* Sparse::extract(typed_list* _pArgs)
1426 Sparse* pOut = NULL;
1427 int iDims = (int)_pArgs->size();
1430 int* piMaxDim = new int[iDims];
1431 int* piCountDim = new int[iDims];
1433 //evaluate each argument and replace by appropriate value and compute the count of combinations
1434 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1438 cleanIndexesArguments(_pArgs, &pArg);
1439 if (_pArgs->size() == 0)
1447 return Double::Empty();
1453 if (piMaxDim[0] <= getSize())
1458 if (getRows() == 1 && getCols() != 1 && (*_pArgs)[0]->isColon() == false)
1460 //special case for row vector
1462 iNewCols = piCountDim[0];
1466 iNewRows = piCountDim[0];
1470 pOut = new Sparse(iNewRows, iNewCols, isComplex());
1471 double* pIdx = pArg[0]->getAs<Double>()->get();
1472 for (int i = 0 ; i < iSeqCount ; i++)
1480 int iRowRead = static_cast<int>(pIdx[i] - 1) % getRows();
1481 int iColRead = static_cast<int>(pIdx[i] - 1) / getRows();
1483 int iRowWrite = static_cast<int>(i) % iNewRows;
1484 int iColWrite = static_cast<int>(i) / iNewRows;
1487 std::complex<double> dbl = getImg(iRowRead, iColRead);
1488 if (dbl.real() != 0 || dbl.imag() != 0)
1490 //only non zero values
1491 pOut->set(iRowWrite, iColWrite, dbl, false);
1496 double dbl = get(iRowRead, iColRead);
1499 //only non zero values
1500 pOut->set(iRowWrite, iColWrite, dbl, false);
1508 cleanIndexesArguments(_pArgs, &pArg);
1514 if (piMaxDim[0] <= getRows() && piMaxDim[1] <= getCols())
1516 double* pIdxRow = pArg[0]->getAs<Double>()->get();
1517 double* pIdxCol = pArg[1]->getAs<Double>()->get();
1519 int iNewRows = pArg[0]->getAs<Double>()->getSize();
1520 int iNewCols = pArg[1]->getAs<Double>()->getSize();
1522 pOut = new Sparse(iNewRows, iNewCols, isComplex());
1525 for (int iRow = 0 ; iRow < iNewRows ; iRow++)
1527 for (int iCol = 0 ; iCol < iNewCols ; iCol++)
1529 if ((pIdxRow[iRow] < 1) || (pIdxCol[iCol] < 1))
1537 std::complex<double> dbl = getImg((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
1538 if (dbl.real() != 0 || dbl.imag() != 0)
1540 //only non zero values
1541 pOut->set(iRow, iCol, dbl, false);
1546 double dbl = get((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
1549 //only non zero values
1550 pOut->set(iRow, iCol, dbl, false);
1560 cleanIndexesArguments(_pArgs, &pArg);
1568 cleanIndexesArguments(_pArgs, &pArg);
1573 Sparse* Sparse::extract(int nbCoords, int SPARSE_CONST* coords, int SPARSE_CONST* maxCoords, int SPARSE_CONST* resSize, bool asVector) SPARSE_CONST
1575 if ( (asVector && maxCoords[0] > getSize()) ||
1576 (asVector == false && maxCoords[0] > getRows()) ||
1577 (asVector == false && maxCoords[1] > getCols()))
1582 bool const cplx(isComplex());
1586 pSp = (getRows() == 1) ? new Sparse(1, resSize[0], cplx) : new Sparse(resSize[0], 1, cplx);
1590 pSp = new Sparse(resSize[0], resSize[1], cplx);
1592 // std::cerr<<"extracted sparse:"<<pSp->getRows()<<", "<<pSp->getCols()<<"seqCount="<<nbCoords<<"maxDim="<<maxCoords[0] <<","<< maxCoords[1]<<std::endl;
1594 ? copyToSparse(*this, Coords<true>(coords, getRows()), nbCoords
1595 , *pSp, RowWiseFullIterator(pSp->getRows(), pSp->getCols()))
1596 : copyToSparse(*this, Coords<false>(coords), nbCoords
1597 , *pSp, RowWiseFullIterator(pSp->getRows(), pSp->getCols()))))
1605 coords are Scilab 1-based
1606 extract std::make_pair(coords, asVector), rowIter
1608 template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
1609 bool Sparse::copyToSparse(Src SPARSE_CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav)
1611 if (!(src.isComplex() || sp.isComplex()))
1613 mycopy_n(makeMatrixIterator<double>(src, srcTrav), n
1614 , makeMatrixIterator<double>(*sp.matrixReal, destTrav));
1619 mycopy_n(makeMatrixIterator<std::complex<double> >(src, srcTrav), n
1620 , makeMatrixIterator<std::complex<double> >(*sp.matrixCplx, destTrav));
1627 // GenericType because we might return a Double* for scalar operand
1628 Sparse* Sparse::add(Sparse const& o) const
1630 RealSparse_t* realSp(0);
1631 CplxSparse_t* cplxSp(0);
1632 if (isComplex() == false && o.isComplex() == false)
1635 realSp = new RealSparse_t(*matrixReal + * (o.matrixReal));
1637 else if (isComplex() == false && o.isComplex() == true)
1639 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() + * (o.matrixCplx));
1641 else if (isComplex() == true && o.isComplex() == false)
1643 cplxSp = new CplxSparse_t(*matrixCplx + o.matrixReal->cast<std::complex<double> >());
1645 else if (isComplex() == true && o.isComplex() == true)
1647 cplxSp = new CplxSparse_t(*matrixCplx + * (o.matrixCplx));
1650 return new Sparse(realSp, cplxSp);
1653 Sparse* Sparse::substract(Sparse const& o) const
1655 RealSparse_t* realSp(0);
1656 CplxSparse_t* cplxSp(0);
1657 if (isComplex() == false && o.isComplex() == false)
1660 realSp = new RealSparse_t(*matrixReal - * (o.matrixReal));
1662 else if (isComplex() == false && o.isComplex() == true)
1665 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() - * (o.matrixCplx));
1667 else if (isComplex() == true && o.isComplex() == false)
1670 cplxSp = new CplxSparse_t(*matrixCplx - o.matrixReal->cast<std::complex<double> >());
1672 else if (isComplex() == true && o.isComplex() == true)
1675 cplxSp = new CplxSparse_t(*matrixCplx - * (o.matrixCplx));
1678 return new Sparse(realSp, cplxSp);
1681 Sparse* Sparse::multiply(double s) const
1683 return new Sparse( isComplex() ? 0 : new RealSparse_t((*matrixReal)*s)
1684 , isComplex() ? new CplxSparse_t((*matrixCplx)*s) : 0);
1687 Sparse* Sparse::multiply(std::complex<double> s) const
1689 return new Sparse( 0
1690 , isComplex() ? new CplxSparse_t((*matrixCplx) * s) : new CplxSparse_t((*matrixReal) * s));
1693 Sparse* Sparse::multiply(Sparse const& o) const
1695 RealSparse_t* realSp(0);
1696 CplxSparse_t* cplxSp(0);
1698 if (isComplex() == false && o.isComplex() == false)
1700 realSp = new RealSparse_t(*matrixReal **(o.matrixReal));
1702 else if (isComplex() == false && o.isComplex() == true)
1704 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() **(o.matrixCplx));
1706 else if (isComplex() == true && o.isComplex() == false)
1708 cplxSp = new CplxSparse_t(*matrixCplx * o.matrixReal->cast<std::complex<double> >());
1710 else if (isComplex() == true && o.isComplex() == true)
1712 cplxSp = new CplxSparse_t(*matrixCplx **(o.matrixCplx));
1715 return new Sparse(realSp, cplxSp);
1718 Sparse* Sparse::dotMultiply(Sparse SPARSE_CONST& o) const
1720 RealSparse_t* realSp(0);
1721 CplxSparse_t* cplxSp(0);
1722 if (isComplex() == false && o.isComplex() == false)
1724 realSp = new RealSparse_t(matrixReal->cwiseProduct(*(o.matrixReal)));
1726 else if (isComplex() == false && o.isComplex() == true)
1728 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >().cwiseProduct( *(o.matrixCplx)));
1730 else if (isComplex() == true && o.isComplex() == false)
1732 cplxSp = new CplxSparse_t(matrixCplx->cwiseProduct(o.matrixReal->cast<std::complex<double> >()));
1734 else if (isComplex() == true && o.isComplex() == true)
1736 cplxSp = new CplxSparse_t(matrixCplx->cwiseProduct(*(o.matrixCplx)));
1739 return new Sparse(realSp, cplxSp);
1742 Sparse* Sparse::dotDivide(Sparse SPARSE_CONST& o) const
1744 RealSparse_t* realSp(0);
1745 CplxSparse_t* cplxSp(0);
1746 if (isComplex() == false && o.isComplex() == false)
1748 realSp = new RealSparse_t(matrixReal->cwiseQuotient(*(o.matrixReal)));
1750 else if (isComplex() == false && o.isComplex() == true)
1752 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >().cwiseQuotient( *(o.matrixCplx)));
1754 else if (isComplex() == true && o.isComplex() == false)
1756 cplxSp = new CplxSparse_t(matrixCplx->cwiseQuotient(o.matrixReal->cast<std::complex<double> >()));
1758 else if (isComplex() == true && o.isComplex() == true)
1760 cplxSp = new CplxSparse_t(matrixCplx->cwiseQuotient(*(o.matrixCplx)));
1763 return new Sparse(realSp, cplxSp);
1768 BoolCast(std::complex<double> const& c): b(c.real() || c.imag()) {}
1769 operator bool () const
1773 operator double() const
1779 Sparse* Sparse::newOnes() const
1781 // result is never cplx
1782 return new Sparse( matrixReal
1783 ? new RealSparse_t(matrixReal->cast<bool>().cast<double>())
1784 : new RealSparse_t(matrixCplx->cast<BoolCast>().cast<double>())
1790 RealCast(std::complex<double> const& c): b(c.real()) {}
1791 operator bool () const
1795 operator double() const
1801 Sparse* Sparse::newReal() const
1803 return new Sparse( matrixReal
1805 : new RealSparse_t(matrixCplx->cast<RealCast>().cast<double>())
1809 std::size_t Sparse::nonZeros() const
1813 return matrixCplx->nonZeros();
1817 return matrixReal->nonZeros();
1820 std::size_t Sparse::nonZeros(std::size_t r) const
1825 int* piIndex = matrixReal->outerIndexPtr();
1826 res = piIndex[r + 1] - piIndex[r];
1830 int* piIndex = matrixCplx->outerIndexPtr();
1831 res = piIndex[r + 1] - piIndex[r];
1837 int* Sparse::getNbItemByRow(int* _piNbItemByRows)
1839 int* piNbItemByCols = new int[getRows() + 1];
1842 mycopy_n(matrixCplx->outerIndexPtr(), getRows() + 1, piNbItemByCols);
1846 mycopy_n(matrixReal->outerIndexPtr(), getRows() + 1, piNbItemByCols);
1849 for (int i = 0 ; i < getRows() ; i++)
1851 _piNbItemByRows[i] = piNbItemByCols[i + 1] - piNbItemByCols[i];
1854 delete[] piNbItemByCols;
1855 return _piNbItemByRows;
1858 int* Sparse::getColPos(int* _piColPos)
1862 mycopy_n(matrixCplx->innerIndexPtr(), nonZeros(), _piColPos);
1866 mycopy_n(matrixReal->innerIndexPtr(), nonZeros(), _piColPos);
1869 for (int i = 0; i < nonZeros(); i++)
1879 template<typename S> struct GetReal: std::unary_function<typename S::InnerIterator, double>
1881 double operator()(typename S::InnerIterator it) const
1886 template<> struct GetReal< Eigen::SparseMatrix<std::complex<double >, Eigen::RowMajor > >
1887 : std::unary_function<Sparse::CplxSparse_t::InnerIterator, double>
1889 double operator()( Sparse::CplxSparse_t::InnerIterator it) const
1891 return it.value().real();
1894 template<typename S> struct GetImag: std::unary_function<typename S::InnerIterator, double>
1896 double operator()(typename S::InnerIterator it) const
1898 return it.value().imag();
1901 template<typename S> struct GetRow: std::unary_function<typename S::InnerIterator, int>
1903 int operator()(typename S::InnerIterator it) const
1905 return it.row() + 1;
1908 template<typename S> struct GetCol: std::unary_function<typename S::InnerIterator, int>
1910 int operator()(typename S::InnerIterator it) const
1912 return it.col() + 1;
1916 template<typename S, typename Out, typename F> Out sparseTransform(S& s, Out o, F f)
1918 for (std::size_t k(0); k < s.outerSize(); ++k)
1920 for (typename S::InnerIterator it(s, (int)k); it; ++it, ++o)
1929 std::pair<double*, double*> Sparse::outputValues(double* outReal, double* outImag)const
1932 ? std::make_pair(sparseTransform(*matrixReal, outReal, GetReal<RealSparse_t>()), outImag)
1933 : std::make_pair(sparseTransform(*matrixCplx, outReal, GetReal<CplxSparse_t>())
1934 , sparseTransform(*matrixCplx, outImag, GetImag<CplxSparse_t>()));
1937 int* Sparse::outputRowCol(int* out)const
1940 ? sparseTransform(*matrixReal, sparseTransform(*matrixReal, out, GetRow<RealSparse_t>()), GetCol<RealSparse_t>())
1941 : sparseTransform(*matrixCplx, sparseTransform(*matrixCplx, out, GetRow<CplxSparse_t>()), GetCol<CplxSparse_t>());
1943 double* Sparse::outputCols(double* out) const
1947 mycopy_n(matrixCplx->innerIndexPtr(), nonZeros(), out);
1951 mycopy_n(matrixReal->innerIndexPtr(), nonZeros(), out);
1954 return std::transform(out, out, out, std::bind2nd(std::plus<double>(), 1));
1958 void Sparse::opposite(void)
1962 std::complex<double>* data = matrixCplx->valuePtr();
1963 std::transform(data, data + matrixCplx->nonZeros(), data, std::negate<std::complex<double> >());
1967 double* data = matrixReal->valuePtr();
1968 std::transform(data, data + matrixReal->nonZeros(), data, std::negate<double>());
1972 SparseBool* Sparse::newLessThan(Sparse const&o) const
1974 return cwiseOp<std::less>(*this, o);
1977 SparseBool* Sparse::newGreaterThan(Sparse const&o) const
1979 return cwiseOp<std::greater>(*this, o);
1982 SparseBool* Sparse::newNotEqualTo(Sparse const&o) const
1984 return cwiseOp<std::not_equal_to>(*this, o);
1987 SparseBool* Sparse::newLessOrEqual(Sparse const&o) const
1989 return cwiseOp<std::less_equal>(*this, o);
1992 SparseBool* Sparse::newGreaterOrEqual(Sparse const&o) const
1994 return cwiseOp<std::greater_equal>(*this, o);
1997 SparseBool* Sparse::newEqualTo(Sparse const&o) const
1999 return cwiseOp<std::equal_to>(*this, o);
2002 bool Sparse::reshape(int* _piDims, int _iDims)
2014 bOk = reshape(_piDims[0], iCols);
2020 bool Sparse::reshape(int _iNewRows, int _iNewCols)
2022 if (_iNewRows * _iNewCols != getRows() * getCols())
2033 size_t iNonZeros = nonZeros();
2034 RealSparse_t *newReal = new RealSparse_t(_iNewRows, _iNewCols);
2035 newReal->reserve((int)iNonZeros);
2038 int* pRows = new int[iNonZeros * 2];
2039 outputRowCol(pRows);
2040 int* pCols = pRows + iNonZeros;
2043 double* pNonZeroR = new double[iNonZeros];
2044 double* pNonZeroI = new double[iNonZeros];
2045 outputValues(pNonZeroR, pNonZeroI);
2047 typedef Eigen::Triplet<double> triplet;
2048 std::vector<triplet> tripletList;
2050 for (size_t i = 0 ; i < iNonZeros ; i++)
2052 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
2053 tripletList.push_back(triplet((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), pNonZeroR[i]));
2056 newReal->setFromTriplets(tripletList.begin(), tripletList.end());
2059 matrixReal = newReal;
2067 size_t iNonZeros = nonZeros();
2068 CplxSparse_t *newCplx = new CplxSparse_t(_iNewRows, _iNewCols);
2069 newCplx->reserve((int)iNonZeros);
2072 int* pRows = new int[iNonZeros * 2];
2073 outputRowCol(pRows);
2074 int* pCols = pRows + iNonZeros;
2077 double* pNonZeroR = new double[iNonZeros];
2078 double* pNonZeroI = new double[iNonZeros];
2079 outputValues(pNonZeroR, pNonZeroI);
2081 typedef Eigen::Triplet<std::complex<double> > triplet;
2082 std::vector<triplet> tripletList;
2084 for (size_t i = 0 ; i < iNonZeros ; i++)
2086 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
2087 tripletList.push_back(triplet((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), std::complex<double>(pNonZeroR[i], pNonZeroI[i])));
2090 newCplx->setFromTriplets(tripletList.begin(), tripletList.end());
2093 matrixCplx = newCplx;
2099 m_iRows = _iNewRows;
2100 m_iCols = _iNewCols;
2101 m_iSize = _iNewRows * _iNewCols;
2104 m_piDims[0] = m_iRows;
2105 m_piDims[1] = m_iCols;
2118 // SparseBool* SparseBool::new
2120 SparseBool::SparseBool(Bool SPARSE_CONST& src)
2122 create(src.getRows(), src.getCols(), src, RowWiseFullIterator(src.getRows(), src.getCols()), src.getSize());
2124 /* @param src : Bool matrix to copy into a new sparse matrix
2125 @param idx : Double matrix to use as indexes to get values from the src
2127 SparseBool::SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx)
2129 double SPARSE_CONST* const endOfRow(idx.getReal() + idx.getRows());
2130 create( static_cast<int>(*std::max_element(idx.getReal(), endOfRow))
2131 , static_cast<int>(*std::max_element(endOfRow, endOfRow + idx.getRows()))
2132 , src, makeIteratorFromVar(idx), idx.getSize() / 2 );
2135 /* @param src : Bool matrix to copy into a new sparse matrix
2136 @param idx : Double matrix to use as indexes to get values from the src
2137 @param dims : Double matrix containing the dimensions of the new matrix
2139 SparseBool::SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims)
2141 create((int)dims.getReal(0, 0) , (int)dims.getReal(0, 1) , src, makeIteratorFromVar(idx), (int)idx.getSize() / 2);
2144 SparseBool::SparseBool(int _iRows, int _iCols) : matrixBool(new BoolSparse_t(_iRows, _iCols))
2148 m_iSize = _iRows * _iCols;
2150 m_piDims[0] = _iRows;
2151 m_piDims[1] = _iCols;
2154 SparseBool::SparseBool(SparseBool const& src) : GenericType(src), matrixBool(new BoolSparse_t(*src.matrixBool))
2157 m_iRows = const_cast<SparseBool*>(&src)->getRows();
2158 m_iCols = const_cast<SparseBool*>(&src)->getCols();
2159 m_iSize = m_iRows * m_iCols;
2160 m_piDims[0] = m_iRows;
2161 m_piDims[1] = m_iCols;
2164 SparseBool::SparseBool(BoolSparse_t* src) : matrixBool(src)
2166 m_iRows = src->rows();
2167 m_iCols = src->cols();
2168 m_iSize = m_iRows * m_iCols;
2170 m_piDims[0] = m_iRows;
2171 m_piDims[1] = m_iCols;
2174 template<typename DestIter>
2175 void SparseBool::create(int rows, int cols, Bool SPARSE_CONST& src, DestIter o, std::size_t n)
2179 m_iSize = cols * rows;
2181 m_piDims[0] = m_iRows;
2182 m_piDims[1] = m_iCols;
2184 matrixBool = new BoolSparse_t(rows, cols);
2186 matrixBool->reserve((int)n);
2187 mycopy_n(makeMatrixIterator<int>(src, RowWiseFullIterator(src.getRows(), src.getCols())), n
2188 , makeMatrixIterator<bool>(*matrixBool, o));
2193 bool SparseBool::toString(std::wostringstream& ostr) const
2195 ostr << ::toString(*matrixBool, 0);
2199 void SparseBool::whoAmI() SPARSE_CONST
2201 std::cout << "types::SparseBool";
2204 SparseBool* SparseBool::clone(void) const
2206 return new SparseBool(*this);
2209 bool SparseBool::resize(int _iNewRows, int _iNewCols)
2211 if (_iNewRows <= getRows() && _iNewCols <= getCols())
2213 //nothing to do: hence we do NOT fail
2221 size_t iNonZeros = nbTrue();
2223 BoolSparse_t *newBool = new BoolSparse_t(_iNewRows, _iNewCols);
2224 newBool->reserve((int)iNonZeros);
2227 int* pRows = new int[iNonZeros * 2];
2228 outputRowCol(pRows);
2229 int* pCols = pRows + iNonZeros;
2231 typedef Eigen::Triplet<bool> triplet;
2232 std::vector<triplet> tripletList;
2234 for (size_t i = 0 ; i < iNonZeros ; i++)
2236 tripletList.push_back(triplet((int)pRows[i] - 1, (int)pCols[i] - 1, true));
2239 newBool->setFromTriplets(tripletList.begin(), tripletList.end());
2242 matrixBool = newBool;
2245 m_iRows = _iNewRows;
2246 m_iCols = _iNewCols;
2247 m_iSize = _iNewRows * _iNewCols;
2248 m_piDims[0] = m_iRows;
2249 m_piDims[1] = m_iCols;
2261 SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
2263 bool bNeedToResize = false;
2264 int iDims = (int)_pArgs->size();
2267 //sparse are only in 2 dims
2280 //evaluate each argument and replace by appropriate value and compute the count of combinations
2281 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
2285 cleanIndexesArguments(_pArgs, &pArg);
2292 if (getRows() == 1 || getCols() == 1)
2295 if (getSize() < piMaxDim[0])
2297 bNeedToResize = true;
2299 //need to enlarge sparse dimensions
2300 if (getCols() == 1 || getSize() == 0)
2303 iNewRows = piMaxDim[0];
2306 else if (getRows() == 1)
2310 iNewCols = piMaxDim[0];
2314 else if (getSize() < piMaxDim[0])
2317 cleanIndexesArguments(_pArgs, &pArg);
2324 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
2326 bNeedToResize = true;
2327 iNewRows = std::max(getRows(), piMaxDim[0]);
2328 iNewCols = std::max(getCols(), piMaxDim[1]);
2332 //check number of insertion
2333 if (_pSource->isScalar() == false && _pSource->getSize() != iSeqCount)
2336 cleanIndexesArguments(_pArgs, &pArg);
2340 //now you are sure to be able to insert values
2343 if (resize(iNewRows, iNewCols) == false)
2346 cleanIndexesArguments(_pArgs, &pArg);
2353 double* pIdx = pArg[0]->getAs<Double>()->get();
2354 for (int i = 0 ; i < iSeqCount ; i++)
2356 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
2357 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
2359 if (_pSource->isScalar())
2361 set(iRow, iCol, _pSource->get(0, 0), false);
2365 int iRowOrig = i % _pSource->getRows();
2366 int iColOrig = i / _pSource->getRows();
2367 set(iRow, iCol, _pSource->get(iRowOrig, iColOrig), false);
2373 double* pIdxRow = pArg[0]->getAs<Double>()->get();
2374 int iRowSize = pArg[0]->getAs<Double>()->getSize();
2375 double* pIdxCol = pArg[1]->getAs<Double>()->get();
2377 for (int i = 0 ; i < iSeqCount ; i++)
2379 if (_pSource->isScalar())
2381 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(0, 0), false);
2385 int iRowOrig = i % _pSource->getRows();
2386 int iColOrig = i / _pSource->getRows();
2387 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(iRowOrig, iColOrig), false);
2395 cleanIndexesArguments(_pArgs, &pArg);
2400 SparseBool* SparseBool::insert(typed_list* _pArgs, InternalType* _pSource)
2402 bool bNeedToResize = false;
2403 int iDims = (int)_pArgs->size();
2406 //sparse are only in 2 dims
2418 Bool* pSource = _pSource->getAs<Bool>();
2420 //evaluate each argument and replace by appropriate value and compute the count of combinations
2421 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
2425 cleanIndexesArguments(_pArgs, &pArg);
2432 if (getRows() == 1 || getCols() == 1)
2435 bNeedToResize = true;
2436 if (getSize() < piMaxDim[0])
2438 //need to enlarge sparse dimensions
2439 if (getCols() == 1 || getSize() == 0)
2442 iNewRows = piMaxDim[0];
2445 else if (getRows() == 1)
2449 iNewCols = piMaxDim[0];
2453 else if (getSize() < piMaxDim[0])
2456 cleanIndexesArguments(_pArgs, &pArg);
2463 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
2465 bNeedToResize = true;
2466 iNewRows = std::max(getRows(), piMaxDim[0]);
2467 iNewCols = std::max(getCols(), piMaxDim[1]);
2471 //check number of insertion
2472 if (pSource->isScalar() == false && pSource->getSize() != iSeqCount)
2475 cleanIndexesArguments(_pArgs, &pArg);
2479 //now you are sure to be able to insert values
2482 if (resize(iNewRows, iNewCols) == false)
2485 cleanIndexesArguments(_pArgs, &pArg);
2492 double* pIdx = pArg[0]->getAs<Double>()->get();
2493 for (int i = 0 ; i < iSeqCount ; i++)
2495 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
2496 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
2497 if (pSource->isScalar())
2499 set(iRow, iCol, pSource->get(0) != 0, false);
2503 set(iRow, iCol, pSource->get(i) != 0, false);
2509 double* pIdxRow = pArg[0]->getAs<Double>()->get();
2510 int iRowSize = pArg[0]->getAs<Double>()->getSize();
2511 double* pIdxCol = pArg[1]->getAs<Double>()->get();
2513 for (int i = 0 ; i < iSeqCount ; i++)
2515 if (pSource->isScalar())
2517 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(0) != 0, false);
2521 int iRowOrig = i % pSource->getRows();
2522 int iColOrig = i / pSource->getRows();
2524 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(iRowOrig, iColOrig) != 0, false);
2532 cleanIndexesArguments(_pArgs, &pArg);
2536 SparseBool* SparseBool::remove(typed_list* _pArgs)
2538 SparseBool* pOut = NULL;
2539 int iDims = (int)_pArgs->size();
2542 //sparse are only in 2 dims
2551 //evaluate each argument and replace by appropriate value and compute the count of combinations
2552 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
2556 cleanIndexesArguments(_pArgs, &pArg);
2560 bool* pbFull = new bool[iDims];
2561 //coord must represent all values on a dimension
2562 for (int i = 0 ; i < iDims ; i++)
2565 int iDimToCheck = getVarMaxDim(i, iDims);
2566 int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
2568 //we can have index more than once
2569 if (iIndexSize >= iDimToCheck)
2571 //size is good, now check datas
2572 double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
2573 for (int j = 0 ; j < iDimToCheck ; j++)
2576 for (int k = 0 ; k < iIndexSize ; k++)
2578 if ((int)pIndexes[k] == j + 1)
2589 //only one dims can be not full/entire
2590 bool bNotEntire = false;
2592 bool bTooMuchNotEntire = false;
2593 for (int i = 0 ; i < iDims ; i++)
2595 if (pbFull[i] == false)
2597 if (bNotEntire == false)
2604 bTooMuchNotEntire = true;
2610 if (bTooMuchNotEntire == true)
2613 cleanIndexesArguments(_pArgs, &pArg);
2619 //find index to keep
2620 int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
2621 double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
2622 int iKeepSize = getVarMaxDim(iNotEntire, iDims);
2623 bool* pbKeep = new bool[iKeepSize];
2625 //fill pbKeep with true value
2626 for (int i = 0 ; i < iKeepSize ; i++)
2631 for (int i = 0 ; i < iNotEntireSize ; i++)
2633 int idx = (int)piNotEntireIndex[i] - 1;
2635 //don't care of value out of bounds
2636 if (idx < iKeepSize)
2638 pbKeep[idx] = false;
2642 int iNewDimSize = 0;
2643 for (int i = 0 ; i < iKeepSize ; i++)
2645 if (pbKeep[i] == true)
2652 int* piNewDims = new int[iDims];
2653 for (int i = 0 ; i < iDims ; i++)
2655 if (i == iNotEntire)
2657 piNewDims[i] = iNewDimSize;
2661 piNewDims[i] = getVarMaxDim(i, iDims);
2665 //remove last dimension if are == 1
2666 int iOrigDims = iDims;
2667 for (int i = (iDims - 1) ; i >= 2 ; i--)
2669 if (piNewDims[i] == 1)
2681 if (iNewDimSize == 0)
2684 cleanIndexesArguments(_pArgs, &pArg);
2685 return new SparseBool(0, 0);
2689 //two cases, depends of original matrix/vector
2690 if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
2692 //special case for row vector
2693 pOut = new SparseBool(1, iNewDimSize);
2694 //in this case we have to care of 2nd dimension
2699 pOut = new SparseBool(iNewDimSize, 1);
2705 pOut = new SparseBool(piNewDims[0], piNewDims[0]);
2709 //find a way to copy existing data to new variable ...
2711 int* piIndexes = new int[iOrigDims];
2712 int* piViewDims = new int[iOrigDims];
2713 for (int i = 0 ; i < iOrigDims ; i++)
2715 piViewDims[i] = getVarMaxDim(i, iOrigDims);
2718 for (int i = 0 ; i < getSize() ; i++)
2720 bool bByPass = false;
2721 getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
2723 //check if piIndexes use removed indexes
2724 for (int j = 0 ; j < iNotEntireSize ; j++)
2726 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
2728 //by pass this value
2734 if (bByPass == false)
2737 pOut->set(iNewPos, get(i));
2742 //free allocated data
2743 for (int i = 0 ; i < iDims ; i++)
2745 if (pArg[i] != (*_pArgs)[i])
2752 delete[] piViewDims;
2755 cleanIndexesArguments(_pArgs, &pArg);
2760 bool SparseBool::append(int r, int c, SparseBool SPARSE_CONST* src)
2762 doAppend(*src, r, c, *matrixBool);
2767 InternalType* SparseBool::insertNew(typed_list* _pArgs, InternalType* _pSource)
2770 InternalType *pOut = NULL;
2771 SparseBool* pSource = _pSource->getAs<SparseBool>();
2773 int iDims = (int)_pArgs->size();
2774 int* piMaxDim = new int[iDims];
2775 int* piCountDim = new int[iDims];
2776 bool bUndefine = false;
2778 //evaluate each argument and replace by appropriate value and compute the count of combinations
2779 int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
2783 cleanIndexesArguments(_pArgs, &pArg);
2784 return createEmptyDouble();
2789 iSeqCount = -iSeqCount;
2795 //manage : and $ in creation by insertion
2797 int *piSourceDims = pSource->getDimsArray();
2799 for (int i = 0 ; i < iDims ; i++)
2801 if (pArg[i] == NULL)
2804 if (pSource->isScalar())
2811 piMaxDim[i] = piSourceDims[iSource];
2812 piCountDim[i] = piSourceDims[iSource];
2815 //replace pArg value by the new one
2816 pArg[i] = createDoubleVector(piMaxDim[i]);
2820 // piMaxDim[i] = piCountDim[i];
2825 //remove last dimension at size 1
2826 //remove last dimension if are == 1
2827 for (int i = (iDims - 1) ; i >= 2 ; i--)
2829 if (piMaxDim[i] == 1)
2840 if (checkArgValidity(pArg) == false)
2843 cleanIndexesArguments(_pArgs, &pArg);
2844 //contain bad index, like <= 0, ...
2850 if (pSource->getCols() == 1)
2852 pOut = new SparseBool(piCountDim[0], 1);
2857 pOut = new SparseBool(1, piCountDim[0]);
2862 pOut = new SparseBool(piMaxDim[0], piMaxDim[1]);
2865 //fill with null item
2866 SparseBool* pSpOut = pOut->getAs<SparseBool>();
2868 //insert values in new matrix
2869 InternalType* pOut2 = pSpOut->insert(&pArg, pSource);
2876 cleanIndexesArguments(_pArgs, &pArg);
2881 SparseBool* SparseBool::extract(int nbCoords, int SPARSE_CONST* coords, int SPARSE_CONST* maxCoords, int SPARSE_CONST* resSize, bool asVector) SPARSE_CONST
2883 if ( (asVector && maxCoords[0] > getSize()) ||
2884 (asVector == false && maxCoords[0] > getRows()) ||
2885 (asVector == false && maxCoords[1] > getCols()))
2890 SparseBool * pSp (0);
2893 pSp = (getRows() == 1) ? new SparseBool(1, resSize[0]) : new SparseBool(resSize[0], 1);
2894 mycopy_n(makeMatrixIterator<bool>(*this, Coords<true>(coords, getRows())), nbCoords
2895 , makeMatrixIterator<bool>(*(pSp->matrixBool), RowWiseFullIterator(pSp->getRows(), pSp->getCols())));
2899 pSp = new SparseBool(resSize[0], resSize[1]);
2900 mycopy_n(makeMatrixIterator<bool>(*this, Coords<false>(coords, getRows())), nbCoords
2901 , makeMatrixIterator<bool>(*(pSp->matrixBool), RowWiseFullIterator(pSp->getRows(), pSp->getCols())));
2908 * create a new SparseBool of dims according to resSize and fill it from currentSparseBool (along coords)
2910 InternalType* SparseBool::extract(typed_list* _pArgs)
2912 SparseBool* pOut = NULL;
2913 int iDims = (int)_pArgs->size();
2916 int* piMaxDim = new int[iDims];
2917 int* piCountDim = new int[iDims];
2919 //evaluate each argument and replace by appropriate value and compute the count of combinations
2920 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
2924 cleanIndexesArguments(_pArgs, &pArg);
2925 if (_pArgs->size() == 0)
2933 return Double::Empty();
2939 // Check that we stay inside the input size.
2940 if (piMaxDim[0] <= getSize())
2945 if (getRows() == 1 && getCols() != 1 && (*_pArgs)[0]->isColon() == false)
2947 //special case for row vector
2949 iNewCols = piCountDim[0];
2953 iNewRows = piCountDim[0];
2957 pOut = new SparseBool(iNewRows, iNewCols);
2958 double* pIdx = pArg[0]->getAs<Double>()->get();
2959 // Write in output all elements extract from input.
2960 for (int i = 0 ; i < iSeqCount ; i++)
2968 int iRowRead = static_cast<int>(pIdx[i] - 1) % getRows();
2969 int iColRead = static_cast<int>(pIdx[i] - 1) / getRows();
2971 int iRowWrite = static_cast<int>(i) % iNewRows;
2972 int iColWrite = static_cast<int>(i) / iNewRows;
2974 bool bValue = get(iRowRead, iColRead);
2977 //only non zero values
2978 pOut->set(iRowWrite, iColWrite, true, false);
2985 cleanIndexesArguments(_pArgs, &pArg);
2991 // Check that we stay inside the input size.
2992 if (piMaxDim[0] <= getRows() && piMaxDim[1] <= getCols())
2994 double* pIdxRow = pArg[0]->getAs<Double>()->get();
2995 double* pIdxCol = pArg[1]->getAs<Double>()->get();
2997 int iNewRows = pArg[0]->getAs<Double>()->getSize();
2998 int iNewCols = pArg[1]->getAs<Double>()->getSize();
3000 pOut = new SparseBool(iNewRows, iNewCols);
3003 // Write in output all elements extract from input.
3004 for (int iRow = 0 ; iRow < iNewRows ; iRow++)
3006 for (int iCol = 0 ; iCol < iNewCols ; iCol++)
3008 if ((pIdxRow[iRow] < 1) || (pIdxCol[iCol] < 1))
3014 bool bValue = get((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
3017 //only non zero values
3018 pOut->set(iRow, iCol, true, false);
3027 cleanIndexesArguments(_pArgs, &pArg);
3035 cleanIndexesArguments(_pArgs, &pArg);
3040 std::size_t SparseBool::nbTrue() const
3042 return matrixBool->nonZeros() ;
3044 std::size_t SparseBool::nbTrue(std::size_t r) const
3046 int* piIndex = matrixBool->outerIndexPtr();
3047 return piIndex[r + 1] - piIndex[r];
3050 int* SparseBool::getNbItemByRow(int* _piNbItemByRows)
3052 int* piNbItemByRows = new int[getRows() + 1];
3053 mycopy_n(matrixBool->outerIndexPtr(), getRows() + 1, piNbItemByRows);
3055 for (int i = 0 ; i < getRows() ; i++)
3057 _piNbItemByRows[i] = piNbItemByRows[i + 1] - piNbItemByRows[i];
3060 delete[] piNbItemByRows;
3061 return _piNbItemByRows;
3064 int* SparseBool::getColPos(int* _piColPos)
3066 mycopy_n(matrixBool->innerIndexPtr(), nbTrue(), _piColPos);
3067 for (int i = 0; i < nbTrue(); i++)
3075 int* SparseBool::outputRowCol(int* out)const
3077 return sparseTransform(*matrixBool, sparseTransform(*matrixBool, out, GetRow<BoolSparse_t>()), GetCol<BoolSparse_t>());
3080 bool SparseBool::operator==(const InternalType& it) SPARSE_CONST
3082 SparseBool* otherSparse = const_cast<SparseBool*>(dynamic_cast<SparseBool const*>(&it));/* types::GenericType is not const-correct :( */
3084 && (otherSparse->getRows() == getRows())
3085 && (otherSparse->getCols() == getCols())
3086 && equal(*matrixBool, *otherSparse->matrixBool));
3089 bool SparseBool::operator!=(const InternalType& it) SPARSE_CONST
3091 return !(*this == it);
3094 void SparseBool::finalize()
3096 matrixBool->prune(&keepForSparse<bool>);
3097 matrixBool->finalize();
3100 bool SparseBool::get(int r, int c) SPARSE_CONST
3102 return matrixBool->coeff(r, c);
3105 bool SparseBool::set(int _iRows, int _iCols, bool _bVal, bool _bFinalize) SPARSE_CONST
3107 matrixBool->coeffRef(_iRows, _iCols) = _bVal;
3116 void SparseBool::fill(Bool& dest, int r, int c) SPARSE_CONST
3118 mycopy_n(makeMatrixIterator<bool >(*matrixBool, RowWiseFullIterator(getRows(), getCols())), getSize()
3119 , makeMatrixIterator<bool >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
3122 Sparse* SparseBool::newOnes() const
3124 return new Sparse(new types::Sparse::RealSparse_t(matrixBool->cast<double>()), 0);
3127 SparseBool* SparseBool::newNotEqualTo(SparseBool const&o) const
3129 return cwiseOp<std::not_equal_to>(*this, o);
3132 SparseBool* SparseBool::newEqualTo(SparseBool const&o) const
3134 return cwiseOp<std::equal_to>(*this, o);
3137 SparseBool* SparseBool::newLogicalOr(SparseBool const&o) const
3139 return cwiseOp<std::logical_or>(*this, o);
3142 SparseBool* SparseBool::newLogicalAnd(SparseBool const&o) const
3144 return cwiseOp<std::logical_and>(*this, o);
3147 bool SparseBool::reshape(int* _piDims, int _iDims)
3159 bOk = reshape(_piDims[0], iCols);
3165 bool SparseBool::reshape(int _iNewRows, int _iNewCols)
3167 if (_iNewRows * _iNewCols != getRows() * getCols())
3176 size_t iNonZeros = matrixBool->nonZeros();
3177 BoolSparse_t *newBool = new BoolSparse_t(_iNewRows, _iNewCols);
3178 newBool->reserve((int)iNonZeros);
3181 int* pRows = new int[iNonZeros * 2];
3182 outputRowCol(pRows);
3183 int* pCols = pRows + iNonZeros;
3185 typedef Eigen::Triplet<bool> triplet;
3186 std::vector<triplet> tripletList;
3188 for (size_t i = 0 ; i < iNonZeros ; i++)
3190 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
3191 tripletList.push_back(triplet((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), true));
3194 newBool->setFromTriplets(tripletList.begin(), tripletList.end());
3197 matrixBool = newBool;
3200 m_iRows = _iNewRows;
3201 m_iCols = _iNewCols;
3202 m_iSize = _iNewRows * _iNewCols;
3205 m_piDims[0] = m_iRows;
3206 m_piDims[1] = m_iCols;