Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Sparse / SparseMatrixBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_SPARSEMATRIXBASE_H
26 #define EIGEN_SPARSEMATRIXBASE_H
27
28 template<typename Derived> class SparseMatrixBase
29 {
30   public:
31
32     typedef typename ei_traits<Derived>::Scalar Scalar;
33 //     typedef typename Derived::InnerIterator InnerIterator;
34
35     enum {
36
37       RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
38         /**< The number of rows at compile-time. This is just a copy of the value provided
39           * by the \a Derived type. If a value is not known at compile-time,
40           * it is set to the \a Dynamic constant.
41           * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
42
43       ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
44         /**< The number of columns at compile-time. This is just a copy of the value provided
45           * by the \a Derived type. If a value is not known at compile-time,
46           * it is set to the \a Dynamic constant.
47           * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
48
49
50       SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime,
51                                                    ei_traits<Derived>::ColsAtCompileTime>::ret),
52         /**< This is equal to the number of coefficients, i.e. the number of
53           * rows times the number of columns, or to \a Dynamic if this is not
54           * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
55
56       MaxRowsAtCompileTime = RowsAtCompileTime,
57       MaxColsAtCompileTime = ColsAtCompileTime,
58
59       MaxSizeAtCompileTime = (ei_size_at_compile_time<MaxRowsAtCompileTime,
60                                                       MaxColsAtCompileTime>::ret),
61
62       IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
63         /**< This is set to true if either the number of rows or the number of
64           * columns is known at compile-time to be equal to 1. Indeed, in that case,
65           * we are dealing with a column-vector (if there is only one column) or with
66           * a row-vector (if there is only one row). */
67
68       Flags = ei_traits<Derived>::Flags,
69         /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
70           * constructed from this one. See the \ref flags "list of flags".
71           */
72       
73       CoeffReadCost = ei_traits<Derived>::CoeffReadCost,
74         /**< This is a rough measure of how expensive it is to read one coefficient from
75           * this expression.
76           */
77
78       IsRowMajor = Flags&RowMajorBit ? 1 : 0
79     };
80
81     /** \internal the return type of MatrixBase::conjugate() */
82     typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
83                         const SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
84                         const Derived&
85                      >::ret ConjugateReturnType;
86     /** \internal the return type of MatrixBase::real() */
87     typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
88     /** \internal the return type of MatrixBase::imag() */
89     typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
90     /** \internal the return type of MatrixBase::adjoint() */
91     typedef SparseTranspose</*NestByValue<*/typename ei_cleantype<ConjugateReturnType>::type> /*>*/
92             AdjointReturnType;
93
94 #ifndef EIGEN_PARSED_BY_DOXYGEN
95     /** This is the "real scalar" type; if the \a Scalar type is already real numbers
96       * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
97       * \a Scalar is \a std::complex<T> then RealScalar is \a T.
98       *
99       * \sa class NumTraits
100       */
101     typedef typename NumTraits<Scalar>::Real RealScalar;
102
103     /** type of the equivalent square matrix */
104     typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime),
105                           EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
106
107     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
108     inline Derived& derived() { return *static_cast<Derived*>(this); }
109     inline Derived& const_cast_derived() const
110     { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
111 #endif // not EIGEN_PARSED_BY_DOXYGEN
112
113     /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
114     inline int rows() const { return derived().rows(); }
115     /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
116     inline int cols() const { return derived().cols(); }
117     /** \returns the number of coefficients, which is \a rows()*cols().
118       * \sa rows(), cols(), SizeAtCompileTime. */
119     inline int size() const { return rows() * cols(); }
120     /** \returns the number of nonzero coefficients which is in practice the number
121       * of stored coefficients. */
122     inline int nonZeros() const { return derived().nonZeros(); }
123     /** \returns true if either the number of rows or the number of columns is equal to 1.
124       * In other words, this function returns
125       * \code rows()==1 || cols()==1 \endcode
126       * \sa rows(), cols(), IsVectorAtCompileTime. */
127     inline bool isVector() const { return rows()==1 || cols()==1; }
128     /** \returns the size of the storage major dimension,
129       * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
130     int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
131     /** \returns the size of the inner dimension according to the storage order,
132       * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
133     int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
134
135     bool isRValue() const { return m_isRValue; }
136     Derived& markAsRValue() { m_isRValue = true; return derived(); }
137
138     SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
139
140     inline Derived& operator=(const Derived& other)
141     {
142 //       std::cout << "Derived& operator=(const Derived& other)\n";
143 //       if (other.isRValue())
144 //         derived().swap(other.const_cast_derived());
145 //       else
146         this->operator=<Derived>(other);
147       return derived();
148     }
149
150
151     template<typename OtherDerived>
152     inline void assignGeneric(const OtherDerived& other)
153     {
154 //       std::cout << "Derived& operator=(const MatrixBase<OtherDerived>& other)\n";
155       //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
156       ei_assert(( ((ei_traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
157                   (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
158                   "the transpose operation is supposed to be handled in SparseMatrix::operator=");
159
160       const int outerSize = other.outerSize();
161       //typedef typename ei_meta_if<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::ret TempType;
162       // thanks to shallow copies, we always eval to a tempary
163       Derived temp(other.rows(), other.cols());
164
165       temp.startFill(std::max(this->rows(),this->cols())*2);
166       for (int j=0; j<outerSize; ++j)
167       {
168         for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
169         {
170           Scalar v = it.value();
171           if (v!=Scalar(0))
172           {
173             if (OtherDerived::Flags & RowMajorBit) temp.fill(j,it.index()) = v;
174             else temp.fill(it.index(),j) = v;
175           }
176         }
177       }
178       temp.endFill();
179
180       derived() = temp.markAsRValue();
181     }
182
183
184     template<typename OtherDerived>
185     inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
186     {
187 //       std::cout << typeid(OtherDerived).name() << "\n";
188 //       std::cout << Flags << " " << OtherDerived::Flags << "\n";
189       const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
190 //       std::cout << "eval transpose = " << transpose << "\n";
191       const int outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
192       if ((!transpose) && other.isRValue())
193       {
194         // eval without temporary
195         derived().resize(other.rows(), other.cols());
196         derived().startFill(std::max(this->rows(),this->cols())*2);
197         for (int j=0; j<outerSize; ++j)
198         {
199           for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
200           {
201             Scalar v = it.value();
202             if (v!=Scalar(0))
203             {
204               if (IsRowMajor) derived().fill(j,it.index()) = v;
205               else derived().fill(it.index(),j) = v;
206             }
207           }
208         }
209         derived().endFill();
210       }
211       else
212       {
213         assignGeneric(other.derived());
214       }
215       return derived();
216     }
217
218     template<typename Lhs, typename Rhs>
219     inline Derived& operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product);
220
221     friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
222     {
223       if (Flags&RowMajorBit)
224       {
225         for (int row=0; row<m.outerSize(); ++row)
226         {
227           int col = 0;
228           for (typename Derived::InnerIterator it(m.derived(), row); it; ++it)
229           {
230             for ( ; col<it.index(); ++col)
231               s << "0 ";
232             s << it.value() << " ";
233             ++col;
234           }
235           for ( ; col<m.cols(); ++col)
236             s << "0 ";
237           s << std::endl;
238         }
239       }
240       else
241       {
242         if (m.cols() == 1) {
243           int row = 0;
244           for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it)
245           {
246             for ( ; row<it.index(); ++row)
247               s << "0" << std::endl;
248             s << it.value() << std::endl;
249             ++row;
250           }
251           for ( ; row<m.rows(); ++row)
252             s << "0" << std::endl;
253         }
254         else
255         {
256           SparseMatrix<Scalar, RowMajorBit> trans = m.derived();
257           s << trans;
258         }
259       }
260       return s;
261     }
262
263     const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const;
264
265     template<typename OtherDerived>
266     const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
267     operator+(const SparseMatrixBase<OtherDerived> &other) const;
268
269     template<typename OtherDerived>
270     const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
271     operator-(const SparseMatrixBase<OtherDerived> &other) const;
272
273     template<typename OtherDerived>
274     Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
275     template<typename OtherDerived>
276     Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
277
278 //     template<typename Lhs,typename Rhs>
279 //     Derived& operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other);
280
281     Derived& operator*=(const Scalar& other);
282     Derived& operator/=(const Scalar& other);
283
284     const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
285     operator*(const Scalar& scalar) const;
286     const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
287     operator/(const Scalar& scalar) const;
288
289     inline friend const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
290     operator*(const Scalar& scalar, const SparseMatrixBase& matrix)
291     { return matrix*scalar; }
292
293
294     template<typename OtherDerived>
295     const typename SparseProductReturnType<Derived,OtherDerived>::Type
296     operator*(const SparseMatrixBase<OtherDerived> &other) const;
297     
298     // dense * sparse (return a dense object)
299     template<typename OtherDerived> friend 
300     const typename SparseProductReturnType<OtherDerived,Derived>::Type
301     operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
302     { return typename SparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
303     
304     template<typename OtherDerived>
305     const typename SparseProductReturnType<Derived,OtherDerived>::Type
306     operator*(const MatrixBase<OtherDerived> &other) const;
307
308     template<typename OtherDerived>
309     Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
310
311     template<typename OtherDerived>
312     typename ei_plain_matrix_type_column_major<OtherDerived>::type
313     solveTriangular(const MatrixBase<OtherDerived>& other) const;
314
315     template<typename OtherDerived>
316     void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
317
318     template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
319     template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
320     RealScalar squaredNorm() const;
321     RealScalar norm()  const;
322 //     const PlainMatrixType normalized() const;
323 //     void normalize();
324
325     SparseTranspose<Derived> transpose() { return derived(); }
326     const SparseTranspose<Derived> transpose() const { return derived(); }
327     // void transposeInPlace();
328     const AdjointReturnType adjoint() const { return conjugate()/*.nestByValue()*/; }
329
330     // sub-vector
331     SparseInnerVectorSet<Derived,1> row(int i);
332     const SparseInnerVectorSet<Derived,1> row(int i) const;
333     SparseInnerVectorSet<Derived,1> col(int j);
334     const SparseInnerVectorSet<Derived,1> col(int j) const;
335     SparseInnerVectorSet<Derived,1> innerVector(int outer);
336     const SparseInnerVectorSet<Derived,1> innerVector(int outer) const;
337     
338     // set of sub-vectors
339     SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size);
340     const SparseInnerVectorSet<Derived,Dynamic> subrows(int start, int size) const;
341     SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size);
342     const SparseInnerVectorSet<Derived,Dynamic> subcols(int start, int size) const;
343     SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize);
344     const SparseInnerVectorSet<Derived,Dynamic> innerVectors(int outerStart, int outerSize) const;
345
346 //     typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
347 //     const typename BlockReturnType<Derived>::Type
348 //     block(int startRow, int startCol, int blockRows, int blockCols) const;
349 //
350 //     typename BlockReturnType<Derived>::SubVectorType segment(int start, int size);
351 //     const typename BlockReturnType<Derived>::SubVectorType segment(int start, int size) const;
352 //
353 //     typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size);
354 //     const typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size) const;
355 //
356 //     typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size);
357 //     const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) const;
358 //
359 //     typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
360 //     const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
361 //
362 //     template<int BlockRows, int BlockCols>
363 //     typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
364 //     template<int BlockRows, int BlockCols>
365 //     const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
366
367 //     template<int CRows, int CCols>
368 //     typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
369 //     template<int CRows, int CCols>
370 //     const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
371
372 //     template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void);
373 //     template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const;
374
375 //     template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType end();
376 //     template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType end() const;
377
378 //     template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType segment(int start);
379 //     template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType segment(int start) const;
380
381 //     DiagonalCoeffs<Derived> diagonal();
382 //     const DiagonalCoeffs<Derived> diagonal() const;
383
384 //     template<unsigned int Mode> Part<Derived, Mode> part();
385 //     template<unsigned int Mode> const Part<Derived, Mode> part() const;
386
387
388 //     static const ConstantReturnType Constant(int rows, int cols, const Scalar& value);
389 //     static const ConstantReturnType Constant(int size, const Scalar& value);
390 //     static const ConstantReturnType Constant(const Scalar& value);
391
392 //     template<typename CustomNullaryOp>
393 //     static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int rows, int cols, const CustomNullaryOp& func);
394 //     template<typename CustomNullaryOp>
395 //     static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(int size, const CustomNullaryOp& func);
396 //     template<typename CustomNullaryOp>
397 //     static const CwiseNullaryOp<CustomNullaryOp, Derived> NullaryExpr(const CustomNullaryOp& func);
398
399 //     static const ConstantReturnType Zero(int rows, int cols);
400 //     static const ConstantReturnType Zero(int size);
401 //     static const ConstantReturnType Zero();
402 //     static const ConstantReturnType Ones(int rows, int cols);
403 //     static const ConstantReturnType Ones(int size);
404 //     static const ConstantReturnType Ones();
405 //     static const IdentityReturnType Identity();
406 //     static const IdentityReturnType Identity(int rows, int cols);
407 //     static const BasisReturnType Unit(int size, int i);
408 //     static const BasisReturnType Unit(int i);
409 //     static const BasisReturnType UnitX();
410 //     static const BasisReturnType UnitY();
411 //     static const BasisReturnType UnitZ();
412 //     static const BasisReturnType UnitW();
413
414 //     const DiagonalMatrix<Derived> asDiagonal() const;
415
416 //     Derived& setConstant(const Scalar& value);
417 //     Derived& setZero();
418 //     Derived& setOnes();
419 //     Derived& setRandom();
420 //     Derived& setIdentity();
421
422       Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
423       {
424         Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> res(rows(),cols());
425         res.setZero();
426         for (int j=0; j<outerSize(); ++j)
427         {
428           for (typename Derived::InnerIterator i(derived(),j); i; ++i)
429             if(IsRowMajor)
430               res.coeffRef(j,i.index()) = i.value();
431             else
432               res.coeffRef(i.index(),j) = i.value();
433         }
434         return res;
435       }
436
437     template<typename OtherDerived>
438     bool isApprox(const SparseMatrixBase<OtherDerived>& other,
439                   RealScalar prec = precision<Scalar>()) const
440     { return toDense().isApprox(other.toDense(),prec); }
441
442     template<typename OtherDerived>
443     bool isApprox(const MatrixBase<OtherDerived>& other,
444                   RealScalar prec = precision<Scalar>()) const
445     { return toDense().isApprox(other,prec); }
446 //     bool isMuchSmallerThan(const RealScalar& other,
447 //                            RealScalar prec = precision<Scalar>()) const;
448 //     template<typename OtherDerived>
449 //     bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
450 //                            RealScalar prec = precision<Scalar>()) const;
451
452 //     bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
453 //     bool isZero(RealScalar prec = precision<Scalar>()) const;
454 //     bool isOnes(RealScalar prec = precision<Scalar>()) const;
455 //     bool isIdentity(RealScalar prec = precision<Scalar>()) const;
456 //     bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
457
458 //     bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
459 //     bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
460
461 //     template<typename OtherDerived>
462 //     bool isOrthogonal(const MatrixBase<OtherDerived>& other,
463 //                       RealScalar prec = precision<Scalar>()) const;
464 //     bool isUnitary(RealScalar prec = precision<Scalar>()) const;
465
466 //     template<typename OtherDerived>
467 //     inline bool operator==(const MatrixBase<OtherDerived>& other) const
468 //     { return (cwise() == other).all(); }
469
470 //     template<typename OtherDerived>
471 //     inline bool operator!=(const MatrixBase<OtherDerived>& other) const
472 //     { return (cwise() != other).any(); }
473
474
475     template<typename NewType>
476     const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const;
477
478     /** \returns the matrix or vector obtained by evaluating this expression.
479       *
480       * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
481       * a const reference, in order to avoid a useless copy.
482       */
483     EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const
484     { return typename ei_eval<Derived>::type(derived()); }
485
486 //     template<typename OtherDerived>
487 //     void swap(const MatrixBase<OtherDerived>& other);
488
489     template<unsigned int Added>
490     const SparseFlagged<Derived, Added, 0> marked() const;
491 //     const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const;
492
493     /** \returns number of elements to skip to pass from one row (resp. column) to another
494       * for a row-major (resp. column-major) matrix.
495       * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data
496       * of the underlying matrix.
497       */
498 //     inline int stride(void) const { return derived().stride(); }
499
500 //     inline const NestByValue<Derived> nestByValue() const;
501
502
503     ConjugateReturnType conjugate() const;
504     const RealReturnType real() const;
505     const ImagReturnType imag() const;
506
507     template<typename CustomUnaryOp>
508     const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const;
509
510 //     template<typename CustomBinaryOp, typename OtherDerived>
511 //     const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
512 //     binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
513
514
515     Scalar sum() const;
516 //     Scalar trace() const;
517
518 //     typename ei_traits<Derived>::Scalar minCoeff() const;
519 //     typename ei_traits<Derived>::Scalar maxCoeff() const;
520
521 //     typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const;
522 //     typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const;
523
524 //     template<typename BinaryOp>
525 //     typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
526 //     redux(const BinaryOp& func) const;
527
528 //     template<typename Visitor>
529 //     void visit(Visitor& func) const;
530
531
532     const SparseCwise<Derived> cwise() const;
533     SparseCwise<Derived> cwise();
534
535 //     inline const WithFormat<Derived> format(const IOFormat& fmt) const;
536
537 /////////// Array module ///////////
538     /*
539     bool all(void) const;
540     bool any(void) const;
541
542     const PartialRedux<Derived,Horizontal> rowwise() const;
543     const PartialRedux<Derived,Vertical> colwise() const;
544
545     static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols);
546     static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size);
547     static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random();
548
549     template<typename ThenDerived,typename ElseDerived>
550     const Select<Derived,ThenDerived,ElseDerived>
551     select(const MatrixBase<ThenDerived>& thenMatrix,
552            const MatrixBase<ElseDerived>& elseMatrix) const;
553
554     template<typename ThenDerived>
555     inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
556     select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
557
558     template<typename ElseDerived>
559     inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
560     select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
561
562     template<int p> RealScalar lpNorm() const;
563     */
564
565
566 //     template<typename OtherDerived>
567 //     Scalar dot(const MatrixBase<OtherDerived>& other) const
568 //     {
569 //       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
570 //       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
571 //       EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
572 //         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
573 //
574 //       ei_assert(derived().size() == other.size());
575 //       // short version, but the assembly looks more complicated because
576 //       // of the CwiseBinaryOp iterator complexity
577 //       // return res = (derived().cwise() * other.derived().conjugate()).sum();
578 //
579 //       // optimized, generic version
580 //       typename Derived::InnerIterator i(derived(),0);
581 //       typename OtherDerived::InnerIterator j(other.derived(),0);
582 //       Scalar res = 0;
583 //       while (i && j)
584 //       {
585 //         if (i.index()==j.index())
586 //         {
587 // //           std::cerr << i.value() << " * " << j.value() << "\n";
588 //           res += i.value() * ei_conj(j.value());
589 //           ++i; ++j;
590 //         }
591 //         else if (i.index()<j.index())
592 //           ++i;
593 //         else
594 //           ++j;
595 //       }
596 //       return res;
597 //     }
598 //
599 //     Scalar sum() const
600 //     {
601 //       Scalar res = 0;
602 //       for (typename Derived::InnerIterator iter(*this,0); iter; ++iter)
603 //       {
604 //         res += iter.value();
605 //       }
606 //       return res;
607 //     }
608
609     #ifdef EIGEN_TAUCS_SUPPORT
610     taucs_ccs_matrix asTaucsMatrix();
611     #endif
612
613     #ifdef EIGEN_CHOLMOD_SUPPORT
614     cholmod_sparse asCholmodMatrix();
615     #endif
616
617     #ifdef EIGEN_SUPERLU_SUPPORT
618     SluMatrix asSluMatrix();
619     #endif
620
621   protected:
622
623     bool m_isRValue;
624 };
625
626 #endif // EIGEN_SPARSEMATRIXBASE_H