G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BlockDiag.h
Go to the documentation of this file.
1 
15 namespace Eigen {
16 
25 namespace internal {
26 template<typename MatrixType,int NumBlocks>
27 struct traits<BlockDiag<MatrixType,NumBlocks> >
28  : traits<MatrixType>
29 {
30  typedef typename MatrixType::Scalar Scalar;
31  typedef typename traits<MatrixType>::StorageKind StorageKind;
32  typedef typename traits<MatrixType>::XprKind XprKind;
33  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
34  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
35  enum {
36  RowsAtCompileTime = NumBlocks==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
37  ? Dynamic
38  : NumBlocks * MatrixType::RowsAtCompileTime,
39  ColsAtCompileTime = NumBlocks==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
40  ? Dynamic
41  : NumBlocks * MatrixType::ColsAtCompileTime,
42  //FIXME we don't propagate the max sizes !!!
43  MaxRowsAtCompileTime = RowsAtCompileTime,
44  MaxColsAtCompileTime = ColsAtCompileTime,
45  IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
46  : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
47  : (MatrixType::Flags & RowMajorBit) ? 1 : 0,
48 
49  // FIXME enable DirectAccess with negative strides?
50  Flags = IsRowMajor ? RowMajorBit : 0
51  };
52 };
53 }
54 
55 template<typename MatrixType,int NumBlocks> class BlockDiag
56  : public internal::dense_xpr_base< BlockDiag<MatrixType,NumBlocks> >::type
57 {
58  typedef typename internal::traits<BlockDiag>::MatrixTypeNested MatrixTypeNested;
59  typedef typename internal::traits<BlockDiag>::_MatrixTypeNested _MatrixTypeNested;
60  public:
61 
62  typedef typename internal::dense_xpr_base<BlockDiag>::type Base;
63  EIGEN_DENSE_PUBLIC_INTERFACE(BlockDiag)
64  typedef typename internal::remove_all<MatrixType>::type NestedExpression;
65 
66  template<typename OriginalMatrixType>
67  EIGEN_DEVICE_FUNC
68  inline explicit BlockDiag(const OriginalMatrixType& a_matrix)
69  : m_matrix(a_matrix), m_numBlocks(NumBlocks)
70  {
71  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
72  THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
73  eigen_assert(NumBlocks!=Dynamic);
74  }
75 
76  template<typename OriginalMatrixType>
77  EIGEN_DEVICE_FUNC
78  inline BlockDiag(const OriginalMatrixType& a_matrix, Index numBlocks)
79  : m_matrix(a_matrix), m_numBlocks(numBlocks)
80  {
81  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
82  THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
83  }
84 
85  EIGEN_DEVICE_FUNC
86  inline Index rows() const { return m_matrix.rows() * m_numBlocks.value(); }
87 
88  EIGEN_DEVICE_FUNC
89  inline Index cols() const { return m_matrix.cols() * m_numBlocks.value(); }
90 /*
91  inline Scalar coeff(Index rowId, Index colId) const
92  {
93  if ( rowId / m_matrix.rows() != colId / m_matrix.cols() )
94  return Scalar(0);
95  // try to avoid using modulo; this is a pure optimization strategy
96  const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
97  : NumBlocks==1 ? rowId
98  : rowId%m_matrix.rows();
99  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
100  : NumBlocks==1 ? colId
101  : colId%m_matrix.cols();
102 
103  return m_matrix.coeff(actual_row, actual_col);
104  }
105  template<int LoadMode>
106  inline PacketScalar packet(Index rowId, Index colId) const
107  {
108 
109  if ( rowId / m_matrix.rows() != colId / m_matrix.cols() )
110  GISMO_ERROR("not implemented");
111 
112  const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
113  : NumBlocks==1 ? rowId
114  : rowId%m_matrix.rows();
115  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
116  : NumBlocks==1 ? colId
117  : colId%m_matrix.cols();
118 
119  return m_matrix.template packet<LoadMode>(actual_row, actual_col);
120  }
121 */
122  EIGEN_DEVICE_FUNC
123  const _MatrixTypeNested& nestedExpression() const
124  {
125  return m_matrix;
126  }
127 
128  protected:
129  MatrixTypeNested m_matrix;
130  const internal::variable_if_dynamic<Index, NumBlocks> m_numBlocks;
131 };
132 
133 namespace internal {
134 template<typename ArgType, int NumBlocks>
135 struct unary_evaluator<BlockDiag<ArgType, NumBlocks> >
136  : evaluator_base<BlockDiag<ArgType, NumBlocks> >
137 {
138  typedef BlockDiag<ArgType, NumBlocks> XprType;
139  typedef typename XprType::CoeffReturnType CoeffReturnType;
140  enum {
141  Factor = (NumBlocks==Dynamic) ? Dynamic : NumBlocks*NumBlocks
142  };
143  typedef typename internal::nested_eval<ArgType,Factor>::type ArgTypeNested;
144  typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
145 
146  enum {
147  CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
148  LinearAccessMask = XprType::IsVectorAtCompileTime ? LinearAccessBit : 0,
149  Flags = (evaluator<ArgTypeNestedCleaned>::Flags & (HereditaryBits|LinearAccessMask) & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit),
150 
151  Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
152  };
153 
154  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr)
155  : m_arg(xpr.nestedExpression()),
156  m_argImpl(m_arg),
157  m_rows(xpr.nestedExpression().rows()),
158  m_cols(xpr.nestedExpression().cols())
159  {}
160 
161  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
162  CoeffReturnType coeff(Index rowId, Index colId) const
163  {
164  if ( rowId / m_rows.value() != colId / m_cols.value() )
165  return CoeffReturnType(0);
166  // try to avoid using modulo; this is a pure optimization strategy
167  const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
168  : NumBlocks==1 ? rowId
169  : rowId%m_rows.value();
170  const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
171  : NumBlocks==1 ? colId
172  : colId%m_cols.value();
173 
174  return m_argImpl.coeff(actual_row, actual_col);
175  }
176 
177  template<int LoadMode, typename PacketType>
178  EIGEN_STRONG_INLINE
179  PacketType packet(Index rowId, Index colId) const
180  {
181  assert( rowId / m_rows.value() != colId / m_cols.value() &&
182  "Not implemented");
183 
184  const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
185  : NumBlocks==1 ? rowId
186  : rowId%m_rows.value();
187  const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
188  : NumBlocks==1 ? colId
189  : colId%m_cols.value();
190 
191  return m_argImpl.template packet<LoadMode>(actual_row, actual_col);
192  }
193 
194 protected:
195  ArgTypeNested m_arg;
196  evaluator<ArgTypeNestedCleaned> m_argImpl;
197  const variable_if_dynamic<Index, ArgType::RowsAtCompileTime> m_rows;
198  const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
199 };
200 
201 } // namespace internal
202 
211 template<typename Derived>
212 const typename MatrixBase<Derived>::BlockDiagReturnType
213 MatrixBase<Derived>::blockDiag(Index numBlocks) const
214 {
215  return BlockDiag<Derived,Dynamic>(derived(),numBlocks);
216 }
217 
218 } // namespace eigen
Expression for block diagonal replication of a matrix or vector.
Definition: BlockDiag.h:55