diff --git a/include/eigenpy/numpy-allocator.hpp b/include/eigenpy/numpy-allocator.hpp index 50b9a5a9bb6eeb9d89b4e8a77e3aed86556d7faa..30c287366623bf6d4336844dc00423d953743ce1 100644 --- a/include/eigenpy/numpy-allocator.hpp +++ b/include/eigenpy/numpy-allocator.hpp @@ -70,11 +70,11 @@ struct NumpyAllocator<Eigen::Ref<MatType, Options, Stride> > { if (NumpyType::sharedMemory()) { const int Scalar_type_code = Register::getTypeCode<Scalar>(); - - Eigen::DenseIndex inner_stride = MatType::IsRowMajor ? mat.outerStride() - : mat.innerStride(), - outer_stride = MatType::IsRowMajor ? mat.innerStride() - : mat.outerStride(); + const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1); + Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride() + : mat.innerStride(), + outer_stride = reverse_strides ? mat.innerStride() + : mat.outerStride(); const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride}; @@ -135,10 +135,11 @@ struct NumpyAllocator<const Eigen::Ref<const MatType, Options, Stride> > { if (NumpyType::sharedMemory()) { const int Scalar_type_code = Register::getTypeCode<Scalar>(); - Eigen::DenseIndex inner_stride = MatType::IsRowMajor ? mat.outerStride() - : mat.innerStride(), - outer_stride = MatType::IsRowMajor ? mat.innerStride() - : mat.outerStride(); + const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1); + Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride() + : mat.innerStride(), + outer_stride = reverse_strides ? mat.innerStride() + : mat.outerStride(); const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride}; diff --git a/unittest/python/test_eigen_ref.py b/unittest/python/test_eigen_ref.py index 32a7910a9d04b36b388fd801005e87fe7eeb89ab..0ff13547fa702625d9ab758bd6e8852a91d57928 100644 --- a/unittest/python/test_eigen_ref.py +++ b/unittest/python/test_eigen_ref.py @@ -35,17 +35,28 @@ def test(mat): assert np.all(mat[:2, :3] == np.ones((2, 3))) mat.fill(0.0) + mat[:, :] = np.arange(rows * cols).reshape(rows, cols) + printMatrix(mat) + mat0 = mat.copy() mat_as_C_order = np.array(mat, order="F") - getBlock(mat_as_C_order, 0, 0, 3, 2)[:, :] = 1.0 + for i, rowsize, colsize in ([0, 3, 2], [1, 1, 2], [0, 3, 1]): + print("taking block [{}:{}, {}:{}]".format(i, rowsize + i, 0, colsize)) + B = getBlock(mat_as_C_order, i, 0, rowsize, colsize) + lhs = mat_as_C_order[i : rowsize + i, :colsize] + print("should be:\n{}\ngot:\n{}".format(lhs, B)) + assert np.array_equal(lhs, B.reshape(rowsize, colsize)) + + B[:] = 1.0 + rhs = np.ones((rowsize, colsize)) + assert np.array_equal(mat_as_C_order[i : rowsize + i, :colsize], rhs) - assert np.all(mat_as_C_order[:3, :2] == np.ones((3, 2))) + mat_as_C_order[:, :] = mat0 - mat_as_C_order[:3, :2] = 0.0 mat_copy = mat_as_C_order.copy() editBlock(mat_as_C_order, 0, 0, 3, 2) mat_copy[:3, :2] = np.arange(6).reshape(3, 2) - assert np.all(mat_as_C_order == mat_copy) + assert np.array_equal(mat_as_C_order, mat_copy) class ModifyBlockImpl(modify_block): def __init__(self):