2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
18 #include <Eigen/Sparse>
25 #include <Eigen/IterativeLinearSolvers>
26 #include <Eigen/SparseCholesky>
30 #include "tostring_common.hxx"
32 #include "matrixiterator.hxx"
33 #include "types_subtraction.hxx"
34 #include "types_addition.hxx"
35 #include "types_multiplication.hxx"
36 #include "configvariable.hxx"
37 #include "scilabWrite.hxx"
39 #include "types_tools.hxx"
41 #include "sparseOp.hxx"
45 #include "elem_common.h"
50 typedef Eigen::Triplet<double> RealTriplet_t;
51 typedef Eigen::Triplet<std::complex<double>> CplxTriplet_t;
52 typedef Eigen::Triplet<bool> BoolTriplet_t;
54 /* used for debuging output
56 template<typename Os, typename In, typename Sz> Os& writeData(wchar_t const* title, In beg, Sz n, Os& os)
59 /* TODO: use tostring_common (with a kind of std::boolalpha for boolean output)
61 mycopy_n(beg, n, std::ostream_iterator<typename std::iterator_traits<In>::value_type, char>(os, L" "));
68 Printer(int precision) : p(precision)
72 std::wstring typeName( /* */) const
78 std::wstring emptyName( /* */) const
84 std::wstring allZeroName( /* */) const
89 std::wstring operator()(T const& t) const
92 std::wostringstream ostr;
101 std::wstring Printer::operator()(bool const& b) const
114 std::wstring Printer::operator()(double const& d) const
116 std::wostringstream ostr;
118 getDoubleFormat(d, &df);
119 addDoubleValue(&ostr, d, &df);
124 std::wstring Printer::operator()(std::complex<double > const& c) const
126 std::wostringstream ostr;
128 DoubleFormat dfR, dfI;
129 getComplexFormat(c.real(), c.imag(), &iLen, &dfR, &dfI);
130 addDoubleComplexValue(&ostr, c.real(), c.imag(), iLen, &dfR, &dfI);
135 std::wstring Printer::typeName<bool>() const
137 return L"sparse boolean";
141 std::wstring Printer::allZeroName<bool>() const
147 std::wstring Printer::emptyName<bool>() const
152 template<typename T> std::wstring toString(T const& m, int precision)
154 std::wostringstream ostr;
158 getIntFormat(m.rows(), &iWidthRows);
159 getIntFormat(m.cols(), &iWidthCols);
162 addIntValue<unsigned long long>(&ostr, m.rows(), iWidthRows);
164 addIntValue<unsigned long long>(&ostr, m.cols(), iWidthCols);
167 Printer p(precision);
168 if (m.rows()*m.cols() ==0)
170 ostr << (p.emptyName<typename Eigen::internal::traits<T>::Scalar>());
172 else if (!m.nonZeros())
174 ostr << (p.allZeroName<typename Eigen::internal::traits<T>::Scalar>());
176 ostr << " " << p.typeName<typename Eigen::internal::traits<T>::Scalar>() << L" matrix\n\n";
178 auto * pIColPos = m.innerIndexPtr();
179 auto * pINbItemByRow = m.outerIndexPtr();
183 int size = static_cast<int>(m.rows() + 1);
184 for (size_t j = 1; j < size; j++)
186 for (size_t i = pINbItemByRow[j - 1]; i < pINbItemByRow[j]; i++)
189 addIntValue<unsigned long long>(&ostr, (int)j, iWidthRows);
191 addIntValue<unsigned long long>(&ostr, pIColPos[iPos] + 1, iWidthCols);
192 ostr << L")\t" << p(m.valuePtr()[iPos]) << std::endl;
201 /** utility function to compare two Eigen::Sparse matrices to equality
203 template<typename T> bool equal(T const& s1, T const& s2)
206 // only compares elts when both inner iterators are "defined", so we assert that we compared all the non zero values
207 // i.e. the inner iterators where defined for the same values
208 std::size_t nbElts(0);
210 for (int k = 0; res && k != s1.outerSize(); ++k)
212 for (typename T::InnerIterator it1(s1, k), it2(s2, k); res && it1 && it2; ++it1, ++it2, ++nbElts)
214 res = (it1.value() == it2.value()
215 && it1.row() == it2.row()
216 && it1.col() == it2.col());
219 return res && (nbElts == s1.nonZeros()) && (nbElts == s2.nonZeros());
222 utility function to set non zero values of an Eigen::Sparse matrix to a fixed values
223 @param s : sparse matrix to modify
224 @param v : value to set (default to 1.)
226 template<typename T> bool setNonZero(T& s, typename Eigen::internal::traits<T>::Scalar v = 1.)
228 for (auto j = 0; j < s.outerSize(); ++j)
230 for (typename T::InnerIterator it(s, j); it; ++it)
240 template<typename Src, typename Sp>
241 void doAppend(Src SPARSE_CONST& src, int r, int c, Sp& dest)
243 typedef typename Eigen::internal::traits<Sp>::Scalar data_t;
244 mycopy_n(makeMatrixIterator<data_t>(src, makeNonZerosIterator(src)), nonZeros(src)
245 , makeMatrixIterator<data_t>(dest, makeTranslatedIterator(makeNonZerosIterator(src), Coords2D(r, c))));
248 template<typename Scalar1, typename Scalar2>
249 void doAppend(Eigen::SparseMatrix<Scalar1, Eigen::RowMajor> SPARSE_CONST& src, int r, int c, Eigen::SparseMatrix<Scalar2, Eigen::RowMajor>& dest)
251 typedef typename Eigen::SparseMatrix<Scalar1, Eigen::RowMajor>::InnerIterator srcIt_t;
252 for (std::size_t k = 0; k != src.outerSize(); ++k)
254 for (srcIt_t it(src, (int)k); it; ++it)
256 if (dest.isCompressed() && dest.coeff(it.row() + r, it.col() + c) == Scalar2(0))
258 dest.reserve(dest.nonZeros() + 1);
261 dest.insert(it.row() + r, it.col() + c) = it.value();
266 Sp is an Eigen::SparseMatrix
268 template<typename Sp, typename M>
269 void cwiseInPlaceProduct(Sp& sp, M SPARSE_CONST& m)
271 // should be a transform_n() over makeNonZerosIterator(src)
272 for (std::size_t k = 0; k != sp.outerSize(); ++k)
274 for (typename Sp::InnerIterator it(sp, k); it; ++it)
276 it.valueRef() *= get<typename Eigen::internal::traits<Sp>::Scalar >(m, it.row(), it.col());
288 inline T& operator()(T& /*x*/, T& y)
295 void getinsertedupdated(T* sp, types::Double* i, types::Double* j, int& updated, int& inserted)
297 int iRowSize = i->getSize();
298 int iColSize = j->getSize();
299 double* pI = i->get();
300 double* pJ = j->get();
305 for (int i = 0; i < iRowSize; i++)
307 for (int j = 0; j < iColSize; j++)
309 auto val = sp->coeff(static_cast<int>(pI[i] - 1), static_cast<int>(pJ[j] - 1));
323 void getinsertedupdated(T* sp, types::Double* i, int& updated, int& inserted)
325 int iSize = i->getSize();
326 double* pIdx = i->get();
327 int rows = static_cast<int>(sp->rows());
332 for (int i = 0; i < iSize; i++)
334 int iRow = static_cast<int>(pIdx[i] - 1) % rows;
335 int iCol = static_cast<int>(pIdx[i] - 1) / rows;
336 auto val = sp->coeff(iRow, iCol);
348 template<typename T, typename Arg>
349 T* create_new(Arg const& a)
355 Double* create_new(double const& d)
357 Double* res(new Double(1, 1, false));
363 Double* create_new(std::complex<double>const& c)
365 Double* res(new Double(1, 1, true));
366 res->set(0, 0, c.real());
367 res->setImg(0, 0, c.imag());
372 Double* create_new(Sparse const& s)
374 Sparse& cs(const_cast<Sparse&>(s)); // inherited member functions are not const-correct
375 Double* res(new Double(cs.getRows(), cs.getCols(), cs.isComplex()));
376 const_cast<Sparse&>(s).fill(*res);
386 Inspector::removeItem(this);
390 Sparse::Sparse(Sparse const& src)
391 : matrixReal(src.matrixReal ? new RealSparse_t(*src.matrixReal) : 0)
392 , matrixCplx(src.matrixCplx ? new CplxSparse_t(*src.matrixCplx) : 0)
395 m_iRows = const_cast<Sparse*>(&src)->getRows();
396 m_iCols = const_cast<Sparse*>(&src)->getCols();
397 m_iSize = m_iRows * m_iCols;
399 m_piDims[0] = m_iRows;
400 m_piDims[1] = m_iCols;
402 Inspector::addItem(this);
406 Sparse::Sparse(int _iRows, int _iCols, bool cplx)
407 : matrixReal(cplx ? 0 : new RealSparse_t(_iRows, _iCols))
408 , matrixCplx(cplx ? new CplxSparse_t(_iRows, _iCols) : 0)
412 m_iSize = _iRows * _iCols;
414 m_piDims[0] = _iRows;
415 m_piDims[1] = _iCols;
417 Inspector::addItem(this);
421 Sparse::Sparse(Double SPARSE_CONST& src)
424 int size = src.getSize();
425 int row = src.getRows();
426 Double* idx = new Double(src.getSize(), 2);
427 double* p = idx->get();
428 for (int i = 0; i < size; ++i)
430 p[i] = (double)(i % row) + 1;
431 p[i + size] = (double)(i / row) + 1;
433 create2(src.getRows(), src.getCols(), src, *idx);
436 Inspector::addItem(this);
440 Sparse::Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx)
442 int idxrow = idx.getRows();
443 int rows = static_cast<int>(*std::max_element(idx.get(), idx.get() + idxrow));
444 int cols = static_cast<int>(*std::max_element(idx.get() + idxrow, idx.get() + idxrow * 2));
446 create2(rows, cols, src, idx);
448 Inspector::removeItem(this);
452 Sparse::Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims)
454 create2(static_cast<int>(dims.get(0)), static_cast<int>(dims.get(1)), src, idx);
456 Inspector::addItem(this);
460 Sparse::Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp) : matrixReal(realSp), matrixCplx(cplxSp)
464 m_iCols = static_cast<int>(realSp->cols());
465 m_iRows = static_cast<int>(realSp->rows());
469 m_iCols = static_cast<int>(cplxSp->cols());
470 m_iRows = static_cast<int>(cplxSp->rows());
472 m_iSize = m_iCols * m_iRows;
474 m_piDims[0] = m_iRows;
475 m_piDims[1] = m_iCols;
479 Inspector::addItem(this);
483 Sparse::Sparse(Double SPARSE_CONST& xadj, Double SPARSE_CONST& adjncy, Double SPARSE_CONST& src, std::size_t r, std::size_t c)
485 Adjacency a(xadj.get(), adjncy.get());
486 create(static_cast<int>(r), static_cast<int>(c), src, makeIteratorFromVar(a), src.getSize());
488 Inspector::addItem(this);
492 Sparse::Sparse(int rows, int cols, int nonzeros, int* inner, int* outer, double* real, double* img)
499 matrixCplx = new CplxSparse_t(rows, cols);
500 matrixCplx->reserve((int)nonzeros);
501 out = matrixCplx->outerIndexPtr();
502 in = matrixCplx->innerIndexPtr();
503 matrixReal = nullptr;
507 matrixReal = new RealSparse_t(rows, cols);
508 matrixReal->reserve((int)nonzeros);
509 out = matrixReal->outerIndexPtr();
510 in = matrixReal->innerIndexPtr();
511 matrixCplx = nullptr;
514 //update outerIndexPtr
515 memcpy(out, outer, sizeof(int) * (rows + 1));
516 //update innerIndexPtr
517 memcpy(in, inner, sizeof(int) * nonzeros);
521 std::complex<double>* data = matrixCplx->valuePtr();
522 for (int i = 0; i < nonzeros; ++i)
524 data[i] = std::complex<double>(real[i], img[i]);
529 double* data = matrixReal->valuePtr();
530 for (int i = 0; i < nonzeros; ++i)
539 m_iSize = cols * rows;
541 m_piDims[0] = m_iRows;
542 m_piDims[1] = m_iCols;
544 matrixCplx ? matrixCplx->resizeNonZeros(nonzeros) : matrixReal->resizeNonZeros(nonzeros);
549 bool Sparse::getMemory(long long *_piSize, long long* _piSizePlusType)
551 *_piSize = nonZeros() * sizeof(double) * (isComplex() ? 2 : 1);
552 *_piSizePlusType = *_piSize + sizeof(*this);
556 template<typename DestIter>
557 void Sparse::create(int rows, int cols, Double SPARSE_CONST& src, DestIter o, std::size_t n)
561 m_iSize = cols * rows;
563 m_piDims[0] = m_iRows;
564 m_piDims[1] = m_iCols;
569 matrixCplx = new CplxSparse_t(rows, cols);
570 matrixCplx->reserve((int)n);
571 mycopy_n(makeMatrixIterator<std::complex<double> >(src, RowWiseFullIterator(src.getRows(), src.getCols())), n, makeMatrixIterator<std::complex<double> >(*matrixCplx, o));
575 matrixReal = new RealSparse_t(rows, cols);
576 matrixReal->reserve((int)n);
578 mycopy_n(makeMatrixIterator<double >(src, RowWiseFullIterator(src.getRows(), src.getCols())), n
579 , makeMatrixIterator<double>(*matrixReal, o));
584 void Sparse::create2(int rows, int cols, Double SPARSE_CONST& src, Double SPARSE_CONST& idx)
586 int nnz = src.getSize();
587 double* i = idx.get();
588 double* j = i + idx.getRows();
589 double* valR = src.get();
595 std::vector<CplxTriplet_t> tripletList;
596 tripletList.reserve((int)nnz);
598 double* valI = src.getImg();
600 for (int k = 0; k < nnz; ++k)
602 tripletList.emplace_back(static_cast<int>(i[k]) - 1, static_cast<int>(j[k]) - 1, std::complex<double>(valR[k], valI[k]));
605 matrixCplx = new CplxSparse_t(rows, cols);
606 matrixCplx->setFromTriplets(tripletList.begin(), tripletList.end());
607 m_iRows = static_cast<int>(matrixCplx->rows());
608 m_iCols = static_cast<int>(matrixCplx->cols());
614 std::vector<RealTriplet_t> tripletList;
615 tripletList.reserve((int)nnz);
617 for (int k = 0; k < nnz; ++k)
619 tripletList.emplace_back(static_cast<int>(i[k]) - 1, static_cast<int>(j[k]) - 1, valR[k]);
622 matrixReal = new RealSparse_t(rows, cols);
623 matrixReal->setFromTriplets(tripletList.begin(), tripletList.end());
625 m_iRows = static_cast<int>(matrixReal->rows());
626 m_iCols = static_cast<int>(matrixReal->cols());
629 m_iSize = m_iCols * m_iRows;
631 m_piDims[0] = m_iRows;
632 m_piDims[1] = m_iCols;
636 void Sparse::fill(Double& dest, int r, int c) SPARSE_CONST
638 Sparse & cthis(const_cast<Sparse&>(*this));
641 mycopy_n(makeMatrixIterator<std::complex<double> >(*matrixCplx, RowWiseFullIterator(cthis.getRows(), cthis.getCols())), cthis.getSize()
642 , makeMatrixIterator<std::complex<double> >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
646 mycopy_n(makeMatrixIterator<double>(*matrixReal, RowWiseFullIterator(cthis.getRows(), cthis.getCols())), cthis.getSize()
647 , makeMatrixIterator<double >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
651 Sparse* Sparse::set(int _iRows, int _iCols, std::complex<double> v, bool _bFinalize)
653 if (_iRows >= getRows() || _iCols >= getCols())
658 typedef Sparse* (Sparse::*set_t)(int, int, std::complex<double>, bool);
659 Sparse* pIT = checkRef(this, (set_t)&Sparse::set, _iRows, _iCols, v, _bFinalize);
667 if (matrixReal->isCompressed() && matrixReal->coeff(_iRows, _iCols) == 0)
669 matrixReal->reserve(nonZeros() + 1);
672 matrixReal->coeffRef(_iRows, _iCols) = v.real();
676 if (matrixCplx->isCompressed() && matrixCplx->coeff(_iRows, _iCols) == std::complex<double>(0, 0))
678 matrixCplx->reserve(nonZeros() + 1);
681 matrixCplx->coeffRef(_iRows, _iCols) = v;
691 Sparse* Sparse::set(int _iRows, int _iCols, double _dblReal, bool _bFinalize)
693 if (_iRows >= getRows() || _iCols >= getCols())
698 typedef Sparse* (Sparse::*set_t)(int, int, double, bool);
699 Sparse* pIT = checkRef(this, (set_t)&Sparse::set, _iRows, _iCols, _dblReal, _bFinalize);
707 if (matrixReal->isCompressed() && matrixReal->coeff(_iRows, _iCols) == 0)
709 matrixReal->reserve(nonZeros() + 1);
712 matrixReal->coeffRef(_iRows, _iCols) = _dblReal;
716 if (matrixCplx->isCompressed() && matrixCplx->coeff(_iRows, _iCols) == std::complex<double>(0, 0))
718 matrixCplx->reserve(nonZeros() + 1);
721 matrixCplx->coeffRef(_iRows, _iCols) = std::complex<double>(_dblReal, 0);
733 void Sparse::finalize()
737 matrixCplx->prune(&keepForSparse<std::complex<double> >);
738 matrixCplx->finalize();
742 matrixReal->prune(&keepForSparse<double>);
743 matrixReal->finalize();
748 bool Sparse::neg(InternalType *& out)
750 SparseBool * _out = new SparseBool(getRows(), getCols());
751 types::neg(getRows(), getCols(), matrixReal, _out->matrixBool);
758 bool Sparse::isComplex() const
760 return static_cast<bool>(matrixCplx != NULL);
763 // TODO: should have both a bounds checking and a non-checking interface to elt access
764 double* Sparse::get()
766 if (isComplex() == false)
768 return matrixReal->valuePtr();
774 double Sparse::get(int _iRows, int _iCols) const
776 return getReal(_iRows, _iCols);
779 double Sparse::getReal(int _iRows, int _iCols) const
784 res = matrixReal->coeff(_iRows, _iCols);
788 res = matrixCplx->coeff(_iRows, _iCols).real();
793 std::complex<double>* Sparse::getImg()
797 return matrixCplx->valuePtr();
803 std::complex<double> Sparse::getImg(int _iRows, int _iCols) const
805 std::complex<double> res;
808 res = matrixCplx->coeff(_iRows, _iCols);
812 res = std::complex<double>(matrixReal->coeff(_iRows, _iCols), 0.);
818 void Sparse::whoAmI() SPARSE_CONST
820 std::cout << "types::Sparse";
823 Sparse* Sparse::clone(void)
825 return new Sparse(*this);
828 bool Sparse::zero_set()
832 matrixReal->setZero();
836 matrixCplx->setZero();
842 // TODO: handle precision and line length
843 bool Sparse::toString(std::wostringstream& ostr)
845 int iPrecision = ConfigVariable::getFormatSize();
849 res = ::toString(*matrixReal, iPrecision);
853 res = ::toString(*matrixCplx, iPrecision);
860 Sparse* Sparse::resize(int _iNewRows, int _iNewCols)
862 typedef Sparse* (Sparse::*resize_t)(int, int);
863 Sparse* pIT = checkRef(this, (resize_t)&Sparse::resize, _iNewRows, _iNewCols);
869 if (_iNewRows <= getRows() && _iNewCols <= getCols())
871 //nothing to do: hence we do NOT fail
881 size_t iNonZeros = nonZeros();
882 RealSparse_t *newReal = new RealSparse_t(_iNewRows, _iNewCols);
883 newReal->reserve((int)iNonZeros);
887 int* pRows = new int[iNonZeros * 2];
889 int* pCols = pRows + iNonZeros;
892 double* pNonZeroR = new double[iNonZeros];
893 double* pNonZeroI = new double[iNonZeros];
894 outputValues(pNonZeroR, pNonZeroI);
896 std::vector<RealTriplet_t> tripletList;
897 for (size_t i = 0; i < iNonZeros; i++)
899 tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, pNonZeroR[i]);
902 newReal->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
905 matrixReal = newReal;
913 size_t iNonZeros = nonZeros();
914 CplxSparse_t *newCplx = new CplxSparse_t(_iNewRows, _iNewCols);
915 newCplx->reserve((int)iNonZeros);
918 int* pRows = new int[iNonZeros * 2];
920 int* pCols = pRows + iNonZeros;
923 double* pNonZeroR = new double[iNonZeros];
924 double* pNonZeroI = new double[iNonZeros];
925 outputValues(pNonZeroR, pNonZeroI);
927 std::vector<CplxTriplet_t> tripletList;
928 for (size_t i = 0; i < iNonZeros; i++)
930 tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, std::complex<double>(pNonZeroR[i], pNonZeroI[i]));
933 newCplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
937 matrixCplx = newCplx;
945 m_iSize = _iNewRows * _iNewCols;
946 m_piDims[0] = m_iRows;
947 m_piDims[1] = m_iCols;
957 // TODO decide if a complex matrix with 0 imag can be == to a real matrix
958 // not true for dense (cf double.cpp)
959 bool Sparse::operator==(const InternalType& it) SPARSE_CONST
961 Sparse* otherSparse = const_cast<Sparse*>(dynamic_cast<Sparse const*>(&it));/* types::GenericType is not const-correct :( */
962 Sparse & cthis(const_cast<Sparse&>(*this));
964 if (otherSparse == NULL)
969 if (otherSparse->getRows() != cthis.getRows())
974 if (otherSparse->getCols() != cthis.getCols())
979 if (otherSparse->isComplex() != isComplex())
986 return equal(*matrixCplx, *otherSparse->matrixCplx);
990 return equal(*matrixReal, *otherSparse->matrixReal);
994 bool Sparse::one_set()
998 return setNonZero(*matrixCplx);
1002 return setNonZero(*matrixReal);
1006 void Sparse::toComplex()
1012 matrixCplx = new CplxSparse_t(matrixReal->cast<std::complex<double> >());
1025 GenericType* Sparse::insertNew(typed_list* _pArgs)
1028 Sparse *pOut = NULL;
1030 int iDims = (int)_pArgs->size();
1031 int* piMaxDim = new int[iDims];
1032 int* piCountDim = new int[iDims];
1033 bool bComplex = isComplex();
1034 bool bUndefine = false;
1036 //evaluate each argument and replace by appropriate value and compute the count of combinations
1037 int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
1041 cleanIndexesArguments(_pArgs, &pArg);
1042 return createEmptyDouble();
1047 iSeqCount = -iSeqCount;
1053 //manage : and $ in creation by insertion
1055 int *piSourceDims = getDimsArray();
1057 for (int i = 0; i < iDims; i++)
1059 if (pArg[i] == NULL)
1069 piMaxDim[i] = piSourceDims[iSource];
1070 piCountDim[i] = piSourceDims[iSource];
1073 //replace pArg value by the new one
1074 pArg[i] = createDoubleVector(piMaxDim[i]);
1078 // piMaxDim[i] = piCountDim[i];
1083 //remove last dimension at size 1
1084 //remove last dimension if are == 1
1085 for (int i = (iDims - 1); i >= 2; i--)
1087 if (piMaxDim[i] == 1)
1098 if (checkArgValidity(pArg) == false)
1101 cleanIndexesArguments(_pArgs, &pArg);
1102 //contain bad index, like <= 0, ...
1110 pOut = new Sparse(piCountDim[0], 1, bComplex);
1115 pOut = new Sparse(1, piCountDim[0], bComplex);
1120 pOut = new Sparse(piMaxDim[0], piMaxDim[1], bComplex);
1121 //pOut = createEmpty(iDims, piMaxDim, bComplex);
1124 //insert values in new matrix
1125 Sparse* pOut2 = pOut->insert(&pArg, this);
1132 cleanIndexesArguments(_pArgs, &pArg);
1137 Sparse* Sparse::insert(typed_list* _pArgs, InternalType* _pSource)
1139 typedef Sparse* (Sparse::*insert_t)(typed_list*, InternalType*);
1140 Sparse* pIT = checkRef(this, (insert_t)&Sparse::insert, _pArgs, _pSource);
1146 if (_pSource->isSparse())
1148 return insert(_pArgs, _pSource->getAs<Sparse>());
1151 bool bNeedToResize = false;
1152 int iDims = (int)_pArgs->size();
1155 //sparse are only in 2 dims
1167 Double* pSource = _pSource->getAs<Double>();
1169 //evaluate each argument and replace by appropriate value and compute the count of combinations
1170 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1174 cleanIndexesArguments(_pArgs, &pArg);
1181 if (getRows() == 1 || getCols() == 1)
1184 if (getRows() * getCols() < piMaxDim[0])
1186 bNeedToResize = true;
1188 //need to enlarge sparse dimensions
1189 if (getCols() == 1 || getRows() * getCols() == 0)
1192 iNewRows = piMaxDim[0];
1195 else if (getRows() == 1)
1199 iNewCols = piMaxDim[0];
1203 else if ((size_t)getRows() * (size_t)getCols() < (size_t)piMaxDim[0])
1206 cleanIndexesArguments(_pArgs, &pArg);
1213 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
1215 bNeedToResize = true;
1216 iNewRows = std::max(getRows(), piMaxDim[0]);
1217 iNewCols = std::max(getCols(), piMaxDim[1]);
1221 //check number of insertion
1222 if (pSource->isScalar() == false && pSource->getSize() != iSeqCount)
1225 cleanIndexesArguments(_pArgs, &pArg);
1229 //now you are sure to be able to insert values
1232 if (resize(iNewRows, iNewCols) == NULL)
1235 cleanIndexesArguments(_pArgs, &pArg);
1241 if (pSource->isComplex() && isComplex() == false)
1246 int rows = getRows();
1247 int cols = getCols();
1249 int nnz = static_cast<int>(nonZeros());
1261 getinsertedupdated(matrixCplx, pArg[0]->getAs<Double>(), pArg[1]->getAs<Double>(), updated, inserted);
1265 getinsertedupdated(matrixReal, pArg[0]->getAs<Double>(), pArg[1]->getAs<Double>(), updated, inserted);
1272 getinsertedupdated(matrixCplx, pArg[0]->getAs<Double>(), updated, inserted);
1276 getinsertedupdated(matrixReal, pArg[0]->getAs<Double>(), updated, inserted);
1280 ratio = (double)inserted / (double)nnz;
1283 if (ratio < 0.05) // less 5%
1285 int nnzFinal = nnz + inserted;
1288 matrixCplx->reserve(nnzFinal);
1292 matrixReal->reserve(nnzFinal);
1297 double* pIdx = pArg[0]->getAs<Double>()->get();
1298 int rows = getRows();
1299 double* pR = pSource->get();
1300 double* pI = pSource->getImg();
1302 for (int i = 0; i < iSeqCount; i++)
1304 int iRow = static_cast<int>(pIdx[i] - 1) % rows;
1305 int iCol = static_cast<int>(pIdx[i] - 1) / rows;
1306 if (pSource->isScalar())
1308 if (pSource->isComplex())
1310 set(iRow, iCol, std::complex<double>(pR[0], pI[0]), false);
1314 set(iRow, iCol, pR[0], false);
1319 if (pSource->isComplex())
1321 set(iRow, iCol, std::complex<double>(pR[i], pI[i]), false);
1325 set(iRow, iCol, pR[i], false);
1332 double* pIdxRow = pArg[0]->getAs<Double>()->get();
1333 int iRowSize = pArg[0]->getAs<Double>()->getSize();
1334 double* pIdxCol = pArg[1]->getAs<Double>()->get();
1335 double* pR = pSource->get();
1336 double* pI = pSource->getImg();
1337 if (pSource->isScalar())
1342 std::complex<double> val(pR[0], pI[0]);
1343 for (int i = 0; i < iSeqCount; i++)
1345 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, val, false);
1352 for (int i = 0; i < iSeqCount; i++)
1354 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, val, false);
1363 for (int i = 0; i < iSeqCount; i++)
1365 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, std::complex<double>(pR[i], pI[i]), false);
1371 for (int i = 0; i < iSeqCount; i++)
1373 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pR[i], false);
1385 std::vector<CplxTriplet_t> tripletList;
1387 double* pIdx = pArg[0]->getAs<Double>()->get();
1388 double* srcR = pSource->get();
1389 double* srcI = NULL;
1391 int incR = pSource->isScalar() ? 0 : 1;
1394 if (pSource->isComplex())
1396 srcI = pSource->getImg();
1397 incI = pSource->isScalar() ? 0 : 1;
1408 std::complex<double>* val = matrixCplx->valuePtr();
1411 for (int k = 0; k < matrixCplx->outerSize(); ++k)
1413 for (CplxSparse_t::InnerIterator it(*matrixCplx, k); it; ++it)
1415 //m[static_cast<size_t>(it.row()) + static_cast<size_t>(it.col()) * rows] = it.value();
1416 tripletList.emplace_back(it.row(), it.col(), it.value());
1420 matrixCplx->setZero();
1423 for (int i = 0; i < iSeqCount; i++)
1425 size_t idx = static_cast<size_t>(pIdx[i] - 1);
1426 int iRow = static_cast<int>(idx % rows);
1427 int iCol = static_cast<int>(idx / rows);
1428 //m[static_cast<size_t>(pIdx[i]) - 1] = std::complex<double>(*srcR, *srcI);
1429 tripletList.emplace_back(iRow, iCol, std::complex<double>(*srcR, *srcI));
1434 matrixCplx->reserve(static_cast<int>(tripletList.size()));
1435 matrixCplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
1440 std::vector<RealTriplet_t> tripletList;
1442 double* pIdx = pArg[0]->getAs<Double>()->get();
1443 double* src = pSource->get();
1444 int inc = pSource->isScalar() ? 0 : 1;
1449 for (int k = 0; k < matrixReal->outerSize(); ++k)
1451 for (RealSparse_t::InnerIterator it(*matrixReal, k); it; ++it)
1453 //m[static_cast<size_t>(it.row()) + static_cast<size_t>(it.col()) * rows] = it.value();
1454 tripletList.emplace_back(it.row(), it.col(), it.value());
1458 matrixReal->setZero();
1461 for (int i = 0; i < iSeqCount; i++)
1463 size_t idx = static_cast<size_t>(pIdx[i] - 1);
1464 int iRow = static_cast<int>(idx % rows);
1465 int iCol = static_cast<int>(idx / rows);
1466 //m[static_cast<size_t>(pIdx[i]) - 1] = *src;
1467 tripletList.emplace_back(iRow, iCol, *src);
1471 matrixReal->reserve(static_cast<int>(tripletList.size()));
1472 matrixReal->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
1478 int iRowSize = pArg[0]->getAs<Double>()->getSize();
1479 double* pI = pArg[0]->getAs<Double>()->get();
1480 double* pJ = pArg[1]->getAs<Double>()->get();
1484 std::vector<CplxTriplet_t> tripletList;
1485 double* srcR = pSource->get();
1486 double* srcI = NULL;
1488 int incR = pSource->isScalar() ? 0 : 1;
1491 if (pSource->isComplex())
1493 srcI = pSource->getImg();
1494 incI = pSource->isScalar() ? 0 : 1;
1505 for (int k = 0; k < matrixCplx->outerSize(); ++k)
1507 for (CplxSparse_t::InnerIterator it(*matrixCplx, k); it; ++it)
1509 //m[static_cast<size_t>(it.row()) + static_cast<size_t>(it.col()) * rows] = it.value();
1510 tripletList.emplace_back(it.row(), it.col(), it.value());
1514 matrixCplx->setZero();
1518 for (int i = 0; i < iSeqCount; i++)
1520 int iRow = static_cast<int>(i % iRowSize);
1521 int iCol = static_cast<int>(i / iRowSize);
1522 tripletList.emplace_back(static_cast<int>(pI[iRow] - 1), static_cast<int>(pJ[iCol] - 1), std::complex<double>(*srcR, *srcI));
1527 matrixCplx->reserve(static_cast<int>(tripletList.size()));
1528 matrixCplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
1532 std::vector<RealTriplet_t> tripletList;
1533 double* src = pSource->get();
1534 int inc = pSource->isScalar() ? 0 : 1;
1538 double* val = matrixReal->valuePtr();
1541 for (int k = 0; k < matrixReal->outerSize(); ++k)
1543 for (RealSparse_t::InnerIterator it(*matrixReal, k); it; ++it)
1545 //m[static_cast<size_t>(it.row()) + static_cast<size_t>(it.col()) * rows] = it.value();
1546 tripletList.emplace_back(it.row(), it.col(), it.value());
1552 for (int i = 0; i < iSeqCount; ++i)
1554 int iRow = static_cast<int>(i % iRowSize);
1555 int iCol = static_cast<int>(i / iRowSize);
1556 tripletList.emplace_back(static_cast<int>(pI[iRow]) - 1, static_cast<int>(pJ[iCol]) - 1, *src);
1560 matrixReal->setZero();
1561 matrixReal->reserve(static_cast<int>(tripletList.size()));
1562 matrixReal->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
1570 cleanIndexesArguments(_pArgs, &pArg);
1574 Sparse* Sparse::insert(typed_list* _pArgs, Sparse* _pSource)
1576 bool bNeedToResize = false;
1577 int iDims = (int)_pArgs->size();
1580 //sparse are only in 2 dims
1593 //evaluate each argument and replace by appropriate value and compute the count of combinations
1594 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1598 cleanIndexesArguments(_pArgs, &pArg);
1605 if (getRows() == 1 || getCols() == 1)
1608 bNeedToResize = true;
1609 if (getSize() < piMaxDim[0])
1611 //need to enlarge sparse dimensions
1612 if (getCols() == 1 || getSize() == 0)
1615 iNewRows = piMaxDim[0];
1618 else if (getRows() == 1)
1622 iNewCols = piMaxDim[0];
1626 else if (getSize() < piMaxDim[0])
1629 cleanIndexesArguments(_pArgs, &pArg);
1636 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
1638 bNeedToResize = true;
1639 iNewRows = std::max(getRows(), piMaxDim[0]);
1640 iNewCols = std::max(getCols(), piMaxDim[1]);
1644 //check number of insertion
1645 if (_pSource->isScalar() == false && _pSource->getSize() != iSeqCount)
1648 cleanIndexesArguments(_pArgs, &pArg);
1652 //now you are sure to be able to insert values
1655 if (resize(iNewRows, iNewCols) == NULL)
1658 cleanIndexesArguments(_pArgs, &pArg);
1664 if (_pSource->isComplex() && isComplex() == false)
1671 double* pIdx = pArg[0]->getAs<Double>()->get();
1672 for (int i = 0; i < iSeqCount; i++)
1674 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
1675 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
1677 if (_pSource->isScalar())
1679 if (_pSource->isComplex())
1681 set(iRow, iCol, _pSource->getImg(0, 0), false);
1685 set(iRow, iCol, _pSource->get(0, 0), false);
1690 int iRowOrig = i % _pSource->getRows();
1691 int iColOrig = i / _pSource->getRows();
1692 if (_pSource->isComplex())
1694 set(iRow, iCol, _pSource->getImg(iRowOrig, iColOrig), false);
1698 set(iRow, iCol, _pSource->get(iRowOrig, iColOrig), false);
1705 double* pIdxRow = pArg[0]->getAs<Double>()->get();
1706 int iRowSize = pArg[0]->getAs<Double>()->getSize();
1707 double* pIdxCol = pArg[1]->getAs<Double>()->get();
1709 for (int i = 0; i < iSeqCount; i++)
1711 if (_pSource->isScalar())
1713 if (_pSource->isComplex())
1715 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->getImg(0, 0), false);
1719 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(0, 0), false);
1724 int iRowOrig = i % _pSource->getRows();
1725 int iColOrig = i / _pSource->getRows();
1726 if (_pSource->isComplex())
1728 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->getImg(iRowOrig, iColOrig), false);
1732 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(iRowOrig, iColOrig), false);
1741 cleanIndexesArguments(_pArgs, &pArg);
1746 GenericType* Sparse::remove(typed_list* _pArgs)
1748 Sparse* pOut = NULL;
1749 int iDims = (int)_pArgs->size();
1752 //sparse are only in 2 dims
1761 //evaluate each argument and replace by appropriate value and compute the count of combinations
1762 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
1766 cleanIndexesArguments(_pArgs, &pArg);
1770 bool* pbFull = new bool[iDims];
1771 //coord must represent all values on a dimension
1772 for (int i = 0; i < iDims; i++)
1775 int iDimToCheck = getVarMaxDim(i, iDims);
1776 int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
1778 //we can have index more than once
1779 if (iIndexSize >= iDimToCheck)
1781 //size is good, now check datas
1782 double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
1783 for (int j = 0; j < iDimToCheck; j++)
1786 for (int k = 0; k < iIndexSize; k++)
1788 if ((int)pIndexes[k] == j + 1)
1799 //only one dims can be not full/entire
1800 bool bNotEntire = false;
1802 bool bTooMuchNotEntire = false;
1803 for (int i = 0; i < iDims; i++)
1805 if (pbFull[i] == false)
1807 if (bNotEntire == false)
1814 bTooMuchNotEntire = true;
1822 if (bTooMuchNotEntire == true)
1825 cleanIndexesArguments(_pArgs, &pArg);
1829 //find index to keep
1830 int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
1831 double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
1832 int iKeepSize = getVarMaxDim(iNotEntire, iDims);
1833 bool* pbKeep = new bool[iKeepSize];
1835 //fill pbKeep with true value
1836 for (int i = 0; i < iKeepSize; i++)
1841 for (int i = 0; i < iNotEntireSize; i++)
1843 int idx = (int)piNotEntireIndex[i] - 1;
1845 //don't care of value out of bounds
1846 if (idx < iKeepSize)
1848 pbKeep[idx] = false;
1852 int iNewDimSize = 0;
1853 for (int i = 0; i < iKeepSize; i++)
1855 if (pbKeep[i] == true)
1862 int* piNewDims = new int[iDims];
1863 for (int i = 0; i < iDims; i++)
1865 if (i == iNotEntire)
1867 piNewDims[i] = iNewDimSize;
1871 piNewDims[i] = getVarMaxDim(i, iDims);
1875 //remove last dimension if are == 1
1876 int iOrigDims = iDims;
1877 for (int i = (iDims - 1); i >= 2; i--)
1879 if (piNewDims[i] == 1)
1889 if (iNewDimSize == 0)
1893 cleanIndexesArguments(_pArgs, &pArg);
1894 return new Sparse(0, 0);
1899 //two cases, depends of original matrix/vector
1900 if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
1902 //special case for row vector
1903 pOut = new Sparse(1, iNewDimSize, isComplex());
1904 //in this case we have to care of 2nd dimension
1909 pOut = new Sparse(iNewDimSize, 1, isComplex());
1914 pOut = new Sparse(piNewDims[0], piNewDims[1], isComplex());
1918 //find a way to copy existing data to new variable ...
1920 int* piIndexes = new int[iOrigDims];
1921 int* piViewDims = new int[iOrigDims];
1922 for (int i = 0; i < iOrigDims; i++)
1924 piViewDims[i] = getVarMaxDim(i, iOrigDims);
1927 for (int i = 0; i < getSize(); i++)
1929 bool bByPass = false;
1930 getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
1932 //check if piIndexes use removed indexes
1933 for (int j = 0; j < iNotEntireSize; j++)
1935 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
1937 //by pass this value
1943 if (bByPass == false)
1948 pOut->set(iNewPos, getImg(i));
1952 pOut->set(iNewPos, get(i));
1959 delete[] piViewDims;
1962 cleanIndexesArguments(_pArgs, &pArg);
1967 Sparse* Sparse::append(int r, int c, types::Sparse SPARSE_CONST* src)
1969 Sparse* pIT = checkRef(this, &Sparse::append, r, c, src);
1975 // 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;
1976 if (src->isComplex())
1982 if (src->isComplex())
1984 doAppend(*(src->matrixCplx), r, c, *matrixCplx);
1988 doAppend(*(src->matrixReal), r, c, *matrixCplx);
1993 doAppend(*(src->matrixReal), r, c, *matrixReal);
1998 return this; // realloc is meaningless for sparse matrices
2002 * create a new Sparse of dims according to resSize and fill it from currentSparse (along coords)
2004 GenericType* Sparse::extract(typed_list* _pArgs)
2006 Sparse* pOut = NULL;
2007 int iDims = (int)_pArgs->size();
2010 int* piMaxDim = new int[iDims];
2011 int* piCountDim = new int[iDims];
2013 //evaluate each argument and replace by appropriate value and compute the count of combinations
2014 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
2018 cleanIndexesArguments(_pArgs, &pArg);
2019 if (_pArgs->size() == 0)
2023 delete[] piCountDim;
2025 cleanIndexesArguments(_pArgs, &pArg);
2032 delete[] piCountDim;
2034 cleanIndexesArguments(_pArgs, &pArg);
2035 return new types::Sparse(0,0,false);
2041 if (piMaxDim[0] <= getSize())
2046 if (getRows() == 1 && getCols() != 1 && (*_pArgs)[0]->isColon() == false)
2048 //special case for row vector
2050 iNewCols = piCountDim[0];
2054 iNewRows = piCountDim[0];
2058 double* pIdx = pArg[0]->getAs<Double>()->get();
2061 bool bIsReal = true;
2062 std::vector<CplxTriplet_t> tripletList;
2063 std::vector<RealTriplet_t> realTripletList;
2064 int row = getRows();
2065 for (int i = 0; i < iSeqCount; i++)
2067 int iRowRead = static_cast<int>(pIdx[i] - 1) % row;
2068 int iColRead = static_cast<int>(pIdx[i] - 1) / row;
2069 int iRowWrite = i % iNewRows;
2070 int iColWrite = i / iNewRows;
2072 std::complex<double> dbl = getImg(iRowRead, iColRead);
2075 //only non zero values
2076 tripletList.emplace_back(iRowWrite, iColWrite, dbl);
2077 bIsReal &= (dbl.imag() == 0);
2080 realTripletList.emplace_back(iRowWrite, iColWrite, dbl.real());
2086 RealSparse_t* real = new RealSparse_t(iNewRows, iNewCols);
2087 real->setFromTriplets(realTripletList.begin(), realTripletList.end(), DupFunctor<double>());
2088 pOut = new Sparse(real, nullptr);
2092 CplxSparse_t* cplx = new CplxSparse_t(iNewRows, iNewCols);
2093 cplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
2094 pOut = new Sparse(nullptr, cplx);
2099 RealSparse_t* real = new RealSparse_t(iNewRows, iNewCols);
2100 std::vector<RealTriplet_t> tripletList;
2101 int row = getRows();
2102 for (int i = 0; i < iSeqCount; i++)
2104 int iRowRead = static_cast<int>(pIdx[i] - 1) % row;
2105 int iColRead = static_cast<int>(pIdx[i] - 1) / row;
2106 int iRowWrite = i % iNewRows;
2107 int iColWrite = i / iNewRows;
2109 double dbl = get(iRowRead, iColRead);
2112 //only non zero values
2113 tripletList.emplace_back(iRowWrite, iColWrite, dbl);
2117 real->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
2118 pOut = new Sparse(real, nullptr);
2124 delete[] piCountDim;
2126 cleanIndexesArguments(_pArgs, &pArg);
2132 if (piMaxDim[0] <= getRows() && piMaxDim[1] <= getCols())
2134 double* pIdxRow = pArg[0]->getAs<Double>()->get();
2135 double* pIdxCol = pArg[1]->getAs<Double>()->get();
2137 int iNewRows = pArg[0]->getAs<Double>()->getSize();
2138 int iNewCols = pArg[1]->getAs<Double>()->getSize();
2142 bool bIsReal = true;
2143 std::vector<CplxTriplet_t> tripletList;
2144 std::vector<RealTriplet_t> realTripletList;
2146 for (int iRow = 0; iRow < iNewRows; iRow++)
2148 for (int iCol = 0; iCol < iNewCols; iCol++)
2150 std::complex<double> dbl = getImg((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
2153 //only non zero values
2154 tripletList.emplace_back(iRow, iCol, dbl);
2155 bIsReal &= (dbl.imag() == 0.);
2158 realTripletList.emplace_back(iRow, iCol, dbl.real());
2165 RealSparse_t* real = new RealSparse_t(iNewRows, iNewCols);
2166 real->setFromTriplets(realTripletList.begin(), realTripletList.end(), DupFunctor<double>());
2167 pOut = new Sparse(real, nullptr);
2171 CplxSparse_t* cplx = new CplxSparse_t(iNewRows, iNewCols);
2172 cplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
2173 pOut = new Sparse(nullptr, cplx);
2178 RealSparse_t* real = new RealSparse_t(iNewRows, iNewCols);
2179 std::vector<RealTriplet_t> tripletList;
2180 for (int iRow = 0; iRow < iNewRows; iRow++)
2182 for (int iCol = 0; iCol < iNewCols; iCol++)
2184 double dbl = get((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
2187 //only non zero values
2188 tripletList.emplace_back(iRow, iCol, dbl);
2193 real->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
2194 pOut = new Sparse(real, nullptr);
2200 delete[] piCountDim;
2202 cleanIndexesArguments(_pArgs, &pArg);
2210 delete[] piCountDim;
2212 cleanIndexesArguments(_pArgs, &pArg);
2217 Sparse* Sparse::extract(int nbCoords, int SPARSE_CONST* coords, int SPARSE_CONST* maxCoords, int SPARSE_CONST* resSize, bool asVector) SPARSE_CONST
2219 if ((asVector && maxCoords[0] > getSize()) ||
2220 (asVector == false && maxCoords[0] > getRows()) ||
2221 (asVector == false && maxCoords[1] > getCols()))
2226 bool const cplx(isComplex());
2230 pSp = (getRows() == 1) ? new Sparse(1, resSize[0], cplx) : new Sparse(resSize[0], 1, cplx);
2234 pSp = new Sparse(resSize[0], resSize[1], cplx);
2236 // std::cerr<<"extracted sparse:"<<pSp->getRows()<<", "<<pSp->getCols()<<"seqCount="<<nbCoords<<"maxDim="<<maxCoords[0] <<","<< maxCoords[1]<<std::endl;
2238 ? copyToSparse(*this, Coords<true>(coords, getRows()), nbCoords
2239 , *pSp, RowWiseFullIterator(pSp->getRows(), pSp->getCols()))
2240 : copyToSparse(*this, Coords<false>(coords), nbCoords
2241 , *pSp, RowWiseFullIterator(pSp->getRows(), pSp->getCols()))))
2249 bool Sparse::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
2253 out.push_back(this);
2257 InternalType * _out = extract(&in);
2260 std::wostringstream os;
2261 os << _W("Invalid index.\n");
2262 throw ast::InternalError(os.str(), 999, e.getLocation());
2264 out.push_back(_out);
2271 bool Sparse::isInvokable() const
2276 bool Sparse::hasInvokeOption() const
2281 int Sparse::getInvokeNbIn()
2286 int Sparse::getInvokeNbOut()
2292 coords are Scilab 1-based
2293 extract std::make_pair(coords, asVector), rowIter
2295 template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
2296 bool Sparse::copyToSparse(Src SPARSE_CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav)
2298 if (!(src.isComplex() || sp.isComplex()))
2300 mycopy_n(makeMatrixIterator<double>(src, srcTrav), n
2301 , makeMatrixIterator<double>(*sp.matrixReal, destTrav));
2306 mycopy_n(makeMatrixIterator<std::complex<double> >(src, srcTrav), n
2307 , makeMatrixIterator<std::complex<double> >(*sp.matrixCplx, destTrav));
2314 // GenericType because we might return a Double* for scalar operand
2315 Sparse* Sparse::add(Sparse const& o) const
2317 RealSparse_t* realSp(0);
2318 CplxSparse_t* cplxSp(0);
2319 if (isComplex() == false && o.isComplex() == false)
2322 realSp = new RealSparse_t(*matrixReal + * (o.matrixReal));
2324 else if (isComplex() == false && o.isComplex() == true)
2326 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() + * (o.matrixCplx));
2328 else if (isComplex() == true && o.isComplex() == false)
2330 cplxSp = new CplxSparse_t(*matrixCplx + o.matrixReal->cast<std::complex<double> >());
2332 else if (isComplex() == true && o.isComplex() == true)
2334 cplxSp = new CplxSparse_t(*matrixCplx + * (o.matrixCplx));
2337 return new Sparse(realSp, cplxSp);
2340 Sparse* Sparse::substract(Sparse const& o) const
2342 RealSparse_t* realSp(0);
2343 CplxSparse_t* cplxSp(0);
2344 if (isComplex() == false && o.isComplex() == false)
2347 realSp = new RealSparse_t(*matrixReal - * (o.matrixReal));
2349 else if (isComplex() == false && o.isComplex() == true)
2352 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() - * (o.matrixCplx));
2354 else if (isComplex() == true && o.isComplex() == false)
2357 cplxSp = new CplxSparse_t(*matrixCplx - o.matrixReal->cast<std::complex<double> >());
2359 else if (isComplex() == true && o.isComplex() == true)
2362 cplxSp = new CplxSparse_t(*matrixCplx - * (o.matrixCplx));
2365 return new Sparse(realSp, cplxSp);
2368 Sparse* Sparse::multiply(double s) const
2370 return new Sparse(isComplex() ? 0 : new RealSparse_t((*matrixReal)*s)
2371 , isComplex() ? new CplxSparse_t((*matrixCplx)*s) : 0);
2374 Sparse* Sparse::multiply(std::complex<double> s) const
2377 , isComplex() ? new CplxSparse_t((*matrixCplx) * s) : new CplxSparse_t((*matrixReal) * s));
2380 Sparse* Sparse::multiply(Sparse const& o) const
2382 RealSparse_t* realSp(0);
2383 CplxSparse_t* cplxSp(0);
2385 if (isComplex() == false && o.isComplex() == false)
2387 realSp = new RealSparse_t(*matrixReal **(o.matrixReal));
2389 else if (isComplex() == false && o.isComplex() == true)
2391 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >() **(o.matrixCplx));
2393 else if (isComplex() == true && o.isComplex() == false)
2395 cplxSp = new CplxSparse_t(*matrixCplx * o.matrixReal->cast<std::complex<double> >());
2397 else if (isComplex() == true && o.isComplex() == true)
2399 cplxSp = new CplxSparse_t(*matrixCplx **(o.matrixCplx));
2402 return new Sparse(realSp, cplxSp);
2405 Sparse* Sparse::dotMultiply(Sparse SPARSE_CONST& o) const
2407 RealSparse_t* realSp(0);
2408 CplxSparse_t* cplxSp(0);
2409 if (isComplex() == false && o.isComplex() == false)
2411 realSp = new RealSparse_t(matrixReal->cwiseProduct(*(o.matrixReal)));
2413 else if (isComplex() == false && o.isComplex() == true)
2415 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >().cwiseProduct(*(o.matrixCplx)));
2417 else if (isComplex() == true && o.isComplex() == false)
2419 cplxSp = new CplxSparse_t(matrixCplx->cwiseProduct(o.matrixReal->cast<std::complex<double> >()));
2421 else if (isComplex() == true && o.isComplex() == true)
2423 cplxSp = new CplxSparse_t(matrixCplx->cwiseProduct(*(o.matrixCplx)));
2426 return new Sparse(realSp, cplxSp);
2429 Sparse* Sparse::dotDivide(Sparse SPARSE_CONST& o) const
2431 RealSparse_t* realSp(0);
2432 CplxSparse_t* cplxSp(0);
2433 if (isComplex() == false && o.isComplex() == false)
2435 realSp = new RealSparse_t(matrixReal->cwiseQuotient(*(o.matrixReal)));
2437 else if (isComplex() == false && o.isComplex() == true)
2439 cplxSp = new CplxSparse_t(matrixReal->cast<std::complex<double> >().cwiseQuotient(*(o.matrixCplx)));
2441 else if (isComplex() == true && o.isComplex() == false)
2443 cplxSp = new CplxSparse_t(matrixCplx->cwiseQuotient(o.matrixReal->cast<std::complex<double> >()));
2445 else if (isComplex() == true && o.isComplex() == true)
2447 cplxSp = new CplxSparse_t(matrixCplx->cwiseQuotient(*(o.matrixCplx)));
2450 return new Sparse(realSp, cplxSp);
2453 int Sparse::newCholLLT(Sparse** _SpPermut, Sparse** _SpFactor) const
2455 typedef Eigen::SparseMatrix<double, Eigen::ColMajor> RealSparseCol_t;
2456 RealSparseCol_t spColMajor = RealSparseCol_t((const RealSparse_t&) * matrixReal);
2458 // Constructs and performs the LLT factorization of sparse
2459 Eigen::SimplicialLLT<RealSparseCol_t> pLLT(spColMajor);
2460 int iInfo = pLLT.info();
2461 if (iInfo != Eigen::Success)
2468 // Get the lower matrix of factorization.
2469 // The new RealSparse_t will be set in Sparse without copy.
2470 *_SpFactor = new Sparse(new RealSparse_t(pLLT.matrixL()), NULL);
2472 // Get the permutation matrix.
2473 Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic, int> p = pLLT.permutationP();
2474 *_SpPermut = new Sparse(static_cast<int>(p.rows()), static_cast<int>(p.cols()));
2475 for (int i = 0; i < p.rows(); i++)
2477 (*_SpPermut)->set(i, p.indices()[i], 1, false);
2480 (*_SpPermut)->finalize();
2485 bool Sparse::transpose(InternalType *& out)
2487 out = new Sparse(matrixReal ? new RealSparse_t(matrixReal->transpose()) : 0, matrixCplx ? new CplxSparse_t(matrixCplx->transpose()) : 0);
2491 bool Sparse::adjoint(InternalType *& out)
2493 out = new Sparse(matrixReal ? new RealSparse_t(matrixReal->adjoint()) : 0, matrixCplx ? new CplxSparse_t(matrixCplx->adjoint()) : 0);
2499 BoolCast(std::complex<double> const& c) : b(c.real() || c.imag()) {}
2500 operator bool() const
2504 operator double() const
2510 Sparse* Sparse::newOnes() const
2512 // result is never cplx
2513 return new Sparse(matrixReal
2514 ? new RealSparse_t(matrixReal->cast<bool>().cast<double>())
2515 : new RealSparse_t(matrixCplx->cast<BoolCast>().cast<double>())
2521 RealCast(std::complex<double> const& c) : b(c.real()) {}
2522 operator bool() const
2526 operator double() const
2532 Sparse* Sparse::newReal() const
2534 return new Sparse(matrixReal
2536 : new RealSparse_t(matrixCplx->cast<RealCast>().cast<double>())
2540 std::size_t Sparse::nonZeros() const
2544 return matrixCplx->nonZeros();
2548 return matrixReal->nonZeros();
2551 std::size_t Sparse::nonZeros(std::size_t r) const
2556 int* piIndex = matrixReal->outerIndexPtr();
2557 res = piIndex[r + 1] - piIndex[r];
2561 int* piIndex = matrixCplx->outerIndexPtr();
2562 res = piIndex[r + 1] - piIndex[r];
2568 int* Sparse::getNbItemByRow(int* _piNbItemByRows)
2570 int* piNbItemByCols = new int[getRows() + 1];
2573 mycopy_n(matrixCplx->outerIndexPtr(), getRows() + 1, piNbItemByCols);
2577 mycopy_n(matrixReal->outerIndexPtr(), getRows() + 1, piNbItemByCols);
2580 for (int i = 0; i < getRows(); i++)
2582 _piNbItemByRows[i] = piNbItemByCols[i + 1] - piNbItemByCols[i];
2585 delete[] piNbItemByCols;
2586 return _piNbItemByRows;
2589 int* Sparse::getColPos(int* _piColPos)
2593 mycopy_n(matrixCplx->innerIndexPtr(), nonZeros(), _piColPos);
2597 mycopy_n(matrixReal->innerIndexPtr(), nonZeros(), _piColPos);
2600 for (size_t i = 0; i < nonZeros(); i++)
2608 int* Sparse::getInnerPtr(int* count)
2613 ret = matrixCplx->innerIndexPtr();
2614 *count = static_cast<int>(matrixCplx->innerSize());
2618 ret = matrixReal->innerIndexPtr();
2619 *count = static_cast<int>(matrixReal->innerSize());
2625 int* Sparse::getOuterPtr(int* count)
2630 ret = matrixCplx->outerIndexPtr();
2631 *count = static_cast<int>(matrixCplx->outerSize());
2635 ret = matrixReal->outerIndexPtr();
2636 *count = static_cast<int>(matrixReal->outerSize());
2644 template<typename S> struct GetReal : std::unary_function<typename S::InnerIterator, double>
2646 double operator()(typename S::InnerIterator it) const
2651 template<> struct GetReal< Eigen::SparseMatrix<std::complex<double >, Eigen::RowMajor > >
2652 : std::unary_function<Sparse::CplxSparse_t::InnerIterator, double>
2654 double operator()(Sparse::CplxSparse_t::InnerIterator it) const
2656 return it.value().real();
2659 template<typename S> struct GetImag : std::unary_function<typename S::InnerIterator, double>
2661 double operator()(typename S::InnerIterator it) const
2663 return it.value().imag();
2666 template<typename S> struct GetRow : std::unary_function<typename S::InnerIterator, int>
2668 int operator()(typename S::InnerIterator it) const
2670 return static_cast<int>(it.row() + 1);
2673 template<typename S> struct GetCol : std::unary_function<typename S::InnerIterator, int>
2675 int operator()(typename S::InnerIterator it) const
2677 return static_cast<int>(it.col() + 1);
2681 template<typename S, typename Out, typename F> Out sparseTransform(S& s, Out o, F f)
2683 int size = static_cast<int>(s.outerSize());
2684 for (std::size_t k(0); k < size; ++k)
2686 for (typename S::InnerIterator it(s, (int)k); it; ++it, ++o)
2695 std::pair<double*, double*> Sparse::outputValues(double* outReal, double* outImag)const
2698 ? std::make_pair(sparseTransform(*matrixReal, outReal, GetReal<RealSparse_t>()), outImag)
2699 : std::make_pair(sparseTransform(*matrixCplx, outReal, GetReal<CplxSparse_t>())
2700 , sparseTransform(*matrixCplx, outImag, GetImag<CplxSparse_t>()));
2703 int* Sparse::outputRowCol(int* out)const
2706 ? sparseTransform(*matrixReal, sparseTransform(*matrixReal, out, GetRow<RealSparse_t>()), GetCol<RealSparse_t>())
2707 : sparseTransform(*matrixCplx, sparseTransform(*matrixCplx, out, GetRow<CplxSparse_t>()), GetCol<CplxSparse_t>());
2709 double* Sparse::outputCols(double* out) const
2713 mycopy_n(matrixCplx->innerIndexPtr(), nonZeros(), out);
2717 mycopy_n(matrixReal->innerIndexPtr(), nonZeros(), out);
2720 return std::transform(out, out, out, std::bind(std::plus<double>(), std::placeholders::_1, 1));
2724 void Sparse::opposite(void)
2728 std::complex<double>* data = matrixCplx->valuePtr();
2729 std::transform(data, data + matrixCplx->nonZeros(), data, std::negate<std::complex<double> >());
2733 double* data = matrixReal->valuePtr();
2734 std::transform(data, data + matrixReal->nonZeros(), data, std::negate<double>());
2738 SparseBool* Sparse::newLessThan(Sparse &o)
2740 //only real values !
2742 //return cwiseOp<std::less>(*this, o);
2743 int rowL = getRows();
2744 int colL = getCols();
2746 int rowR = o.getRows();
2747 int colR = o.getCols();
2748 int row = std::max(rowL, rowR);
2749 int col = std::max(colL, colR);
2751 //create a boolean sparse matrix with dims of sparses
2752 types::SparseBool* ret = new types::SparseBool(row, col);
2753 if (isScalar() && o.isScalar())
2755 double l = get(0, 0);
2756 double r = o.get(0, 0);
2757 ret->set(0, 0, l < r, false);
2759 else if (isScalar())
2761 int nnzR = static_cast<int>(o.nonZeros());
2762 std::vector<int> rowcolR(nnzR * 2, 0);
2763 o.outputRowCol(rowcolR.data());
2765 //compare all items of R with R[0]
2766 double l = get(0, 0);
2770 ret->setTrue(false);
2773 for (int i = 0; i < nnzR; ++i)
2775 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2776 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l < r, false);
2779 else if (o.isScalar())
2781 int nnzL = static_cast<int>(nonZeros());
2782 std::vector<int> rowcolL(nnzL * 2, 0);
2783 outputRowCol(rowcolL.data());
2785 double r = o.get(0, 0);
2791 for (int i = 0; i < nnzL; ++i)
2793 double l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
2794 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l < r, false);
2799 int nnzR = static_cast<int>(o.nonZeros());
2800 std::vector<int> rowcolR(nnzR * 2, 0);
2801 o.outputRowCol(rowcolR.data());
2802 int nnzL = static_cast<int>(nonZeros());
2803 std::vector<int> rowcolL(nnzL * 2, 0);
2804 outputRowCol(rowcolL.data());
2805 //set all values to %t
2806 ret->setFalse(false);
2808 for (int i = 0; i < nnzL; ++i)
2810 double l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
2811 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l < 0, false);
2815 //set _pR[i] == _pL[i] for each _pR values
2816 for (int i = 0; i < nnzR; ++i)
2818 //get l and r following non zeros value of R
2819 double l = get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2820 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2821 //set value following non zeros value of R
2822 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l < r, false);
2830 SparseBool* Sparse::newNotEqualTo(Sparse const&o) const
2832 return cwiseOp<std::not_equal_to>(*this, o);
2835 SparseBool* Sparse::newLessOrEqual(Sparse &o)
2837 //only real values !
2839 //return cwiseOp<std::less>(*this, o);
2840 int rowL = getRows();
2841 int colL = getCols();
2843 int rowR = o.getRows();
2844 int colR = o.getCols();
2845 int row = std::max(rowL, rowR);
2846 int col = std::max(colL, colR);
2848 //create a boolean sparse matrix with dims of sparses
2849 types::SparseBool* ret = new types::SparseBool(row, col);
2850 if (isScalar() && o.isScalar())
2852 double l = get(0, 0);
2853 double r = o.get(0, 0);
2854 ret->set(0, 0, l <= r, false);
2856 else if (isScalar())
2858 int nnzR = static_cast<int>(o.nonZeros());
2859 std::vector<int> rowcolR(nnzR * 2, 0);
2860 o.outputRowCol(rowcolR.data());
2862 //compare all items of R with R[0]
2863 double l = get(0, 0);
2867 ret->setTrue(false);
2870 for (int i = 0; i < nnzR; ++i)
2872 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2873 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l <= r, false);
2876 else if (o.isScalar())
2878 int nnzL = static_cast<int>(nonZeros());
2879 std::vector<int> rowcolL(nnzL * 2, 0);
2880 outputRowCol(rowcolL.data());
2882 double r = o.get(0, 0);
2888 for (int i = 0; i < nnzL; ++i)
2890 double l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
2891 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l <= r, false);
2896 int nnzR = static_cast<int>(o.nonZeros());
2897 std::vector<int> rowcolR(nnzR * 2, 0);
2898 o.outputRowCol(rowcolR.data());
2899 int nnzL = static_cast<int>(nonZeros());
2900 std::vector<int> rowcolL(nnzL * 2, 0);
2901 outputRowCol(rowcolL.data());
2902 //set all values to %t
2903 ret->setTrue(false);
2905 for (int i = 0; i < nnzL; ++i)
2907 double l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
2908 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l <= 0, false);
2912 //set _pR[i] == _pL[i] for each _pR values
2913 for (int i = 0; i < nnzR; ++i)
2915 //get l and r following non zeros value of R
2916 double l = get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2917 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2918 //set value following non zeros value of R
2919 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l <= r, false);
2927 SparseBool* Sparse::newEqualTo(Sparse &o)
2929 int rowL = getRows();
2930 int colL = getCols();
2932 int rowR = o.getRows();
2933 int colR = o.getCols();
2934 int row = std::max(rowL, rowR);
2935 int col = std::max(colL, colR);
2937 //create a boolean sparse matrix with dims of sparses
2938 types::SparseBool* ret = new types::SparseBool(row, col);
2939 if (isScalar() && o.isScalar())
2941 if (isComplex() || o.isComplex())
2943 std::complex<double> l = getImg(0, 0);
2944 std::complex<double> r = o.getImg(0, 0);
2945 ret->set(0, 0, l == r, false);
2949 double l = get(0, 0);
2950 double r = o.get(0, 0);
2951 ret->set(0, 0, l == r, false);
2954 else if (isScalar())
2956 int nnzR = static_cast<int>(o.nonZeros());
2957 std::vector<int> rowcolR(nnzR * 2, 0);
2958 o.outputRowCol(rowcolR.data());
2960 //compare all items of R with R[0]
2961 if (isComplex() || o.isComplex())
2963 std::complex<double> l = getImg(0, 0);
2964 for (int i = 0; i < nnzR; ++i)
2966 std::complex<double> r = o.getImg(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2967 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
2972 double l = get(0, 0);
2973 for (int i = 0; i < nnzR; ++i)
2975 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
2976 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
2980 else if (o.isScalar())
2982 int nnzL = static_cast<int>(nonZeros());
2983 std::vector<int> rowcolL(nnzL * 2, 0);
2984 outputRowCol(rowcolL.data());
2986 if (isComplex() || o.isComplex())
2988 std::complex<double> r = o.getImg(0, 0);
2989 for (int i = 0; i < nnzL; ++i)
2991 std::complex<double> l = getImg(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
2992 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l == r, false);
2997 double r = get(0, 0);
2998 for (int i = 0; i < nnzL; ++i)
3000 double l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
3001 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l == r, false);
3007 int nnzR = static_cast<int>(o.nonZeros());
3008 std::vector<int> rowcolR(nnzR * 2, 0);
3009 o.outputRowCol(rowcolR.data());
3010 int nnzL = static_cast<int>(nonZeros());
3011 std::vector<int> rowcolL(nnzL * 2, 0);
3012 outputRowCol(rowcolL.data());
3013 //set all values to %t
3014 ret->setTrue(false);
3015 //set %f in each pL values
3016 for (int i = 0; i < nnzL; ++i)
3018 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, false, false);
3022 //set _pR[i] == _pL[i] for each _pR values
3023 if (isComplex() || o.isComplex())
3025 for (int i = 0; i < nnzR; ++i)
3027 //get l and r following non zeros value of R
3028 std::complex<double> l = getImg(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
3029 std::complex<double> r = o.getImg(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
3030 //set value following non zeros value of R
3031 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
3036 for (int i = 0; i < nnzR; ++i)
3038 //get l and r following non zeros value of R
3039 double l = get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
3040 double r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
3041 //set value following non zeros value of R
3042 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
3051 Sparse* Sparse::reshape(int* _piDims, int _iDims)
3063 pSp = reshape(_piDims[0], iCols);
3069 Sparse* Sparse::reshape(int _iNewRows, int _iNewCols)
3071 typedef Sparse* (Sparse::*reshape_t)(int, int);
3072 Sparse* pIT = checkRef(this, (reshape_t)&Sparse::reshape, _iNewRows, _iNewCols);
3078 if (_iNewRows * _iNewCols != getRows() * getCols())
3089 size_t iNonZeros = nonZeros();
3090 RealSparse_t *newReal = new RealSparse_t(_iNewRows, _iNewCols);
3091 newReal->reserve((int)iNonZeros);
3094 int* pRows = new int[iNonZeros * 2];
3095 outputRowCol(pRows);
3096 int* pCols = pRows + iNonZeros;
3099 double* pNonZeroR = new double[iNonZeros];
3100 double* pNonZeroI = new double[iNonZeros];
3101 outputValues(pNonZeroR, pNonZeroI);
3103 std::vector<RealTriplet_t> tripletList;
3104 for (size_t i = 0; i < iNonZeros; i++)
3106 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
3107 tripletList.emplace_back((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), pNonZeroR[i]);
3110 newReal->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<double>());
3113 matrixReal = newReal;
3121 size_t iNonZeros = nonZeros();
3122 CplxSparse_t *newCplx = new CplxSparse_t(_iNewRows, _iNewCols);
3123 newCplx->reserve((int)iNonZeros);
3126 int* pRows = new int[iNonZeros * 2];
3127 outputRowCol(pRows);
3128 int* pCols = pRows + iNonZeros;
3131 double* pNonZeroR = new double[iNonZeros];
3132 double* pNonZeroI = new double[iNonZeros];
3133 outputValues(pNonZeroR, pNonZeroI);
3135 std::vector<CplxTriplet_t> tripletList;
3137 for (size_t i = 0; i < iNonZeros; i++)
3139 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
3140 tripletList.emplace_back((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), std::complex<double>(pNonZeroR[i], pNonZeroI[i]));
3143 newCplx->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<std::complex<double>>());
3146 matrixCplx = newCplx;
3152 m_iRows = _iNewRows;
3153 m_iCols = _iNewCols;
3154 m_iSize = _iNewRows * _iNewCols;
3157 m_piDims[0] = m_iRows;
3158 m_piDims[1] = m_iCols;
3171 // SparseBool* SparseBool::new
3173 SparseBool::SparseBool(Bool SPARSE_CONST& src)
3176 int size = src.getSize();
3177 int row = src.getRows();
3178 Double* idx = new Double(src.getSize(), 2);
3179 double* p = idx->get();
3180 for (int i = 0; i < size; ++i)
3182 p[i] = (double)(i % row) + 1;
3183 p[i + size] = (double)(i / row) + 1;
3185 create2(src.getRows(), src.getCols(), src, *idx);
3188 Inspector::addItem(this);
3191 /* @param src : Bool matrix to copy into a new sparse matrix
3192 @param idx : Double matrix to use as indexes to get values from the src
3194 SparseBool::SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx)
3196 int idxrow = idx.getRows();
3197 int rows = static_cast<int>(*std::max_element(idx.get(), idx.get() + idxrow));
3198 int cols = static_cast<int>(*std::max_element(idx.get() + idxrow, idx.get() + idxrow * 2));
3199 create2(rows, cols, src, idx);
3201 Inspector::addItem(this);
3205 /* @param src : Bool matrix to copy into a new sparse matrix
3206 @param idx : Double matrix to use as indexes to get values from the src
3207 @param dims : Double matrix containing the dimensions of the new matrix
3209 SparseBool::SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims)
3211 create2(static_cast<int>(dims.get(0)), static_cast<int>(dims.get(1)), src, idx);
3213 Inspector::addItem(this);
3217 SparseBool::SparseBool(int _iRows, int _iCols) : matrixBool(new BoolSparse_t(_iRows, _iCols))
3221 m_iSize = _iRows * _iCols;
3223 m_piDims[0] = _iRows;
3224 m_piDims[1] = _iCols;
3226 Inspector::addItem(this);
3230 SparseBool::SparseBool(SparseBool const& src) : matrixBool(new BoolSparse_t(*src.matrixBool))
3233 m_iRows = const_cast<SparseBool*>(&src)->getRows();
3234 m_iCols = const_cast<SparseBool*>(&src)->getCols();
3235 m_iSize = m_iRows * m_iCols;
3236 m_piDims[0] = m_iRows;
3237 m_piDims[1] = m_iCols;
3239 Inspector::addItem(this);
3243 SparseBool::SparseBool(BoolSparse_t* src) : matrixBool(src)
3245 m_iRows = static_cast<int>(src->rows());
3246 m_iCols = static_cast<int>(src->cols());
3247 m_iSize = m_iRows * m_iCols;
3249 m_piDims[0] = m_iRows;
3250 m_piDims[1] = m_iCols;
3252 Inspector::addItem(this);
3256 SparseBool::SparseBool(int rows, int cols, int trues, int* inner, int* outer)
3261 matrixBool = new BoolSparse_t(rows, cols);
3262 matrixBool->reserve((int)trues);
3263 out = matrixBool->outerIndexPtr();
3264 in = matrixBool->innerIndexPtr();
3266 //update outerIndexPtr
3267 memcpy(out, outer, sizeof(int) * (rows + 1));
3268 //update innerIndexPtr
3269 memcpy(in, inner, sizeof(int) * trues);
3271 bool* data = matrixBool->valuePtr();
3272 for (int i = 0; i < trues; ++i)
3279 m_iSize = cols * rows;
3281 m_piDims[0] = m_iRows;
3282 m_piDims[1] = m_iCols;
3284 matrixBool->resizeNonZeros(trues);
3287 bool SparseBool::getMemory(long long *_piSize, long long* _piSizePlusType)
3289 *_piSize = nbTrue() * sizeof(bool);
3290 *_piSizePlusType = *_piSize + sizeof(*this);
3294 void SparseBool::create2(int rows, int cols, Bool SPARSE_CONST& src, Double SPARSE_CONST& idx)
3296 int nnz = src.getSize();
3297 double* i = idx.get();
3298 double* j = i + idx.getRows();
3299 int* val = src.get();
3301 std::vector<BoolTriplet_t> tripletList;
3302 tripletList.reserve((int)nnz);
3304 for (int k = 0; k < nnz; ++k)
3306 tripletList.emplace_back(static_cast<int>(i[k]) - 1, static_cast<int>(j[k]) - 1, val[k] == 1);
3309 matrixBool = new BoolSparse_t(rows, cols);
3310 matrixBool->setFromTriplets(tripletList.begin(), tripletList.end());
3312 m_iRows = static_cast<int>(matrixBool->rows());
3313 m_iCols = static_cast<int>(matrixBool->cols());
3314 m_iSize = cols * rows;
3316 m_piDims[0] = m_iRows;
3317 m_piDims[1] = m_iCols;
3321 SparseBool::~SparseBool()
3325 Inspector::removeItem(this);
3329 bool SparseBool::toString(std::wostringstream& ostr)
3331 ostr << ::toString(*matrixBool, 0);
3335 void SparseBool::whoAmI() SPARSE_CONST
3337 std::cout << "types::SparseBool";
3340 SparseBool* SparseBool::clone(void)
3342 return new SparseBool(*this);
3345 SparseBool* SparseBool::resize(int _iNewRows, int _iNewCols)
3347 typedef SparseBool* (SparseBool::*resize_t)(int, int);
3348 SparseBool* pIT = checkRef(this, (resize_t)&SparseBool::resize, _iNewRows, _iNewCols);
3354 if (_iNewRows <= getRows() && _iNewCols <= getCols())
3356 //nothing to do: hence we do NOT fail
3360 SparseBool* res = NULL;
3364 size_t iNonZeros = nbTrue();
3366 BoolSparse_t *newBool = new BoolSparse_t(_iNewRows, _iNewCols);
3367 newBool->reserve((int)iNonZeros);
3370 int* pRows = new int[iNonZeros * 2];
3371 outputRowCol(pRows);
3372 int* pCols = pRows + iNonZeros;
3374 std::vector<BoolTriplet_t> tripletList;
3376 for (size_t i = 0; i < iNonZeros; i++)
3378 tripletList.emplace_back((int)pRows[i] - 1, (int)pCols[i] - 1, true);
3381 newBool->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<bool>());
3384 matrixBool = newBool;
3387 m_iRows = _iNewRows;
3388 m_iCols = _iNewCols;
3389 m_iSize = _iNewRows * _iNewCols;
3390 m_piDims[0] = m_iRows;
3391 m_piDims[1] = m_iCols;
3402 SparseBool* SparseBool::insert(typed_list* _pArgs, SparseBool* _pSource)
3404 bool bNeedToResize = false;
3405 int iDims = (int)_pArgs->size();
3408 //sparse are only in 2 dims
3421 //evaluate each argument and replace by appropriate value and compute the count of combinations
3422 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
3426 cleanIndexesArguments(_pArgs, &pArg);
3433 if (getRows() == 1 || getCols() == 1)
3436 if (getRows() * getCols() < piMaxDim[0])
3438 bNeedToResize = true;
3440 //need to enlarge sparse dimensions
3441 if (getCols() == 1 || getSize() == 0)
3444 iNewRows = piMaxDim[0];
3447 else if (getRows() == 1)
3451 iNewCols = piMaxDim[0];
3455 else if (getRows() * getCols() < piMaxDim[0])
3458 cleanIndexesArguments(_pArgs, &pArg);
3465 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
3467 bNeedToResize = true;
3468 iNewRows = std::max(getRows(), piMaxDim[0]);
3469 iNewCols = std::max(getCols(), piMaxDim[1]);
3473 //check number of insertion
3474 if (_pSource->isScalar() == false && _pSource->getSize() != iSeqCount)
3477 cleanIndexesArguments(_pArgs, &pArg);
3481 //now you are sure to be able to insert values
3484 if (resize(iNewRows, iNewCols) == NULL)
3487 cleanIndexesArguments(_pArgs, &pArg);
3494 double* pIdx = pArg[0]->getAs<Double>()->get();
3495 for (int i = 0; i < iSeqCount; i++)
3497 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
3498 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
3500 if (_pSource->isScalar())
3502 set(iRow, iCol, _pSource->get(0, 0), false);
3506 int iRowOrig = i % _pSource->getRows();
3507 int iColOrig = i / _pSource->getRows();
3508 set(iRow, iCol, _pSource->get(iRowOrig, iColOrig), false);
3514 double* pIdxRow = pArg[0]->getAs<Double>()->get();
3515 int iRowSize = pArg[0]->getAs<Double>()->getSize();
3516 double* pIdxCol = pArg[1]->getAs<Double>()->get();
3518 for (int i = 0; i < iSeqCount; i++)
3520 if (_pSource->isScalar())
3522 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(0, 0), false);
3526 int iRowOrig = i % _pSource->getRows();
3527 int iColOrig = i / _pSource->getRows();
3528 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, _pSource->get(iRowOrig, iColOrig), false);
3536 cleanIndexesArguments(_pArgs, &pArg);
3541 SparseBool* SparseBool::insert(typed_list* _pArgs, InternalType* _pSource)
3543 typedef SparseBool* (SparseBool::*insert_t)(typed_list*, InternalType*);
3544 SparseBool* pIT = checkRef(this, (insert_t)&SparseBool::insert, _pArgs, _pSource);
3552 if (_pSource->isSparseBool())
3554 return insert(_pArgs, _pSource->getAs<SparseBool>());
3557 bool bNeedToResize = false;
3558 int iDims = (int)_pArgs->size();
3561 //sparse are only in 2 dims
3573 Bool* pSource = _pSource->getAs<Bool>();
3575 //evaluate each argument and replace by appropriate value and compute the count of combinations
3576 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
3580 cleanIndexesArguments(_pArgs, &pArg);
3587 if (getRows() == 1 || getCols() == 1)
3590 bNeedToResize = true;
3591 if (getRows() * getCols() < piMaxDim[0])
3593 //need to enlarge sparse dimensions
3594 if (getCols() == 1 || getRows() * getCols() == 0)
3597 iNewRows = piMaxDim[0];
3600 else if (getRows() == 1)
3604 iNewCols = piMaxDim[0];
3608 else if (getRows() * getCols() < piMaxDim[0])
3611 cleanIndexesArguments(_pArgs, &pArg);
3618 if (piMaxDim[0] > getRows() || piMaxDim[1] > getCols())
3620 bNeedToResize = true;
3621 iNewRows = std::max(getRows(), piMaxDim[0]);
3622 iNewCols = std::max(getCols(), piMaxDim[1]);
3626 //check number of insertion
3627 if (pSource->isScalar() == false && pSource->getSize() != iSeqCount)
3630 cleanIndexesArguments(_pArgs, &pArg);
3634 //now you are sure to be able to insert values
3637 if (resize(iNewRows, iNewCols) == NULL)
3640 cleanIndexesArguments(_pArgs, &pArg);
3647 double* pIdx = pArg[0]->getAs<Double>()->get();
3648 for (int i = 0; i < iSeqCount; i++)
3650 int iRow = static_cast<int>(pIdx[i] - 1) % getRows();
3651 int iCol = static_cast<int>(pIdx[i] - 1) / getRows();
3652 if (pSource->isScalar())
3654 set(iRow, iCol, pSource->get(0) != 0, false);
3658 set(iRow, iCol, pSource->get(i) != 0, false);
3664 double* pIdxRow = pArg[0]->getAs<Double>()->get();
3665 int iRowSize = pArg[0]->getAs<Double>()->getSize();
3666 double* pIdxCol = pArg[1]->getAs<Double>()->get();
3668 for (int i = 0; i < iSeqCount; i++)
3670 if (pSource->isScalar())
3672 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(0) != 0, false);
3676 int iRowOrig = i % pSource->getRows();
3677 int iColOrig = i / pSource->getRows();
3679 set((int)pIdxRow[i % iRowSize] - 1, (int)pIdxCol[i / iRowSize] - 1, pSource->get(iRowOrig, iColOrig) != 0, false);
3687 cleanIndexesArguments(_pArgs, &pArg);
3691 GenericType* SparseBool::remove(typed_list* _pArgs)
3693 SparseBool* pOut = NULL;
3694 int iDims = (int)_pArgs->size();
3697 //sparse are only in 2 dims
3706 //evaluate each argument and replace by appropriate value and compute the count of combinations
3707 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
3711 cleanIndexesArguments(_pArgs, &pArg);
3715 bool* pbFull = new bool[iDims];
3716 //coord must represent all values on a dimension
3717 for (int i = 0; i < iDims; i++)
3720 int iDimToCheck = getVarMaxDim(i, iDims);
3721 int iIndexSize = pArg[i]->getAs<GenericType>()->getSize();
3723 //we can have index more than once
3724 if (iIndexSize >= iDimToCheck)
3726 //size is good, now check datas
3727 double* pIndexes = getDoubleArrayFromDouble(pArg[i]);
3728 for (int j = 0; j < iDimToCheck; j++)
3731 for (int k = 0; k < iIndexSize; k++)
3733 if ((int)pIndexes[k] == j + 1)
3744 //only one dims can be not full/entire
3745 bool bNotEntire = false;
3747 bool bTooMuchNotEntire = false;
3748 for (int i = 0; i < iDims; i++)
3750 if (pbFull[i] == false)
3752 if (bNotEntire == false)
3759 bTooMuchNotEntire = true;
3767 if (bTooMuchNotEntire == true)
3770 cleanIndexesArguments(_pArgs, &pArg);
3774 //find index to keep
3775 int iNotEntireSize = pArg[iNotEntire]->getAs<GenericType>()->getSize();
3776 double* piNotEntireIndex = getDoubleArrayFromDouble(pArg[iNotEntire]);
3777 int iKeepSize = getVarMaxDim(iNotEntire, iDims);
3778 bool* pbKeep = new bool[iKeepSize];
3780 //fill pbKeep with true value
3781 for (int i = 0; i < iKeepSize; i++)
3786 for (int i = 0; i < iNotEntireSize; i++)
3788 int idx = (int)piNotEntireIndex[i] - 1;
3790 //don't care of value out of bounds
3791 if (idx < iKeepSize)
3793 pbKeep[idx] = false;
3797 int iNewDimSize = 0;
3798 for (int i = 0; i < iKeepSize; i++)
3800 if (pbKeep[i] == true)
3807 int* piNewDims = new int[iDims];
3808 for (int i = 0; i < iDims; i++)
3810 if (i == iNotEntire)
3812 piNewDims[i] = iNewDimSize;
3816 piNewDims[i] = getVarMaxDim(i, iDims);
3820 //remove last dimension if are == 1
3821 int iOrigDims = iDims;
3822 for (int i = (iDims - 1); i >= 2; i--)
3824 if (piNewDims[i] == 1)
3836 if (iNewDimSize == 0)
3839 cleanIndexesArguments(_pArgs, &pArg);
3841 return new SparseBool(0, 0);
3845 //two cases, depends of original matrix/vector
3846 if ((*_pArgs)[0]->isColon() == false && m_iDims == 2 && m_piDims[0] == 1 && m_piDims[1] != 1)
3848 //special case for row vector
3849 pOut = new SparseBool(1, iNewDimSize);
3850 //in this case we have to care of 2nd dimension
3855 pOut = new SparseBool(iNewDimSize, 1);
3861 pOut = new SparseBool(piNewDims[0], piNewDims[0]);
3865 //find a way to copy existing data to new variable ...
3867 int* piIndexes = new int[iOrigDims];
3868 int* piViewDims = new int[iOrigDims];
3869 for (int i = 0; i < iOrigDims; i++)
3871 piViewDims[i] = getVarMaxDim(i, iOrigDims);
3874 for (int i = 0; i < getSize(); i++)
3876 bool bByPass = false;
3877 getIndexesWithDims(i, piIndexes, piViewDims, iOrigDims);
3879 //check if piIndexes use removed indexes
3880 for (int j = 0; j < iNotEntireSize; j++)
3882 if ((piNotEntireIndex[j] - 1) == piIndexes[iNotEntire])
3884 //by pass this value
3890 if (bByPass == false)
3893 pOut->set(iNewPos, get(i));
3899 delete[] piViewDims;
3902 cleanIndexesArguments(_pArgs, &pArg);
3907 SparseBool* SparseBool::append(int r, int c, SparseBool SPARSE_CONST* src)
3909 SparseBool* pIT = checkRef(this, &SparseBool::append, r, c, src);
3915 doAppend(*src, r, c, *matrixBool);
3920 GenericType* SparseBool::insertNew(typed_list* _pArgs)
3923 SparseBool *pOut = NULL;
3925 int iDims = (int)_pArgs->size();
3926 int* piMaxDim = new int[iDims];
3927 int* piCountDim = new int[iDims];
3928 bool bUndefine = false;
3930 //evaluate each argument and replace by appropriate value and compute the count of combinations
3931 int iSeqCount = checkIndexesArguments(NULL, _pArgs, &pArg, piMaxDim, piCountDim);
3935 cleanIndexesArguments(_pArgs, &pArg);
3936 return createEmptyDouble();
3941 iSeqCount = -iSeqCount;
3947 //manage : and $ in creation by insertion
3949 int *piSourceDims = getDimsArray();
3951 for (int i = 0; i < iDims; i++)
3953 if (pArg[i] == NULL)
3963 piMaxDim[i] = piSourceDims[iSource];
3964 piCountDim[i] = piSourceDims[iSource];
3967 //replace pArg value by the new one
3968 pArg[i] = createDoubleVector(piMaxDim[i]);
3972 // piMaxDim[i] = piCountDim[i];
3977 //remove last dimension at size 1
3978 //remove last dimension if are == 1
3979 for (int i = (iDims - 1); i >= 2; i--)
3981 if (piMaxDim[i] == 1)
3992 if (checkArgValidity(pArg) == false)
3995 cleanIndexesArguments(_pArgs, &pArg);
3996 //contain bad index, like <= 0, ...
4004 pOut = new SparseBool(piCountDim[0], 1);
4009 pOut = new SparseBool(1, piCountDim[0]);
4014 pOut = new SparseBool(piMaxDim[0], piMaxDim[1]);
4017 //insert values in new matrix
4018 SparseBool* pOut2 = pOut->insert(&pArg, this);
4025 cleanIndexesArguments(_pArgs, &pArg);
4030 SparseBool* SparseBool::extract(int nbCoords, int SPARSE_CONST* coords, int SPARSE_CONST* maxCoords, int SPARSE_CONST* resSize, bool asVector) SPARSE_CONST
4032 if ((asVector && maxCoords[0] > getSize()) ||
4033 (asVector == false && maxCoords[0] > getRows()) ||
4034 (asVector == false && maxCoords[1] > getCols()))
4039 SparseBool * pSp(0);
4042 pSp = (getRows() == 1) ? new SparseBool(1, resSize[0]) : new SparseBool(resSize[0], 1);
4043 mycopy_n(makeMatrixIterator<bool>(*this, Coords<true>(coords, getRows())), nbCoords
4044 , makeMatrixIterator<bool>(*(pSp->matrixBool), RowWiseFullIterator(pSp->getRows(), pSp->getCols())));
4048 pSp = new SparseBool(resSize[0], resSize[1]);
4049 mycopy_n(makeMatrixIterator<bool>(*this, Coords<false>(coords, getRows())), nbCoords
4050 , makeMatrixIterator<bool>(*(pSp->matrixBool), RowWiseFullIterator(pSp->getRows(), pSp->getCols())));
4057 * create a new SparseBool of dims according to resSize and fill it from currentSparseBool (along coords)
4059 GenericType* SparseBool::extract(typed_list* _pArgs)
4061 SparseBool* pOut = NULL;
4062 int iDims = (int)_pArgs->size();
4065 int* piMaxDim = new int[iDims];
4066 int* piCountDim = new int[iDims];
4068 //evaluate each argument and replace by appropriate value and compute the count of combinations
4069 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
4073 cleanIndexesArguments(_pArgs, &pArg);
4074 if (_pArgs->size() == 0)
4077 delete[] piCountDim;
4084 delete[] piCountDim;
4086 return new types::SparseBool(0,0);
4092 // Check that we stay inside the input size.
4093 if (piMaxDim[0] <= getSize())
4098 if (getRows() == 1 && getCols() != 1 && (*_pArgs)[0]->isColon() == false)
4100 //special case for row vector
4102 iNewCols = piCountDim[0];
4106 iNewRows = piCountDim[0];
4110 pOut = new SparseBool(iNewRows, iNewCols);
4111 double* pIdx = pArg[0]->getAs<Double>()->get();
4112 // Write in output all elements extract from input.
4113 for (int i = 0; i < iSeqCount; i++)
4121 int iRowRead = static_cast<int>(pIdx[i] - 1) % getRows();
4122 int iColRead = static_cast<int>(pIdx[i] - 1) / getRows();
4124 int iRowWrite = static_cast<int>(i) % iNewRows;
4125 int iColWrite = static_cast<int>(i) / iNewRows;
4127 bool bValue = get(iRowRead, iColRead);
4130 //only non zero values
4131 pOut->set(iRowWrite, iColWrite, true, false);
4138 delete[] piCountDim;
4140 cleanIndexesArguments(_pArgs, &pArg);
4146 // Check that we stay inside the input size.
4147 if (piMaxDim[0] <= getRows() && piMaxDim[1] <= getCols())
4149 double* pIdxRow = pArg[0]->getAs<Double>()->get();
4150 double* pIdxCol = pArg[1]->getAs<Double>()->get();
4152 int iNewRows = pArg[0]->getAs<Double>()->getSize();
4153 int iNewCols = pArg[1]->getAs<Double>()->getSize();
4155 pOut = new SparseBool(iNewRows, iNewCols);
4158 // Write in output all elements extract from input.
4159 for (int iRow = 0; iRow < iNewRows; iRow++)
4161 for (int iCol = 0; iCol < iNewCols; iCol++)
4163 if ((pIdxRow[iRow] < 1) || (pIdxCol[iCol] < 1))
4168 delete[] piCountDim;
4170 cleanIndexesArguments(_pArgs, &pArg);
4173 bool bValue = get((int)pIdxRow[iRow] - 1, (int)pIdxCol[iCol] - 1);
4176 //only non zero values
4177 pOut->set(iRow, iCol, true, false);
4186 delete[] piCountDim;
4188 cleanIndexesArguments(_pArgs, &pArg);
4199 delete[] piCountDim;
4201 cleanIndexesArguments(_pArgs, &pArg);
4206 bool SparseBool::invoke(typed_list & in, optional_list &/*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
4210 out.push_back(this);
4214 InternalType * _out = extract(&in);
4217 std::wostringstream os;
4218 os << _W("Invalid index.\n");
4219 throw ast::InternalError(os.str(), 999, e.getLocation());
4221 out.push_back(_out);
4227 bool SparseBool::isInvokable() const
4232 bool SparseBool::hasInvokeOption() const
4237 int SparseBool::getInvokeNbIn()
4242 int SparseBool::getInvokeNbOut()
4247 std::size_t SparseBool::nbTrue() const
4249 return matrixBool->nonZeros();
4251 std::size_t SparseBool::nbTrue(std::size_t r) const
4253 int* piIndex = matrixBool->outerIndexPtr();
4254 return piIndex[r + 1] - piIndex[r];
4258 void SparseBool::setTrue(bool finalize)
4260 int rows = getRows();
4261 int cols = getCols();
4263 std::vector<BoolTriplet_t> tripletList;
4265 for (int i = 0; i < rows; ++i)
4267 for (int j = 0; j < cols; ++j)
4269 tripletList.emplace_back(i, j, true);
4273 matrixBool->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<bool>());
4277 matrixBool->finalize();
4281 void SparseBool::setFalse(bool finalize)
4283 int rows = getRows();
4284 int cols = getCols();
4286 std::vector<BoolTriplet_t> tripletList;
4288 for (int i = 0; i < rows; ++i)
4290 for (int j = 0; j < cols; ++j)
4292 tripletList.emplace_back(i, j, false);
4296 matrixBool->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<bool>());
4300 matrixBool->finalize();
4304 int* SparseBool::getNbItemByRow(int* _piNbItemByRows)
4306 int* piNbItemByRows = new int[getRows() + 1];
4307 mycopy_n(matrixBool->outerIndexPtr(), getRows() + 1, piNbItemByRows);
4309 for (int i = 0; i < getRows(); i++)
4311 _piNbItemByRows[i] = piNbItemByRows[i + 1] - piNbItemByRows[i];
4314 delete[] piNbItemByRows;
4315 return _piNbItemByRows;
4318 int* SparseBool::getColPos(int* _piColPos)
4320 mycopy_n(matrixBool->innerIndexPtr(), nbTrue(), _piColPos);
4321 for (size_t i = 0; i < nbTrue(); i++)
4329 int* SparseBool::outputRowCol(int* out)const
4331 return sparseTransform(*matrixBool, sparseTransform(*matrixBool, out, GetRow<BoolSparse_t>()), GetCol<BoolSparse_t>());
4334 int* SparseBool::getInnerPtr(int* count)
4336 *count = static_cast<int>(matrixBool->innerSize());
4337 return matrixBool->innerIndexPtr();
4340 int* SparseBool::getOuterPtr(int* count)
4342 *count = static_cast<int>(matrixBool->outerSize());
4343 return matrixBool->outerIndexPtr();
4347 bool SparseBool::operator==(const InternalType& it) SPARSE_CONST
4349 SparseBool* otherSparse = const_cast<SparseBool*>(dynamic_cast<SparseBool const*>(&it));/* types::GenericType is not const-correct :( */
4351 && (otherSparse->getRows() == getRows())
4352 && (otherSparse->getCols() == getCols())
4353 && equal(*matrixBool, *otherSparse->matrixBool));
4356 bool SparseBool::operator!=(const InternalType& it) SPARSE_CONST
4358 return !(*this == it);
4361 void SparseBool::finalize()
4363 matrixBool->prune(&keepForSparse<bool>);
4364 matrixBool->finalize();
4367 bool SparseBool::get(int r, int c) SPARSE_CONST
4369 return matrixBool->coeff(r, c);
4372 SparseBool* SparseBool::set(int _iRows, int _iCols, bool _bVal, bool _bFinalize) SPARSE_CONST
4374 typedef SparseBool* (SparseBool::*set_t)(int, int, bool, bool);
4375 SparseBool* pIT = checkRef(this, (set_t)&SparseBool::set, _iRows, _iCols, _bVal, _bFinalize);
4381 if (matrixBool->isCompressed() && matrixBool->coeff(_iRows, _iCols) == false)
4383 matrixBool->reserve(1);
4386 matrixBool->coeffRef(_iRows, _iCols) = _bVal;
4396 void SparseBool::fill(Bool& dest, int r, int c) SPARSE_CONST
4398 mycopy_n(makeMatrixIterator<bool >(*matrixBool, RowWiseFullIterator(getRows(), getCols())), getSize()
4399 , makeMatrixIterator<bool >(dest, RowWiseFullIterator(dest.getRows(), dest.getCols(), r, c)));
4402 Sparse* SparseBool::newOnes() const
4404 return new Sparse(new types::Sparse::RealSparse_t(matrixBool->cast<double>()), 0);
4407 SparseBool* SparseBool::newNotEqualTo(SparseBool const&o) const
4409 return cwiseOp<std::not_equal_to>(*this, o);
4412 SparseBool* SparseBool::newEqualTo(SparseBool& o)
4414 int rowL = getRows();
4415 int colL = getCols();
4417 int rowR = o.getRows();
4418 int colR = o.getCols();
4419 int row = std::max(rowL, rowR);
4420 int col = std::max(colL, colR);
4422 //create a boolean sparse matrix with dims of sparses
4423 types::SparseBool* ret = new types::SparseBool(row, col);
4425 if (isScalar() && o.isScalar())
4428 bool r = o.get(0, 0);
4429 ret->set(0, 0, l == r, false);
4431 else if (isScalar())
4433 int nnzR = static_cast<int>(o.nbTrue());
4434 std::vector<int> rowcolR(nnzR * 2, 0);
4435 o.outputRowCol(rowcolR.data());
4437 //compare all items of R with R[0]
4439 for (int i = 0; i < nnzR; ++i)
4441 bool r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
4442 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
4445 else if (o.isScalar())
4447 int nnzL = static_cast<int>(nbTrue());
4448 std::vector<int> rowcolL(nnzL * 2, 0);
4449 outputRowCol(rowcolL.data());
4452 for (int i = 0; i < nnzL; ++i)
4454 bool l = get(rowcolL[i] - 1, rowcolL[i + nnzL] - 1);
4455 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, l == r, false);
4460 int nnzR = static_cast<int>(o.nbTrue());
4461 std::vector<int> rowcolR(nnzR * 2, 0);
4462 o.outputRowCol(rowcolR.data());
4463 int nnzL = static_cast<int>(nbTrue());
4464 std::vector<int> rowcolL(nnzL * 2, 0);
4465 outputRowCol(rowcolL.data());
4466 //set all values to %t
4467 ret->setTrue(false);
4468 //set %f in each pL values
4469 for (int i = 0; i < nnzL; ++i)
4471 ret->set(rowcolL[i] - 1, rowcolL[i + nnzL] - 1, false, false);
4475 //set _pR[i] == _pL[i] for each _pR values
4476 for (int i = 0; i < nnzR; ++i)
4478 //get l and r following non zeros value of R
4479 bool l = get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
4480 bool r = o.get(rowcolR[i] - 1, rowcolR[i + nnzR] - 1);
4481 //set value following non zeros value of R
4482 ret->set(rowcolR[i] - 1, rowcolR[i + nnzR] - 1, l == r, false);
4490 SparseBool* SparseBool::newLogicalOr(SparseBool const&o) const
4492 return cwiseOp<std::logical_or>(*this, o);
4495 SparseBool* SparseBool::newLogicalAnd(SparseBool const&o) const
4497 return cwiseOp<std::logical_and>(*this, o);
4500 SparseBool* SparseBool::reshape(int* _piDims, int _iDims)
4502 SparseBool* pSpBool = NULL;
4512 pSpBool = reshape(_piDims[0], iCols);
4518 SparseBool* SparseBool::reshape(int _iNewRows, int _iNewCols)
4520 typedef SparseBool* (SparseBool::*reshape_t)(int, int);
4521 SparseBool* pIT = checkRef(this, (reshape_t)&SparseBool::reshape, _iNewRows, _iNewCols);
4527 if (_iNewRows * _iNewCols != getRows() * getCols())
4532 SparseBool* res = NULL;
4536 size_t iNonZeros = matrixBool->nonZeros();
4537 BoolSparse_t *newBool = new BoolSparse_t(_iNewRows, _iNewCols);
4538 newBool->reserve((int)iNonZeros);
4541 int* pRows = new int[iNonZeros * 2];
4542 outputRowCol(pRows);
4543 int* pCols = pRows + iNonZeros;
4545 std::vector<BoolTriplet_t> tripletList;
4547 for (size_t i = 0; i < iNonZeros; i++)
4549 int iCurrentPos = ((int)pCols[i] - 1) * getRows() + ((int)pRows[i] - 1);
4550 tripletList.emplace_back((int)(iCurrentPos % _iNewRows), (int)(iCurrentPos / _iNewRows), true);
4553 newBool->setFromTriplets(tripletList.begin(), tripletList.end(), DupFunctor<bool>());
4556 matrixBool = newBool;
4559 m_iRows = _iNewRows;
4560 m_iCols = _iNewCols;
4561 m_iSize = _iNewRows * _iNewCols;
4564 m_piDims[0] = m_iRows;
4565 m_piDims[1] = m_iCols;
4578 bool SparseBool::transpose(InternalType *& out)
4580 out = new SparseBool(new BoolSparse_t(matrixBool->transpose()));
4584 template<typename T>
4585 void neg(const int r, const int c, const T * const in, Eigen::SparseMatrix<bool, 1> * const out)
4587 for (int i = 0; i < r; i++)
4589 for (int j = 0; j < c; j++)
4591 out->coeffRef(i, j) = !in->coeff(i, j);
4595 out->prune(&keepForSparse<bool>);