merge and add start/end to Eigen2Support

This commit is contained in:
Gael Guennebaud
2010-01-05 13:07:32 +01:00
78 changed files with 1072 additions and 592 deletions

View File

@@ -88,6 +88,7 @@ ei_add_test(meta)
ei_add_test(sizeof)
ei_add_test(dynalloc)
ei_add_test(nomalloc)
ei_add_test(first_aligned)
ei_add_test(mixingtypes)
ei_add_test(packetmath)
ei_add_test(unalignedassert)
@@ -117,7 +118,7 @@ ei_add_test(product_symm)
ei_add_test(product_syrk)
ei_add_test(product_trmv)
ei_add_test(product_trmm)
ei_add_test(product_trsm)
ei_add_test(product_trsolve)
ei_add_test(product_notemporary)
ei_add_test(stable_norm)
ei_add_test(bandmatrix)
@@ -128,6 +129,7 @@ ei_add_test(inverse)
ei_add_test(qr)
ei_add_test(qr_colpivoting)
ei_add_test(qr_fullpivoting)
ei_add_test(hessenberg " " "${GSL_LIBRARIES}")
ei_add_test(eigensolver_selfadjoint " " "${GSL_LIBRARIES}")
ei_add_test(eigensolver_generic " " "${GSL_LIBRARIES}")
ei_add_test(eigensolver_complex)

64
test/first_aligned.cpp Normal file
View File

@@ -0,0 +1,64 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@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/>.
#include "main.h"
template<typename Scalar>
void test_first_aligned_helper(Scalar *array, int size)
{
const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
VERIFY(((size_t(array) + sizeof(Scalar) * ei_first_aligned(array, size)) % packet_size) == 0);
}
template<typename Scalar>
void test_none_aligned_helper(Scalar *array, int size)
{
VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_first_aligned(array, size) == size);
}
struct some_non_vectorizable_type { float x; };
void test_first_aligned()
{
EIGEN_ALIGN16 float array_float[100];
test_first_aligned_helper(array_float, 50);
test_first_aligned_helper(array_float+1, 50);
test_first_aligned_helper(array_float+2, 50);
test_first_aligned_helper(array_float+3, 50);
test_first_aligned_helper(array_float+4, 50);
test_first_aligned_helper(array_float+5, 50);
EIGEN_ALIGN16 double array_double[100];
test_first_aligned_helper(array_float, 50);
test_first_aligned_helper(array_float+1, 50);
test_first_aligned_helper(array_float+2, 50);
double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4);
test_none_aligned_helper(array_double_plus_4_bytes, 50);
test_none_aligned_helper(array_double_plus_4_bytes+1, 50);
some_non_vectorizable_type array_nonvec[100];
test_first_aligned_helper(array_nonvec, 100);
test_none_aligned_helper(array_nonvec, 100);
}

View File

@@ -67,7 +67,7 @@ template<typename Scalar,int Size> void homogeneous(void)
VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
hm0.row(Size-1).setRandom();
for(int j=0; j<Size; ++j)
m0.col(j) = hm0.col(j).start(Size) / hm0(Size,j);
m0.col(j) = hm0.col(j).head(Size) / hm0(Size,j);
VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());
T1MatrixType t1 = T1MatrixType::Random();

View File

@@ -66,7 +66,7 @@ template<typename Scalar> void orthomethods_3()
v41 = Vector4::Random(),
v42 = Vector4::Random();
v40.w() = v41.w() = v42.w() = 0;
v42.template start<3>() = v40.template start<3>().cross(v41.template start<3>());
v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>());
VERIFY_IS_APPROX(v40.cross3(v41), v42);
}
@@ -88,8 +88,8 @@ template<typename Scalar, int Size> void orthomethods(int size=Size)
if (size>=3)
{
v0.template start<2>().setZero();
v0.end(size-2).setRandom();
v0.template head<2>().setZero();
v0.tail(size-2).setRandom();
VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));
VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));

View File

@@ -118,7 +118,7 @@ template<typename Scalar, int Mode> void transformations(void)
t0.scale(v0);
t1.prescale(v0);
VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).template start<3>().norm(), v0.x());
VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).template head<3>().norm(), v0.x());
//VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));
t0.setIdentity();
@@ -290,12 +290,12 @@ template<typename Scalar, int Mode> void transformations(void)
// translation * vector
t0.setIdentity();
t0.translate(v0);
VERIFY_IS_APPROX((t0 * v1).template start<3>(), Translation3(v0) * v1);
VERIFY_IS_APPROX((t0 * v1).template head<3>(), Translation3(v0) * v1);
// AlignedScaling * vector
t0.setIdentity();
t0.scale(v0);
VERIFY_IS_APPROX((t0 * v1).template start<3>(), AlignedScaling3(v0) * v1);
VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);
// test transform inversion
t0.setIdentity();

46
test/hessenberg.cpp Normal file
View File

@@ -0,0 +1,46 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 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/Eigenvalues>
template<typename Scalar,int Size> void hessenberg(int size = Size)
{
typedef Matrix<Scalar,Size,Size> MatrixType;
MatrixType m = MatrixType::Random(size,size);
HessenbergDecomposition<MatrixType> hess(m);
VERIFY_IS_APPROX(m, hess.matrixQ() * hess.matrixH() * hess.matrixQ().adjoint());
}
void test_hessenberg()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1(( hessenberg<std::complex<double>,1>() ));
CALL_SUBTEST_2(( hessenberg<std::complex<double>,2>() ));
CALL_SUBTEST_3(( hessenberg<std::complex<float>,4>() ));
CALL_SUBTEST_4(( hessenberg<float,Dynamic>(ei_random<int>(1,320)) ));
CALL_SUBTEST_5(( hessenberg<std::complex<double>,Dynamic>(ei_random<int>(1,320)) ));
}
}

View File

@@ -53,7 +53,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
v1.makeHouseholder(essential, beta, alpha);
v1.applyHouseholderOnTheLeft(essential,beta,tmp);
VERIFY_IS_APPROX(v1.norm(), v2.norm());
VERIFY_IS_MUCH_SMALLER_THAN(v1.end(rows-1).norm(), v1.norm());
VERIFY_IS_MUCH_SMALLER_THAN(v1.tail(rows-1).norm(), v1.norm());
v1 = VectorType::Random(rows);
v2 = v1;
v1.applyHouseholderOnTheLeft(essential,beta,tmp);
@@ -63,7 +63,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
m2(rows, cols);
v1 = VectorType::Random(rows);
if(even) v1.end(rows-1).setZero();
if(even) v1.tail(rows-1).setZero();
m1.colwise() = v1;
m2 = m1;
m1.col(0).makeHouseholder(essential, beta, alpha);
@@ -74,7 +74,7 @@ template<typename MatrixType> void householder(const MatrixType& m)
VERIFY_IS_APPROX(ei_real(m1(0,0)), alpha);
v1 = VectorType::Random(rows);
if(even) v1.end(rows-1).setZero();
if(even) v1.tail(rows-1).setZero();
SquareMatrixType m3(rows,rows), m4(rows,rows);
m3.rowwise() = v1.transpose();
m4 = m3;

View File

@@ -68,9 +68,9 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
if (rows>1)
{
m2 = m1.template triangularView<LowerTriangular>();
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rankUpdate(v1.end(rows-1),v2.start(cols-1));
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rankUpdate(v1.tail(rows-1),v2.head(cols-1));
m3 = m1;
m3.block(1,1,rows-1,cols-1) += v1.end(rows-1) * v2.start(cols-1).adjoint()+ v2.start(cols-1) * v1.end(rows-1).adjoint();
m3.block(1,1,rows-1,cols-1) += v1.tail(rows-1) * v2.head(cols-1).adjoint()+ v2.head(cols-1) * v1.tail(rows-1).adjoint();
VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDenseMatrix());
}
}

View File

@@ -30,15 +30,21 @@
VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
}
template<typename Scalar> void trsm(int size,int cols)
#define VERIFY_TRSM_ONTHERIGHT(TRI,XB) { \
(XB).setRandom(); ref = (XB); \
(TRI).transpose().template solveInPlace<OnTheRight>(XB.transpose()); \
VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \
}
template<typename Scalar,int Size, int Cols> void trsolve(int size=Size,int cols=Cols)
{
typedef typename NumTraits<Scalar>::Real RealScalar;
Matrix<Scalar,Dynamic,Dynamic,ColMajor> cmLhs(size,size);
Matrix<Scalar,Dynamic,Dynamic,RowMajor> rmLhs(size,size);
Matrix<Scalar,Size,Size,ColMajor> cmLhs(size,size);
Matrix<Scalar,Size,Size,RowMajor> rmLhs(size,size);
Matrix<Scalar,Dynamic,Dynamic,ColMajor> cmRhs(size,cols), ref(size,cols);
Matrix<Scalar,Dynamic,Dynamic,RowMajor> rmRhs(size,cols);
Matrix<Scalar,Size,Cols,ColMajor> cmRhs(size,cols), ref(size,cols);
Matrix<Scalar,Size,Cols,RowMajor> rmRhs(size,cols);
cmLhs.setRandom(); cmLhs *= static_cast<RealScalar>(0.1); cmLhs.diagonal().array() += static_cast<RealScalar>(1);
rmLhs.setRandom(); rmLhs *= static_cast<RealScalar>(0.1); rmLhs.diagonal().array() += static_cast<RealScalar>(1);
@@ -53,13 +59,32 @@ template<typename Scalar> void trsm(int size,int cols)
VERIFY_TRSM(rmLhs .template triangularView<LowerTriangular>(), cmRhs);
VERIFY_TRSM(rmLhs.conjugate().template triangularView<UnitUpperTriangular>(), rmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<LowerTriangular>(), cmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<UpperTriangular>(), cmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<LowerTriangular>(), rmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<UpperTriangular>(), rmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<UnitLowerTriangular>(), cmRhs);
VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<UnitUpperTriangular>(), rmRhs);
VERIFY_TRSM_ONTHERIGHT(rmLhs .template triangularView<LowerTriangular>(), cmRhs);
VERIFY_TRSM_ONTHERIGHT(rmLhs.conjugate().template triangularView<UnitUpperTriangular>(), rmRhs);
}
void test_product_trsm()
void test_product_trsolve()
{
for(int i = 0; i < g_repeat ; i++)
{
CALL_SUBTEST_1((trsm<float>(ei_random<int>(1,320),ei_random<int>(1,320))));
CALL_SUBTEST_2((trsm<std::complex<double> >(ei_random<int>(1,320),ei_random<int>(1,320))));
// matrices
CALL_SUBTEST_1((trsolve<float,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320))));
CALL_SUBTEST_2((trsolve<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320))));
// vectors
CALL_SUBTEST_3((trsolve<std::complex<double>,Dynamic,1>(ei_random<int>(1,320))));
CALL_SUBTEST_4((trsolve<float,1,1>()));
CALL_SUBTEST_5((trsolve<float,1,2>()));
CALL_SUBTEST_6((trsolve<std::complex<float>,4,1>()));
}
}

