Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
E
eigenpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Stack Of Tasks
eigenpy
Commits
a2b653ab
Verified
Commit
a2b653ab
authored
5 years ago
by
Justin Carpentier
Browse files
Options
Downloads
Patches
Plain Diff
core: move EigenFromPy to a dedicated file
parent
821711e2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/eigenpy/details.hpp
+1
-248
1 addition, 248 deletions
include/eigenpy/details.hpp
include/eigenpy/eigen-from-python.hpp
+259
-0
259 additions, 0 deletions
include/eigenpy/eigen-from-python.hpp
with
260 additions
and
248 deletions
include/eigenpy/details.hpp
+
1
−
248
View file @
a2b653ab
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include
"eigenpy/eigen-allocator.hpp"
#include
"eigenpy/eigen-allocator.hpp"
#include
"eigenpy/eigen-to-python.hpp"
#include
"eigenpy/eigen-to-python.hpp"
#include
"eigenpy/eigen-from-python.hpp"
#include
"eigenpy/registration.hpp"
#include
"eigenpy/registration.hpp"
#include
"eigenpy/map.hpp"
#include
"eigenpy/map.hpp"
...
@@ -58,254 +59,6 @@ namespace boost { namespace python { namespace detail {
...
@@ -58,254 +59,6 @@ namespace boost { namespace python { namespace detail {
namespace
eigenpy
namespace
eigenpy
{
{
/* --- FROM PYTHON ------------------------------------------------------------ */
template
<
typename
MatType
>
struct
EigenFromPy
{
static
bool
isScalarConvertible
(
const
int
np_type
)
{
if
(
NumpyEquivalentType
<
typename
MatType
::
Scalar
>::
type_code
==
np_type
)
return
true
;
switch
(
np_type
)
{
case
NPY_INT
:
return
FromTypeToType
<
int
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_LONG
:
return
FromTypeToType
<
long
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_FLOAT
:
return
FromTypeToType
<
float
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CFLOAT
:
return
FromTypeToType
<
std
::
complex
<
float
>
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_DOUBLE
:
return
FromTypeToType
<
double
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CDOUBLE
:
return
FromTypeToType
<
std
::
complex
<
double
>
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_LONGDOUBLE
:
return
FromTypeToType
<
long
double
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CLONGDOUBLE
:
return
FromTypeToType
<
std
::
complex
<
long
double
>
,
typename
MatType
::
Scalar
>::
value
;
default:
return
false
;
}
}
/// \brief Determine if pyObj can be converted into a MatType object
static
void
*
convertible
(
PyArrayObject
*
pyArray
)
{
if
(
!
PyArray_Check
(
pyArray
))
return
0
;
if
(
!
isScalarConvertible
(
EIGENPY_GET_PY_ARRAY_TYPE
(
pyArray
)))
return
0
;
if
(
MatType
::
IsVectorAtCompileTime
)
{
const
Eigen
::
DenseIndex
size_at_compile_time
=
MatType
::
IsRowMajor
?
MatType
::
ColsAtCompileTime
:
MatType
::
RowsAtCompileTime
;
switch
(
PyArray_NDIM
(
pyArray
))
{
case
0
:
return
0
;
case
1
:
{
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
// check that the sizes at compile time matche
if
(
PyArray_DIMS
(
pyArray
)[
0
]
==
size_at_compile_time
)
return
pyArray
;
else
return
0
;
}
else
// This is a dynamic MatType
return
pyArray
;
}
case
2
:
{
// Special care of scalar matrix of dimension 1x1.
if
(
PyArray_DIMS
(
pyArray
)[
0
]
==
1
&&
PyArray_DIMS
(
pyArray
)[
1
]
==
1
)
{
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
if
(
size_at_compile_time
==
1
)
return
pyArray
;
else
return
0
;
}
else
// This is a dynamic MatType
return
pyArray
;
}
if
(
PyArray_DIMS
(
pyArray
)[
0
]
>
1
&&
PyArray_DIMS
(
pyArray
)[
1
]
>
1
)
{
#ifndef NDEBUG
std
::
cerr
<<
"The number of dimension of the object does not correspond to a vector"
<<
std
::
endl
;
#endif
return
0
;
}
if
(((
PyArray_DIMS
(
pyArray
)[
0
]
==
1
)
&&
(
MatType
::
ColsAtCompileTime
==
1
))
||
((
PyArray_DIMS
(
pyArray
)[
1
]
==
1
)
&&
(
MatType
::
RowsAtCompileTime
==
1
)))
{
#ifndef NDEBUG
if
(
MatType
::
ColsAtCompileTime
==
1
)
std
::
cerr
<<
"The object is not a column vector"
<<
std
::
endl
;
else
std
::
cerr
<<
"The object is not a row vector"
<<
std
::
endl
;
#endif
return
0
;
}
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
// This is a fixe size vector
const
Eigen
::
DenseIndex
pyArray_size
=
PyArray_DIMS
(
pyArray
)[
0
]
>
PyArray_DIMS
(
pyArray
)[
1
]
?
PyArray_DIMS
(
pyArray
)[
0
]
:
PyArray_DIMS
(
pyArray
)[
1
];
if
(
size_at_compile_time
!=
pyArray_size
)
return
0
;
}
break
;
}
default
:
return
0
;
}
}
else
// this is a matrix
{
if
(
PyArray_NDIM
(
pyArray
)
==
1
)
// We can always convert a vector into a matrix
{
return
pyArray
;
}
if
(
PyArray_NDIM
(
pyArray
)
!=
2
)
{
#ifndef NDEBUG
std
::
cerr
<<
"The number of dimension of the object is not correct."
<<
std
::
endl
;
#endif
return
0
;
}
if
(
PyArray_NDIM
(
pyArray
)
==
2
)
{
const
int
R
=
(
int
)
PyArray_DIMS
(
pyArray
)[
0
];
const
int
C
=
(
int
)
PyArray_DIMS
(
pyArray
)[
1
];
if
(
(
MatType
::
RowsAtCompileTime
!=
R
)
&&
(
MatType
::
RowsAtCompileTime
!=
Eigen
::
Dynamic
)
)
return
0
;
if
(
(
MatType
::
ColsAtCompileTime
!=
C
)
&&
(
MatType
::
ColsAtCompileTime
!=
Eigen
::
Dynamic
)
)
return
0
;
}
}
#ifdef NPY_1_8_API_VERSION
if
(
!
(
PyArray_FLAGS
(
pyArray
)))
#else
if
(
!
(
PyArray_FLAGS
(
pyArray
)
&
NPY_ALIGNED
))
#endif
{
#ifndef NDEBUG
std
::
cerr
<<
"NPY non-aligned matrices are not implemented."
<<
std
::
endl
;
#endif
return
0
;
}
return
pyArray
;
}
/// \brief Allocate memory and copy pyObj in the new storage
static
void
construct
(
PyObject
*
pyObj
,
bp
::
converter
::
rvalue_from_python_stage1_data
*
memory
)
{
PyArrayObject
*
pyArray
=
reinterpret_cast
<
PyArrayObject
*>
(
pyObj
);
assert
((
PyArray_DIMS
(
pyArray
)[
0
]
<
INT_MAX
)
&&
(
PyArray_DIMS
(
pyArray
)[
1
]
<
INT_MAX
));
void
*
storage
=
reinterpret_cast
<
bp
::
converter
::
rvalue_from_python_storage
<
MatType
>*>
(
reinterpret_cast
<
void
*>
(
memory
))
->
storage
.
bytes
;
EigenAllocator
<
MatType
>::
allocate
(
pyArray
,
storage
);
memory
->
convertible
=
storage
;
}
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
MatType
>
());
}
};
template
<
typename
MatType
>
struct
EigenFromPyConverter
{
static
void
registration
()
{
EigenFromPy
<
MatType
>::
registration
();
// Add also conversion to Eigen::MatrixBase<MatType>
typedef
Eigen
::
MatrixBase
<
MatType
>
MatrixBase
;
EigenFromPy
<
MatrixBase
>::
registration
();
// Add also conversion to Eigen::EigenBase<MatType>
typedef
Eigen
::
EigenBase
<
MatType
>
EigenBase
;
EigenFromPy
<
EigenBase
>::
registration
();
}
};
template
<
typename
MatType
>
struct
EigenFromPy
<
Eigen
::
MatrixBase
<
MatType
>
>
:
EigenFromPy
<
MatType
>
{
typedef
EigenFromPy
<
MatType
>
EigenFromPyDerived
;
typedef
Eigen
::
MatrixBase
<
MatType
>
Base
;
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
Base
>
());
}
};
template
<
typename
MatType
>
struct
EigenFromPy
<
Eigen
::
EigenBase
<
MatType
>
>
:
EigenFromPy
<
MatType
>
{
typedef
EigenFromPy
<
MatType
>
EigenFromPyDerived
;
typedef
Eigen
::
EigenBase
<
MatType
>
Base
;
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
Base
>
());
}
};
#if EIGEN_VERSION_AT_LEAST(3,2,0)
// Template specialization for Eigen::Ref
template
<
typename
MatType
>
struct
EigenFromPyConverter
<
eigenpy
::
Ref
<
MatType
>
>
{
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
<
MatType
>::
convertible
),
&
EigenFromPy
<
MatType
>::
construct
,
bp
::
type_id
<
MatType
>
());
}
};
#endif
template
<
typename
MatType
,
typename
EigenEquivalentType
>
template
<
typename
MatType
,
typename
EigenEquivalentType
>
EIGENPY_DEPRECATED
EIGENPY_DEPRECATED
void
enableEigenPySpecific
()
void
enableEigenPySpecific
()
...
...
This diff is collapsed.
Click to expand it.
include/eigenpy/eigen-from-python.hpp
0 → 100644
+
259
−
0
View file @
a2b653ab
//
// Copyright (c) 2014-2020 CNRS INRIA
//
#ifndef __eigenpy_eigen_from_python_hpp__
#define __eigenpy_eigen_from_python_hpp__
#include
"eigenpy/fwd.hpp"
#include
"eigenpy/numpy-type.hpp"
#include
"eigenpy/eigen-allocator.hpp"
#include
"eigenpy/scalar-conversion.hpp"
namespace
eigenpy
{
template
<
typename
MatType
>
struct
EigenFromPy
{
static
bool
isScalarConvertible
(
const
int
np_type
)
{
if
(
NumpyEquivalentType
<
typename
MatType
::
Scalar
>::
type_code
==
np_type
)
return
true
;
switch
(
np_type
)
{
case
NPY_INT
:
return
FromTypeToType
<
int
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_LONG
:
return
FromTypeToType
<
long
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_FLOAT
:
return
FromTypeToType
<
float
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CFLOAT
:
return
FromTypeToType
<
std
::
complex
<
float
>
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_DOUBLE
:
return
FromTypeToType
<
double
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CDOUBLE
:
return
FromTypeToType
<
std
::
complex
<
double
>
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_LONGDOUBLE
:
return
FromTypeToType
<
long
double
,
typename
MatType
::
Scalar
>::
value
;
case
NPY_CLONGDOUBLE
:
return
FromTypeToType
<
std
::
complex
<
long
double
>
,
typename
MatType
::
Scalar
>::
value
;
default:
return
false
;
}
}
/// \brief Determine if pyObj can be converted into a MatType object
static
void
*
convertible
(
PyArrayObject
*
pyArray
)
{
if
(
!
PyArray_Check
(
pyArray
))
return
0
;
if
(
!
isScalarConvertible
(
EIGENPY_GET_PY_ARRAY_TYPE
(
pyArray
)))
return
0
;
if
(
MatType
::
IsVectorAtCompileTime
)
{
const
Eigen
::
DenseIndex
size_at_compile_time
=
MatType
::
IsRowMajor
?
MatType
::
ColsAtCompileTime
:
MatType
::
RowsAtCompileTime
;
switch
(
PyArray_NDIM
(
pyArray
))
{
case
0
:
return
0
;
case
1
:
{
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
// check that the sizes at compile time matche
if
(
PyArray_DIMS
(
pyArray
)[
0
]
==
size_at_compile_time
)
return
pyArray
;
else
return
0
;
}
else
// This is a dynamic MatType
return
pyArray
;
}
case
2
:
{
// Special care of scalar matrix of dimension 1x1.
if
(
PyArray_DIMS
(
pyArray
)[
0
]
==
1
&&
PyArray_DIMS
(
pyArray
)[
1
]
==
1
)
{
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
if
(
size_at_compile_time
==
1
)
return
pyArray
;
else
return
0
;
}
else
// This is a dynamic MatType
return
pyArray
;
}
if
(
PyArray_DIMS
(
pyArray
)[
0
]
>
1
&&
PyArray_DIMS
(
pyArray
)[
1
]
>
1
)
{
#ifndef NDEBUG
std
::
cerr
<<
"The number of dimension of the object does not correspond to a vector"
<<
std
::
endl
;
#endif
return
0
;
}
if
(((
PyArray_DIMS
(
pyArray
)[
0
]
==
1
)
&&
(
MatType
::
ColsAtCompileTime
==
1
))
||
((
PyArray_DIMS
(
pyArray
)[
1
]
==
1
)
&&
(
MatType
::
RowsAtCompileTime
==
1
)))
{
#ifndef NDEBUG
if
(
MatType
::
ColsAtCompileTime
==
1
)
std
::
cerr
<<
"The object is not a column vector"
<<
std
::
endl
;
else
std
::
cerr
<<
"The object is not a row vector"
<<
std
::
endl
;
#endif
return
0
;
}
if
(
size_at_compile_time
!=
Eigen
::
Dynamic
)
{
// This is a fixe size vector
const
Eigen
::
DenseIndex
pyArray_size
=
PyArray_DIMS
(
pyArray
)[
0
]
>
PyArray_DIMS
(
pyArray
)[
1
]
?
PyArray_DIMS
(
pyArray
)[
0
]
:
PyArray_DIMS
(
pyArray
)[
1
];
if
(
size_at_compile_time
!=
pyArray_size
)
return
0
;
}
break
;
}
default
:
return
0
;
}
}
else
// this is a matrix
{
if
(
PyArray_NDIM
(
pyArray
)
==
1
)
// We can always convert a vector into a matrix
{
return
pyArray
;
}
if
(
PyArray_NDIM
(
pyArray
)
!=
2
)
{
#ifndef NDEBUG
std
::
cerr
<<
"The number of dimension of the object is not correct."
<<
std
::
endl
;
#endif
return
0
;
}
if
(
PyArray_NDIM
(
pyArray
)
==
2
)
{
const
int
R
=
(
int
)
PyArray_DIMS
(
pyArray
)[
0
];
const
int
C
=
(
int
)
PyArray_DIMS
(
pyArray
)[
1
];
if
(
(
MatType
::
RowsAtCompileTime
!=
R
)
&&
(
MatType
::
RowsAtCompileTime
!=
Eigen
::
Dynamic
)
)
return
0
;
if
(
(
MatType
::
ColsAtCompileTime
!=
C
)
&&
(
MatType
::
ColsAtCompileTime
!=
Eigen
::
Dynamic
)
)
return
0
;
}
}
#ifdef NPY_1_8_API_VERSION
if
(
!
(
PyArray_FLAGS
(
pyArray
)))
#else
if
(
!
(
PyArray_FLAGS
(
pyArray
)
&
NPY_ALIGNED
))
#endif
{
#ifndef NDEBUG
std
::
cerr
<<
"NPY non-aligned matrices are not implemented."
<<
std
::
endl
;
#endif
return
0
;
}
return
pyArray
;
}
/// \brief Allocate memory and copy pyObj in the new storage
static
void
construct
(
PyObject
*
pyObj
,
bp
::
converter
::
rvalue_from_python_stage1_data
*
memory
)
{
PyArrayObject
*
pyArray
=
reinterpret_cast
<
PyArrayObject
*>
(
pyObj
);
assert
((
PyArray_DIMS
(
pyArray
)[
0
]
<
INT_MAX
)
&&
(
PyArray_DIMS
(
pyArray
)[
1
]
<
INT_MAX
));
void
*
storage
=
reinterpret_cast
<
bp
::
converter
::
rvalue_from_python_storage
<
MatType
>*>
(
reinterpret_cast
<
void
*>
(
memory
))
->
storage
.
bytes
;
EigenAllocator
<
MatType
>::
allocate
(
pyArray
,
storage
);
memory
->
convertible
=
storage
;
}
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
MatType
>
());
}
};
template
<
typename
MatType
>
struct
EigenFromPyConverter
{
static
void
registration
()
{
EigenFromPy
<
MatType
>::
registration
();
// Add also conversion to Eigen::MatrixBase<MatType>
typedef
Eigen
::
MatrixBase
<
MatType
>
MatrixBase
;
EigenFromPy
<
MatrixBase
>::
registration
();
// Add also conversion to Eigen::EigenBase<MatType>
typedef
Eigen
::
EigenBase
<
MatType
>
EigenBase
;
EigenFromPy
<
EigenBase
>::
registration
();
}
};
template
<
typename
MatType
>
struct
EigenFromPy
<
Eigen
::
MatrixBase
<
MatType
>
>
:
EigenFromPy
<
MatType
>
{
typedef
EigenFromPy
<
MatType
>
EigenFromPyDerived
;
typedef
Eigen
::
MatrixBase
<
MatType
>
Base
;
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
Base
>
());
}
};
template
<
typename
MatType
>
struct
EigenFromPy
<
Eigen
::
EigenBase
<
MatType
>
>
:
EigenFromPy
<
MatType
>
{
typedef
EigenFromPy
<
MatType
>
EigenFromPyDerived
;
typedef
Eigen
::
EigenBase
<
MatType
>
Base
;
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
::
convertible
),
&
EigenFromPy
::
construct
,
bp
::
type_id
<
Base
>
());
}
};
#if EIGEN_VERSION_AT_LEAST(3,2,0)
// Template specialization for Eigen::Ref
template
<
typename
MatType
>
struct
EigenFromPyConverter
<
eigenpy
::
Ref
<
MatType
>
>
{
static
void
registration
()
{
bp
::
converter
::
registry
::
push_back
(
reinterpret_cast
<
void
*
(
*
)(
_object
*
)
>
(
&
EigenFromPy
<
MatType
>::
convertible
),
&
EigenFromPy
<
MatType
>::
construct
,
bp
::
type_id
<
MatType
>
());
}
};
#endif
}
#endif // __eigenpy_eigen_from_python_hpp__
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment