Replicate.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef EIGEN_REPLICATE_H
26 #define EIGEN_REPLICATE_H
27 
28 namespace Eigen {
29 
45 namespace internal {
46 template<typename MatrixType,int RowFactor,int ColFactor>
47 struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
48  : traits<MatrixType>
49 {
50  typedef typename MatrixType::Scalar Scalar;
51  typedef typename traits<MatrixType>::StorageKind StorageKind;
52  typedef typename traits<MatrixType>::XprKind XprKind;
53  enum {
54  Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
55  };
56  typedef typename nested<MatrixType,Factor>::type MatrixTypeNested;
57  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
58  enum {
59  RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
60  ? Dynamic
61  : RowFactor * MatrixType::RowsAtCompileTime,
62  ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
63  ? Dynamic
64  : ColFactor * MatrixType::ColsAtCompileTime,
65  //FIXME we don't propagate the max sizes !!!
66  MaxRowsAtCompileTime = RowsAtCompileTime,
67  MaxColsAtCompileTime = ColsAtCompileTime,
68  IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
69  : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
70  : (MatrixType::Flags & RowMajorBit) ? 1 : 0,
71  Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0),
72  CoeffReadCost = _MatrixTypeNested::CoeffReadCost
73  };
74 };
75 }
76 
77 template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
78  : public internal::dense_xpr_base< Replicate<MatrixType,RowFactor,ColFactor> >::type
79 {
80  typedef typename internal::traits<Replicate>::MatrixTypeNested MatrixTypeNested;
81  typedef typename internal::traits<Replicate>::_MatrixTypeNested _MatrixTypeNested;
82  public:
83 
84  typedef typename internal::dense_xpr_base<Replicate>::type Base;
86 
87  template<typename OriginalMatrixType>
88  inline explicit Replicate(const OriginalMatrixType& matrix)
89  : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
90  {
91  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
92  THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
93  eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic);
94  }
95 
96  template<typename OriginalMatrixType>
97  inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor)
98  : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
99  {
100  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
101  THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
102  }
103 
104  inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
105  inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
106 
107  inline Scalar coeff(Index row, Index col) const
108  {
109  // try to avoid using modulo; this is a pure optimization strategy
110  const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
111  : RowFactor==1 ? row
112  : row%m_matrix.rows();
113  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
114  : ColFactor==1 ? col
115  : col%m_matrix.cols();
116 
117  return m_matrix.coeff(actual_row, actual_col);
118  }
119  template<int LoadMode>
120  inline PacketScalar packet(Index row, Index col) const
121  {
122  const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
123  : RowFactor==1 ? row
124  : row%m_matrix.rows();
125  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
126  : ColFactor==1 ? col
127  : col%m_matrix.cols();
128 
129  return m_matrix.template packet<LoadMode>(actual_row, actual_col);
130  }
131 
132  const _MatrixTypeNested& nestedExpression() const
133  {
134  return m_matrix;
135  }
136 
137  protected:
138  MatrixTypeNested m_matrix;
139  const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor;
140  const internal::variable_if_dynamic<Index, ColFactor> m_colFactor;
141 };
142 
151 template<typename Derived>
152 template<int RowFactor, int ColFactor>
155 {
156  return Replicate<Derived,RowFactor,ColFactor>(derived());
157 }
158 
167 template<typename Derived>
169 DenseBase<Derived>::replicate(Index rowFactor,Index colFactor) const
170 {
171  return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor);
172 }
173 
182 template<typename ExpressionType, int Direction>
185 {
187  (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1);
188 }
189 
190 } // end namespace Eigen
191 
192 #endif // EIGEN_REPLICATE_H