Add Matrix::Map() and Matrix::AlignedMap() static methods

This commit is contained in:
Benoit Jacob 2008-11-03 21:49:03 +00:00
parent 3d90c13970
commit a0ec0fca5a
3 changed files with 82 additions and 12 deletions

View File

@ -40,9 +40,9 @@
* It can be used to let Eigen interface without any overhead with non-Eigen data structures, * It can be used to let Eigen interface without any overhead with non-Eigen data structures,
* such as plain C arrays or structures from other libraries. * such as plain C arrays or structures from other libraries.
* *
* This class is the return type of Matrix::map() but can also be used directly. * This class is the return type of Matrix::Map() but can also be used directly.
* *
* \sa Matrix::map() * \sa Matrix::Map()
*/ */
template<typename MatrixType, int _PacketAccess> template<typename MatrixType, int _PacketAccess>
struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType> struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType>
@ -106,13 +106,13 @@ template<typename MatrixType, int PacketAccess> class Map
* for the dimensions. * for the dimensions.
* *
* \sa Matrix(const Scalar *, int), Matrix(const Scalar *, int, int), * \sa Matrix(const Scalar *, int), Matrix(const Scalar *, int, int),
* Matrix::map(const Scalar *) * Matrix::Map(const Scalar *)
*/ */
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>
::Matrix(const Scalar *data) ::Matrix(const Scalar *data)
{ {
*this = Map<Matrix>(data); *this = Eigen::Map<Matrix>(data);
} }
#endif // EIGEN_MAP_H #endif // EIGEN_MAP_H

View File

@ -108,7 +108,9 @@ class Matrix
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
friend class Eigen::Map<Matrix, Unaligned>; friend class Eigen::Map<Matrix, Unaligned>;
typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
friend class Eigen::Map<Matrix, Aligned>; friend class Eigen::Map<Matrix, Aligned>;
typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
protected: protected:
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime> m_storage; ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime> m_storage;
@ -406,7 +408,7 @@ class Matrix
/** Override MatrixBase::eval() since matrices don't need to be evaluated, it is enough to just read them. /** Override MatrixBase::eval() since matrices don't need to be evaluated, it is enough to just read them.
* This prevents a useless copy when doing e.g. "m1 = m2.eval()" * This prevents a useless copy when doing e.g. "m1 = m2.eval()"
*/ */
const Matrix& eval() const inline const Matrix& eval() const
{ {
return *this; return *this;
} }
@ -414,7 +416,7 @@ class Matrix
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
* data pointers. * data pointers.
*/ */
void swap(Matrix& other) inline void swap(Matrix& other)
{ {
if (Base::SizeAtCompileTime==Dynamic) if (Base::SizeAtCompileTime==Dynamic)
m_storage.swap(other.m_storage); m_storage.swap(other.m_storage);
@ -422,6 +424,41 @@ class Matrix
this->Base::swap(other); this->Base::swap(other);
} }
/**
* These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
* while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
* \a data pointers.
*
* \see class Map
*/
//@}
inline static const UnalignedMapType Map(const Scalar* data)
{ return UnalignedMapType(data); }
inline static UnalignedMapType Map(Scalar* data)
{ return UnalignedMapType(data); }
inline static const UnalignedMapType Map(const Scalar* data, int size)
{ return UnalignedMapType(data, size); }
inline static UnalignedMapType Map(Scalar* data, int size)
{ return UnalignedMapType(data, size); }
inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols)
{ return UnalignedMapType(data, rows, cols); }
inline static UnalignedMapType Map(Scalar* data, int rows, int cols)
{ return UnalignedMapType(data, rows, cols); }
inline static const AlignedMapType MapAligned(const Scalar* data)
{ return AlignedMapType(data); }
inline static AlignedMapType MapAligned(Scalar* data)
{ return AlignedMapType(data); }
inline static const AlignedMapType MapAligned(const Scalar* data, int size)
{ return AlignedMapType(data, size); }
inline static AlignedMapType MapAligned(Scalar* data, int size)
{ return AlignedMapType(data, size); }
inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols)
{ return AlignedMapType(data, rows, cols); }
inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols)
{ return AlignedMapType(data, rows, cols); }
//@}
/////////// Geometry module /////////// /////////// Geometry module ///////////
template<typename OtherDerived> template<typename OtherDerived>

View File

@ -24,7 +24,7 @@
#include "main.h" #include "main.h"
template<typename VectorType> void tmap(const VectorType& m) template<typename VectorType> void map_class(const VectorType& m)
{ {
typedef typename VectorType::Scalar Scalar; typedef typename VectorType::Scalar Scalar;
@ -50,13 +50,46 @@ template<typename VectorType> void tmap(const VectorType& m)
delete[] array3; delete[] array3;
} }
template<typename VectorType> void map_static_methods(const VectorType& m)
{
typedef typename VectorType::Scalar Scalar;
int size = m.size();
// test Map.h
Scalar* array1 = ei_aligned_malloc<Scalar>(size);
Scalar* array2 = ei_aligned_malloc<Scalar>(size);
Scalar* array3 = new Scalar[size+1];
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
VectorType::MapAligned(array1, size) = VectorType::Random(size);
VectorType::Map(array2, size) = VectorType::Map(array1, size);
VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);
VectorType ma1 = VectorType::Map(array1, size);
VectorType ma2 = VectorType::MapAligned(array2, size);
VectorType ma3 = VectorType::Map(array3unaligned, size);
VERIFY_IS_APPROX(ma1, ma2);
VERIFY_IS_APPROX(ma1, ma3);
ei_aligned_free(array1);
ei_aligned_free(array2);
delete[] array3;
}
void test_map() void test_map()
{ {
for(int i = 0; i < g_repeat; i++) { for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST( tmap(Matrix<float, 1, 1>()) ); CALL_SUBTEST( map_class(Matrix<float, 1, 1>()) );
CALL_SUBTEST( tmap(Vector4d()) ); CALL_SUBTEST( map_class(Vector4d()) );
CALL_SUBTEST( tmap(RowVector4f()) ); CALL_SUBTEST( map_class(RowVector4f()) );
CALL_SUBTEST( tmap(VectorXcf(8)) ); CALL_SUBTEST( map_class(VectorXcf(8)) );
CALL_SUBTEST( tmap(VectorXi(12)) ); CALL_SUBTEST( map_class(VectorXi(12)) );
CALL_SUBTEST( map_static_methods(Matrix<double, 1, 1>()) );
CALL_SUBTEST( map_static_methods(Vector3f()) );
CALL_SUBTEST( map_static_methods(RowVector3d()) );
CALL_SUBTEST( map_static_methods(VectorXcd(8)) );
CALL_SUBTEST( map_static_methods(VectorXf(12)) );
} }
} }