ArrayWrapper.h 8.19 KB
Newer Older
LM's avatar
LM committed
1 2 3 4 5
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
Don Gagne's avatar
Don Gagne committed
6 7 8
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
LM's avatar
LM committed
9 10 11 12

#ifndef EIGEN_ARRAYWRAPPER_H
#define EIGEN_ARRAYWRAPPER_H

Don Gagne's avatar
Don Gagne committed
13 14
namespace Eigen { 

LM's avatar
LM committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/** \class ArrayWrapper
  * \ingroup Core_Module
  *
  * \brief Expression of a mathematical vector or matrix as an array object
  *
  * This class is the return type of MatrixBase::array(), and most of the time
  * this is the only way it is use.
  *
  * \sa MatrixBase::array(), class MatrixWrapper
  */

namespace internal {
template<typename ExpressionType>
struct traits<ArrayWrapper<ExpressionType> >
  : public traits<typename remove_all<typename ExpressionType::Nested>::type >
{
  typedef ArrayXpr XprKind;
32 33 34 35 36
  // Let's remove NestByRefBit
  enum {
    Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
    Flags = Flags0 & ~NestByRefBit
  };
LM's avatar
LM committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
};
}

template<typename ExpressionType>
class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
{
  public:
    typedef ArrayBase<ArrayWrapper> Base;
    EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)

    typedef typename internal::conditional<
                       internal::is_lvalue<ExpressionType>::value,
                       Scalar,
                       const Scalar
                     >::type ScalarWithConstIfNotLvalue;

    typedef typename internal::nested<ExpressionType>::type NestedExpressionType;

Don Gagne's avatar
Don Gagne committed
56
    inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
LM's avatar
LM committed
57 58 59 60 61 62

    inline Index rows() const { return m_expression.rows(); }
    inline Index cols() const { return m_expression.cols(); }
    inline Index outerStride() const { return m_expression.outerStride(); }
    inline Index innerStride() const { return m_expression.innerStride(); }

Don Gagne's avatar
Don Gagne committed
63
    inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
LM's avatar
LM committed
64 65
    inline const Scalar* data() const { return m_expression.data(); }

Don Gagne's avatar
Don Gagne committed
66
    inline CoeffReturnType coeff(Index rowId, Index colId) const
LM's avatar
LM committed
67
    {
Don Gagne's avatar
Don Gagne committed
68
      return m_expression.coeff(rowId, colId);
LM's avatar
LM committed
69 70
    }

Don Gagne's avatar
Don Gagne committed
71
    inline Scalar& coeffRef(Index rowId, Index colId)
LM's avatar
LM committed
72
    {
Don Gagne's avatar
Don Gagne committed
73
      return m_expression.const_cast_derived().coeffRef(rowId, colId);
LM's avatar
LM committed
74 75
    }

Don Gagne's avatar
Don Gagne committed
76
    inline const Scalar& coeffRef(Index rowId, Index colId) const
LM's avatar
LM committed
77
    {
Don Gagne's avatar
Don Gagne committed
78
      return m_expression.const_cast_derived().coeffRef(rowId, colId);
LM's avatar
LM committed
79 80
    }

Don Gagne's avatar
Don Gagne committed
81
    inline CoeffReturnType coeff(Index index) const
LM's avatar
LM committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    {
      return m_expression.coeff(index);
    }

    inline Scalar& coeffRef(Index index)
    {
      return m_expression.const_cast_derived().coeffRef(index);
    }

