Skip to content

Commit 72ff3a8

Browse files
authored
Merge pull request #209 from jcarpent/devel
Fix bug for non square matrix
2 parents a88c06b + c5e81d5 commit 72ff3a8

File tree

5 files changed

+55
-31
lines changed

5 files changed

+55
-31
lines changed

include/eigenpy/eigen-allocator.hpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ namespace eigenpy
6666
}
6767
}
6868
};
69+
70+
template<typename MatType>
71+
bool check_swap(PyArrayObject * pyArray,
72+
const Eigen::MatrixBase<MatType> & mat)
73+
{
74+
if(PyArray_NDIM(pyArray) == 0) return false;
75+
if(mat.rows() == PyArray_DIMS(pyArray)[0])
76+
return false;
77+
else
78+
return true;
79+
}
6980

7081
template<typename Scalar, typename NewScalar, bool cast_is_valid = FromTypeToType<Scalar,NewScalar>::value >
7182
struct cast_matrix_or_array
@@ -75,10 +86,7 @@ namespace eigenpy
7586
const Eigen::MatrixBase<MatrixOut> & dest)
7687
{
7788
MatrixOut & dest_ = const_cast<MatrixOut &>(dest.derived());
78-
if(dest.rows() == input.rows())
79-
dest_ = input.template cast<NewScalar>();
80-
else
81-
dest_ = input.transpose().template cast<NewScalar>();
89+
dest_ = input.template cast<NewScalar>();
8290
}
8391
};
8492

@@ -97,11 +105,11 @@ namespace eigenpy
97105
} // namespace details
98106

99107
#define EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType,Scalar,NewScalar,pyArray,mat) \
100-
details::cast_matrix_or_array<Scalar,NewScalar>::run(NumpyMap<MatType,Scalar>::map(pyArray),mat)
108+
details::cast_matrix_or_array<Scalar,NewScalar>::run(NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat)),mat)
101109

102110
#define EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType,Scalar,NewScalar,mat,pyArray) \
103-
details::cast_matrix_or_array<Scalar,NewScalar>::run(mat,NumpyMap<MatType,NewScalar>::map(pyArray))
104-
111+
details::cast_matrix_or_array<Scalar,NewScalar>::run(mat,NumpyMap<MatType,NewScalar>::map(pyArray,details::check_swap(pyArray,mat)))
112+
105113
template<typename MatType>
106114
struct EigenAllocator
107115
{
@@ -119,7 +127,7 @@ namespace eigenpy
119127
const int Scalar_type_code = Register::getTypeCode<Scalar>();
120128
if(pyArray_type_code == Scalar_type_code)
121129
{
122-
mat = NumpyMap<MatType,Scalar>::map(pyArray); // avoid useless cast
130+
mat = NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat)); // avoid useless cast
123131
return;
124132
}
125133

@@ -167,11 +175,8 @@ namespace eigenpy
167175

168176
if(pyArray_type_code == Scalar_type_code) // no cast needed
169177
{
170-
MapType map_pyArray = NumpyMap<MatType,Scalar>::map(pyArray);
171-
if(mat.rows() == map_pyArray.rows())
172-
map_pyArray = mat;
173-
else
174-
map_pyArray = mat.transpose();
178+
MapType map_pyArray = NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat));
179+
map_pyArray = mat;
175180
return;
176181
}
177182

@@ -252,7 +257,7 @@ namespace eigenpy
252257
RefType & mat = *reinterpret_cast<RefType*>(raw_ptr);
253258
if(pyArray_type_code == Scalar_type_code)
254259
{
255-
mat = NumpyMap<MatType,Scalar>::map(pyArray); // avoid useless cast
260+
mat = NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat)); // avoid useless cast
256261
return;
257262
}
258263

@@ -346,7 +351,7 @@ namespace eigenpy
346351
MatType & mat = *mat_ptr;
347352
if(pyArray_type_code == Scalar_type_code)
348353
{
349-
mat = NumpyMap<MatType,Scalar>::map(pyArray); // avoid useless cast
354+
mat = NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat)); // avoid useless cast
350355
return;
351356
}
352357

include/eigenpy/fwd.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#define EIGENPY_NO_ALIGNMENT_VALUE Eigen::Unaligned
2424

25+
#define EIGENPY_UNUSED_VARIABLE(var) (void)(var)
26+
2527
#include "eigenpy/expose.hpp"
2628

2729
namespace eigenpy

include/eigenpy/numpy-map.hpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace eigenpy
2222
typedef NumpyMapTraits<MatType, InputScalar, AlignmentValue, Stride> Impl;
2323
typedef typename Impl::EigenMap EigenMap;
2424

