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 &o);
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* newNotEqualTo(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 Do not use this function is possible as the result will be dense because
406 0. <= 0. is true, hence the result matrix will hold a non default value (i.e. true)
407 for each pair of default values (0.) of the sparse arguments !
409 @param o other sparse matrix
411 @return ptr to a new Sparse matrix where each element is the result of the logical operator
412 '<=' between the elements of *this and those of o.
414 SparseBool* newLessOrEqual(Sparse &o);
416 /* coefficient wise relational operator == between *this sparse matrix and an other.
417 Matrices must have the same dimensions except if one of them is of size (1,1)
418 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
420 Do not use this function is possible as the result will be dense because
421 0. == 0. is true, hence the result matrix will hold a non default value (i.e. true)
422 for each pair of default values (0.) of the sparse arguments !
424 @param o other sparse matrix
426 @return ptr to a new Sparse matrix where each element is the result of the logical operator
427 '==' between the elements of *this and those of o.
429 SparseBool* newEqualTo(Sparse &o);
432 output 1-base column numbers of the non zero elements
433 @param out : ptr used as an output iterator over double values
434 @return past-the-end output iterator after ouput is done
436 double* outputCols(double* out) const;
439 output real and imaginary values of the non zero elements
440 @param outReal : ptr used as an output iterator over double values for real values
441 @param outImag : ptr used as an output iterator over double values for imaginary values if any
442 @return pair of past-the-end output iterators after ouput is done
444 std::pair<double*, double*> outputValues(double* outReal, double* outImag)const;
447 ouput rows and afterwards columns of the non zero elements
448 @param out : ptr used as an output iterator over double values
449 @return past-the-end output iterators after ouput is done
451 int* outputRowCol(int* out)const;
454 @param dest Double to be filled with values from the current sparse matrix.
456 void fill(Double& dest, int r = 0, int c = 0) SPARSE_CONST;
459 inline ScilabType getType(void) SPARSE_CONST
464 inline ScilabId getId(void) SPARSE_CONST
468 return IdSparseComplex;
475 SparseBool* newLesserThan(Sparse const&o);
477 typedef Eigen::SparseMatrix<double, 0x1, int> RealSparse_t;
478 typedef Eigen::SparseMatrix<std::complex<double>, 0x1, int> CplxSparse_t;
480 One and only one of the args should be 0.
481 @param realSp ptr to an Eigen sparse matrix of double values
482 @param cplxSp ptr to an Eigen sparse matrix of std::complex<double> elements
484 Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp);
486 RealSparse_t* matrixReal;
487 CplxSparse_t* matrixCplx;
492 /** utility function used by constructors
493 @param rows : nb of rows
494 @param cols : nb of columns
495 @param src : Double matrix data source
496 @param : iterator (cf MatrixIterator.hxx) with indices
497 @param n : nb of elements to copy from data source.
499 template<typename DestIter>
500 void create(int rows, int cols, Double SPARSE_CONST& src, DestIter o, std::size_t n);
501 void create2(int rows, int cols, Double SPARSE_CONST& src, Double SPARSE_CONST& idx);
503 /** utility function used by insert functions conceptually : sp[destTrav]= src[srcTrav]
504 @param src : data source
505 @param SrcTrav : iterator over the data source
506 @param n : nb of elements to copy
507 @param sp : sparse destination matrix
508 @param destTrav : iterator over the data sink (i.e. sp)
510 template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
511 static bool copyToSparse(Src SPARSE_CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav);
515 void neg(const int r, const int c, const T * const in, Eigen::SparseMatrix<bool, 1, int> * const out);
519 Implement sparse boolean matrix
521 struct EXTERN_AST SparseBool : GenericType
523 virtual ~SparseBool();
524 /* @param src: Bool matrix to copy into a new sparse matrix
526 SparseBool(Bool SPARSE_CONST& src);
527 /* @param src : Bool matrix to copy into a new sparse matrix
528 @param idx : Double matrix to use as indexes to get values from the src
530 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
531 /* @param src : Bool matrix to copy into a new sparse matrix
532 @param idx : Double matrix to use as indexes to get values from the src
533 @param dims : Double matrix containing the dimensions of the new matrix
535 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims);
537 @param rows : nb of rows of the new matrix
538 @param rows : nb of columns of the new matrix
540 SparseBool(int rows, int cols);
542 SparseBool(SparseBool const& o);
544 //constructor to create a sparse from value extract to another ( save / load operation typically)
545 SparseBool(int rows, int cols, int trues, int* inner, int* outer);
553 bool toString(std::wostringstream& ostr) const;
554 bool toString(std::wostringstream& ostr)
556 return const_cast<SparseBool const*>(this)->toString(ostr);
559 /* Config management and GenericType methods overrides */
560 SparseBool* clone(void) const;
561 SparseBool* clone(void)
563 return const_cast<SparseBool const*>(this)->clone();
565 bool resize(int _iNewRows, int _iNewCols);
567 bool reshape(int* _piNewDims, int _iNewDims);
568 bool reshape(int _iNewRows, int _iNewCols);
570 SparseBool* insert(typed_list* _pArgs, InternalType* _pSource);
571 SparseBool* insert(typed_list* _pArgs, SparseBool* _pSource);
572 SparseBool* remove(typed_list* _pArgs);
574 bool append(int _iRows, int _iCols, SparseBool SPARSE_CONST* _poSource);
576 static InternalType* insertNew(typed_list* _pArgs, InternalType* _pSource);
577 SparseBool* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
578 InternalType* extract(typed_list* _pArgs);
580 virtual bool invoke(typed_list & in, optional_list &/*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::Exp & e)
588 InternalType * _out = extract(&in);
591 std::wostringstream os;
592 os << _W("Invalid index.\n");
593 throw ast::ScilabError(os.str(), 999, e.getLocation());
601 virtual bool isInvokable() const
606 virtual bool hasInvokeOption() const
611 virtual int getInvokeNbIn()
616 virtual int getInvokeNbOut()
621 bool transpose(InternalType *& out);
623 /** @return the nb of non zero values.
625 std::size_t nbTrue() const;
626 /* @param i row of the current sparse matrix
627 @return the nb of non zero values in row i
629 std::size_t nbTrue(std::size_t i) const;
631 void setTrue(bool finalize = true);
632 void setFalse(bool finalize = true);
634 int* getNbItemByRow(int* _piNbItemByRows);
635 int* getColPos(int* _piColPos);
636 int* getInnerPtr(int* count);
637 int* getOuterPtr(int* count);
639 output 1-base column numbers of the non zero elements
640 @param out : ptr used as an output iterator over double values
641 @return past-the-end output iterator after ouput is done
644 int* outputRowCol(int* out)const;
646 bool operator==(const InternalType& it) SPARSE_CONST;
647 bool operator!=(const InternalType& it) SPARSE_CONST;
649 /* return type as string ( double, int, cell, list, ... )*/
650 virtual std::wstring getTypeStr() SPARSE_CONST {return std::wstring(L"boolean sparse");}
651 /* return type as short string ( s, i, ce, l, ... )*/
652 virtual std::wstring getShortTypeStr() SPARSE_CONST {return std::wstring(L"spb");}
654 inline ScilabType getType(void) SPARSE_CONST
656 return ScilabSparseBool;
659 inline ScilabId getId(void) SPARSE_CONST
664 inline bool isScalar()
666 return (getRows() == 1 && getCols() == 1);
671 if (nbTrue() == m_iSize)
678 bool neg(InternalType *& out)
680 SparseBool * _out = new SparseBool(getRows(), getCols());
681 types::neg(getRows(), getCols(), matrixBool, _out->matrixBool);
687 void whoAmI() SPARSE_CONST;
690 bool get(int r, int c) SPARSE_CONST;
691 bool get(int _iIndex) SPARSE_CONST
693 return get(_iIndex % m_iRows, _iIndex / m_iRows);
696 bool set(int r, int c, bool b, bool _bFinalize = true) SPARSE_CONST;
697 bool set(int _iIndex, bool b, bool _bFinalize = true) SPARSE_CONST
699 return set(_iIndex % m_iRows, _iIndex / m_iRows, b, _bFinalize);
702 void fill(Bool& dest, int r = 0, int c = 0) SPARSE_CONST;
704 Sparse* newOnes() const;
705 SparseBool* newNotEqualTo(SparseBool const&o) const;
706 SparseBool* newEqualTo(SparseBool& o);
708 SparseBool* newLogicalOr(SparseBool const&o) const;
709 SparseBool* newLogicalAnd(SparseBool const&o) const;
711 typedef Eigen::SparseMatrix<bool, 0x1, int> BoolSparse_t;
712 SparseBool(BoolSparse_t* o);
713 BoolSparse_t* matrixBool;
716 void create2(int rows, int cols, Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
722 typedef types::Sparse type;
725 struct SparseTraits<types::Bool>
727 typedef types::SparseBool type;
730 struct SparseTraits<types::SparseBool>
732 typedef types::SparseBool type;
737 #endif /* !__SPARSE_HH__ */