1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SPARSEMATRIXBASE_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSEMATRIXBASE_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup SparseCore_Module
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \class SparseMatrixBase
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief Base class of any sparse matrices or sparse expressions
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \tparam Derived
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This class can be extended with the help of the plugin mechanism described on the page
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN.
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::Scalar Scalar;
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::StorageKind StorageKind;
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::Index Index;
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::add_const_on_value_type_if_arithmetic<
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                         typename internal::packet_traits<Scalar>::type
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                     >::type PacketReturnType;
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef SparseMatrixBase StorageBaseType;
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef EigenBase<Derived> Base;
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator=(const EigenBase<OtherDerived> &other)
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      other.derived().evalTo(derived());
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return derived();
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< The number of rows at compile-time. This is just a copy of the value provided
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * by the \a Derived type. If a value is not known at compile-time,
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * it is set to the \a Dynamic constant.
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< The number of columns at compile-time. This is just a copy of the value provided
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * by the \a Derived type. If a value is not known at compile-time,
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * it is set to the \a Dynamic constant.
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                                   internal::traits<Derived>::ColsAtCompileTime>::ret),
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< This is equal to the number of coefficients, i.e. the number of
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * rows times the number of columns, or to \a Dynamic if this is not
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxRowsAtCompileTime = RowsAtCompileTime,
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxColsAtCompileTime = ColsAtCompileTime,
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                                      MaxColsAtCompileTime>::ret),
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< This is set to true if either the number of rows or the number of
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * columns is known at compile-time to be equal to 1. Indeed, in that case,
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * we are dealing with a column-vector (if there is only one column) or with
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * a row-vector (if there is only one row). */
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Flags = internal::traits<Derived>::Flags,
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * constructed from this one. See the \ref flags "list of flags".
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          */
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        /**< This is a rough measure of how expensive it is to read one coefficient from
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          * this expression.
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          */
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      IsRowMajor = Flags&RowMajorBit ? 1 : 0,
927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                             : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #ifndef EIGEN_PARSED_BY_DOXYGEN
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #endif
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \internal the return type of MatrixBase::adjoint() */
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        Transpose<const Derived>
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                     >::type AdjointReturnType;
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject;
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_PARSED_BY_DOXYGEN
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** This is the "real scalar" type; if the \a Scalar type is already real numbers
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \a Scalar is \a std::complex<T> then RealScalar is \a T.
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa class NumTraits
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename NumTraits<Scalar>::Real RealScalar;
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \internal the return type of coeff()
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \internal Represents a matrix with all coefficients equal to one another*/
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** type of the equivalent square matrix */
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& derived() { return *static_cast<Derived*>(this); }
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& const_cast_derived() const
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // not EIGEN_PARSED_BY_DOXYGEN
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   include "../plugins/CommonCwiseUnaryOps.h"
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   include "../plugins/CommonCwiseBinaryOps.h"
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   include "../plugins/MatrixCwiseUnaryOps.h"
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   include "../plugins/MatrixCwiseBinaryOps.h"
1427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#   include "../plugins/BlockMethods.h"
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#     include EIGEN_SPARSEMATRIXBASE_PLUGIN
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   endif
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#   undef EIGEN_CURRENT_STORAGE_BASE_CLASS
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the number of rows. \sa cols() */
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index rows() const { return derived().rows(); }
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the number of columns. \sa rows() */
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index cols() const { return derived().cols(); }
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the number of coefficients, which is \a rows()*cols().
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa rows(), cols(). */
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index size() const { return rows() * cols(); }
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the number of nonzero coefficients which is in practice the number
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * of stored coefficients. */
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index nonZeros() const { return derived().nonZeros(); }
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns true if either the number of rows or the number of columns is equal to 1.
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * In other words, this function returns
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \code rows()==1 || cols()==1 \endcode
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa rows(), cols(), IsVectorAtCompileTime. */
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline bool isVector() const { return rows()==1 || cols()==1; }
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the size of the storage major dimension,
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the size of the inner dimension according to the storage order,
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool isRValue() const { return m_isRValue; }
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& markAsRValue() { m_isRValue = true; return derived(); }
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator=(const ReturnByValue<OtherDerived>& other)
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      other.evalTo(derived());
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return derived();
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assign(other.derived());
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& operator=(const Derived& other)
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       if (other.isRValue())
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//         derived().swap(other.const_cast_derived());
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       else
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assign(other.derived());
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& assign(const OtherDerived& other)
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if ((!transpose) && other.isRValue())
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        // eval without temporary
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        derived().resize(other.rows(), other.cols());
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        derived().setZero();
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        derived().reserve((std::max)(this->rows(),this->cols())*2);
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for (Index j=0; j<outerSize; ++j)
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          derived().startVec(j);
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          {
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            Scalar v = it.value();
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            derived().insertBackByOuterInner(j,it.index()) = v;
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          }
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        derived().finalize();
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        assignGeneric(other);
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return derived();
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline void assignGeneric(const OtherDerived& other)
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  "the transpose operation is supposed to be handled in SparseMatrix::operator=");
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      const Index outerSize = other.outerSize();
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // thanks to shallow copies, we always eval to a tempary
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Derived temp(other.rows(), other.cols());
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      temp.reserve((std::max)(this->rows(),this->cols())*2);
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (Index j=0; j<outerSize; ++j)
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        temp.startVec(j);
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          Scalar v = it.value();
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      temp.finalize();
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      derived() = temp.markAsRValue();
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Lhs, typename Rhs>
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename Derived::Nested Nested;
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::remove_all<Nested>::type NestedCleaned;
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (Flags&RowMajorBit)
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Nested nm(m.derived());
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for (Index row=0; row<nm.outerSize(); ++row)
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          Index col = 0;
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          {
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            for ( ; col<it.index(); ++col)
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              s << "0 ";
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            s << it.value() << " ";
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            ++col;
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          }
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          for ( ; col<m.cols(); ++col)
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            s << "0 ";
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          s << std::endl;
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        const Nested nm(m.derived());
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (m.cols() == 1) {
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          Index row = 0;
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          {
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            for ( ; row<it.index(); ++row)
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              s << "0" << std::endl;
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            s << it.value() << std::endl;
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            ++row;
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          }
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          for ( ; row<m.rows(); ++row)
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            s << "0" << std::endl;
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
3057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          SparseMatrix<Scalar, RowMajorBit, Index> trans = m;
3067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans);
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return s;
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator*=(const Scalar& other);
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator/=(const Scalar& other);
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      CwiseBinaryOp< \
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        internal::scalar_product_op< \
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          typename internal::scalar_product_traits< \
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            typename internal::traits<Derived>::Scalar, \
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            typename internal::traits<OtherDerived>::Scalar \
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          >::ReturnType \
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        >, \
3287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        const Derived, \
3297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        const OtherDerived \
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      >
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    cwiseProduct(const MatrixBase<OtherDerived> &other) const;
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // sparse * sparse
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const SparseMatrixBase<OtherDerived> &other) const;
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // sparse * diagonal
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const SparseDiagonalProduct<Derived,OtherDerived>
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const DiagonalBase<OtherDerived> &other) const;
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // diagonal * sparse
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived> friend
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const SparseDiagonalProduct<OtherDerived,Derived>
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** dense * sparse (return a dense object unless it is an outer product) */
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived> friend
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** sparse * dense (returns a dense object unless it is an outer product) */
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const MatrixBase<OtherDerived> &other) const;
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef EIGEN2_SUPPORT
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // deprecated
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::plain_matrix_type_column_major<OtherDerived>::type
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    solveTriangular(const MatrixBase<OtherDerived>& other) const;
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // deprecated
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif // EIGEN2_SUPPORT
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<int Mode>
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const SparseTriangularView<Derived, Mode> triangularView() const;
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar squaredNorm() const;
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar norm()  const;
3937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    RealScalar blueNorm() const;
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Transpose<Derived> transpose() { return derived(); }
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Transpose<const Derived> transpose() const { return derived(); }
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const AdjointReturnType adjoint() const { return transpose(); }
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
3997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // inner-vector
4007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true>       InnerVectorReturnType;
4017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType;
4027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    InnerVectorReturnType innerVector(Index outer);
4037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const ConstInnerVectorReturnType innerVector(Index outer) const;
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // set of inner-vectors
4067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
4077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
4087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    /** \internal use operator= */
4107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    template<typename DenseDerived>
4117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    void evalTo(MatrixBase<DenseDerived>& dst) const
4127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    {
4137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      dst.setZero();
4147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      for (Index j=0; j<outerSize(); ++j)
4157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        for (typename Derived::InnerIterator i(derived(),j); i; ++i)
4167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          dst.coeffRef(i.row(),i.col()) = i.value();
4177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
4187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
4197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
4207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    {
4217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      return derived();
4227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    }
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool isApprox(const SparseMatrixBase<OtherDerived>& other,
4267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return toDense().isApprox(other.toDense(),prec); }
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool isApprox(const MatrixBase<OtherDerived>& other,
4317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return toDense().isApprox(other,prec); }
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the matrix or vector obtained by evaluating this expression.
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * a const reference, in order to avoid a useless copy.
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const typename internal::eval<Derived>::type eval() const
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return typename internal::eval<Derived>::type(derived()); }
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar sum() const;
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool m_isRValue;
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSEMATRIXBASE_H
452