View File

@@ -68,10 +68,10 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
minc = std::min(minc, ei_real(v[j]));
maxc = std::max(maxc, ei_real(v[j]));
}
VERIFY_IS_APPROX(s, v.start(i).sum());
VERIFY_IS_APPROX(p, v.start(i).prod());
VERIFY_IS_APPROX(minc, v.real().start(i).minCoeff());
VERIFY_IS_APPROX(maxc, v.real().start(i).maxCoeff());
VERIFY_IS_APPROX(s, v.head(i).sum());
VERIFY_IS_APPROX(p, v.head(i).prod());
VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff());
VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff());
}
for(int i = 0; i < size-1; i++)
@@ -85,10 +85,10 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
minc = std::min(minc, ei_real(v[j]));
maxc = std::max(maxc, ei_real(v[j]));
}
VERIFY_IS_APPROX(s, v.end(size-i).sum());
VERIFY_IS_APPROX(p, v.end(size-i).prod());
VERIFY_IS_APPROX(minc, v.real().end(size-i).minCoeff());
VERIFY_IS_APPROX(maxc, v.real().end(size-i).maxCoeff());
VERIFY_IS_APPROX(s, v.tail(size-i).sum());
VERIFY_IS_APPROX(p, v.tail(size-i).prod());
VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff());
VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff());
}
for(int i = 0; i < size/2; i++)

View File

@@ -51,7 +51,7 @@ void makeNoisyCohyperplanarPoints(int numPoints,
{
cur_point = VectorType::Random(size)/*.normalized()*/;
// project cur_point onto the hyperplane
Scalar x = - (hyperplane->coeffs().start(size).cwiseProduct(cur_point)).sum();
Scalar x = - (hyperplane->coeffs().head(size).cwiseProduct(cur_point)).sum();
cur_point *= hyperplane->coeffs().coeff(size) / x;
} while( cur_point.norm() < 0.5
|| cur_point.norm() > 2.0 );

View File

@@ -127,15 +127,15 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
if (rows>2)
{
// test sub vectors
VERIFY_IS_APPROX(v1.template start<2>(), v1.block(0,0,2,1));
VERIFY_IS_APPROX(v1.template start<2>(), v1.start(2));
VERIFY_IS_APPROX(v1.template start<2>(), v1.segment(0,2));
VERIFY_IS_APPROX(v1.template start<2>(), v1.template segment<2>(0));
VERIFY_IS_APPROX(v1.template head<2>(), v1.block(0,0,2,1));
VERIFY_IS_APPROX(v1.template head<2>(), v1.head(2));
VERIFY_IS_APPROX(v1.template head<2>(), v1.segment(0,2));
VERIFY_IS_APPROX(v1.template head<2>(), v1.template segment<2>(0));
int i = rows-2;
VERIFY_IS_APPROX(v1.template end<2>(), v1.block(i,0,2,1));
VERIFY_IS_APPROX(v1.template end<2>(), v1.end(2));
VERIFY_IS_APPROX(v1.template end<2>(), v1.segment(i,2));
VERIFY_IS_APPROX(v1.template end<2>(), v1.template segment<2>(i));
VERIFY_IS_APPROX(v1.template tail<2>(), v1.block(i,0,2,1));
VERIFY_IS_APPROX(v1.template tail<2>(), v1.tail(2));
VERIFY_IS_APPROX(v1.template tail<2>(), v1.segment(i,2));
VERIFY_IS_APPROX(v1.template tail<2>(), v1.template segment<2>(i));
i = ei_random(0,rows-2);
VERIFY_IS_APPROX(v1.segment(i,2), v1.template segment<2>(i));