25-
static EigenMap map(PyArrayObject* pyArray);
25+
static EigenMap map(PyArrayObject* pyArray, bool swap_dimensions = false);
2626
};
2727

2828
} // namespace eigenpy
@@ -39,7 +39,7 @@ namespace eigenpy
3939
typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime,MatType::Options> EquivalentInputMatrixType;
4040
typedef Eigen::Map<EquivalentInputMatrixType,AlignmentValue,Stride> EigenMap;
4141

42-
static EigenMap mapImpl(PyArrayObject* pyArray)
42+
static EigenMap mapImpl(PyArrayObject* pyArray, bool swap_dimensions = false)
4343
{
4444
enum {
4545
OuterStrideAtCompileTime = Stride::OuterStrideAtCompileTime,
@@ -77,11 +77,22 @@ namespace eigenpy
7777
assert( (PyArray_DIMS(pyArray)[0] < INT_MAX)
7878
&& (PyArray_STRIDE(pyArray,0) < INT_MAX));
7979

80-
rows = (int)PyArray_DIMS(pyArray)[0];
81-
cols = 1;
82-
83-
inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
84-
outer_stride = 0;
80+
if(!swap_dimensions)
81+
{
82+
rows = (int)PyArray_DIMS(pyArray)[0];
83+
cols = 1;
84+
85+
inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
86+
outer_stride = 0;
87+
}
88+
else
89+
{
90+
rows = 1;
91+
cols = (int)PyArray_DIMS(pyArray)[0];
92+
93+
inner_stride = 0;
94+
outer_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
95+
}
8596
}
8697

8798
// Specific care for Eigen::Stride<-1,0>
@@ -113,8 +124,9 @@ namespace eigenpy
113124
typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime,MatType::Options> EquivalentInputMatrixType;
114125
typedef Eigen::Map<EquivalentInputMatrixType,AlignmentValue,Stride> EigenMap;
115126

116-
static EigenMap mapImpl(PyArrayObject* pyArray)
127+
static EigenMap mapImpl(PyArrayObject* pyArray, bool swap_dimensions = false)
117128
{
129+
EIGENPY_UNUSED_VARIABLE(swap_dimensions);
118130
assert( PyArray_NDIM(pyArray) <= 2 );
119131

120132
int rowMajor;
@@ -141,9 +153,9 @@ namespace eigenpy
141153

142154
template<typename MatType, typename InputScalar, int AlignmentValue, typename Stride>
143155
typename NumpyMap<MatType,InputScalar,AlignmentValue,Stride>::EigenMap
144-
NumpyMap<MatType,InputScalar,AlignmentValue,Stride>::map(PyArrayObject * pyArray)
156+
NumpyMap<MatType,InputScalar,AlignmentValue,Stride>::map(PyArrayObject * pyArray, bool swap_dimensions)
145157
{
146-
return Impl::mapImpl(pyArray);
158+
return Impl::mapImpl(pyArray,swap_dimensions);
147159
}
148160

149161
} // namespace eigenpy

include/eigenpy/user-type.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,12 @@ namespace eigenpy
191191
PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc;
192192
// PyArray_CastFunc * cast = &internal::SpecialMethods<Scalar>::cast;
193193

194-
int code = Register::registerNewType(py_type_ptr,
195-
&typeid(Scalar),
196-
sizeof(Scalar),
197-
getitem, setitem, nonzero,
198-
copyswap, copyswapn,
199-
dotfunc);
194+
int code = Register::registerNewType(py_type_ptr,
195+
&typeid(Scalar),
196+
sizeof(Scalar),
197+
getitem, setitem, nonzero,
198+
copyswap, copyswapn,
199+
dotfunc);
200200

201201
return code;
202202
}

unittest/matrix.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ BOOST_PYTHON_MODULE(matrix)
9494
namespace bp = boost::python;
9595
eigenpy::enableEigenPy();
9696

97+
// Square matrix
9798
typedef Eigen::Matrix<double,6,6> Matrix6;
9899
eigenpy::enableEigenPySpecific<Matrix6>();
100+
101+
// Non-square matrix
102+
typedef Eigen::Matrix<double,4,6> Matrix46;
103+
eigenpy::enableEigenPySpecific<Matrix46>();
99104

100105
Eigen::MatrixXd (*naturalsXX)(int,int,bool) = naturals;
101106
Eigen::VectorXd (*naturalsX)(int,bool) = naturals;

0 commit comments

Comments
 (0)