    inline const Scalar& coeffRef(Index index) const
    {
      return m_expression.const_cast_derived().coeffRef(index);
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
97
    inline const PacketScalar packet(Index rowId, Index colId) const
LM's avatar
LM committed
98
    {
Don Gagne's avatar
Don Gagne committed
99
      return m_expression.template packet<LoadMode>(rowId, colId);
LM's avatar
LM committed
100 101 102
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
103
    inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
LM's avatar
LM committed
104
    {
Don Gagne's avatar
Don Gagne committed
105
      m_expression.const_cast_derived().template writePacket<LoadMode>(rowId, colId, val);
LM's avatar
LM committed
106 107 108 109 110 111 112 113 114
    }

    template<int LoadMode>
    inline const PacketScalar packet(Index index) const
    {
      return m_expression.template packet<LoadMode>(index);
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
115
    inline void writePacket(Index index, const PacketScalar& val)
LM's avatar
LM committed
116
    {
Don Gagne's avatar
Don Gagne committed
117
      m_expression.const_cast_derived().template writePacket<LoadMode>(index, val);
LM's avatar
LM committed
118 119 120 121 122
    }

    template<typename Dest>
    inline void evalTo(Dest& dst) const { dst = m_expression; }

Don Gagne's avatar
Don Gagne committed
123 124 125 126 127 128 129 130 131 132 133 134 135
    const typename internal::remove_all<NestedExpressionType>::type& 
    nestedExpression() const 
    {
      return m_expression;
    }

    /** Forwards the resizing request to the nested expression
      * \sa DenseBase::resize(Index)  */
    void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
    /** Forwards the resizing request to the nested expression
      * \sa DenseBase::resize(Index,Index)*/
    void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }

LM's avatar
LM committed
136
  protected:
Don Gagne's avatar
Don Gagne committed
137
    NestedExpressionType m_expression;
LM's avatar
LM committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
};

/** \class MatrixWrapper
  * \ingroup Core_Module
  *
  * \brief Expression of an array as a mathematical vector or matrix
  *
  * This class is the return type of ArrayBase::matrix(), and most of the time
  * this is the only way it is use.
  *
  * \sa MatrixBase::matrix(), class ArrayWrapper
  */

namespace internal {
template<typename ExpressionType>
struct traits<MatrixWrapper<ExpressionType> >
 : public traits<typename remove_all<typename ExpressionType::Nested>::type >
{
  typedef MatrixXpr XprKind;
157 158 159 160 161
  // Let's remove NestByRefBit
  enum {
    Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
    Flags = Flags0 & ~NestByRefBit
  };
LM's avatar
LM committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
};
}

template<typename ExpressionType>
class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
{
  public:
    typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
    EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)

    typedef typename internal::conditional<
                       internal::is_lvalue<ExpressionType>::value,
                       Scalar,
                       const Scalar
                     >::type ScalarWithConstIfNotLvalue;

    typedef typename internal::nested<ExpressionType>::type NestedExpressionType;

Don Gagne's avatar
Don Gagne committed
181
    inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {}
LM's avatar
LM committed
182 183 184 185 186 187

    inline Index rows() const { return m_expression.rows(); }
    inline Index cols() const { return m_expression.cols(); }
    inline Index outerStride() const { return m_expression.outerStride(); }
    inline Index innerStride() const { return m_expression.innerStride(); }

Don Gagne's avatar
Don Gagne committed
188
    inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
LM's avatar
LM committed
189 190
    inline const Scalar* data() const { return m_expression.data(); }

Don Gagne's avatar
Don Gagne committed
191
    inline CoeffReturnType coeff(Index rowId, Index colId) const
LM's avatar
LM committed
192
    {
Don Gagne's avatar
Don Gagne committed
193
      return m_expression.coeff(rowId, colId);
LM's avatar
LM committed
194 195
    }

Don Gagne's avatar
Don Gagne committed
196
    inline Scalar& coeffRef(Index rowId, Index colId)
LM's avatar
LM committed
197
    {
Don Gagne's avatar
Don Gagne committed
198
      return m_expression.const_cast_derived().coeffRef(rowId, colId);
LM's avatar
LM committed
199 200
    }

Don Gagne's avatar
Don Gagne committed
201
    inline const Scalar& coeffRef(Index rowId, Index colId) const
LM's avatar
LM committed
202
    {
Don Gagne's avatar
Don Gagne committed
203
      return m_expression.derived().coeffRef(rowId, colId);
LM's avatar
LM committed
204 205
    }

Don Gagne's avatar
Don Gagne committed
206
    inline CoeffReturnType coeff(Index index) const
LM's avatar
LM committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
    {
      return m_expression.coeff(index);
    }

    inline Scalar& coeffRef(Index index)
    {
      return m_expression.const_cast_derived().coeffRef(index);
    }

    inline const Scalar& coeffRef(Index index) const
    {
      return m_expression.const_cast_derived().coeffRef(index);
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
222
    inline const PacketScalar packet(Index rowId, Index colId) const
LM's avatar
LM committed
223
    {
Don Gagne's avatar
Don Gagne committed
224
      return m_expression.template packet<LoadMode>(rowId, colId);
LM's avatar
LM committed
225 226 227
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
228
    inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
LM's avatar
LM committed
229
    {
Don Gagne's avatar
Don Gagne committed
230
      m_expression.const_cast_derived().template writePacket<LoadMode>(rowId, colId, val);
LM's avatar
LM committed
231 232 233 234 235 236 237 238 239
    }

    template<int LoadMode>
    inline const PacketScalar packet(Index index) const
    {
      return m_expression.template packet<LoadMode>(index);
    }

    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
240 241 242 243 244 245 246
    inline void writePacket(Index index, const PacketScalar& val)
    {
      m_expression.const_cast_derived().template writePacket<LoadMode>(index, val);
    }

    const typename internal::remove_all<NestedExpressionType>::type& 
    nestedExpression() const 
LM's avatar
LM committed
247
    {
Don Gagne's avatar
Don Gagne committed
248
      return m_expression;
LM's avatar
LM committed
249 250
    }

Don Gagne's avatar
Don Gagne committed
251 252 253 254 255 256 257
    /** Forwards the resizing request to the nested expression
      * \sa DenseBase::resize(Index)  */
    void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
    /** Forwards the resizing request to the nested expression
      * \sa DenseBase::resize(Index,Index)*/
    void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }

LM's avatar
LM committed
258
  protected:
Don Gagne's avatar
Don Gagne committed
259
    NestedExpressionType m_expression;
LM's avatar
LM committed
260 261
};

Don Gagne's avatar
Don Gagne committed
262 263
} // end namespace Eigen

LM's avatar
LM committed
264
#endif // EIGEN_ARRAYWRAPPER_H