2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-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.
19 //#include <Eigen/Sparse>
23 #include "keepForSparse.hxx"
29 template<typename _Scalar, int _Flags, typename _Index> class SparseMatrix;
34 /* Utility function to create a new var on the heap from another type
36 template<typename Dest, typename Arg>
37 Dest* create_new(Arg const&);
42 Sparse is a wrapper over Eigen sparse matrices templates for either double or std::complex<double> values.
44 struct EXTERN_AST Sparse : GenericType
47 /* @param src: Double matrix to copy into a new sparse matrix
49 Sparse(Double SPARSE_CONST& src);
50 /* @param src : Double matrix to copy into a new sparse matrix
51 @param idx : Double matrix to use as indexes to get values from the src
53 Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx);
54 /* @param src : Double matrix to copy into a new sparse matrix
55 @param idx : Double matrix to use as indexes to get values from the src
56 @param dims : Double matrix containing the dimensions of the new matrix
58 Sparse(Double SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims);
60 @param rows : nb of rows of the new matrix
61 @param rows : nb of columns of the new matrix
62 @param cplx : if the new matrix contains complex numbers
64 Sparse(int rows, int cols, bool cplx = false);
65 Sparse(Sparse const& o);
67 @param xadj : adjacency matrix for the new matrix
68 @param adjncy : adjacency matrix (row indexes) for the new matrix
69 @param src : data for the new matrix
70 @param r : nb of rows for the new matrix
71 @param c : nb of columns for the new matrix
73 Sparse(Double SPARSE_CONST& xadj, Double SPARSE_CONST& adjncy, Double SPARSE_CONST& src, std::size_t r, std::size_t c);
75 //constructor to create a sparse from value extract to another ( save / load operation typically)
76 Sparse(int rows, int cols, int nonzeros, int* inner, int* outer, double* real, double* img);
84 bool getMemory(long long *_piSize, long long* _piSizePlusType);
86 /*data management member function defined for compatibility with the Double API*/
87 Sparse* set(int _iRows, int _iCols, double _dblReal, bool _bFinalize = true);
88 Sparse* set(int _iIndex, double _dblReal, bool _bFinalize = true)
90 return set(_iIndex % m_iRows, _iIndex / m_iRows, _dblReal, _bFinalize);
93 Sparse* set(int _iRows, int _iCols, std::complex<double> v, bool _bFinalize = true);
94 Sparse* set(int _iIndex, std::complex<double> v, bool _bFinalize = true)
96 return set(_iIndex % m_iRows, _iIndex / m_iRows, v, _bFinalize);
99 set non zero values to 1.
102 /* get real value at coords (r,c)
104 double getReal(int r, int c) const;
105 double getReal(int _iIndex) const
107 return getReal(_iIndex % m_iRows, _iIndex / m_iRows);
111 double get(int r, int c) const;
112 double get(int _iIndex) const
114 return get(_iIndex % m_iRows, _iIndex / m_iRows);
117 std::complex<double>* getImg();
118 std::complex<double> getImg(int r, int c) const;
119 std::complex<double> getImg(int _iIndex) const
121 return getImg(_iIndex % m_iRows, _iIndex / m_iRows);
124 /* return true if matrix contains complex numbers, false otherwise.
126 bool isComplex() const;
127 // overload of GenericType methode.
130 // force const to call isComplex const method.
131 const Sparse* sp = this;
132 return sp->isComplex();
135 inline bool isScalar()
137 return (getRows() == 1 && getCols() == 1);
139 /* clear all the values of the matrix to 0. (or 0.+0.i if complex)
144 Config management and GenericType methods overrides
146 void whoAmI() SPARSE_CONST;
147 bool isExtract() const;
149 bool toString(std::wostringstream& ostr);
151 /* post condition: dimensions are at least _iNewRows, _iNewCols
152 preserving existing data.
153 If dimensions where already >=, this is a no-op.
155 @param _iNewRows new minimum nb of rows
156 @param _iNewCols new minimum nb of cols
157 @return true upon succes, false otherwise.
159 Sparse* resize(int _iNewRows, int _iNewCols);
160 /* post condition: new total size must be equal to the old size.
161 Two dimensions maximum.
163 @param _iNewRows new nb of rows
164 @param _iNewCols new nb of cols
165 @param _piNewDims new nb of dimension
166 @param _iNewDims new size for each dimension
167 @return true upon succes, false otherwise.
169 Sparse* reshape(int* _piNewDims, int _iNewDims);
170 Sparse* reshape(int _iNewRows, int _iNewCols);
172 insert _iSeqCount elements from _poSource at coords given by _piSeqCoord (max in _piMaxDim).
173 coords are considered 1D if _bAsVector, 2D otherwise.
174 @param _iSeqCount nb of elts to insert
175 @param _piSeqCoord dest coords
177 @param _bAsVector if _piSeqCoord contains 1D coords.
179 Sparse* insert(typed_list* _pArgs, InternalType* _pSource);
181 GenericType* remove(typed_list* _pArgs);
183 GenericType* insertNew(typed_list* _pArgs);
185 /* append _poSource from coords _iRows, _iCols
186 @param _iRows row to append from
187 @param _iCols col to append from
188 @param _poSource src data to append
190 Sparse* append(int r, int c, types::Sparse SPARSE_CONST* src);
194 @param _iSeqCount nb of elts to extract
195 @param _piSeqCoord src coords
196 @param _piMaxDim max coords
197 @param _piDimSize size of the extracted matrix
198 @param _bAsVector if _piSeqCoord contains 1D coords.
201 GenericType* extract(typed_list* _pArgs);
202 Sparse* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
203 virtual bool invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e);
204 virtual bool isInvokable() const;
205 virtual bool hasInvokeOption() const;
206 virtual int getInvokeNbIn();
207 virtual int getInvokeNbOut();
210 change the sign (inplace).
215 compares with another value for equality (same nb of elts, with same values)
216 TODO: should it handle other types ?
218 bool operator==(const InternalType& it) SPARSE_CONST;
220 compares with another value for inequality (same nb of elts, with same values)
221 TODO: should it handle other types ?
223 bool operator!=(const InternalType& it) SPARSE_CONST
225 return !(*this == it);
229 /* return type as string ( double, int, cell, list, ... )*/
230 virtual std::wstring getTypeStr() const
232 return std::wstring(L"sparse");
235 /* return type as short string ( s, i, ce, l, ... ), as in overloading macros*/
236 virtual std::wstring getShortTypeStr() const
238 return std::wstring(L"sp");
241 /* create a new sparse matrix containing the result of an addition
242 @param o other matrix to add
243 @return ptr to the new matrix, 0 in case of failure
245 Sparse* add(Sparse const& o) const;
247 /* create a new sparse matrix containing the result of an addition
248 @param d scalar to add
249 @return ptr to the new matrix, 0 in case of failure
251 Double* add(double d) const;
253 /* create a new sparse matrix containing the result of an addition
254 @param c complex to add
255 @return ptr to the new matrix, 0 in case of failure
257 Double* add(std::complex<double> c) const;
262 /* create a new sparse matrix containing the result of a substraction
263 @param o other matrix to substract
264 @return ptr to the new matrix, 0 in case of failure
266 Sparse* substract(Sparse const& o) const;
268 /* create a new sparse matrix containing the result of an subtraction
269 @param d scalar to subtract
270 @return ptr to the new matrix, 0 in case of failure
272 Double* substract(double d) const;
274 /* create a new sparse matrix containing the result of an subtraction
275 @param c scalar to subtract
276 @return ptr to the new matrix, 0 in case of failure
278 Double* substract(std::complex<double> c) const;
281 /* create a new sparse matrix containing the result of a multiplication
282 @param o other matrix to substract
283 @return ptr to the new matrix, 0 in case of failure
285 Sparse* multiply(Sparse const& o) const;
287 /* create a new sparse matrix containing the result of an multiplication
288 @param s scalar to multiply by
289 @return ptr to the new matrix, 0 in case of failure
291 Sparse* multiply(double s) const;
293 /* create a new sparse matrix containing the result of an multiplication
294 @param c scalar to subtract
295 @return ptr to the new matrix, 0 in case of failure
297 Sparse* multiply(std::complex<double> c) const;
299 /* create a new matrix containing the result of an .*
300 @param o sparse matrix to .*
301 @return ptr to the new matrix, 0 in case of failure
303 Sparse* dotMultiply(Sparse SPARSE_CONST& o) const;
305 /* create a new matrix containing the result of an ./
306 @param o sparse matrix to ./
307 @return ptr to the new matrix, 0 in case of failure
309 Sparse* dotDivide(Sparse SPARSE_CONST& o) const;
311 bool neg(InternalType *& out);
313 bool transpose(InternalType *& out);
314 bool adjoint(InternalType *& out);
315 int newCholLLT(Sparse** permut, Sparse** factor) const;
317 /** create a new sparse matrix containing the non zero values set to 1.
318 equivalent but faster than calling one_set() on a new copy of the
320 @return ptr to the new matrix, 0 in case of failure
322 Sparse* newOnes() const;
324 Sparse* newReal() const;
325 /** @return the nb of non zero values.
327 std::size_t nonZeros() const;
329 /* @param i row of the current sparse matrix
330 @return the nb of non zero values in row i
332 std::size_t nonZeros(std::size_t i) const;
334 int* getNbItemByRow(int* _piNbItemByRows);
335 int* getColPos(int* _piColPos);
336 int* getInnerPtr(int* count);
337 int* getOuterPtr(int* count);
341 "in-place" cast into a sparse matrix of comlpex values
345 /* coefficient wise relational operator < between *this sparse matrix and another.
346 Matrices must have the same dimensions except if one of them is of size (1,1)
347 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
349 @param o other sparse matrix
351 @return ptr to a new Sparse matrix where each element is the result of the logical operator
352 '<' between the elements of *this and those of o.
354 SparseBool* newLessThan(Sparse &o);
356 /* coefficient wise relational operator != between *this sparse matrix and another.
357 Matrices must have the same dimensions except if one of them is of size (1,1)
358 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
360 @param o other sparse matrix
362 @return ptr to a new Sparse matrix where each element is the result of the logical operator
363 '!=' between the elements of *this and those of o.
365 SparseBool* newNotEqualTo(Sparse const&o) const;
367 /* coefficient wise relational operator <= between *this sparse matrix and another.
368 Matrices must have the same dimensions except if one of them is of size (1,1)
369 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
371 Do not use this function is possible as the result will be dense because
372 0. <= 0. is true, hence the result matrix will hold a non default value (i.e. true)
373 for each pair of default values (0.) of the sparse arguments !
375 @param o other sparse matrix
377 @return ptr to a new Sparse matrix where each element is the result of the logical operator
378 '<=' between the elements of *this and those of o.
380 SparseBool* newLessOrEqual(Sparse &o);
382 /* coefficient wise relational operator == between *this sparse matrix and another.
383 Matrices must have the same dimensions except if one of them is of size (1,1)
384 (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
386 Do not use this function is possible as the result will be dense because
387 0. == 0. is true, hence the result matrix will hold a non default value (i.e. true)
388 for each pair of default values (0.) of the sparse arguments !
390 @param o other sparse matrix
392 @return ptr to a new Sparse matrix where each element is the result of the logical operator
393 '==' between the elements of *this and those of o.
395 SparseBool* newEqualTo(Sparse &o);
398 output 1-base column numbers of the non zero elements
399 @param out : ptr used as an output iterator over double values
400 @return past-the-end output iterator after ouput is done
402 double* outputCols(double* out) const;
405 output real and imaginary values of the non zero elements
406 @param outReal : ptr used as an output iterator over double values for real values
407 @param outImag : ptr used as an output iterator over double values for imaginary values if any
408 @return pair of past-the-end output iterators after ouput is done
410 std::pair<double*, double*> outputValues(double* outReal, double* outImag)const;
413 ouput rows and afterwards columns of the non zero elements
414 @param out : ptr used as an output iterator over double values
415 @return past-the-end output iterators after ouput is done
417 int* outputRowCol(int* out)const;
420 @param dest Double to be filled with values from the current sparse matrix.
422 void fill(Double& dest, int r = 0, int c = 0) SPARSE_CONST;
425 inline ScilabType getType(void) SPARSE_CONST
430 inline ScilabId getId(void) SPARSE_CONST
434 return IdSparseComplex;
441 SparseBool* newLesserThan(Sparse const&o);
443 typedef Eigen::SparseMatrix<double, 0x1, int> RealSparse_t;
444 typedef Eigen::SparseMatrix<std::complex<double>, 0x1, int> CplxSparse_t;
446 One and only one of the args should be 0.
447 @param realSp ptr to an Eigen sparse matrix of double values
448 @param cplxSp ptr to an Eigen sparse matrix of std::complex<double> elements
450 Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp);
452 RealSparse_t* matrixReal;
453 CplxSparse_t* matrixCplx;
458 /** utility function used by constructors
459 @param rows : nb of rows
460 @param cols : nb of columns
461 @param src : Double matrix data source
462 @param : iterator (cf MatrixIterator.hxx) with indices
463 @param n : nb of elements to copy from data source.
465 template<typename DestIter>
466 void create(int rows, int cols, Double SPARSE_CONST& src, DestIter o, std::size_t n);
467 void create2(int rows, int cols, Double SPARSE_CONST& src, Double SPARSE_CONST& idx);
469 /** utility function used by insert functions conceptually : sp[destTrav]= src[srcTrav]
470 @param src : data source
471 @param SrcTrav : iterator over the data source
472 @param n : nb of elements to copy
473 @param sp : sparse destination matrix
474 @param destTrav : iterator over the data sink (i.e. sp)
476 template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
477 static bool copyToSparse(Src SPARSE_CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav);
479 Sparse* insert(typed_list* _pArgs, Sparse* _pSource);
483 void neg(const int r, const int c, const T * const in, Eigen::SparseMatrix<bool, 1, int> * const out);
487 Implement sparse boolean matrix
489 struct EXTERN_AST SparseBool : GenericType
491 virtual ~SparseBool();
492 /* @param src: Bool matrix to copy into a new sparse matrix
494 SparseBool(Bool SPARSE_CONST& src);
495 /* @param src : Bool matrix to copy into a new sparse matrix
496 @param idx : Double matrix to use as indexes to get values from the src
498 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
499 /* @param src : Bool matrix to copy into a new sparse matrix
500 @param idx : Double matrix to use as indexes to get values from the src
501 @param dims : Double matrix containing the dimensions of the new matrix
503 SparseBool(Bool SPARSE_CONST& src, Double SPARSE_CONST& idx, Double SPARSE_CONST& dims);
505 @param rows : nb of rows of the new matrix
506 @param rows : nb of columns of the new matrix
508 SparseBool(int rows, int cols);
510 SparseBool(SparseBool const& o);
512 //constructor to create a sparse from value extract to another ( save / load operation typically)
513 SparseBool(int rows, int cols, int trues, int* inner, int* outer);
521 bool getMemory(long long *_piSize, long long* _piSizePlusType);
523 bool toString(std::wostringstream& ostr);
525 /* Config management and GenericType methods overrides */
526 SparseBool* clone(void);
528 SparseBool* resize(int _iNewRows, int _iNewCols);
529 SparseBool* reshape(int* _piNewDims, int _iNewDims);
530 SparseBool* reshape(int _iNewRows, int _iNewCols);
531 SparseBool* insert(typed_list* _pArgs, InternalType* _pSource);
532 SparseBool* append(int _iRows, int _iCols, SparseBool SPARSE_CONST* _poSource);
534 GenericType* remove(typed_list* _pArgs);
535 GenericType* insertNew(typed_list* _pArgs);
536 GenericType* extract(typed_list* _pArgs);
538 SparseBool* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
540 virtual bool invoke(typed_list & in, optional_list &/*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e);
541 virtual bool isInvokable() const;
542 virtual bool hasInvokeOption() const;
543 virtual int getInvokeNbIn();
544 virtual int getInvokeNbOut();
546 bool transpose(InternalType *& out);
548 /** @return the nb of non zero values.
550 std::size_t nbTrue() const;
551 /* @param i row of the current sparse matrix
552 @return the nb of non zero values in row i
554 std::size_t nbTrue(std::size_t i) const;
556 void setTrue(bool finalize = true);
557 void setFalse(bool finalize = true);
559 int* getNbItemByRow(int* _piNbItemByRows);
560 int* getColPos(int* _piColPos);
561 int* getInnerPtr(int* count);
562 int* getOuterPtr(int* count);
564 output 1-base column numbers of the non zero elements
565 @param out : ptr used as an output iterator over double values
566 @return past-the-end output iterator after ouput is done
569 int* outputRowCol(int* out)const;
571 bool operator==(const InternalType& it) SPARSE_CONST;
572 bool operator!=(const InternalType& it) SPARSE_CONST;
574 /* return type as string ( double, int, cell, list, ... )*/
575 virtual std::wstring getTypeStr() const
577 return std::wstring(L"boolean sparse");
579 /* return type as short string ( s, i, ce, l, ... )*/
580 virtual std::wstring getShortTypeStr() const
582 return std::wstring(L"spb");
585 inline ScilabType getType(void) SPARSE_CONST
587 return ScilabSparseBool;
590 inline ScilabId getId(void) SPARSE_CONST
595 inline bool isScalar()
597 return (getRows() == 1 && getCols() == 1);
602 if (m_iSize > 0 && static_cast<int>(nbTrue()) == m_iSize)
609 bool neg(InternalType *& out)
611 SparseBool * _out = new SparseBool(getRows(), getCols());
612 types::neg(getRows(), getCols(), matrixBool, _out->matrixBool);
618 void whoAmI() SPARSE_CONST;
621 bool get(int r, int c) SPARSE_CONST;
622 bool get(int _iIndex) SPARSE_CONST
624 return get(_iIndex % m_iRows, _iIndex / m_iRows);
627 SparseBool* set(int r, int c, bool b, bool _bFinalize = true) SPARSE_CONST;
628 SparseBool* set(int _iIndex, bool b, bool _bFinalize = true) SPARSE_CONST
630 return set(_iIndex % m_iRows, _iIndex / m_iRows, b, _bFinalize);
633 void fill(Bool& dest, int r = 0, int c = 0) SPARSE_CONST;
635 Sparse* newOnes() const;
636 SparseBool* newNotEqualTo(SparseBool const&o) const;
637 SparseBool* newEqualTo(SparseBool& o);
639 SparseBool* newLogicalOr(SparseBool const&o) const;
640 SparseBool* newLogicalAnd(SparseBool const&o) const;
642 typedef Eigen::SparseMatrix<bool, 0x1, int> BoolSparse_t;
643 SparseBool(BoolSparse_t* o);
644 BoolSparse_t* matrixBool;
647 void create2(int rows, int cols, Bool SPARSE_CONST& src, Double SPARSE_CONST& idx);
648 SparseBool* insert(typed_list* _pArgs, SparseBool* _pSource);
654 typedef types::Sparse type;
657 struct SparseTraits<types::Bool>
659 typedef types::SparseBool type;
662 struct SparseTraits<types::SparseBool>
664 typedef types::SparseBool type;
669 #endif /* !__SPARSE_HH__ */