elementary_functions module.
[scilab.git] / scilab / modules / types / includes / sparse.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Bernard Hugueney
4  *
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
10  *
11  */
12
13 #ifndef __SPARSE_HH__
14 #define __SPARSE_HH__
15
16 //#define EIGEN_SUPERLU_SUPPORT
17 #include <Eigen/Core>
18 #include <Eigen/Sparse>
19 #include <complex>
20 #include "double.hxx"
21 #include "bool.hxx"
22
23 #define CONST
24
25 #include "dynlib_types.h"
26
27
28 namespace types
29 {
30     /* Utility function to create a new var on the heap from another type
31      */
32     template<typename Dest, typename Arg>
33     Dest* create_new(Arg const&);
34
35     struct SparseBool;
36
37 /**
38    Sparse is a wrapper over Eigen sparse matrices templates for either double or std::complex<double> values.
39  */
40     struct TYPES_IMPEXP Sparse : GenericType
41     {
42         virtual ~Sparse();
43         /* @param src: Double matrix to copy into a new sparse matrix
44         **/
45         Sparse(Double CONST& src);
46         /* @param src : Double matrix to copy into a new sparse matrix
47            @param idx : Double matrix to use as indexes to get values from the src
48         **/
49         Sparse(Double CONST& src, Double CONST& idx);
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
52            @param dims : Double matrix containing the dimensions of the new matrix
53         **/
54         Sparse(Double CONST& src, Double CONST& idx, Double CONST& dims);
55         /*
56           @param rows : nb of rows of the new matrix
57           @param rows : nb of columns of the new matrix
58           @param cplx : if the new matrix contains complex numbers
59         **/
60         Sparse(int rows, int cols, bool cplx=false);
61         Sparse(Sparse const& o);
62         /* cf. adj2sp()
63           @param xadj : adjacency matrix for the new matrix
64           @param adjncy : adjacency matrix (row indexes) for the new matrix
65           @param src : data for the new matrix
66           @param r : nb of rows for the new matrix
67           @param c : nb of columns for the new matrix
68         **/
69         Sparse(Double CONST& xadj, Double CONST& adjncy, Double CONST& src, std::size_t r, std::size_t c);
70
71
72         bool isSparse() {return true;}
73         void finalize();
74
75         /*data management member function defined for compatibility with the Double API*/
76         bool set(int _iRows, int _iCols, double _dblReal);
77         bool set(int _iRows, int _iCols, std::complex<double> v);
78         /*
79           set non zero values to 1.
80         **/
81         bool one_set();
82         /* get real value at coords (r,c)
83         **/
84         double getReal(int r, int c) const;
85         double get(int r, int c) const;
86         std::complex<double> getImg(int r, int c) const;
87
88         /* return true if matrix contains complex numbers, false otherwise.
89         **/
90         bool isComplex() const;
91         bool isScalar() {return (getRows() == 1 && getCols() == 1);}
92         /* clear all the values of the matrix to 0. (or 0.+0.i if complex)
93         **/
94         bool zero_set();
95
96         Sparse* getColumnValues(int _iPos){return NULL;}
97
98         /*
99           Config management and GenericType methods overrides
100         */
101         void whoAmI() CONST;
102         bool isExtract() const;
103         Sparse* clone(void) const;
104         Sparse* clone(void) { return const_cast<Sparse const*>(this)->clone();}
105         bool toString(std::wostringstream& ostr) const;
106         bool toString(std::wostringstream& ostr)
107         { return const_cast<Sparse const*>(this)->toString(ostr); }
108
109         /* post condition: dimensions are at least _iNewRows, _iNewCols
110            preserving existing data.
111            If dimensions where already >=, this is a no-op.
112
113            @param _iNewRows new minimum nb of rows
114            @param _iNewCols new minimum nb of cols
115            @return true upon succes, false otherwise.
116          */
117         bool resize(int _iNewRows, int _iNewCols);
118         /* post condition: new total size must be equal to the old size.
119                            Two dimensions maximum.
120
121            @param _iNewRows new nb of rows
122            @param _iNewCols new nb of cols
123            @param _piNewDims new nb of dimension
124            @param _iNewDims new size for each dimension
125            @return true upon succes, false otherwise.
126         */
127         bool reshape(int* _piNewDims, int _iNewDims);
128         bool reshape(int _iNewRows, int _iNewCols);
129         /*
130           insert _iSeqCount elements from _poSource at coords given by _piSeqCoord (max in _piMaxDim).
131           coords are considered 1D if _bAsVector, 2D otherwise.
132           @param _iSeqCount nb of elts to insert
133           @param _piSeqCoord dest coords
134           @param _poSource src
135           @param  _bAsVector if _piSeqCoord contains 1D coords.
136          */
137         Sparse* insert(typed_list* _pArgs, InternalType* _pSource);
138         Sparse* insert(typed_list* _pArgs, Sparse* _pSource);
139
140         static InternalType* insertNew(typed_list* _pArgs, InternalType* _pSource);
141
142         /* append _poSource from coords _iRows, _iCols
143            @param _iRows row to append from
144            @param _iCols col to append from
145            @param _poSource src data to append
146          */
147         bool append(int r, int c, types::Sparse CONST* src);
148
149         /*
150           extract a submatrix
151           @param _iSeqCount nb of elts to extract
152           @param _piSeqCoord src coords
153           @param _piMaxDim max coords
154           @param _piDimSize size of the extracted matrix
155           @param  _bAsVector if _piSeqCoord contains 1D coords.
156
157          */
158         InternalType* extract(typed_list* _pArgs);
159         Sparse* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) CONST;
160
161         /*
162            change the sign (inplace).
163          */
164         void opposite();
165
166         /*
167           compares with an other value for equality (same nb of elts, with same values)
168           TODO: should it handle other types ?
169          */
170         bool operator==(const InternalType& it) CONST;
171         /*
172           compares with an other value for inequality (same nb of elts, with same values)
173           TODO: should it handle other types ?
174          */
175         bool operator!=(const InternalType& it) CONST
176         {
177             return !(*this == it);
178         }
179
180
181         /* return type as string ( double, int, cell, list, ... )*/
182         virtual std::wstring         getTypeStr() CONST {return std::wstring(L"sparse");}
183         /* return type as short string ( s, i, ce, l, ... ), as in overloading macros*/
184         virtual std::wstring         getShortTypeStr() CONST {return std::wstring(L"sp");}
185
186         /* create a new sparse matrix containing the result of an addition
187            @param o other matrix to add
188            @return ptr to the new matrix, 0 in case of failure
189          */
190         Sparse* add(Sparse const& o) const;
191
192         /* create a new sparse matrix containing the result of an addition
193            @param d scalar to add
194            @return ptr to the new matrix, 0 in case of failure
195          */
196         Double* add(double d) const;
197
198         /* create a new sparse matrix containing the result of an addition
199            @param c complex  to add
200            @return ptr to the new matrix, 0 in case of failure
201          */
202         Double* add(std::complex<double> c) const;
203
204
205
206
207         /* create a new sparse matrix containing the result of a substraction
208            @param o other matrix to substract
209            @return ptr to the new matrix, 0 in case of failure
210          */
211         GenericType* substract(Sparse const& o) const;
212
213         /* create a new sparse matrix containing the result of an subtraction
214            @param d scalar to subtract
215            @return ptr to the new matrix, 0 in case of failure
216          */
217         Double* substract(double d) const;
218
219         /* create a new sparse matrix containing the result of an subtraction
220            @param c scalar to subtract
221            @return ptr to the new matrix, 0 in case of failure
222          */
223         Double* substract(std::complex<double> c) const;
224
225
226         /* create a new sparse matrix containing the result of a multiplication
227            @param o other matrix to substract
228            @return ptr to the new matrix, 0 in case of failure
229          */
230         Sparse* multiply(Sparse const& o) const;
231
232         /* create a new sparse matrix containing the result of an multiplication
233            @param s scalar to multiply by
234            @return ptr to the new matrix, 0 in case of failure
235          */
236         Sparse* multiply(double s) const;
237
238         /* create a new sparse matrix containing the result of an multiplication
239            @param c scalar to subtract
240            @return ptr to the new matrix, 0 in case of failure
241          */
242         Sparse* multiply(std::complex<double> c) const;
243
244         /* create a new matrix containing the result of an .*
245            @param o sparse matrix to .*
246            @return ptr to the new matrix, 0 in case of failure
247          */
248         Sparse* dotMultiply(Sparse CONST& o) const;
249
250         /* create a new sparse matrix containing the result of a transposition
251            @return ptr to the new matrix, 0 in case of failure
252          */
253         Sparse* newTransposed() const;
254
255         /** create a new sparse matrix containing the non zero values set to 1.
256            equivalent but faster than calling one_set() on a new copy of the
257            current matrix.
258            @return ptr to the new matrix, 0 in case of failure
259          */
260         Sparse* newOnes() const;
261
262         /** @return the nb of non zero values.
263          */
264         std::size_t nonZeros() const;
265
266         /* @param i row of the current sparse matrix
267            @return the nb of non zero values in row i
268          */
269         std::size_t nonZeros(std::size_t i) const;
270
271
272         /**
273            "in-place" cast into a sparse matrix of comlpex values
274          */
275         void toComplex();
276
277         /* coefficient wise relational operator < between *this sparse matrix and an other.
278            Matrices must have the same dimensions except if one of them is of size (1,1)
279            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
280
281            @param o other sparse matrix
282
283            @return ptr to a new Sparse matrix where each element is the result of the logical operator
284             '<' between the elements of *this and those of o.
285          */
286         SparseBool* newLessThan(Sparse const&o) const;
287
288         /* coefficient wise relational operator > between *this sparse matrix and an other.
289            Matrices must have the same dimensions except if one of them is of size (1,1)
290            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
291
292            @param o other sparse matrix
293
294            @return ptr to a new Sparse matrix where each element is the result of the logical operator
295             '>' between the elements of *this and those of o.
296          */
297         SparseBool* newGreaterThan(Sparse const&o) const;
298
299         /* coefficient wise relational operator != between *this sparse matrix and an other.
300            Matrices must have the same dimensions except if one of them is of size (1,1)
301            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
302
303            @param o other sparse matrix
304
305            @return ptr to a new Sparse matrix where each element is the result of the logical operator
306             '!=' between the elements of *this and those of o.
307          */
308         SparseBool* newNotEqualTo(Sparse const&o) const;
309
310         /* coefficient wise relational operator <= between *this sparse matrix and an other.
311            Matrices must have the same dimensions except if one of them is of size (1,1)
312            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
313
314            Do not use this function is possible as the result will be dense because
315            0. <= 0. is true, hence the result matrix will hold a non default value (i.e. true)
316            for each pair of default values (0.) of the sparse arguments !
317
318            @param o other sparse matrix
319
320            @return ptr to a new Sparse matrix where each element is the result of the logical operator
321             '<=' between the elements of *this and those of o.
322          */
323         SparseBool* newLessOrEqual(Sparse const&o) const;
324
325         /* coefficient wise relational operator >= between *this sparse matrix and an other.
326            Matrices must have the same dimensions except if one of them is of size (1,1)
327            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
328
329            Do not use this function is possible as the result will be dense because
330            0. >= 0. is true, hence the result matrix will hold a non default value (i.e. true)
331            for each pair of default values (0.) of the sparse arguments !
332
333            @param o other sparse matrix
334
335            @return ptr to a new Sparse matrix where each element is the result of the logical operator
336             '>=' between the elements of *this and those of o.
337          */
338         SparseBool* newGreaterOrEqual(Sparse const&o) const;
339
340         /* coefficient wise relational operator == between *this sparse matrix and an other.
341            Matrices must have the same dimensions except if one of them is of size (1,1)
342            (i.e. a scalar) : it is then treated as a constant matrix of thre required dimensions.
343
344            Do not use this function is possible as the result will be dense because
345            0. == 0. is true, hence the result matrix will hold a non default value (i.e. true)
346            for each pair of default values (0.) of the sparse arguments !
347
348            @param o other sparse matrix
349
350            @return ptr to a new Sparse matrix where each element is the result of the logical operator
351             '==' between the elements of *this and those of o.
352          */
353         SparseBool* newEqualTo(Sparse const&o) const;
354
355         /**
356            output 1-base column numbers of the non zero elements
357            @param out : ptr used as an output iterator over double values
358            @return past-the-end output iterator after ouput is done
359          */
360         double* outputCols(double* out) const;
361
362         /**
363            output real and imaginary values of the non zero elements
364            @param outReal : ptr used as an output iterator over double values for real values
365            @param outImag : ptr used as an output iterator over double values for imaginary values if any
366            @return pair of past-the-end output iterators after ouput is done
367          */
368         std::pair<double*, double*> outputValues(double* outReal, double* outImag)const;
369
370         /**
371            ouput rows and afterwards columns of the non zero elements
372            @param out : ptr used as an output iterator over double values
373            @return past-the-end output iterators after ouput is done
374          */
375         double* outputRowCol(double* out)const;
376
377         /**
378            @param dest Double to be filled with values from the current sparse matrix.
379          */
380         void fill(Double& dest, int r=0, int c=0) CONST;
381
382
383         RealType getType(void) CONST;
384
385
386         SparseBool* newLesserThan(Sparse const&o);
387
388         typedef Eigen::SparseMatrix<double >   RealSparse_t;
389         typedef Eigen::SparseMatrix<std::complex<double > >    CplxSparse_t;
390         /**
391            One and only one of the args should be 0.
392            @param realSp ptr to an Eigen sparse matrix of double values
393            @param cplxSp ptr to an Eigen sparse matrix of std::complex<double> elements
394          */
395         Sparse(RealSparse_t* realSp, CplxSparse_t* cplxSp);
396
397         RealSparse_t* matrixReal;
398         CplxSparse_t* matrixCplx;
399
400     protected :
401     private :
402
403         /** utility function used by constructors
404             @param rows : nb of rows
405             @param cols : nb of columns
406             @param src : Double matrix data source
407             @param : iterator (cf MatrixIterator.hxx) with indices
408             @param n : nb of elements to copy from data source.
409          */
410         template<typename DestIter>
411         void create(int rows, int cols, Double CONST& src, DestIter o, std::size_t n);
412
413         /** utility function used by insert functions conceptually : sp[destTrav]= src[srcTrav]
414             @param src : data source
415             @param SrcTrav : iterator over the data source
416             @param n : nb of elements to copy
417             @param sp : sparse destination matrix
418             @param destTrav : iterator over the data sink (i.e. sp)
419          */
420         template<typename Src, typename SrcTraversal, typename Sz, typename DestTraversal>
421         static bool copyToSparse(Src CONST& src, SrcTraversal srcTrav, Sz n, Sparse& sp, DestTraversal destTrav);
422     };
423     /*
424       Implement sparse boolean matrix
425      */
426     struct TYPES_IMPEXP SparseBool : GenericType
427     {
428
429         /* @param src: Bool matrix to copy into a new sparse matrix
430         **/
431         SparseBool(Bool CONST& src);
432         /* @param src : Bool matrix to copy into a new sparse matrix
433            @param idx : Double matrix to use as indexes to get values from the src
434         **/
435         SparseBool(Bool CONST& src, Double CONST& idx);
436         /* @param src : Bool matrix to copy into a new sparse matrix
437            @param idx : Double matrix to use as indexes to get values from the src
438            @param dims : Double matrix containing the dimensions of the new matrix
439         **/
440         SparseBool(Bool CONST& src, Double CONST& idx, Double CONST& dims);
441        /*
442           @param rows : nb of rows of the new matrix
443           @param rows : nb of columns of the new matrix
444        */
445         SparseBool(int rows, int cols);
446
447         SparseBool(SparseBool const& o);
448
449         bool isSparseBool(){return true;}
450         void finalize();
451
452         bool toString(std::wostringstream& ostr) const;
453         bool toString(std::wostringstream& ostr)
454         { return const_cast<SparseBool const*>(this)->toString(ostr); }
455
456         /* Config management and GenericType methods overrides */
457         SparseBool* clone(void) const;
458         SparseBool* clone(void) { return const_cast<SparseBool const*>(this)->clone();}
459         bool resize(int _iNewRows, int _iNewCols);
460         bool insert(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, GenericType CONST* _poSource, bool _bAsVector);
461
462         bool append(int _iRows, int _iCols, SparseBool CONST* _poSource);
463
464         static SparseBool* insert_new(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, GenericType CONST* _poSource, bool _bAsVector);
465         SparseBool* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) CONST;
466         InternalType* extract(typed_list* _pArgs);
467
468         SparseBool* getColumnValues(int _iPos){return NULL;}
469
470         /* create a new sparse matrix containing the result of a transposition
471            @return ptr to the new matrix, 0 in case of failure
472          */
473         SparseBool* newTransposed() const;
474
475         /** @return the nb of non zero values.
476          */
477         std::size_t nbTrue() const;
478         /* @param i row of the current sparse matrix
479            @return the nb of non zero values in row i
480          */
481         std::size_t nbTrue(std::size_t i) const;
482         /**
483            output 1-base column numbers of the non zero elements
484            @param out : ptr used as an output iterator over double values
485            @return past-the-end output iterator after ouput is done
486          */
487
488         double* outputRowCol(double* out)const;
489
490         bool operator==(const InternalType& it) CONST;
491         bool operator!=(const InternalType& it) CONST;
492
493         /* return type as string ( double, int, cell, list, ... )*/
494         virtual std::wstring getTypeStr() CONST {return std::wstring(L"boolean sparse");}
495         /* return type as short string ( s, i, ce, l, ... )*/
496         virtual std::wstring getShortTypeStr() CONST {return std::wstring(L"spb");}
497
498         RealType getType(void) CONST;
499
500         void whoAmI() CONST;
501
502         bool get(int r, int c) CONST;
503         bool set(int r, int c, bool b) CONST;
504
505         void fill(Bool& dest, int r=0, int c=0) CONST;
506
507         Sparse* newOnes() const;
508         SparseBool* newNotEqualTo(SparseBool const&o) const;
509         SparseBool* newEqualTo(SparseBool const&o) const;
510
511         SparseBool* newLogicalOr(SparseBool const&o) const;
512         SparseBool* newLogicalAnd(SparseBool const&o) const;
513
514         typedef Eigen::SparseMatrix<bool> BoolSparse_t;
515         SparseBool(BoolSparse_t* o);
516         BoolSparse_t* matrixBool;
517
518     private:
519         template<typename DestIter>
520         void create(int rows, int cols, Bool CONST& src, DestIter o, std::size_t n);
521
522     };
523     template<typename T>
524     struct SparseTraits
525     {
526         typedef types::Sparse type;
527     };
528     template<>
529     struct SparseTraits<types::Bool>
530     {
531         typedef types::SparseBool type;
532     };
533     template<>
534     struct SparseTraits<types::SparseBool>
535     {
536         typedef types::SparseBool type;
537     };
538
539 }
540
541 #endif /* !__SPARSE_HH__ */