6 #ifndef __eigenpy_numpy_map_hpp__
7 #define __eigenpy_numpy_map_hpp__
15 template <
typename MatType,
typename InputScalar,
int AlignmentValue,
16 typename Stride,
bool IsVector = MatType::IsVectorAtCompileTime>
19 template <
typename EigenType,
typename InputScalar,
int AlignmentValue,
24 template <
typename MatType,
typename InputScalar,
int AlignmentValue,
27 Eigen::MatrixBase<MatType> >
30 template <
typename MatType,
typename InputScalar,
int AlignmentValue,
33 const
Eigen::MatrixBase<MatType> >
37 template <
typename MatType,
typename InputScalar,
int AlignmentValue,
41 typedef Eigen::Matrix<InputScalar, MatType::RowsAtCompileTime,
42 MatType::ColsAtCompileTime, MatType::Options>
44 typedef Eigen::Map<EquivalentInputMatrixType, AlignmentValue, Stride>
47 static EigenMap map(PyArrayObject* pyArray,
bool swap_dimensions =
false) {
49 OuterStrideAtCompileTime = Stride::OuterStrideAtCompileTime,
50 InnerStrideAtCompileTime = Stride::InnerStrideAtCompileTime,
53 assert(PyArray_NDIM(pyArray) == 2 || PyArray_NDIM(pyArray) == 1);
55 const long int itemsize = PyArray_ITEMSIZE(pyArray);
56 int inner_stride = -1, outer_stride = -1;
58 if (PyArray_NDIM(pyArray) == 2) {
59 assert((PyArray_DIMS(pyArray)[0] < INT_MAX) &&
60 (PyArray_DIMS(pyArray)[1] < INT_MAX) &&
61 (PyArray_STRIDE(pyArray, 0) < INT_MAX) &&
62 (PyArray_STRIDE(pyArray, 1) < INT_MAX));
64 rows = (int)PyArray_DIMS(pyArray)[0];
65 cols = (int)PyArray_DIMS(pyArray)[1];
67 if (EquivalentInputMatrixType::IsRowMajor) {
68 inner_stride = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize;
69 outer_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
71 inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
72 outer_stride = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize;
74 }
else if (PyArray_NDIM(pyArray) == 1) {
75 assert((PyArray_DIMS(pyArray)[0] < INT_MAX) &&
76 (PyArray_STRIDE(pyArray, 0) < INT_MAX));
78 if (!swap_dimensions) {
79 rows = (int)PyArray_DIMS(pyArray)[0];
82 if (EquivalentInputMatrixType::IsRowMajor) {
83 outer_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
86 inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
91 cols = (int)PyArray_DIMS(pyArray)[0];
93 if (EquivalentInputMatrixType::IsRowMajor) {
94 inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
98 outer_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
104 if (InnerStrideAtCompileTime == 0 &&
105 OuterStrideAtCompileTime == Eigen::Dynamic) {
106 outer_stride = std::max(inner_stride, outer_stride);
111 OuterStrideAtCompileTime == Eigen::Dynamic ? outer_stride
112 : OuterStrideAtCompileTime,
113 InnerStrideAtCompileTime == Eigen::Dynamic ? inner_stride
114 : InnerStrideAtCompileTime);
116 if ((MatType::RowsAtCompileTime !=
rows) &&
117 (MatType::RowsAtCompileTime != Eigen::Dynamic)) {
119 "The number of rows does not fit with the matrix type.");
122 if ((MatType::ColsAtCompileTime !=
cols) &&
123 (MatType::ColsAtCompileTime != Eigen::Dynamic)) {
125 "The number of columns does not fit with the matrix type.");
128 InputScalar* pyData =
reinterpret_cast<InputScalar*
>(PyArray_DATA(pyArray));
134 template <
typename MatType,
typename InputScalar,
int AlignmentValue,
138 typedef Eigen::Matrix<InputScalar, MatType::RowsAtCompileTime,
139 MatType::ColsAtCompileTime, MatType::Options>
141 typedef Eigen::Map<EquivalentInputMatrixType, AlignmentValue, Stride>
144 static EigenMap map(PyArrayObject* pyArray,
bool swap_dimensions =
false) {
146 assert(PyArray_NDIM(pyArray) <= 2);
149 if (PyArray_NDIM(pyArray) == 1)
151 else if (PyArray_DIMS(pyArray)[0] == 0)
153 else if (PyArray_DIMS(pyArray)[1] == 0)
156 rowMajor = (PyArray_DIMS(pyArray)[0] > PyArray_DIMS(pyArray)[1]) ? 0 : 1;
158 assert(PyArray_DIMS(pyArray)[rowMajor] < INT_MAX);
159 const int R = (int)PyArray_DIMS(pyArray)[rowMajor];
160 const long int itemsize = PyArray_ITEMSIZE(pyArray);
161 const int stride = (int)PyArray_STRIDE(pyArray, rowMajor) / (int)itemsize;
163 if ((MatType::MaxSizeAtCompileTime !=
R) &&
164 (MatType::MaxSizeAtCompileTime != Eigen::Dynamic)) {
166 "The number of elements does not fit with the vector type.");
169 InputScalar* pyData =
reinterpret_cast<InputScalar*
>(PyArray_DATA(pyArray));
171 assert(Stride(stride).inner() == stride &&
172 "Stride should be a dynamic stride");
173 return EigenMap(pyData,
R, Stride(stride));
177 #ifdef EIGENPY_WITH_TENSOR_SUPPORT
179 template <
typename TensorType,
typename InputScalar,
int AlignmentValue,
181 struct numpy_map_impl_tensor;
183 template <
typename TensorType,
typename InputScalar,
int AlignmentValue,
185 struct numpy_map_impl<TensorType, InputScalar, AlignmentValue, Stride,
186 Eigen::TensorBase<TensorType> >
187 : numpy_map_impl_tensor<TensorType, InputScalar, AlignmentValue, Stride> {};
189 template <
typename TensorType,
typename InputScalar,
int AlignmentValue,
191 struct numpy_map_impl<const TensorType, InputScalar, AlignmentValue, Stride,
192 const
Eigen::TensorBase<TensorType> >
193 : numpy_map_impl_tensor<const TensorType, InputScalar, AlignmentValue,
196 template <
typename TensorType,
typename InputScalar,
int AlignmentValue,
198 struct numpy_map_impl_tensor {
199 typedef TensorType Tensor;
200 typedef typename Eigen::internal::traits<TensorType>::Index Index;
201 static const int Options = Eigen::internal::traits<TensorType>::Options;
202 static const int NumIndices = TensorType::NumIndices;
204 typedef Eigen::Tensor<InputScalar, NumIndices, Options, Index>
205 EquivalentInputTensorType;
206 typedef typename EquivalentInputTensorType::Dimensions Dimensions;
207 typedef Eigen::TensorMap<EquivalentInputTensorType, Options> EigenMap;
209 static EigenMap map(PyArrayObject* pyArray,
bool swap_dimensions =
false) {
211 assert(PyArray_NDIM(pyArray) == NumIndices || NumIndices == Eigen::Dynamic);
213 Eigen::DSizes<Index, NumIndices> dimensions;
214 for (
int k = 0; k < PyArray_NDIM(pyArray); ++k)
215 dimensions[k] = PyArray_DIMS(pyArray)[k];
217 InputScalar* pyData =
reinterpret_cast<InputScalar*
>(PyArray_DATA(pyArray));
218 return EigenMap(pyData, dimensions);
224 template <
typename EigenType,
typename InputScalar,
228 :
numpy_map_impl<EigenType, InputScalar, AlignmentValue, Stride> {};
232 #endif // define __eigenpy_numpy_map_hpp__