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,
* 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>
struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType>
@ -106,13 +106,13 @@ template<typename MatrixType, int PacketAccess> class Map
* for the dimensions.
*
* \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>
inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>
::Matrix(const Scalar *data)
{
*this = Map<Matrix>(data);
*this = Eigen::Map<Matrix>(data);
}
#endif // EIGEN_MAP_H

View File

@ -108,7 +108,9 @@ class Matrix
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
friend class Eigen::Map<Matrix, Unaligned>;
typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
friend class Eigen::Map<Matrix, Aligned>;
typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
protected:
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.
* This prevents a useless copy when doing e.g. "m1 = m2.eval()"
*/
const Matrix& eval() const
inline const Matrix& eval() const
{
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
* data pointers.
*/
void swap(Matrix& other)
inline void swap(Matrix& other)
{
if (Base::SizeAtCompileTime==Dynamic)
m_storage.swap(other.m_storage);
@ -422,6 +424,41 @@ class Matrix
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 ///////////
template<typename OtherDerived>

View File

@ -24,7 +24,7 @@
#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;
@ -50,13 +50,46 @@ template<typename VectorType> void tmap(const VectorType& m)
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()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST( tmap(Matrix<float, 1, 1>()) );
CALL_SUBTEST( tmap(Vector4d()) );
CALL_SUBTEST( tmap(RowVector4f()) );
CALL_SUBTEST( tmap(VectorXcf(8)) );
CALL_SUBTEST( tmap(VectorXi(12)) );
CALL_SUBTEST( map_class(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class(Vector4d()) );
CALL_SUBTEST( map_class(RowVector4f()) );
CALL_SUBTEST( map_class(VectorXcf(8)) );
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)) );
}
}