mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-02-17 18:09:55 +08:00
Based on code + help from Alex Stapleton:
*Add Eigen/StdVector header. Including it #includes<vector> and "Core" and generates a partial specialization of std::vector<T> for T=Eigen::Matrix<...> that will work even with vectorizable fixed-size Eigen types (working around a design issue in the c++ STL) *Add unit-test CCMAIL: alex.stapleton@gmail.com
This commit is contained in:
parent
5052d3659b
commit
335d3bcf05
@ -1,4 +1,4 @@
|
||||
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD Regression LeastSquares)
|
||||
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD Regression LeastSquares StdVector)
|
||||
|
||||
if(EIGEN_BUILD_LIB)
|
||||
set(Eigen_SRCS
|
||||
|
75
Eigen/StdVector
Normal file
75
Eigen/StdVector
Normal file
@ -0,0 +1,75 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2009 Alex Stapleton <alex.stapleton@gmail.com>
|
||||
//
|
||||
// Eigen 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.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen 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 or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef EIGEN_STDVECTOR_MODULE_H
|
||||
#define EIGEN_STDVECTOR_MODULE_H
|
||||
|
||||
#include "Core"
|
||||
#include <vector>
|
||||
|
||||
namespace Eigen{
|
||||
template<typename aligned_type> class ei_unaligned_type;
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
class ei_unaligned_type<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >
|
||||
: public Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>
|
||||
{
|
||||
public:
|
||||
typedef Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> aligned_base;
|
||||
ei_unaligned_type() : aligned_base(ei_select_matrix_constructor_doing_absolutely_nothing()) {}
|
||||
ei_unaligned_type(const aligned_base& other)
|
||||
{
|
||||
ei_assign_impl<ei_unaligned_type,aligned_base,NoVectorization>::run(*this, other);
|
||||
}
|
||||
};
|
||||
} // namespace Eigen
|
||||
|
||||
namespace std {
|
||||
|
||||
template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols, typename _Alloc>
|
||||
class vector<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>, _Alloc>
|
||||
: public vector<Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >,
|
||||
Eigen::aligned_allocator<Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > > >
|
||||
{
|
||||
public:
|
||||
typedef Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > value_type;
|
||||
typedef Eigen::aligned_allocator<value_type> allocator_type;
|
||||
typedef vector<value_type, allocator_type > unaligned_base;
|
||||
typedef typename unaligned_base::size_type size_type;
|
||||
typedef typename unaligned_base::iterator iterator;
|
||||
|
||||
explicit vector(const allocator_type& __a = allocator_type()) : unaligned_base(__a) {}
|
||||
vector(const vector& c) : unaligned_base(c) {}
|
||||
vector(size_type num, const value_type& val = value_type()) : unaligned_base(num, val) {}
|
||||
vector(iterator start, iterator end) : unaligned_base(start, end) {}
|
||||
vector& operator=(const vector& __x) {
|
||||
unaligned_base::operator=(__x);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // EIGEN_STDVECTOR_MODULE_H
|
@ -52,6 +52,8 @@ template <typename T, int Size, int MatrixOptions,
|
||||
template <typename T, int Size, int MatrixOptions> struct ei_matrix_array<T,Size,MatrixOptions,false>
|
||||
{
|
||||
T array[Size];
|
||||
ei_matrix_array() {}
|
||||
ei_matrix_array(ei_select_matrix_array_constructor_doing_absolutely_nothing) {}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
|
@ -186,6 +186,7 @@ ei_add_test(hyperplane)
|
||||
ei_add_test(parametrizedline)
|
||||
ei_add_test(alignedbox)
|
||||
ei_add_test(regression)
|
||||
ei_add_test(stdvector)
|
||||
ei_add_test(sparse_basic " " "${SPARSE_LIBS}")
|
||||
ei_add_test(sparse_vector " " "${SPARSE_LIBS}")
|
||||
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
|
||||
|
64
test/stdvector.cpp
Normal file
64
test/stdvector.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// Eigen 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.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen 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 or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <Eigen/StdVector>
|
||||
|
||||
template<typename MatrixType>
|
||||
void check_stdvector_fixedsize()
|
||||
{
|
||||
MatrixType x = MatrixType::Random(), y = MatrixType::Random();
|
||||
std::vector<MatrixType> v(10), w(20, y);
|
||||
v[5] = x;
|
||||
w[6] = v[5];
|
||||
VERIFY_IS_APPROX(w[6], v[5]);
|
||||
v = w;
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
VERIFY_IS_APPROX(w[i], v[i]);
|
||||
}
|
||||
v.resize(21);
|
||||
v[20] = x;
|
||||
VERIFY_IS_APPROX(v[20], x);
|
||||
v.resize(22,y);
|
||||
VERIFY_IS_APPROX(v[21], y);
|
||||
v.push_back(x);
|
||||
VERIFY_IS_APPROX(v[22], x);
|
||||
}
|
||||
|
||||
|
||||
void test_stdvector()
|
||||
{
|
||||
// some non vectorizable fixed sizes
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Vector2f>());
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Matrix3f>());
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Matrix3d>());
|
||||
|
||||
// some vectorizable fixed sizes
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Vector2d>());
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Vector4f>());
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Matrix4f>());
|
||||
CALL_SUBTEST(check_stdvector_fixedsize<Matrix4d>());
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user