1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_SKYLINEMATRIXBASE_H
11 #define EIGEN_SKYLINEMATRIXBASE_H
12 
13 #include "SkylineUtil.h"
14 
15 namespace Eigen {
16 
17 /** \ingroup Skyline_Module
18  *
19  * \class SkylineMatrixBase
20  *
21  * \brief Base class of any skyline matrices or skyline expressions
22  *
23  * \param Derived
24  *
25  */
26 template<typename Derived> class SkylineMatrixBase : public EigenBase<Derived> {
27 public:
28 
29     typedef typename internal::traits<Derived>::Scalar Scalar;
30     typedef typename internal::traits<Derived>::StorageKind StorageKind;
31     typedef typename internal::index<StorageKind>::type Index;
32 
33     enum {
34         RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
35         /**< The number of rows at compile-time. This is just a copy of the value provided
36          * by the \a Derived type. If a value is not known at compile-time,
37          * it is set to the \a Dynamic constant.
38          * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
39 
40         ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
41         /**< The number of columns at compile-time. This is just a copy of the value provided
42          * by the \a Derived type. If a value is not known at compile-time,
43          * it is set to the \a Dynamic constant.
44          * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
45 
46 
47         SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
48         internal::traits<Derived>::ColsAtCompileTime>::ret),
49         /**< This is equal to the number of coefficients, i.e. the number of
50          * rows times the number of columns, or to \a Dynamic if this is not
51          * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
52 
53         MaxRowsAtCompileTime = RowsAtCompileTime,
54         MaxColsAtCompileTime = ColsAtCompileTime,
55 
56         MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
57         MaxColsAtCompileTime>::ret),
58 
59         IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
60         /**< This is set to true if either the number of rows or the number of
61          * columns is known at compile-time to be equal to 1. Indeed, in that case,
62          * we are dealing with a column-vector (if there is only one column) or with
63          * a row-vector (if there is only one row). */
64 
65         Flags = internal::traits<Derived>::Flags,
66         /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
67          * constructed from this one. See the \ref flags "list of flags".
68          */
69 
70         CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
71         /**< This is a rough measure of how expensive it is to read one coefficient from
72          * this expression.
73          */
74 
75         IsRowMajor = Flags & RowMajorBit ? 1 : 0
76     };
77 
78 #ifndef EIGEN_PARSED_BY_DOXYGEN
79     /** This is the "real scalar" type; if the \a Scalar type is already real numbers
80      * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
81      * \a Scalar is \a std::complex<T> then RealScalar is \a T.
82      *
83      * \sa class NumTraits
84      */
85     typedef typename NumTraits<Scalar>::Real RealScalar;
86 
87     /** type of the equivalent square matrix */
88     typedef Matrix<Scalar, EIGEN_SIZE_MAX(RowsAtCompileTime, ColsAtCompileTime),
89                            EIGEN_SIZE_MAX(RowsAtCompileTime, ColsAtCompileTime) > SquareMatrixType;
90 
derived()91     inline const Derived& derived() const {
92         return *static_cast<const Derived*> (this);
93     }
94 
derived()95     inline Derived& derived() {
96         return *static_cast<Derived*> (this);
97     }
98 
const_cast_derived()99     inline Derived& const_cast_derived() const {
100         return *static_cast<Derived*> (const_cast<SkylineMatrixBase*> (this));
101     }
102 #endif // not EIGEN_PARSED_BY_DOXYGEN
103 
104     /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
rows()105     inline Index rows() const {
106         return derived().rows();
107     }
108 
109     /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
cols()110     inline Index cols() const {
111         return derived().cols();
112     }
113 
114     /** \returns the number of coefficients, which is \a rows()*cols().
115      * \sa rows(), cols(), SizeAtCompileTime. */
size()116     inline Index size() const {
117         return rows() * cols();
118     }
119 
120     /** \returns the number of nonzero coefficients which is in practice the number
121      * of stored coefficients. */
nonZeros()122     inline Index nonZeros() const {
123         return derived().nonZeros();
124     }
125 
126     /** \returns the size of the storage major dimension,
127      * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
outerSize()128     Index outerSize() const {
129         return (int(Flags) & RowMajorBit) ? this->rows() : this->cols();
130     }
131 
132     /** \returns the size of the inner dimension according to the storage order,
133      * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
innerSize()134     Index innerSize() const {
135         return (int(Flags) & RowMajorBit) ? this->cols() : this->rows();
136     }
137 
isRValue()138     bool isRValue() const {
139         return m_isRValue;
140     }
141 
markAsRValue()142     Derived& markAsRValue() {
143         m_isRValue = true;
144         return derived();
145     }
146 
SkylineMatrixBase()147     SkylineMatrixBase() : m_isRValue(false) {
148         /* TODO check flags */
149     }
150 
151     inline Derived & operator=(const Derived& other) {
152         this->operator=<Derived > (other);
153         return derived();
154     }
155 
156     template<typename OtherDerived>
assignGeneric(const OtherDerived & other)157     inline void assignGeneric(const OtherDerived& other) {
158         derived().resize(other.rows(), other.cols());
159         for (Index row = 0; row < rows(); row++)
160             for (Index col = 0; col < cols(); col++) {
161                 if (other.coeff(row, col) != Scalar(0))
162                     derived().insert(row, col) = other.coeff(row, col);
163             }
164         derived().finalize();
165     }
166 
167     template<typename OtherDerived>
168             inline Derived & operator=(const SkylineMatrixBase<OtherDerived>& other) {
169         //TODO
170     }
171 
172     template<typename Lhs, typename Rhs>
173             inline Derived & operator=(const SkylineProduct<Lhs, Rhs, SkylineTimeSkylineProduct>& product);
174 
175     friend std::ostream & operator <<(std::ostream & s, const SkylineMatrixBase& m) {
176         s << m.derived();
177         return s;
178     }
179 
180     template<typename OtherDerived>
181     const typename SkylineProductReturnType<Derived, OtherDerived>::Type
182     operator*(const MatrixBase<OtherDerived> &other) const;
183 
184     /** \internal use operator= */
185     template<typename DenseDerived>
evalTo(MatrixBase<DenseDerived> & dst)186     void evalTo(MatrixBase<DenseDerived>& dst) const {
187         dst.setZero();
188         for (Index i = 0; i < rows(); i++)
189             for (Index j = 0; j < rows(); j++)
190                 dst(i, j) = derived().coeff(i, j);
191     }
192 
toDense()193     Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime> toDense() const {
194         return derived();
195     }
196 
197     /** \returns the matrix or vector obtained by evaluating this expression.
198      *
199      * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
200      * a const reference, in order to avoid a useless copy.
201      */
eval()202     EIGEN_STRONG_INLINE const typename internal::eval<Derived, IsSkyline>::type eval() const {
203         return typename internal::eval<Derived>::type(derived());
204     }
205 
206 protected:
207     bool m_isRValue;
208 };
209 
210 } // end namespace Eigen
211 
212 #endif // EIGEN_SkylineMatrixBase_H
213