G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VecAsSymmMatrix.h
Go to the documentation of this file.
1 
15 namespace Eigen {
16 
25 namespace internal {
26 template<typename MatrixType,int Dim>
27 struct traits<VecAsSymmMatrix<MatrixType,Dim> >
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 = Dim==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
37  ? Dynamic
38  : Dim * MatrixType::RowsAtCompileTime,
39  ColsAtCompileTime = Dim==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
40  ? Dynamic
41  : Dim * 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 Dim> class VecAsSymmMatrix
56  : public internal::dense_xpr_base< VecAsSymmMatrix<MatrixType,Dim> >::type
57 {
58  typedef typename internal::traits<VecAsSymmMatrix>::MatrixTypeNested MatrixTypeNested;
59  typedef typename internal::traits<VecAsSymmMatrix>::_MatrixTypeNested _MatrixTypeNested;
60  public:
61 
62  typedef typename internal::dense_xpr_base<VecAsSymmMatrix>::type Base;
63  EIGEN_DENSE_PUBLIC_INTERFACE(VecAsSymmMatrix)
64  typedef typename internal::remove_all<MatrixType>::type NestedExpression;
65 
66  template<typename OriginalMatrixType>
67  EIGEN_DEVICE_FUNC
68  inline explicit VecAsSymmMatrix(const OriginalMatrixType& a_matrix)
69  : m_matrix(a_matrix), m_mdim(Dim)
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(Dim!=Dynamic);
74  }
75 
76  template<typename OriginalMatrixType>
77  EIGEN_DEVICE_FUNC
78  inline VecAsSymmMatrix(const OriginalMatrixType& a_matrix, Index mdim)
79  : m_matrix(a_matrix), m_mdim(mdim)
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_mdim.value(); }
87 
88  EIGEN_DEVICE_FUNC
89  inline Index cols() const { return m_mdim.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  : Dim==1 ? rowId
98  : rowId%m_matrix.rows();
99  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
100  : Dim==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  : Dim==1 ? rowId
114  : rowId%m_matrix.rows();
115  const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
116  : Dim==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, Dim> m_mdim;
131 };
132 
133 namespace internal {
134 template<typename ArgType, int Dim>
135 struct unary_evaluator<VecAsSymmMatrix<ArgType, Dim> >
136  : evaluator_base<VecAsSymmMatrix<ArgType, Dim> >
137 {
138  typedef VecAsSymmMatrix<ArgType, Dim> XprType;
139  typedef typename XprType::CoeffReturnType CoeffReturnType;
140  enum {
141  Factor = (Dim==Dynamic) ? Dynamic : Dim*Dim
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  : Dim==1 ? rowId
169  : rowId%m_rows.value();
170  const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
171  : Dim==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  : Dim==1 ? rowId
186  : rowId%m_rows.value();
187  const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
188  : Dim==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>::VecAsSymmMatrixReturnType
213 MatrixBase<Derived>::blockDiag(Index mdim) const
214 {
215  return VecAsSymmMatrix<Derived,Dynamic>(derived(),mdim);
216 }
217 
218 } // namespace eigen
Expression for presenting a vector as a DimxDim symmetric matrix.
Definition: VecAsSymmMatrix.h:55