Replicate.h 6.83 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_REPLICATE_H
#define EIGEN_REPLICATE_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 32 33 34 35 36 37
/**
  * \class Replicate
  * \ingroup Core_Module
  *
  * \brief Expression of the multiple replication of a matrix or vector
  *
  * \param MatrixType the type of the object we are replicating
  *
  * This class represents an expression of the multiple replication of a matrix or vector.
  * It is the return type of DenseBase::replicate() and most of the time
  * this is the only way it is used.
  *
  * \sa DenseBase::replicate()
  */

namespace internal {
template<typename MatrixType,int RowFactor,int ColFactor>
struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
 : traits<MatrixType>
{
  typedef typename MatrixType::Scalar Scalar;
  typedef typename traits<MatrixType>::StorageKind StorageKind;
  typedef typename traits<MatrixType>::XprKind XprKind;
Don Gagne's avatar
Don Gagne committed
38 39 40 41
  enum {
    Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
  };
  typedef typename nested<MatrixType,Factor>::type MatrixTypeNested;
LM's avatar
LM committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
  enum {
    RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
                      ? Dynamic
                      : RowFactor * MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
                      ? Dynamic
                      : ColFactor * MatrixType::ColsAtCompileTime,
   //FIXME we don't propagate the max sizes !!!
    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,
    IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
               : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
               : (MatrixType::Flags & RowMajorBit) ? 1 : 0,
    Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0),
    CoeffReadCost = _MatrixTypeNested::CoeffReadCost
  };
};
}

template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
  : public internal::dense_xpr_base< Replicate<MatrixType,RowFactor,ColFactor> >::type
{
Don Gagne's avatar
Don Gagne committed
65 66
    typedef typename internal::traits<Replicate>::MatrixTypeNested MatrixTypeNested;
    typedef typename internal::traits<Replicate>::_MatrixTypeNested _MatrixTypeNested;
LM's avatar
LM committed
67 68 69 70 71 72
  public:

    typedef typename internal::dense_xpr_base<Replicate>::type Base;
    EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)

    template<typename OriginalMatrixType>
Don Gagne's avatar
Don Gagne committed
73 74
    inline explicit Replicate(const OriginalMatrixType& a_matrix)
      : m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
LM's avatar
LM committed
75 76 77 78 79 80 81
    {
      EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
                          THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
      eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic);
    }

    template<typename OriginalMatrixType>
Don Gagne's avatar
Don Gagne committed
82 83
    inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor)
      : m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
LM's avatar
LM committed
84 85 86 87 88 89 90 91
    {
      EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
                          THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
    }

    inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
    inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }

Don Gagne's avatar
Don Gagne committed
92
    inline Scalar coeff(Index rowId, Index colId) const
LM's avatar
LM committed
93 94 95
    {
      // try to avoid using modulo; this is a pure optimization strategy
      const Index actual_row  = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
Don Gagne's avatar
Don Gagne committed
96 97
                            : RowFactor==1 ? rowId
                            : rowId%m_matrix.rows();
LM's avatar
LM committed
98
      const Index actual_col  = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
Don Gagne's avatar
Don Gagne committed
99 100
                            : ColFactor==1 ? colId
                            : colId%m_matrix.cols();
LM's avatar
LM committed
101 102 103 104

      return m_matrix.coeff(actual_row, actual_col);
    }
    template<int LoadMode>
Don Gagne's avatar
Don Gagne committed
105
    inline PacketScalar packet(Index rowId, Index colId) const
LM's avatar
LM committed
106 107
    {
      const Index actual_row  = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
Don Gagne's avatar
Don Gagne committed
108 109
                            : RowFactor==1 ? rowId
                            : rowId%m_matrix.rows();
LM's avatar
LM committed
110
      const Index actual_col  = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
Don Gagne's avatar
Don Gagne committed
111 112
                            : ColFactor==1 ? colId
                            : colId%m_matrix.cols();
LM's avatar
LM committed
113 114 115 116

      return m_matrix.template packet<LoadMode>(actual_row, actual_col);
    }

Don Gagne's avatar
Don Gagne committed
117 118 119 120
    const _MatrixTypeNested& nestedExpression() const
    { 
      return m_matrix; 
    }
LM's avatar
LM committed
121 122

  protected:
Don Gagne's avatar
Don Gagne committed
123
    MatrixTypeNested m_matrix;
LM's avatar
LM committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
    const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor;
    const internal::variable_if_dynamic<Index, ColFactor> m_colFactor;
};

/**
  * \return an expression of the replication of \c *this
  *
  * Example: \include MatrixBase_replicate.cpp
  * Output: \verbinclude MatrixBase_replicate.out
  *
  * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate
  */
template<typename Derived>
template<int RowFactor, int ColFactor>
inline const Replicate<Derived,RowFactor,ColFactor>
DenseBase<Derived>::replicate() const
{
  return Replicate<Derived,RowFactor,ColFactor>(derived());
}

/**
  * \return an expression of the replication of \c *this
  *
  * Example: \include MatrixBase_replicate_int_int.cpp
  * Output: \verbinclude MatrixBase_replicate_int_int.out
  *
  * \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
  */
template<typename Derived>
inline const Replicate<Derived,Dynamic,Dynamic>
DenseBase<Derived>::replicate(Index rowFactor,Index colFactor) const
{
  return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor);
}

/**
  * \return an expression of the replication of each column (or row) of \c *this
  *
  * Example: \include DirectionWise_replicate_int.cpp
  * Output: \verbinclude DirectionWise_replicate_int.out
  *
  * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
  */
template<typename ExpressionType, int Direction>
const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const
{
  return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
          (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1);
}

Don Gagne's avatar
Don Gagne committed
175 176
} // end namespace Eigen

LM's avatar
LM committed
177
#endif // EIGEN_REPLICATE_H