Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stack Of Tasks
eigenpy
Commits
cae5ff22
Commit
cae5ff22
authored
Jul 11, 2014
by
Nicolas Mansard
Committed by
nmansard
Jul 11, 2014
Browse files
IVIGIT.
parent
df670c2b
Changes
5
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
cae5ff22
...
...
@@ -8,7 +8,9 @@ IF(NOT BOOST_NUMPY_DIR)
ENDIF
()
FIND_PACKAGE
(
Boost 1.45.0
)
IF
(
Boost_FOUND
)
INCLUDE_DIRECTORIES
(
"
${
Boost_INCLUDE_DIRS
}
"
"/usr/include/python2.7"
"/usr/include/eigen3"
"Boost.NumPy"
)
LINK_DIRECTORIES
(
${
BOOST_NUMPY_DIR
}
)
...
...
@@ -29,6 +31,12 @@ IF(Boost_FOUND)
ADD_LIBRARY
(
eigen SHARED src/eigen.cpp
)
TARGET_LINK_LIBRARIES
(
eigen
${
Boost_LIBRARIES
}
libboost_numpy.so
)
ADD_LIBRARY
(
eigenc SHARED src/eigenc.cpp
)
TARGET_LINK_LIBRARIES
(
eigenc
${
Boost_LIBRARIES
}
)
ADD_LIBRARY
(
eigentemplate SHARED src/eigentemplate.cpp
)
TARGET_LINK_LIBRARIES
(
eigentemplate
${
Boost_LIBRARIES
}
)
ELSEIF
(
NOT Boost_FOUND
)
MESSAGE
(
FATAL_ERROR
"Unable to find correct Boost version. Did you set BOOST_ROOT?"
)
ENDIF
()
...
...
python/
unittes
t.py
→
python/
test_uni
t.py
View file @
cae5ff22
...
...
@@ -2,6 +2,7 @@
import
numpy
as
np
'''
import libsimple
print libsimple.char()
...
...
@@ -28,6 +29,25 @@ print "matrix ===> "
libeigen.test2(a)
print "array ===> "
libeigen.test2(b)
'''
import
libeigentemplate
print
"===> From C++ to Py"
print
libeigentemplate
.
test
()
print
"===> From Vec C++ to Py"
print
libeigentemplate
.
testVec
()
print
"===> From Py to C++"
a
=
np
.
random
.
random
([
5
,
5
])
for
i
in
range
(
5
):
for
j
in
range
(
5
):
a
[
i
,
j
]
=
i
*
5
+
j
#a = np.random.random([
print
a
libeigentemplate
.
test2
(
a
)
print
"===> From Py::slice to C++"
b
=
a
[
1
:
5
,
1
:
3
]
print
b
libeigentemplate
.
test2
(
b
)
...
...
src/eigenc.cpp
0 → 100644
View file @
cae5ff22
#include
<Eigen/Core>
#include
<boost/python.hpp>
#include
<numpy/arrayobject.h>
namespace
boopy
{
namespace
bp
=
boost
::
python
;
template
<
typename
SCALAR
>
struct
NumpyEquivalentType
{};
template
<
>
struct
NumpyEquivalentType
<
double
>
{
enum
{
type_code
=
NPY_DOUBLE
};};
template
<
>
struct
NumpyEquivalentType
<
int
>
{
enum
{
type_code
=
NPY_INT
};};
template
<
>
struct
NumpyEquivalentType
<
float
>
{
enum
{
type_code
=
NPY_FLOAT
};};
struct
EigenMatrix_to_python_matrix
{
static
PyObject
*
convert
(
Eigen
::
MatrixXd
const
&
mat
)
{
typedef
Eigen
::
MatrixXd
::
Scalar
T
;
npy_intp
shape
[
2
]
=
{
mat
.
rows
(),
mat
.
cols
()
};
PyArrayObject
*
pyArray
=
(
PyArrayObject
*
)
PyArray_SimpleNew
(
2
,
shape
,
NumpyEquivalentType
<
T
>::
type_code
);
T
*
pyData
=
(
T
*
)
PyArray_DATA
(
pyArray
);
for
(
int
i
=
0
;
i
<
mat
.
rows
();
++
i
)
for
(
int
j
=
0
;
j
<
mat
.
cols
();
++
j
)
pyData
[
i
*
mat
.
cols
()
+
j
]
=
mat
(
i
,
j
);
return
((
PyObject
*
)
pyArray
);
}
};
struct
EigenMatrix_from_python_array
{
EigenMatrix_from_python_array
()
{
bp
::
converter
::
registry
::
push_back
(
&
convertible
,
&
construct
,
bp
::
type_id
<
Eigen
::
MatrixXd
>
());
}
// Determine if obj_ptr can be converted in a Eigenvec
static
void
*
convertible
(
PyObject
*
obj_ptr
)
{
typedef
Eigen
::
MatrixXd
::
Scalar
T
;
if
(
!
PyArray_Check
(
obj_ptr
))
{
return
0
;
}
if
(
PyArray_NDIM
(
obj_ptr
)
>
2
)
{
return
0
;
}
if
(
PyArray_ObjectType
(
obj_ptr
,
0
)
!=
NumpyEquivalentType
<
T
>::
type_code
)
{
return
0
;
}
int
flags
=
PyArray_FLAGS
(
obj_ptr
);
if
(
!
(
flags
&
NPY_C_CONTIGUOUS
))
{
return
0
;
}
if
(
!
(
flags
&
NPY_ALIGNED
))
{
return
0
;
}
return
obj_ptr
;
}
// Convert obj_ptr into a Eigenvec
static
void
construct
(
PyObject
*
pyObj
,
bp
::
converter
::
rvalue_from_python_stage1_data
*
memory
)
{
typedef
Eigen
::
MatrixXd
::
Scalar
T
;
using
namespace
Eigen
;
PyArrayObject
*
pyArray
=
reinterpret_cast
<
PyArrayObject
*>
(
pyObj
);
int
ndims
=
PyArray_NDIM
(
pyArray
);
assert
(
ndims
==
2
);
int
dtype_size
=
(
PyArray_DESCR
(
pyArray
))
->
elsize
;
int
s1
=
PyArray_STRIDE
(
pyArray
,
0
);
assert
(
s1
%
dtype_size
==
0
);
int
R
=
MatrixXd
::
RowsAtCompileTime
;
int
C
=
MatrixXd
::
ColsAtCompileTime
;
if
(
R
==
Eigen
::
Dynamic
)
R
=
PyArray_DIMS
(
pyArray
)[
0
];
else
assert
(
PyArray_DIMS
(
pyArray
)[
0
]
==
R
);
if
(
C
==
Eigen
::
Dynamic
)
C
=
PyArray_DIMS
(
pyArray
)[
1
];
else
assert
(
PyArray_DIMS
(
pyArray
)[
1
]
==
C
);
T
*
pyData
=
reinterpret_cast
<
T
*>
(
PyArray_DATA
(
pyArray
));
void
*
storage
=
((
bp
::
converter
::
rvalue_from_python_storage
<
MatrixXd
>*
)
(
memory
))
->
storage
.
bytes
;
MatrixXd
&
mat
=
*
new
(
storage
)
MatrixXd
(
R
,
C
);
for
(
int
i
=
0
;
i
<
R
;
++
i
)
for
(
int
j
=
0
;
j
<
C
;
++
j
)
mat
(
i
,
j
)
=
pyData
[
i
*
C
+
j
];
memory
->
convertible
=
storage
;
}
};
}
Eigen
::
MatrixXd
test
()
{
Eigen
::
MatrixXd
mat
=
Eigen
::
MatrixXd
::
Random
(
5
,
5
);
std
::
cout
<<
"EigenMAt = "
<<
mat
<<
std
::
endl
;
return
mat
;
}
void
test2
(
Eigen
::
MatrixXd
mat
)
{
std
::
cout
<<
"test2: dim = "
<<
mat
.
rows
()
<<
" ||| m[0,0] = "
<<
mat
(
0
,
0
)
<<
std
::
endl
;
}
BOOST_PYTHON_MODULE
(
libeigenc
)
{
import_array
();
namespace
bp
=
boost
::
python
;
bp
::
to_python_converter
<
Eigen
::
MatrixXd
,
boopy
::
EigenMatrix_to_python_matrix
>
();
boopy
::
EigenMatrix_from_python_array
();
bp
::
def
(
"test"
,
test
);
bp
::
def
(
"test2"
,
test2
);
}
src/eigentemplate.cpp
0 → 100644
View file @
cae5ff22
#include
<Eigen/Core>
#include
<boost/python.hpp>
#include
<numpy/arrayobject.h>
namespace
boopy
{
namespace
bp
=
boost
::
python
;
template
<
typename
SCALAR
>
struct
NumpyEquivalentType
{};
template
<
>
struct
NumpyEquivalentType
<
double
>
{
enum
{
type_code
=
NPY_DOUBLE
};};
template
<
>
struct
NumpyEquivalentType
<
int
>
{
enum
{
type_code
=
NPY_INT
};};
template
<
>
struct
NumpyEquivalentType
<
float
>
{
enum
{
type_code
=
NPY_FLOAT
};};
/* --- TO PYTHON -------------------------------------------------------------- */
template
<
typename
MatType
>
struct
EigenMatrix_to_python_matrix
{
static
PyObject
*
convert
(
MatType
const
&
mat
)
{
typedef
typename
MatType
::
Scalar
T
;
const
int
R
=
mat
.
rows
(),
C
=
mat
.
cols
();
npy_intp
shape
[
2
]
=
{
R
,
C
};
PyArrayObject
*
pyArray
=
(
PyArrayObject
*
)
PyArray_SimpleNew
(
2
,
shape
,
NumpyEquivalentType
<
T
>::
type_code
);
T
*
pyData
=
(
T
*
)
PyArray_DATA
(
pyArray
);
Eigen
::
Map
<
Eigen
::
Matrix
<
T
,
Eigen
::
Dynamic
,
Eigen
::
Dynamic
,
Eigen
::
RowMajor
>
>
pyMatrix
(
pyData
,
R
,
C
);
pyMatrix
=
mat
;
return
(
PyObject
*
)
pyArray
;
}
};
/* --- FROM PYTHON ------------------------------------------------------------ */
struct
EigenMatrix_from_python_array
{
EigenMatrix_from_python_array
()
{
bp
::
converter
::
registry
::
push_back
(
&
convertible
,
&
construct
,
bp
::
type_id
<
Eigen
::
MatrixXd
>
());
}
// Determine if obj_ptr can be converted in a Eigenvec
static
void
*
convertible
(
PyObject
*
obj_ptr
)
{
typedef
Eigen
::
MatrixXd
MatType
;
typedef
MatType
::
Scalar
T
;
if
(
!
PyArray_Check
(
obj_ptr
))
return
0
;
if
(
PyArray_NDIM
(
obj_ptr
)
!=
2
)
if
(
(
PyArray_NDIM
(
obj_ptr
)
!=
1
)
||
(
MatType
::
IsVectorAtCompileTime
)
)
return
0
;
if
(
PyArray_ObjectType
(
obj_ptr
,
0
)
!=
NumpyEquivalentType
<
T
>::
type_code
)
return
0
;
if
(
!
(
PyArray_FLAGS
(
obj_ptr
)
&
NPY_ALIGNED
))
{
std
::
cerr
<<
"NPY non-aligned matrices are not implemented."
<<
std
::
endl
;
return
0
;
}
return
obj_ptr
;
}
// Convert obj_ptr into a Eigenvec
static
void
construct
(
PyObject
*
pyObj
,
bp
::
converter
::
rvalue_from_python_stage1_data
*
memory
)
{
typedef
Eigen
::
MatrixXd
MatType
;
typedef
MatType
::
Scalar
T
;
using
namespace
Eigen
;
PyArrayObject
*
pyArray
=
reinterpret_cast
<
PyArrayObject
*>
(
pyObj
);
int
ndims
=
PyArray_NDIM
(
pyArray
);
assert
(
ndims
==
2
);
// TODO: handle vectors
int
itemsize
=
PyArray_ITEMSIZE
(
pyArray
);
int
stride1
=
PyArray_STRIDE
(
pyArray
,
0
)
/
itemsize
;
int
stride2
=
PyArray_STRIDE
(
pyArray
,
1
)
/
itemsize
;
std
::
cout
<<
"STRIDE = "
<<
stride1
<<
" x "
<<
stride2
<<
std
::
endl
;
int
R
=
MatrixXd
::
RowsAtCompileTime
;
int
C
=
MatrixXd
::
ColsAtCompileTime
;
if
(
R
==
Eigen
::
Dynamic
)
R
=
PyArray_DIMS
(
pyArray
)[
0
];
else
assert
(
PyArray_DIMS
(
pyArray
)[
0
]
==
R
);
if
(
C
==
Eigen
::
Dynamic
)
C
=
PyArray_DIMS
(
pyArray
)[
1
];
else
assert
(
PyArray_DIMS
(
pyArray
)[
1
]
==
C
);
T
*
pyData
=
reinterpret_cast
<
T
*>
(
PyArray_DATA
(
pyArray
));
void
*
storage
=
((
bp
::
converter
::
rvalue_from_python_storage
<
MatrixXd
>*
)
(
memory
))
->
storage
.
bytes
;
MatrixXd
&
mat
=
*
new
(
storage
)
MatrixXd
(
R
,
C
);
for
(
int
i
=
0
;
i
<
R
;
++
i
)
for
(
int
j
=
0
;
j
<
C
;
++
j
)
mat
(
i
,
j
)
=
pyData
[
i
*
C
+
j
];
memory
->
convertible
=
storage
;
}
};
}
Eigen
::
MatrixXd
test
()
{
Eigen
::
MatrixXd
mat
=
Eigen
::
MatrixXd
::
Random
(
3
,
6
);
std
::
cout
<<
"EigenMAt = "
<<
mat
<<
std
::
endl
;
return
mat
;
}
Eigen
::
VectorXd
testVec
()
{
Eigen
::
VectorXd
mat
=
Eigen
::
VectorXd
::
Random
(
6
);
std
::
cout
<<
"EigenVec = "
<<
mat
<<
std
::
endl
;
return
mat
;
}
void
test2
(
Eigen
::
MatrixXd
mat
)
{
std
::
cout
<<
mat
<<
std
::
endl
;
}
BOOST_PYTHON_MODULE
(
libeigentemplate
)
{
import_array
();
namespace
bp
=
boost
::
python
;
bp
::
to_python_converter
<
Eigen
::
MatrixXd
,
boopy
::
EigenMatrix_to_python_matrix
<
Eigen
::
MatrixXd
>
>
();
bp
::
to_python_converter
<
Eigen
::
VectorXd
,
boopy
::
EigenMatrix_to_python_matrix
<
Eigen
::
VectorXd
>
>
();
boopy
::
EigenMatrix_from_python_array
();
bp
::
def
(
"test"
,
test
);
bp
::
def
(
"testVec"
,
testVec
);
bp
::
def
(
"test2"
,
test2
);
}
src/simple.cpp
View file @
cae5ff22
...
...
@@ -20,7 +20,7 @@ std::string teststr()
Eigen
::
VectorXd
testeigenvec
()
{
Eigen
::
VectorXd
v
(
5
);
Eigen
::
VectorXd
v
(
5
55
);
return
v
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment