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
15namespace 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 */
26template<typename Derived> class SkylineMatrixBase : public EigenBase<Derived> {
27public:
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
91    inline const Derived& derived() const {
92        return *static_cast<const Derived*> (this);
93    }
94
95    inline Derived& derived() {
96        return *static_cast<Derived*> (this);
97    }
98
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 */
105    inline Index rows() const {
106        return derived().rows();
107    }
108
109    /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
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. */
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. */
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 */
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 */
134    Index innerSize() const {
135        return (int(Flags) & RowMajorBit) ? this->cols() : this->rows();
136    }
137
138    bool isRValue() const {
139        return m_isRValue;
140    }
141
142    Derived& markAsRValue() {
143        m_isRValue = true;
144        return derived();
145    }
146
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>
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>
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
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     */
202    EIGEN_STRONG_INLINE const typename internal::eval<Derived, IsSkyline>::type eval() const {
203        return typename internal::eval<Derived>::type(derived());
204    }
205
206protected:
207    bool m_isRValue;
208};
209
210} // end namespace Eigen
211
212#endif // EIGEN_SkylineMatrixBase_H
213