Commit 7e0c4a8d authored by Nicolas Mansard's avatar Nicolas Mansard Committed by nmansard
Browse files

Refactoring of src files. No serious modifs, only shape.

parent cd6e8a48
......@@ -37,11 +37,14 @@ INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS})
SET(${PROJECT_NAME}_HEADERS
src/eigenpy.hpp
src/exception.hpp
src/details.hpp
src/fwd.hpp
src/map.hpp
src/simple.hpp
src/geometry.hpp
src/angle-axis.hpp
src/quaternion.hpp
# Deprec
src/simple.hpp
)
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy")
INCLUDE_DIRECTORIES(${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy)
......@@ -68,7 +71,8 @@ ENDFOREACH(header)
ADD_LIBRARY(eigenpy SHARED
src/exception.cpp
src/simple.cpp
src/eigenpy.cpp
src/details.cpp
src/angle-axis.cpp
src/quaternion.cpp
)
......
#!/usr/bin/python
import numpy as np
'''
import libsimple
print libsimple.char()
print libsimple.str()
try:
a = libsimple.eigenvec()
print a
except:
print "Error when calling simple eigenvec"
import libmystring
print libmystring.hello()
print libmystring.size("toto+5")
import libeigen
print libeigen.test()
a = np.matrix([11,2,3,4,5]).T
b = np.array([11,2,3,4,5])
#b = np.array([[15,],[1,],[1,],[1,],[1,],])
#b = np.array([ [[10,2],[3,4]],[[10,2],[3,4]] ])
print "matrix ===> "
libeigen.test2(a)
print "array ===> "
libeigen.test2(b)
'''
import libeigenpy
# 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)
# print "===> From Py::transpose to C++"
# b=a[1:5,1:3].T
# print b
# libeigentemplate.test2(b)
print "===> From py::vec to C++ Vec"
v = np.array([range(5),],np.float64).T
print v
libeigentemplate.test2Vec(v)
v = np.array(range(5),np.float64)
print "v = ", v
libeigentemplate.test2Vec(v)
v = np.array(range(10),np.float64)
v2 = v[0:10:5]
print "v2 = ", v2
libeigentemplate.test2Vec(v2)
'''
import libbnpy
a=libbnpy.array()
print a.__class__
b=libbnpy.matrix()
print b.__class__
'''
......@@ -2,10 +2,10 @@ from geometry import *
import numpy as np
from numpy import cos,sin
verbose = True
verbose = False
def isapprox(a,b,epsilon=1e-6):
if a.__class__ == b.__class__ == np.ndarray:
if issubclass(a.__class__,np.ndarray) and issubclass(b.__class__,np.ndarray):
return np.allclose(a,b,epsilon)
else:
return abs(a-b)<epsilon
......@@ -23,7 +23,7 @@ assert(isapprox(q.coeffs(),q2.coeffs()))
Rq = q.matrix()
Rr = r.matrix()
assert(isapprox(np.dot(Rq,Rq.T),np.eye(3)))
assert(isapprox(Rq*Rq.T,np.eye(3)))
assert(isapprox(Rr,Rq))
qR = Quaternion(Rr)
......@@ -41,7 +41,7 @@ except Exception,e:
r = AngleAxis(.1,np.array([1,0,0],np.double))
if verbose: print "Rx(.1) = \n\n",r.matrix(),"\n"
assert( isapprox(r.matrix()[2,2],cos(r.angle)))
assert( isapprox(r.axis,np.array([[1,0,0],],np.double).T) )
assert( isapprox(r.axis,np.matrix("1;0;0")) )
assert( isapprox(r.angle,0.1) )
r.axis = np.array([0,1,0],np.double)
......
/*
* Copyright 2014, Nicolas Mansard, LAAS-CNRS
*
* This file is part of eigenpy.
* eigenpy is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* eigenpy is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
*/
#include "eigenpy/angle-axis.hpp"
#include "eigenpy/geometry.hpp"
......
#ifndef __eigenpy_Angle_Axis_hpp__
#define __eigenpy_Angle_Axis_hpp__
/*
* Copyright 2014, Nicolas Mansard, LAAS-CNRS
*
* This file is part of eigenpy.
* eigenpy is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* eigenpy is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __eigenpy_angle_axis_hpp__
#define __eigenpy_angle_axis_hpp__
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <boost/python.hpp>
#include "eigenpy/simple.hpp"
#include "eigenpy/eigenpy.hpp"
namespace eigenpy
{
......@@ -127,5 +143,4 @@ namespace eigenpy
} // namespace eigenpy
#endif //ifndef __eigenpy_Angle_Axis_hpp__
#endif //ifndef __eigenpy_angle_axis_hpp__
#include "eigenpy/details.hpp"
namespace eigenpy
{
PyMatrixType pyMatrixType = PyMatrixType();
} // namespace eigenpy
/*
* Copyright 2014, Nicolas Mansard, LAAS-CNRS
*
* This file is part of eigenpy.
* eigenpy is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* eigenpy is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __eigenpy_details_hpp__
#define __eigenpy_details_hpp__
#include <Eigen/Core>
#include <boost/python.hpp>
#include <numpy/arrayobject.h>
#include <iostream>
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/exception.hpp"
#include "eigenpy/map.hpp"
namespace eigenpy
{
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 PyMatrixType
{
boost::python::object pyMatrixType;
boost::python::object pyModule;
PyMatrixType()
{
pyModule = boost::python::import("numpy");
pyMatrixType = pyModule.attr("matrix");
}
operator boost::python::object () { return pyMatrixType; }
boost::python::object make(PyArrayObject* pyArray, bool copy = false)
{ return make((PyObject*)pyArray,copy); }
boost::python::object make(PyObject* pyObj, bool copy = false)
{
boost::python::object m
= pyMatrixType( boost::python::object(boost::python::handle<>(pyObj)),
boost::python::object(), copy );
Py_INCREF(m.ptr());
return m;
}
};
extern PyMatrixType pyMatrixType;
/* --- TO PYTHON -------------------------------------------------------------- */
template< typename MatType,typename EquivalentEigenType >
struct EigenToPy
{
static PyObject* convert(MatType const& mat)
{
typedef typename MatType::Scalar T;
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX)
&& "Matrix range larger than int ... should never happen." );
const int R = (int)mat.rows(), C = (int)mat.cols();
npy_intp shape[2] = { R,C };
PyArrayObject* pyArray = (PyArrayObject*)
PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
MapNumpy<EquivalentEigenType>::map(pyArray) = mat;
return pyMatrixType.make(pyArray).ptr();
}
};
/* --- FROM PYTHON ------------------------------------------------------------ */
namespace bp = boost::python;
template<typename MatType, int ROWS,int COLS>
struct TraitsMatrixConstructor
{
static MatType & construct(void*storage,int /*r*/,int /*c*/)
{
return * new(storage) MatType();
}
};
template<typename MatType>
struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,Eigen::Dynamic>
{
static MatType & construct(void*storage,int r,int c)
{
return * new(storage) MatType(r,c);
}
};
template<typename MatType,int R>
struct TraitsMatrixConstructor<MatType,R,Eigen::Dynamic>
{
static MatType & construct(void*storage,int /*r*/,int c)
{
return * new(storage) MatType(c);
}
};
template<typename MatType,int C>
struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,C>
{
static MatType & construct(void*storage,int r,int /*c*/)
{
return * new(storage) MatType(r);
}
};
template<typename MatType,typename EquivalentEigenType>
struct EigenFromPy
{
EigenFromPy()
{
bp::converter::registry::push_back
(&convertible,&construct,bp::type_id<MatType>());
}
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyObject* obj_ptr)
{
typedef typename MatType::Scalar T;
if (!PyArray_Check(obj_ptr))
{
std::cerr << "The python object is not a numpy array." << std::endl;
return 0;
}
if (PyArray_NDIM(obj_ptr) != 2)
if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
{
std::cerr << "The number of dimension of the object is not correct." << std::endl;
return 0;
}
if ((PyArray_ObjectType(obj_ptr, 0)) != NumpyEquivalentType<T>::type_code)
{
std::cerr << "The internal type as no Eigen equivalent." << std::endl;
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 typename MatType::Scalar T;
using namespace Eigen;
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
typename MapNumpy<EquivalentEigenType>::EigenMap numpyMap = MapNumpy<EquivalentEigenType>::map(pyArray);
void* storage = ((bp::converter::rvalue_from_python_storage<MatType>*)
(memory))->storage.bytes;
assert( (numpyMap.rows()<INT_MAX) && (numpyMap.cols()<INT_MAX)
&& "Map range larger than int ... can never happen." );
int r=(int)numpyMap.rows(),c=(int)numpyMap.cols();
EquivalentEigenType & eigenMatrix = //* new(storage) MatType(numpyMap.rows(),numpyMap.cols());
TraitsMatrixConstructor<MatType,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime>::construct (storage,r,c);
memory->convertible = storage;
eigenMatrix = numpyMap;
}
};
template<typename MatType,typename EigenEquivalentType>
void enableEigenPySpecific()
{
import_array();
#ifdef EIGEN_DONT_VECTORIZE
boost::python::to_python_converter<MatType,
eigenpy::EigenToPy<MatType,MatType> >();
eigenpy::EigenFromPy<MatType,MatType>();
#else
typedef typename eigenpy::UnalignedEquivalent<MatType>::type MatTypeDontAlign;
boost::python::to_python_converter<MatType,
eigenpy::EigenToPy<MatType,MatType> >();
boost::python::to_python_converter<MatTypeDontAlign,
eigenpy::EigenToPy<MatTypeDontAlign,MatTypeDontAlign> >();
eigenpy::EigenFromPy<MatTypeDontAlign,MatTypeDontAlign>();
#endif
}
} // namespace eigenpy
#endif // ifndef __eigenpy_details_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/simple.hpp"
namespace eigenpy
{
/* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
void enableEigenPy()
{
Exception::registerException();
enableEigenPySpecific<Eigen::MatrixXd,Eigen::MatrixXd>();
enableEigenPySpecific<Eigen::Matrix2d,Eigen::Matrix2d>();
enableEigenPySpecific<Eigen::Matrix3d,Eigen::Matrix3d>();
enableEigenPySpecific<Eigen::Matrix4d,Eigen::Matrix4d>();
enableEigenPySpecific<Eigen::VectorXd,Eigen::VectorXd>();
enableEigenPySpecific<Eigen::Vector2d,Eigen::Vector2d>();
enableEigenPySpecific<Eigen::Vector3d,Eigen::Vector3d>();
enableEigenPySpecific<Eigen::Vector4d,Eigen::Vector4d>();
}
} // namespace eigenpy
......@@ -14,205 +14,32 @@
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Eigen/Core>
#include <boost/python.hpp>
#include <numpy/arrayobject.h>
#include <iostream>
#include <eigenpy/exception.hpp>
#include <eigenpy/simple.hpp>
#include <eigenpy/map.hpp>
#ifndef __eigenpy_eigenpy_hpp__
#define __eigenpy_eigenpy_hpp__
#include "eigenpy/fwd.hpp"
namespace eigenpy
{
/* Enable the Eigen--Numpy serialization for the templated MatrixBase class. */
typedef UnalignedEquivalent<Eigen::MatrixXd>::type MatrixXd_fx;
typedef UnalignedEquivalent<Eigen::Matrix3d>::type Matrix3d_fx;
typedef UnalignedEquivalent<Eigen::Matrix4d>::type Matrix4d_fx;
typedef UnalignedEquivalent<Eigen::VectorXd>::type VectorXd_fx;
typedef UnalignedEquivalent<Eigen::Vector3d>::type Vector3d_fx;
typedef UnalignedEquivalent<Eigen::Vector4d>::type Vector4d_fx;
/* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
void enableEigenPy();
/* Enable the Eigen--Numpy serialization for the templated MatrixBase class.
* The second template argument is used for inheritance of Eigen classes. If
* using a native Eigen::MatrixBase, simply repeat the same arg twice. */
template<typename MatType,typename EigenEquivalentType>
void enableEigenPySpecific();
}
/* --- DETAILS ------------------------------------------------------------------ */
/* --- DETAILS ------------------------------------------------------------------ */
/* --- DETAILS ------------------------------------------------------------------ */
namespace eigenpy
{
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 PyMatrixType
{
boost::python::object pyMatrixType;
boost::python::object pyModule;
PyMatrixType()
{
pyModule = boost::python::import("numpy");
pyMatrixType = pyModule.attr("matrix");
}
operator boost::python::object () { return pyMatrixType; }
boost::python::object make(PyArrayObject* pyArray, bool copy = false)
{ return make((PyObject*)pyArray,copy); }
boost::python::object make(PyObject* pyObj, bool copy = false)
{
boost::python::object m
= pyMatrixType( boost::python::object(boost::python::handle<>(pyObj)),
boost::python::object(), copy );
Py_INCREF(m.ptr());
return m;
}
};
static PyMatrixType pyMatrixType = PyMatrixType();
/* --- TO PYTHON -------------------------------------------------------------- */
template< typename MatType,typename EquivalentEigenType >
struct EigenToPy
{
static PyObject* convert(MatType const& mat)
{
typedef typename MatType::Scalar T;
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX)
&& "Matrix range larger than int ... should never happen." );
const int R = (int)mat.rows(), C = (int)mat.cols();
npy_intp shape[2] = { R,C };
PyArrayObject* pyArray = (PyArrayObject*)
PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
MapNumpy<EquivalentEigenType>::map(pyArray) = mat;
return pyMatrixType.make(pyArray).ptr();
}
};
/* --- FROM PYTHON ------------------------------------------------------------ */
namespace bp = boost::python;
template<typename MatType, int ROWS,int COLS>
struct TraitsMatrixConstructor
{
static MatType & construct(void*storage,int /*r*/,int /*c*/)
{
return * new(storage) MatType();
}
};
template<typename MatType>
struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,Eigen::Dynamic>
{
static MatType & construct(void*storage,int r,int c)
{
return * new(storage) MatType(r,c);
}
};
template<typename MatType,int R>
struct TraitsMatrixConstructor<MatType,R,Eigen::Dynamic>
{
static MatType & construct(void*storage,int /*r*/,int c)
{
return * new(storage) MatType(c);
}
};
template<typename MatType,int C>
struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,C>
{
static MatType & construct(void*storage,int r,int /*c*/)
{
return * new(storage) MatType(r);
}
};
template<typename MatType,typename EquivalentEigenType>
struct EigenFromPy
{
EigenFromPy()
{
bp::converter::registry::push_back
(&convertible,&construct,bp::type_id<MatType>());
}
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyObject* obj_ptr)
{
typedef typename MatType::Scalar T;
if (!PyArray_Check(obj_ptr))
{
std::cerr << "The python object is not a numpy array." << std::endl;
return 0;
}
if (PyArray_NDIM(obj_ptr) != 2)
if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
{
std::cerr << "The number of dimension of the object is not correct." << std::endl;
return 0;
}
if ((PyArray_ObjectType(obj_ptr, 0)) != NumpyEquivalentType<T>::type_code)
{
std::cerr << "The internal type as no Eigen equivalent." << std::endl;
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)