2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-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
16 //#include <Eigen/Sparse>
20 #include "keepForSparse.hxx"
26 template<typename _Scalar, int _Flags, typename _Index> class SparseMatrix;
31 /* Utility function to create a new var on the heap from another type
33 template<typename Dest, typename Arg>
34 Dest* create_new(Arg const&);
39 Sparse is a wrapper over Eigen sparse matrices templates for either double or std::complex<double> values.
41 struct EXTERN_AST Sparse : GenericType
44 /* @param src: Double matrix to copy into a new sparse matrix
46 Sparse(Double SPARSE_CONST& src);
47 /* @param src : Double matrix to copy into a new sparse matrix
48 @param idx : Double matrix to use as indexes to get values from the src
50 Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx);
51 /* @param src : Double matrix to copy into a new sparse matrix
52 @param idx : Double matrix to use as indexes to get values from the src
53 @param dims : Double matrix containing the dimensions of the new matrix
55 Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims);
57 @param rows : nb of rows of the new matrix
58 @param rows : nb of columns of the new matrix
59 @param cplx : if the new matrix contains complex numbers
61 Sparse(int rows, int cols, bool cplx = false);
62 Sparse(Sparse const& o);
64 @param xadj : adjacency matrix for the new matrix
65 @param adjncy : adjacency matrix (row indexes) for the new matrix
66 @param src : data for the new matrix
67 @param r : nb of rows for the new matrix
68 @param c : nb of columns for the new matrix
70 Sparse(Double SPARSE_CONST& xadj, Double SPARSE_CONST& adjncy, Double SPARSE_CONST& src, std::size_t r, std::size_t c);
72 //constructor to create a sparse from value extract to another ( save / load operation typically)
73 Sparse(int rows, int cols, int nonzeros, int* inner, int* outer, double* real, double* img);
81 /*data management member function defined for compatibility with the Double API*/
82 bool set(int _iRows, int _iCols, double _dblReal, bool _bFinalize = true);
83 bool set(int _iIndex, double _dblReal, bool _bFinalize = true)
85 return set(_iIndex % m_iRows, _iIndex / m_iRows, _dblReal, _bFinalize);
88 bool set(int _iRows, int _iCols, std::complex<double> v, bool _bFinalize = true);
89 bool set(int _iIndex, std::complex<double> v, bool _bFinalize = true)
91 return set(_iIndex % m_iRows, _iIndex / m_iRows, v, _bFinalize);
94 set non zero values to 1.
97 /* get real value at coords (r,c)
99 double getReal(int r, int c) const;
100 double getReal(int _iIndex) const
102 return getReal(_iIndex % m_iRows, _iIndex / m_iRows);
106 double get(int r, int c) const;
107 double get(int _iIndex) const
109 return get(_iIndex % m_iRows, _iIndex / m_iRows);
112 std::complex<double>* getImg();
113 std::complex<double> getImg(int r, int c) const;
114 std::complex<double> getImg(int _iIndex) const
116 return getImg(_iIndex % m_iRows, _iIndex / m_iRows);
119 /* return true if matrix contains complex numbers, false otherwise.
121 bool isComplex() const;
122 // overload of GenericType methode.
125 // force const to call isComplex const method.
126 const Sparse* sp = this;
127 return sp->isComplex();
130 inline bool isScalar()
132 return (getRows() == 1 && getCols() == 1);
134 /* clear all the values of the matrix to 0. (or 0.+0.i if complex)
139 Config management and GenericType methods overrides
141 void whoAmI() SPARSE_CONST;
142 bool isExtract() const;
143 Sparse* clone(void) const;
146 return const_cast<Sparse const*>(this)->clone();
148 bool toString(std::wostringstream& ostr) const;
149 bool toString(std::wostringstream& ostr)
151 return const_cast<Sparse const*>(this)->toString(ostr);
154 /* post condition: dimensions are at least _iNewRows, _iNewCols
155 preserving existing data.
156 If dimensions where already >=, this is a no-op.
158 @param _iNewRows new minimum nb of rows
159 @param _iNewCols new minimum nb of cols
160 @return true upon succes, false otherwise.
162 bool resize(int _iNewRows, int _iNewCols);
163 /* post condition: new total size must be equal to the old size.
164 Two dimensions maximum.
166 @param _iNewRows new nb of rows
167 @param _iNewCols new nb of cols
168 @param _piNewDims new nb of dimension
169 @param _iNewDims new size for each dimension
170 @return true upon succes, false otherwise.
172 bool reshape(int* _piNewDims, int _iNewDims);
173 bool reshape(int _iNewRows, int _iNewCols);
175 insert _iSeqCount elements from _poSource at coords given by _piSeqCoord (max in _piMaxDim).
176 coords are considered 1D if _bAsVector, 2D otherwise.
177 @param _iSeqCount nb of elts to insert
178 @param _piSeqCoord dest coords
180 @param _bAsVector if _piSeqCoord contains 1D coords.
182 Sparse* insert(typed_list* _pArgs, InternalType* _pSource);
183 Sparse* insert(typed_list* _pArgs, Sparse* _pSource);
185 Sparse* remove(typed_list* _pArgs);
187 static InternalType* insertNew(typed_list* _pArgs, InternalType* _pSource);
189 /* append _poSource from coords _iRows, _iCols
190 @param _iRows row to append from
191 @param _iCols col to append from
192 @param _poSource src data to append
194 bool append(int r, int c, types::Sparse SPARSE_CONST* src);
198 @param _iSeqCount nb of elts to extract
199 @param _piSeqCoord src coords
200 @param _piMaxDim max coords
201 @param _piDimSize size of the extracted matrix
202 @param _bAsVector if _piSeqCoord contains 1D coords.
205 InternalType* extract(typed_list* _pArgs);
207 virtual bool invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::Exp & e)
215 InternalType * _out = extract(&in);
218 std::wostringstream os;
219 os << _W("Invalid index.\n");
220 throw ast::ScilabError(os.str(), 999, e.getLocation());
228 virtual bool isInvokable() const
233 virtual bool hasInvokeOption() const
238 virtual int getInvokeNbIn()
243 virtual int getInvokeNbOut()
248 Sparse* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
251 change the sign (inplace).
256 compares with an other value for equality (same nb of elts, with same values)
257 TODO: should it handle other types ?
259 bool operator==(const InternalType& it) SPARSE_CONST;
261 compares with an other value for inequality (same nb of elts, with same values)
262 TODO: should it handle other types ?
264 bool operator!=(const InternalType& it) SPARSE_CONST
266 return !(*this == it);
270 /* return type as string ( double, int, cell, list, ... )*/
271 virtual std::wstring getTypeStr() SPARSE_CONST {return std::wstring(L"sparse");}
272 /* return type as short string ( s, i, ce, l, ... ), as in overloading macros*/
273 virtual std::wstring getShortTypeStr() SPARSE_CONST {return std::wstring(L"sp");}
275 /* create a new sparse matrix containing the result of an addition
276 @param o other matrix to add
277 @return ptr to the new matrix, 0 in case of failure
279 Sparse* add(Sparse const& o) const;
281 /* create a new sparse matrix containing the result of an addition
282 @param d scalar to add
283 @return ptr to the new matrix, 0 in case of failure
285 Double* add(double d) const;
287 /* create a new sparse matrix containing the result of an addition
288 @param c complex to add
289 @return ptr to the new matrix, 0 in case of failure
291 Double* add(std::complex<double> c) const;
296 /* create a new sparse matrix containing the result of a substraction
297 @param o other matrix to substract
298 @return ptr to the new matrix, 0 in case of failure
300 Sparse* substract(Sparse const& o) const;
302 /* create a new sparse matrix containing the result of an subtraction
303 @param d scalar to subtract
304 @return ptr to the new matrix, 0 in case of failure
306 Double* substract(double d) const;
308 /* create a new sparse matrix containing the result of an subtraction
309 @param c scalar to subtract
310 @return ptr to the new matrix, 0 in case of failure
312 Double* substract(std::complex<double> c) const;
315 /* create a new sparse matrix containing the result of a multiplication
316 @param o other matrix to substract
317 @return ptr to the new matrix, 0 in case of failure
319 Sparse* multiply(Sparse const& o) const;
321 /* create a new sparse matrix containing the result of an multiplication
322 @param s scalar to multiply by
323 @return ptr to the new matrix, 0 in case of failure
325 Sparse* multiply(double s) const;
327 /* create a new sparse matrix containing the result of an multiplication
328 @param c scalar to subtract
329 @return ptr to the new matrix, 0 in case of failure
331 Sparse* multiply(std::complex<double> c) const;
333 /* create a new matrix containing the result of an .*
334 @param o sparse matrix to .*
335 @return ptr to the new matrix, 0 in case of failure
337 Sparse* dotMultiply(Sparse SPARSE_CONST& o) const;
339 /* create a new matrix containing the result of an ./
340 @param o sparse matrix to ./
341 @return ptr to the new matrix, 0 in case of failure
343 Sparse* dotDivide(Sparse SPARSE_CONST& o) const;
345 bool neg(InternalType *& out);
347 bool transpose(InternalType *& out);
348 bool adjoint(InternalType *& out);
349 int newCholLLT(Sparse** permut, Sparse** factor) const;
351 /** create a new sparse matrix containing the non zero values set to 1.
352 equivalent but faster than calling one_set() on a new copy of the
354 @return ptr to the new matrix, 0 in case of failure
356 Sparse* newOnes() const;
358 Sparse* newReal() const;
359 /** @return the nb of non zero values.
361 std::size_t nonZeros() const;
363 /* @param i row of the current sparse matrix
364 @return the nb of non zero values in row i
366 std::size_t nonZeros(std::size_t i) const;
368 int* getNbItemByRow(int* _piNbItemByRows);
369 int* getColPos(int* _piColPos);
370 int* getInnerPtr(int* count);
371 int* getOuterPtr(int* count);
375 "in-place" cast into a sparse matrix of comlpex values
379 /* coefficient wise relational operator < between *this sparse matrix and an other.
380 Matrices must have the same dimensions except if one of them is of size (1,1)
381 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
383 @param o other sparse matrix
385 @return ptr to a new Sparse matrix where each element is the result of the logical operator
386 '<' between the elements of *this and those of o.
388 SparseBool* newLessThan(Sparse const&o) const;
390 /* coefficient wise relational operator > between *this sparse matrix and an other.
391 Matrices must have the same dimensions except if one of them is of size (1,1)
392 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
394 @param o other sparse matrix
396 @return ptr to a new Sparse matrix where each element is the result of the logical operator
397 '>' between the elements of *this and those of o.
399 SparseBool* newGreaterThan(Sparse const&o) const;
401 /* coefficient wise relational operator != between *this sparse matrix and an other.
402 Matrices must have the same dimensions except if one of them is of size (1,1)
403 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
405 @param o other sparse matrix
407 @return ptr to a new Sparse matrix where each element is the result of the logical operator
408 '!=' between the elements of *this and those of o.
410 SparseBool* newNotEqualTo(Sparse const&o) const;
412 /* coefficient wise relational operator <= between *this sparse matrix and an other.
413 Matrices must have the same dimensions except if one of them is of size (1,1)
414 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
416 Do not use this function is possible as the result will be dense because
417 0. <= 0. is true, hence the result matrix will hold a non default value (i.e. true)
418 for each pair of default values (0.) of the sparse arguments !
420 @param o other sparse matrix
422 @return ptr to a new Sparse matrix where each element is the result of the logical operator
423 '<=' between the elements of *this and those of o.
425 SparseBool* newLessOrEqual(Sparse const&o) const;
427 /* coefficient wise relational operator >= between *this sparse matrix and an other.
428 Matrices must have the same dimensions except if one of them is of size (1,1)
429 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
431 Do not use this function is possible as the result will be dense because
432 0. >= 0. is true, hence the result matrix will hold a non default value (i.e. true)
433 for each pair of default values (0.) of the sparse arguments !
435 @param o other sparse matrix
437 @return ptr to a new Sparse matrix where each element is the result of the logical operator
438 '>=' between the elements of *this and those of o.
440 SparseBool* newGreaterOrEqual(Sparse const&o) const;
442 /* coefficient wise relational operator == between *this sparse matrix and an other.
443 Matrices must have the same dimensions except if one of them is of size (1,1)
444 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
446 Do not use this function is possible as the result will be dense because
447 0. == 0. is true, hence the result matrix will hold a non default value (i.e. true)
448 for each pair of default values (0.) of the sparse arguments !
450 @param o other sparse matrix
452 @return ptr to a new Sparse matrix where each element is the result of the logical operator
453 '==' between the elements of *this and those of o.
455 SparseBool* newEqualTo(Sparse const&o) const;
458 output 1-base column numbers of the non zero elements
459 @param out : ptr used as an output iterator over double values
460 @return past-the-end output iterator after ouput is done
462 double* outputCols(double* out) const;
465 output real and imaginary values of the non zero elements
466 @param outReal : ptr used as an output iterator over double values for real values
467 @param outImag : ptr used as an output iterator over double values for imaginary values if any
468 @return pair of past-the-end output iterators after ouput is done
470 std::pair<double*, double*> outputValues(double* outReal, double* outImag)const;
473 ouput rows and afterwards columns of the non zero elements
474 @param out : ptr used as an output iterator over double values
475 @return past-the-end output iterators after ouput is done
477 int* outputRowCol(int* out)const;
480 @param dest Double to be filled with values from the current sparse matrix.
482 void fill(Double& dest, int r = 0, int c = 0) SPARSE_CONST;
485 inline ScilabType getType(void) SPARSE_CONST
490 inline ScilabId getId(void) SPARSE_CONST
494 return IdSparseComplex;
501 SparseBool* newLesserThan(Sparse const&o);
503 typedef Eigen::SparseMatrix<double, 0x1, int> RealSparse_t;
504 typedef Eigen::SparseMatrix<std::complex<double>, 0x1, int> CplxSparse_t;
506 One and only one of the args should be 0.
507 @param realSp ptr to an Eigen sparse matrix of double values
508 @param cplxSp ptr to an Eigen sparse matrix of std::complex<double> elements
510 Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp);
512 RealSparse_t* matrixReal;
513 CplxSparse_t* matrixCplx;
518 /** utility function used by constructors
519 @param rows : nb of rows
520 @param cols : nb of columns
521 @param src : Double matrix data source
522 @param : iterator (cf MatrixIterator.hxx) with indices
523 @param n : nb of elements to copy from data source.
525 template<typename DestIter>
526 void create(int rows, int cols, Double SPARSE_CONST& src, DestIter o, std::size_t n);
527 void create2(int rows, int cols, Double SPARSE_CONST& src, Double SPARSE_CONST& idx);
529 /** utility function used by insert functions conceptually : sp[destTrav]= src[srcTrav]
530 @param src : data source
531 @param SrcTrav : iterator over the data source
532 @param n : nb of elements to copy
533 @param sp : sparse destination matrix
534 @param destTrav : iterator over the data sink (i.e. sp)
536 template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
537 static bool copyToSparse(Src SPARSE_CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav);
541 void neg(const int r, const int c, const T * const in, Eigen::SparseMatrix<bool, 1, int> * const out);
545 Implement sparse boolean matrix
547 struct EXTERN_AST SparseBool : GenericType
549 virtual ~SparseBool();
550 /* @param src: Bool matrix to copy into a new sparse matrix
552 SparseBool(Bool SPARSE_CONST& src);
553 /* @param src : Bool matrix to copy into a new sparse matrix
554 @param idx : Double matrix to use as indexes to get values from the src
556 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
557 /* @param src : Bool matrix to copy into a new sparse matrix
558 @param idx : Double matrix to use as indexes to get values from the src
559 @param dims : Double matrix containing the dimensions of the new matrix
561 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims);
563 @param rows : nb of rows of the new matrix
564 @param rows : nb of columns of the new matrix
566 SparseBool(int rows, int cols);
568 SparseBool(SparseBool const& o);
570 //constructor to create a sparse from value extract to another ( save / load operation typically)
571 SparseBool(int rows, int cols, int trues, int* inner, int* outer);
579 bool toString(std::wostringstream& ostr) const;
580 bool toString(std::wostringstream& ostr)
582 return const_cast<SparseBool const*>(this)->toString(ostr);
585 /* Config management and GenericType methods overrides */
586 SparseBool* clone(void) const;
587 SparseBool* clone(void)
589 return const_cast<SparseBool const*>(this)->clone();
591 bool resize(int _iNewRows, int _iNewCols);
593 bool reshape(int* _piNewDims, int _iNewDims);
594 bool reshape(int _iNewRows, int _iNewCols);
596 SparseBool* insert(typed_list* _pArgs, InternalType* _pSource);
597 SparseBool* insert(typed_list* _pArgs, SparseBool* _pSource);
598 SparseBool* remove(typed_list* _pArgs);
600 bool append(int _iRows, int _iCols, SparseBool SPARSE_CONST* _poSource);
602 static InternalType* insertNew(typed_list* _pArgs, InternalType* _pSource);
603 SparseBool* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
604 InternalType* extract(typed_list* _pArgs);
606 virtual bool invoke(typed_list & in, optional_list &/*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::Exp & e)
614 InternalType * _out = extract(&in);
617 std::wostringstream os;
618 os << _W("Invalid index.\n");
619 throw ast::ScilabError(os.str(), 999, e.getLocation());
627 virtual bool isInvokable() const
632 virtual bool hasInvokeOption() const
637 virtual int getInvokeNbIn()
642 virtual int getInvokeNbOut()
647 bool transpose(InternalType *& out);
649 /** @return the nb of non zero values.
651 std::size_t nbTrue() const;
652 /* @param i row of the current sparse matrix
653 @return the nb of non zero values in row i
655 std::size_t nbTrue(std::size_t i) const;
657 void setTrue(bool finalize = true);
658 void setFalse(bool finalize = true);
660 int* getNbItemByRow(int* _piNbItemByRows);
661 int* getColPos(int* _piColPos);
662 int* getInnerPtr(int* count);
663 int* getOuterPtr(int* count);
665 output 1-base column numbers of the non zero elements
666 @param out : ptr used as an output iterator over double values
667 @return past-the-end output iterator after ouput is done
670 int* outputRowCol(int* out)const;
672 bool operator==(const InternalType& it) SPARSE_CONST;
673 bool operator!=(const InternalType& it) SPARSE_CONST;
675 /* return type as string ( double, int, cell, list, ... )*/
676 virtual std::wstring getTypeStr() SPARSE_CONST {return std::wstring(L"boolean sparse");}
677 /* return type as short string ( s, i, ce, l, ... )*/
678 virtual std::wstring getShortTypeStr() SPARSE_CONST {return std::wstring(L"spb");}
680 inline ScilabType getType(void) SPARSE_CONST
682 return ScilabSparseBool;
685 inline ScilabId getId(void) SPARSE_CONST
690 inline bool isScalar()
692 return (getRows() == 1 && getCols() == 1);
697 if (nbTrue() == m_iSize)
704 bool neg(InternalType *& out)
706 SparseBool * _out = new SparseBool(getRows(), getCols());
707 types::neg(getRows(), getCols(), matrixBool, _out->matrixBool);
713 void whoAmI() SPARSE_CONST;
716 bool get(int r, int c) SPARSE_CONST;
717 bool get(int _iIndex) SPARSE_CONST
719 return get(_iIndex % m_iRows, _iIndex / m_iRows);
722 bool set(int r, int c, bool b, bool _bFinalize = true) SPARSE_CONST;
723 bool set(int _iIndex, bool b, bool _bFinalize = true) SPARSE_CONST
725 return set(_iIndex % m_iRows, _iIndex / m_iRows, b, _bFinalize);
728 void fill(Bool& dest, int r = 0, int c = 0) SPARSE_CONST;
730 Sparse* newOnes() const;
731 SparseBool* newNotEqualTo(SparseBool const&o) const;
732 SparseBool* newEqualTo(SparseBool const&o) const;
734 SparseBool* newLogicalOr(SparseBool const&o) const;
735 SparseBool* newLogicalAnd(SparseBool const&o) const;
737 typedef Eigen::SparseMatrix<bool, 0x1, int> BoolSparse_t;
738 SparseBool(BoolSparse_t* o);
739 BoolSparse_t* matrixBool;
742 void create2(int rows, int cols, Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
748 typedef types::Sparse type;
751 struct SparseTraits<types::Bool>
753 typedef types::SparseBool type;
756 struct SparseTraits<types::SparseBool>
758 typedef types::SparseBool type;
763 #endif /* !__SPARSE_HH__ */