Skip to content

Commit 7e87844

Browse files
authored
Merge pull request #332 from jcarpent/devel
Fix handling of Numpy blocks on vector types
2 parents 15b701a + dddbf6d commit 7e87844

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

include/eigenpy/eigen-allocator.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ inline bool is_arr_layout_compatible_with_mat_type(PyArrayObject *pyArray) {
245245
bool is_array_F_cont = PyArray_IS_F_CONTIGUOUS(pyArray);
246246
return (MatType::IsRowMajor && is_array_C_cont) ||
247247
(!MatType::IsRowMajor && is_array_F_cont) ||
248-
MatType::IsVectorAtCompileTime;
248+
(MatType::IsVectorAtCompileTime &&
249+
(is_array_C_cont || is_array_F_cont));
249250
}
250251

251252
template <typename MatType, int Options, typename Stride>

include/eigenpy/numpy-map.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ struct NumpyMapTraits<MatType, InputScalar, AlignmentValue, Stride, true> {
161161
const int R = (int)PyArray_DIMS(pyArray)[rowMajor];
162162
const long int itemsize = PyArray_ITEMSIZE(pyArray);
163163
const int stride = (int)PyArray_STRIDE(pyArray, rowMajor) / (int)itemsize;
164-
;
165164

166165
if ((MatType::MaxSizeAtCompileTime != R) &&
167166
(MatType::MaxSizeAtCompileTime != Eigen::Dynamic)) {
@@ -171,6 +170,8 @@ struct NumpyMapTraits<MatType, InputScalar, AlignmentValue, Stride, true> {
171170

172171
InputScalar* pyData = reinterpret_cast<InputScalar*>(PyArray_DATA(pyArray));
173172

173+
assert(Stride(stride).inner() == stride &&
174+
"Stride should be a dynamic stride");
174175
return EigenMap(pyData, R, Stride(stride));
175176
}
176177
};

unittest/eigen_ref.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ void setOnes(Eigen::Ref<MatType> mat) {
3030
mat.setOnes();
3131
}
3232

33+
template <typename VecType>
34+
VecType copyVectorFromConstRef(const Eigen::Ref<const VecType> vec) {
35+
std::cout << "copyVectorFromConstRef::vec: " << vec.transpose() << std::endl;
36+
return VecType(vec);
37+
}
38+
3339
template <typename MatType>
3440
Eigen::Ref<MatType> getBlock(Eigen::Ref<MatType> mat, Eigen::DenseIndex i,
3541
Eigen::DenseIndex j, Eigen::DenseIndex n,
@@ -120,6 +126,9 @@ BOOST_PYTHON_MODULE(eigen_ref) {
120126
bp::def("getBlock", &getBlock<MatrixXd>);
121127
bp::def("editBlock", &editBlock<MatrixXd>);
122128

129+
bp::def("copyVectorFromConstRef", &copyVectorFromConstRef<VectorXd>);
130+
bp::def("copyRowVectorFromConstRef", &copyVectorFromConstRef<RowVectorXd>);
131+
123132
bp::class_<modify_block_wrap, boost::noncopyable>("modify_block",
124133
bp::init<>())
125134
.def_readonly("J", &modify_block::J)

unittest/python/test_eigen_ref.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
editBlock,
1010
modify_block,
1111
has_ref_member,
12+
copyVectorFromConstRef,
13+
copyRowVectorFromConstRef,
1214
)
1315

1416

@@ -44,6 +46,18 @@ def test_create_ref_to_static(mat):
4446
assert np.array_equal(A_ref, A_ref2)
4547

4648

49+
def test_read_block():
50+
data = np.array([[0, 0.2, 0.3, 0.4], [0, 1, 0, 0], [0, 0, 0, 0], [1, 0, 0, 0]])
51+
52+
data_strided = data[:, 0]
53+
54+
data_strided_copy = copyVectorFromConstRef(data_strided)
55+
assert np.all(data_strided == data_strided_copy)
56+
57+
data_strided_copy = copyRowVectorFromConstRef(data_strided)
58+
assert np.all(data_strided == data_strided_copy)
59+
60+
4761
def test_create_ref(mat):
4862
print("[asRef(mat)]")
4963
ref = asRef(mat)
@@ -116,6 +130,7 @@ def do_test(mat):
116130
test_create_const_ref(mat)
117131
test_create_ref(mat)
118132
test_edit_block(rows, cols)
133+
test_read_block()
119134
print("=" * 10)
120135

121136

0 commit comments

Comments
 (0)