aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
commiteaaba30cacf078335ad41314bf1e4ce993f0b3b4 (patch)
tree61156273b56dc19fc4e661a5aeb42d8e6112a307 /test
parente182e9c6166840b8db44e0be459a2e26d26fda0f (diff)
parenteeec7d842e05394703c42e7569230835f7842089 (diff)
merge with default branch
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt8
-rw-r--r--test/adjoint.cpp8
-rw-r--r--test/bandmatrix.cpp4
-rwxr-xr-xtest/buildtests.in21
-rw-r--r--test/cholesky.cpp4
-rw-r--r--test/eigensolver_complex.cpp1
-rw-r--r--test/geo_hyperplane.cpp2
-rw-r--r--test/geo_quaternion.cpp2
-rw-r--r--test/inverse.cpp19
-rw-r--r--test/jacobisvd.cpp3
-rw-r--r--test/lu.cpp17
-rw-r--r--test/main.h102
-rw-r--r--test/permutationmatrices.cpp35
-rw-r--r--test/prec_inverse_4x4.cpp80
-rw-r--r--test/product.h2
-rw-r--r--test/product_selfadjoint.cpp8
-rw-r--r--test/product_syrk.cpp12
-rw-r--r--test/product_trsm.cpp2
-rw-r--r--test/qr.cpp10
-rw-r--r--test/qr_colpivoting.cpp36
-rw-r--r--test/qr_fullpivoting.cpp5
-rwxr-xr-xtest/runtest.sh2
-rw-r--r--test/sparse_basic.cpp4
-rw-r--r--test/stable_norm.cpp8
-rw-r--r--test/testsuite.cmake8
-rw-r--r--test/triangular.cpp196
-rw-r--r--test/unalignedassert.cpp1
-rw-r--r--test/vectorization_logic.cpp55
28 files changed, 455 insertions, 200 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c6e282a0e..c29331db5 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,10 +3,6 @@ add_custom_target(buildtests)
add_custom_target(check COMMAND "ctest")
add_dependencies(check buildtests)
-
-include(EigenTesting)
-ei_init_testing()
-
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
find_package(GSL)
@@ -162,6 +158,8 @@ ei_add_test(conservative_resize)
ei_add_test(permutationmatrices)
ei_add_test(eigen2support)
+ei_add_test(prec_inverse_4x4)
+
ei_add_property(EIGEN_TESTING_SUMMARY "CXX: ${CMAKE_CXX_COMPILER}\n")
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -169,5 +167,3 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX)
ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")
ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags: ${SPARSE_LIBS}\n")
-
-configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests)
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 344399257..b34112249 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -128,6 +128,14 @@ void test_adjoint()
VERIFY_RAISES_ASSERT(a = a.adjoint());
VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
VERIFY_RAISES_ASSERT(a = b + a.adjoint());
+
+ // no assertion should be triggered for these cases:
+ a.transpose() = a.transpose();
+ a.transpose() += a.transpose();
+ a.transpose() += a.transpose() + b;
+ a.transpose() = a.adjoint();
+ a.transpose() += a.adjoint();
+ a.transpose() += a.adjoint() + b;
}
#endif
}
diff --git a/test/bandmatrix.cpp b/test/bandmatrix.cpp
index ecb7304db..e243dffe5 100644
--- a/test/bandmatrix.cpp
+++ b/test/bandmatrix.cpp
@@ -53,7 +53,7 @@ template<typename MatrixType> void bandmatrix(const MatrixType& _m)
dm1.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
}
//std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n";
- VERIFY_IS_APPROX(dm1,m.toDense());
+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
for (int i=0; i<cols; ++i)
{
@@ -68,7 +68,7 @@ template<typename MatrixType> void bandmatrix(const MatrixType& _m)
dm1.block(subs+1,0,rows-subs-1-b,rows-subs-1-b).template triangularView<LowerTriangular>().setZero();
if(b>0) dm1.block(d+subs,0,b,cols).setZero();
//std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n";
- VERIFY_IS_APPROX(dm1,m.toDense());
+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
}
diff --git a/test/buildtests.in b/test/buildtests.in
deleted file mode 100755
index 52cc66281..000000000
--- a/test/buildtests.in
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-if [ $# == 0 -o $# -ge 3 ]
-then
- echo "usage: ./buildtests regexp [jobs]"
- echo " makes tests matching the regexp, with <jobs> concurrent make jobs"
- exit 0
-fi
-
-TESTSLIST="${cmake_tests_list}"
-targets_to_make=`echo "$TESTSLIST" | grep "$1" | sed s/^/test_/g | xargs echo`
-
-if [ $# == 1 ]
-then
- make $targets_to_make
-fi
-
-if [ $# == 2 ]
-then
- make -j $2 $targets_to_make
-fi
diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index c3ef96752..c658b902c 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
{
LLT<SquareMatrixType,LowerTriangular> chollo(symmLo);
- VERIFY_IS_APPROX(symm, chollo.matrixL().toDense() * chollo.matrixL().adjoint().toDense());
+ VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
vecX = chollo.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = chollo.solve(matB);
@@ -103,7 +103,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
// test the upper mode
LLT<SquareMatrixType,UpperTriangular> cholup(symmUp);
- VERIFY_IS_APPROX(symm, cholup.matrixL().toDense() * cholup.matrixL().adjoint().toDense());
+ VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
vecX = cholup.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = cholup.solve(matB);
diff --git a/test/eigensolver_complex.cpp b/test/eigensolver_complex.cpp
index 11b7be5f7..fa052a9ae 100644
--- a/test/eigensolver_complex.cpp
+++ b/test/eigensolver_complex.cpp
@@ -60,5 +60,6 @@ void test_eigensolver_complex()
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
CALL_SUBTEST_2( eigensolver(MatrixXcd(14,14)) );
+ CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );
}
}
diff --git a/test/geo_hyperplane.cpp b/test/geo_hyperplane.cpp
index 3cf5655c2..1fd1e281a 100644
--- a/test/geo_hyperplane.cpp
+++ b/test/geo_hyperplane.cpp
@@ -64,7 +64,7 @@ template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)
// transform
if (!NumTraits<Scalar>::IsComplex)
{
- MatrixType rot = MatrixType::Random(dim,dim).householderQr().matrixQ();
+ MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
DiagonalMatrix<Scalar,HyperplaneType::AmbientDimAtCompileTime> scaling(VectorType::Random());
Translation<Scalar,HyperplaneType::AmbientDimAtCompileTime> translation(VectorType::Random());
diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp
index 19eb6e78c..a73ff19ec 100644
--- a/test/geo_quaternion.cpp
+++ b/test/geo_quaternion.cpp
@@ -43,7 +43,7 @@ template<typename Scalar> void quaternion(void)
if (ei_is_same_type<Scalar,float>::ret)
largeEps = 1e-3f;
- Scalar eps = ei_random<Scalar>() * 1e-2;
+ Scalar eps = ei_random<Scalar>() * Scalar(1e-2);
Vector3 v0 = Vector3::Random(),
v1 = Vector3::Random(),
diff --git a/test/inverse.cpp b/test/inverse.cpp
index 3ed61d356..b80e139e0 100644
--- a/test/inverse.cpp
+++ b/test/inverse.cpp
@@ -38,18 +38,11 @@ template<typename MatrixType> void inverse(const MatrixType& m)
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
- MatrixType m1 = MatrixType::Random(rows, cols),
+ MatrixType m1(rows, cols),
m2(rows, cols),
mzero = MatrixType::Zero(rows, cols),
identity = MatrixType::Identity(rows, rows);
-
- if (ei_is_same_type<RealScalar,float>::ret)
- {
- // let's build a more stable to inverse matrix
- MatrixType a = MatrixType::Random(rows,cols);
- m1 += m1 * m1.adjoint() + a * a.adjoint();
- }
-
+ createRandomMatrixOfRank(rows,rows,rows,m1);
m2 = m1.inverse();
VERIFY_IS_APPROX(m1, m2.inverse() );
@@ -104,12 +97,4 @@ void test_inverse()
s = ei_random<int>(25,100);
CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );
}
-
-#ifdef EIGEN_TEST_PART_4
- // test some tricky cases for 4x4 matrices
- VERIFY_IS_APPROX((Matrix4f() << 0,0,1,0, 1,0,0,0, 0,1,0,0, 0,0,0,1).finished().inverse(),
- (Matrix4f() << 0,1,0,0, 0,0,1,0, 1,0,0,0, 0,0,0,1).finished());
- VERIFY_IS_APPROX((Matrix4f() << 1,0,0,0, 0,0,1,0, 0,0,0,1, 0,1,0,0).finished().inverse(),
- (Matrix4f() << 1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,1,0).finished());
-#endif
}
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index f3a143e3c..587bc7572 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -54,6 +54,9 @@ template<typename MatrixType, unsigned int Options> void svd(const MatrixType& m
MatrixUType u = svd.matrixU();
MatrixVType v = svd.matrixV();
+ std::cout << "a\n" << a << std::endl;
+ std::cout << "b\n" << u * sigma * v.adjoint() << std::endl;
+
VERIFY_IS_APPROX(a, u * sigma * v.adjoint());
VERIFY_IS_UNITARY(u);
VERIFY_IS_UNITARY(v);
diff --git a/test/lu.cpp b/test/lu.cpp
index 9dcebbeaa..c2237febf 100644
--- a/test/lu.cpp
+++ b/test/lu.cpp
@@ -24,9 +24,11 @@
#include "main.h"
#include <Eigen/LU>
+using namespace std;
template<typename MatrixType> void lu_non_invertible()
{
+ typedef typename MatrixType::Scalar Scalar;
/* this test covers the following files:
LU.h
*/
@@ -65,7 +67,20 @@ template<typename MatrixType> void lu_non_invertible()
createRandomMatrixOfRank(rank, rows, cols, m1);
FullPivLU<MatrixType> lu(m1);
- std::cout << lu.kernel().rows() << " " << lu.kernel().cols() << std::endl;
+ // FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular.
+ DynamicMatrixType u(rows,cols);
+ for(int i = 0; i < rows; i++)
+ for(int j = 0; j < cols; j++)
+ u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j);
+ DynamicMatrixType l(rows,rows);
+ for(int i = 0; i < rows; i++)
+ for(int j = 0; j < rows; j++)
+ l(i,j) = (i<j || j>=cols) ? Scalar(0)
+ : i==j ? Scalar(1)
+ : lu.matrixLU()(i,j);
+
+ VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);
+
KernelMatrixType m1kernel = lu.kernel();
ImageMatrixType m1image = lu.image(m1);
diff --git a/test/main.h b/test/main.h
index 0b9b0bc4c..06c17a9ae 100644
--- a/test/main.h
+++ b/test/main.h
@@ -24,6 +24,7 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib>
+#include <cerrno>
#include <ctime>
#include <iostream>
#include <string>
@@ -49,6 +50,8 @@ namespace Eigen
{
static std::vector<std::string> g_test_stack;
static int g_repeat;
+ static unsigned int g_seed;
+ static bool g_has_set_repeat, g_has_set_seed;
}
#define EI_PP_MAKE_STRING2(S) #S
@@ -350,17 +353,30 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
typedef Matrix<Scalar, Rows, Rows> MatrixAType;
typedef Matrix<Scalar, Cols, Cols> MatrixBType;
+ if(desired_rank == 0)
+ {
+ m.setZero(rows,cols);
+ return;
+ }
+
+ if(desired_rank == 1)
+ {
+ m = VectorType::Random(rows) * VectorType::Random(cols).transpose();
+ return;
+ }
+
MatrixAType a = MatrixAType::Random(rows,rows);
MatrixType d = MatrixType::Identity(rows,cols);
MatrixBType b = MatrixBType::Random(cols,cols);
// set the diagonal such that only desired_rank non-zero entries reamain
const int diag_size = std::min(d.rows(),d.cols());
- d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
+ if(diag_size != desired_rank)
+ d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
HouseholderQR<MatrixAType> qra(a);
HouseholderQR<MatrixBType> qrb(b);
- m = qra.matrixQ() * d * qrb.matrixQ();
+ m = qra.householderQ() * d * qrb.householderQ();
}
} // end namespace Eigen
@@ -372,51 +388,68 @@ template<> struct GetDifferentType<double> { typedef float type; };
template<typename T> struct GetDifferentType<std::complex<T> >
{ typedef std::complex<typename GetDifferentType<T>::type> type; };
+template<typename T> std::string type_name() { return "other"; }
+template<> std::string type_name<float>() { return "float"; }
+template<> std::string type_name<double>() { return "double"; }
+template<> std::string type_name<int>() { return "int"; }
+template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
+template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
+template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
+
// forward declaration of the main test function
void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
using namespace Eigen;
+void set_repeat_from_string(const char *str)
+{
+ errno = 0;
+ g_repeat = int(strtoul(str, 0, 10));
+ if(errno || g_repeat <= 0)
+ {
+ std::cout << "Invalid repeat value " << str << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ g_has_set_repeat = true;
+}
+
+void set_seed_from_string(const char *str)
+{
+ errno = 0;
+ g_seed = strtoul(str, 0, 10);
+ if(errno || g_seed == 0)
+ {
+ std::cout << "Invalid seed value " << str << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ g_has_set_seed = true;
+}
+
int main(int argc, char *argv[])
{
- bool has_set_repeat = false;
- bool has_set_seed = false;
+ g_has_set_repeat = false;
+ g_has_set_seed = false;
bool need_help = false;
- unsigned int seed = 0;
- int repeat = DEFAULT_REPEAT;
for(int i = 1; i < argc; i++)
{
if(argv[i][0] == 'r')
{
- if(has_set_repeat)
+ if(g_has_set_repeat)
{
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
- repeat = atoi(argv[i]+1);
- has_set_repeat = true;
- if(repeat <= 0)
- {
- std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;
- return 1;
- }
+ set_repeat_from_string(argv[i]+1);
}
else if(argv[i][0] == 's')
{
- if(has_set_seed)
+ if(g_has_set_seed)
{
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
- seed = int(strtoul(argv[i]+1, 0, 10));
- has_set_seed = true;
- bool ok = seed!=0;
- if(!ok)
- {
- std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;
- return 1;
- }
+ set_seed_from_string(argv[i]+1);
}
else
{
@@ -429,22 +462,29 @@ int main(int argc, char *argv[])
std::cout << "This test application takes the following optional arguments:" << std::endl;
std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;
+ std::cout << std::endl;
+ std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
+ std::cout << "will be used as default values for these parameters." << std::endl;
return 1;
}
- if(!has_set_seed) seed = (unsigned int) time(NULL);
- if(!has_set_repeat) repeat = DEFAULT_REPEAT;
+ char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
+ if(!g_has_set_repeat && env_EIGEN_REPEAT)
+ set_repeat_from_string(env_EIGEN_REPEAT);
+ char *env_EIGEN_SEED = getenv("EIGEN_SEED");
+ if(!g_has_set_seed && env_EIGEN_SEED)
+ set_seed_from_string(env_EIGEN_SEED);
- std::cout << "Initializing random number generator with seed " << seed << std::endl;
- srand(seed);
- std::cout << "Repeating each test " << repeat << " times" << std::endl;
+ if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
+ if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
+
+ std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
+ srand(g_seed);
+ std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
- Eigen::g_repeat = repeat;
Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
return 0;
}
-
-
diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp
index 13b01cd83..0ef0a371a 100644
--- a/test/permutationmatrices.cpp
+++ b/test/permutationmatrices.cpp
@@ -66,12 +66,45 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
for (int i=0; i<rows; i++)
for (int j=0; j<cols; j++)
- VERIFY_IS_APPROX(m_original(lv(i),j), m_permuted(i,rv(j)));
+ VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));
Matrix<Scalar,Rows,Rows> lm(lp);
Matrix<Scalar,Cols,Cols> rm(rp);
VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
+
+ VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
+ VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
+
+ LeftPermutationVectorType lv2;
+ randomPermutationVector(lv2, rows);
+ LeftPermutationType lp2(lv2);
+ Matrix<Scalar,Rows,Rows> lm2(lp2);
+ VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
+
+ LeftPermutationType identityp;
+ identityp.setIdentity(rows);
+ VERIFY_IS_APPROX(m_original, identityp*m_original);
+
+ if(rows>1 && cols>1)
+ {
+ lp2 = lp;
+ int i = ei_random<int>(0, rows-1);
+ int j;
+ do j = ei_random<int>(0, rows-1); while(j==i);
+ lp2.applyTranspositionOnTheLeft(i, j);
+ lm = lp;
+ lm.row(i).swap(lm.row(j));
+ VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());
+
+ RightPermutationType rp2 = rp;
+ i = ei_random<int>(0, cols-1);
+ do j = ei_random<int>(0, cols-1); while(j==i);
+ rp2.applyTranspositionOnTheRight(i, j);
+ rm = rp;
+ rm.col(i).swap(rm.col(j));
+ VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
+ }
}
void test_permutationmatrices()
diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
new file mode 100644
index 000000000..e1b05aa0d
--- /dev/null
+++ b/test/prec_inverse_4x4.cpp
@@ -0,0 +1,80 @@
+// 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"
+#include <Eigen/LU>
+#include <algorithm>
+
+template<typename MatrixType> void inverse_permutation_4x4()
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ Vector4i indices(0,1,2,3);
+ for(int i = 0; i < 24; ++i)
+ {
+ MatrixType m = PermutationMatrix<4>(indices);
+ MatrixType inv = m.inverse();
+ double error = double( (m*inv-MatrixType::Identity()).norm() / epsilon<Scalar>() );
+ VERIFY(error == 0.0);
+ std::next_permutation(indices.data(),indices.data()+4);
+ }
+}
+
+template<typename MatrixType> void inverse_general_4x4(int repeat)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ double error_sum = 0., error_max = 0.;
+ for(int i = 0; i < repeat; ++i)
+ {
+ MatrixType m;
+ RealScalar absdet;
+ do {
+ m = MatrixType::Random();
+ absdet = ei_abs(m.determinant());
+ } while(absdet < epsilon<Scalar>());
+ MatrixType inv = m.inverse();
+ double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon<Scalar>() );
+ error_sum += error;
+ error_max = std::max(error_max, error);
+ }
+ std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;
+ double error_avg = error_sum / repeat;
+ EIGEN_DEBUG_VAR(error_avg);
+ EIGEN_DEBUG_VAR(error_max);
+ VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.0));
+ VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));
+}
+
+void test_prec_inverse_4x4()
+{
+ CALL_SUBTEST_1((inverse_permutation_4x4<Matrix4f>()));
+ CALL_SUBTEST_1(( inverse_general_4x4<Matrix4f>(200000 * g_repeat) ));
+
+ CALL_SUBTEST_2((inverse_permutation_4x4<Matrix<double,4,4,RowMajor> >()));
+ CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,RowMajor> >(200000 * g_repeat) ));
+
+ CALL_SUBTEST_3((inverse_permutation_4x4<Matrix4cf>()));
+ CALL_SUBTEST_3((inverse_general_4x4<Matrix4cf>(50000 * g_repeat)));
+}
diff --git a/test/product.h b/test/product.h
index 1dcc636e3..c389c33ed 100644
--- a/test/product.h
+++ b/test/product.h
@@ -27,7 +27,7 @@
#include <Eigen/QR>
template<typename Derived1, typename Derived2>
-bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = precision<typename Derived1::RealScalar>())
+bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = dummy_precision<typename Derived1::RealScalar>())
{
return !((m1-m2).cwiseAbs2().maxCoeff() < epsilon * epsilon
* std::max(m1.cwiseAbs2().maxCoeff(), m2.cwiseAbs2().maxCoeff()));
diff --git a/test/product_selfadjoint.cpp b/test/product_selfadjoint.cpp
index aa8da37bd..2e9f8be80 100644
--- a/test/product_selfadjoint.cpp
+++ b/test/product_selfadjoint.cpp
@@ -55,15 +55,15 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
// rank2 update
m2 = m1.template triangularView<LowerTriangular>();
m2.template selfadjointView<LowerTriangular>().rankUpdate(v1,v2);
- VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<LowerTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<LowerTriangular>().toDenseMatrix());
m2 = m1.template triangularView<UpperTriangular>();
m2.template selfadjointView<UpperTriangular>().rankUpdate(-v1,s2*v2,s3);
- VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView<UpperTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView<UpperTriangular>().toDenseMatrix());
m2 = m1.template triangularView<UpperTriangular>();
m2.template selfadjointView<UpperTriangular>().rankUpdate(-r1.adjoint(),r2.adjoint()*s3,s1);
- VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView<UpperTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView<UpperTriangular>().toDenseMatrix());
if (rows>1)
{
@@ -71,7 +71,7 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rankUpdate(v1.end(rows-1),v2.start(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();
- VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDenseMatrix());
}
}
diff --git a/test/product_syrk.cpp b/test/product_syrk.cpp
index 37d54bf16..9f6aec0e2 100644
--- a/test/product_syrk.cpp
+++ b/test/product_syrk.cpp
@@ -46,27 +46,27 @@ template<typename MatrixType> void syrk(const MatrixType& m)
m2.setZero();
VERIFY_IS_APPROX((m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs2,s1)._expression()),
- ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<LowerTriangular>().toDense()));
+ ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<LowerTriangular>().toDenseMatrix()));
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs2,s1)._expression(),
- (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<UpperTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
- (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<LowerTriangular>().toDense());
+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<LowerTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
- (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<UpperTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
- (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<LowerTriangular>().toDense());
+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<LowerTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
- (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<UpperTriangular>().toDenseMatrix());
}
void test_product_syrk()
diff --git a/test/product_trsm.cpp b/test/product_trsm.cpp
index 6c5ca274a..e884f3180 100644
--- a/test/product_trsm.cpp
+++ b/test/product_trsm.cpp
@@ -27,7 +27,7 @@
#define VERIFY_TRSM(TRI,XB) { \
(XB).setRandom(); ref = (XB); \
(TRI).solveInPlace(XB); \
- VERIFY_IS_APPROX((TRI).toDense() * (XB), ref); \
+ VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
}
template<typename Scalar> void trsm(int size,int cols)
diff --git a/test/qr.cpp b/test/qr.cpp
index 90b5c4446..3848ce0a5 100644
--- a/test/qr.cpp
+++ b/test/qr.cpp
@@ -38,13 +38,13 @@ template<typename MatrixType> void qr(const MatrixType& m)
HouseholderQR<MatrixType> qrOfA(a);
MatrixType r = qrOfA.matrixQR();
- MatrixQType q = qrOfA.matrixQ();
+ MatrixQType q = qrOfA.householderQ();
VERIFY_IS_UNITARY(q);
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- VERIFY_IS_APPROX(a, qrOfA.matrixQ() * r);
+ VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);
}
template<typename MatrixType, int Cols2> void qr_fixedsize()
@@ -58,7 +58,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
// FIXME need better way to construct trapezoid
for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
- VERIFY_IS_APPROX(m1, qr.matrixQ() * r);
+ VERIFY_IS_APPROX(m1, qr.householderQ() * r);
Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
@@ -93,7 +93,7 @@ template<typename MatrixType> void qr_invertible()
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
RealScalar absdet = ei_abs(m1.diagonal().prod());
- m3 = qr.matrixQ(); // get a unitary
+ m3 = qr.householderQ(); // get a unitary
m1 = m3 * m1 * m3;
qr.compute(m1);
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -107,7 +107,7 @@ template<typename MatrixType> void qr_verify_assert()
HouseholderQR<MatrixType> qr;
VERIFY_RAISES_ASSERT(qr.matrixQR())
VERIFY_RAISES_ASSERT(qr.solve(tmp))
- VERIFY_RAISES_ASSERT(qr.matrixQ())
+ VERIFY_RAISES_ASSERT(qr.householderQ())
VERIFY_RAISES_ASSERT(qr.absDeterminant())
VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
}
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 763c12067..8b56cd296 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -28,10 +28,11 @@
template<typename MatrixType> void qr()
{
- int rows = ei_random<int>(20,200), cols = ei_random<int>(20,200), cols2 = ei_random<int>(20,200);
+ int rows = ei_random<int>(2,200), cols = ei_random<int>(2,200), cols2 = ei_random<int>(2,200);
int rank = ei_random<int>(1, std::min(rows, cols)-1);
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
MatrixType m1;
@@ -43,19 +44,11 @@ template<typename MatrixType> void qr()
VERIFY(!qr.isInvertible());
VERIFY(!qr.isSurjective());
- MatrixType r = qr.matrixQR();
-
- MatrixQType q = qr.matrixQ();
+ MatrixQType q = qr.householderQ();
VERIFY_IS_UNITARY(q);
-
- // FIXME need better way to construct trapezoid
- for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- MatrixType b = qr.matrixQ() * r;
-
- MatrixType c = MatrixType::Zero(rows,cols);
-
- for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
+ MatrixType r = qr.matrixQR().template triangularView<UpperTriangular>();
+ MatrixType c = q * r * qr.colsPermutation().inverse();
VERIFY_IS_APPROX(m1, c);
MatrixType m2 = MatrixType::Random(cols,cols2);
@@ -79,15 +72,8 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
VERIFY(!qr.isInvertible());
VERIFY(!qr.isSurjective());
- Matrix<Scalar,Rows,Cols> r = qr.matrixQR();
- // FIXME need better way to construct trapezoid
- for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
-
- Matrix<Scalar,Rows,Cols> b = qr.matrixQ() * r;
-
- Matrix<Scalar,Rows,Cols> c = MatrixType::Zero(Rows,Cols);
-
- for(int i = 0; i < Cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
+ Matrix<Scalar,Rows,Cols> r = qr.matrixQR().template triangularView<UpperTriangular>();
+ Matrix<Scalar,Rows,Cols> c = qr.householderQ() * r * qr.colsPermutation().inverse();
VERIFY_IS_APPROX(m1, c);
Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
@@ -117,13 +103,13 @@ template<typename MatrixType> void qr_invertible()
ColPivHouseholderQR<MatrixType> qr(m1);
m3 = MatrixType::Random(size,size);
m2 = qr.solve(m3);
- VERIFY_IS_APPROX(m3, m1*m2);
+ //VERIFY_IS_APPROX(m3, m1*m2);
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
RealScalar absdet = ei_abs(m1.diagonal().prod());
- m3 = qr.matrixQ(); // get a unitary
+ m3 = qr.householderQ(); // get a unitary
m1 = m3 * m1 * m3;
qr.compute(m1);
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -137,7 +123,7 @@ template<typename MatrixType> void qr_verify_assert()
ColPivHouseholderQR<MatrixType> qr;
VERIFY_RAISES_ASSERT(qr.matrixQR())
VERIFY_RAISES_ASSERT(qr.solve(tmp))
- VERIFY_RAISES_ASSERT(qr.matrixQ())
+ VERIFY_RAISES_ASSERT(qr.householderQ())
VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())
VERIFY_RAISES_ASSERT(qr.isInjective())
VERIFY_RAISES_ASSERT(qr.isSurjective())
@@ -149,7 +135,7 @@ template<typename MatrixType> void qr_verify_assert()
void test_qr_colpivoting()
{
- for(int i = 0; i < 1; i++) {
+ for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( qr<MatrixXf>() );
CALL_SUBTEST_2( qr<MatrixXd>() );
CALL_SUBTEST_3( qr<MatrixXcd>() );
diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp
index 65d9a071f..c82ba4c7e 100644
--- a/test/qr_fullpivoting.cpp
+++ b/test/qr_fullpivoting.cpp
@@ -51,11 +51,8 @@ template<typename MatrixType> void qr()
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- MatrixType b = qr.matrixQ() * r;
+ MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse();
- MatrixType c = MatrixType::Zero(rows,cols);
-
- for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
VERIFY_IS_APPROX(m1, c);
MatrixType m2 = MatrixType::Random(cols,cols2);
diff --git a/test/runtest.sh b/test/runtest.sh
index 31d1ca654..2be250819 100755
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -9,7 +9,7 @@ magenta='\E[35m'
cyan='\E[36m'
white='\E[37m'
-if ! ./test_$1 > /dev/null 2> .runtest.log ; then
+if ! ./$1 > /dev/null 2> .runtest.log ; then
echo -e $red Test $1 failed: $black
echo -e $blue
cat .runtest.log
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index dd3245fb1..9de156d38 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -34,7 +34,7 @@ bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref,
std::vector<Vector2i> remaining = nonzeroCoords;
while(!remaining.empty())
{
- int i = ei_random<int>(0,remaining.size()-1);
+ int i = ei_random<int>(0,static_cast<int>(remaining.size())-1);
w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
remaining[i] = remaining.back();
remaining.pop_back();
@@ -50,7 +50,7 @@ bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const
std::vector<Vector2i> remaining = nonzeroCoords;
while(!remaining.empty())
{
- int i = ei_random<int>(0,remaining.size()-1);
+ int i = ei_random<int>(0,static_cast<int>(remaining.size())-1);
sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
remaining[i] = remaining.back();
remaining.pop_back();
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
index 7661fc893..10531dc5d 100644
--- a/test/stable_norm.cpp
+++ b/test/stable_norm.cpp
@@ -79,6 +79,14 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.stableNorm()), ei_sqrt(size)*small);
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.blueNorm()), ei_sqrt(size)*small);
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.hypotNorm()), ei_sqrt(size)*small);
+
+// Test compilation of cwise() version
+ VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.colwise().blueNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.colwise().hypotNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());
}
void test_stable_norm()
diff --git a/test/testsuite.cmake b/test/testsuite.cmake
index 9c38e48b1..90edf2853 100644
--- a/test/testsuite.cmake
+++ b/test/testsuite.cmake
@@ -4,7 +4,7 @@
# Usage:
# - create a new folder, let's call it cdash
# - in that folder, do:
-# ctest -S path/to/eigen2/test/testsuite.cmake[,option1=value1[,option2=value2]]
+# ctest -S path/to/eigen/test/testsuite.cmake[,option1=value1[,option2=value2]]
#
# Options:
# - EIGEN_CXX: compiler, eg.: g++-4.2
@@ -44,9 +44,9 @@
# ARCH=`uname -m`
# SITE=`hostname`
# VERSION=opensuse-11.1
-# WORK_DIR=/home/gael/Coding/eigen2/cdash
+# WORK_DIR=/home/gael/Coding/eigen/cdash
# # get the last version of the script
-# wget http://bitbucket.org/eigen/eigen2/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
+# wget http://bitbucket.org/eigen/eigen/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
# COMMON="ctest -S $WORK_DIR/testsuite.cmake,EIGEN_WORK_DIR=$WORK_DIR,EIGEN_SITE=$SITE,EIGEN_MODE=$1,EIGEN_BUILD_STRING=$OS_VERSION-$ARCH"
# $COMMON-gcc-3.4.6,EIGEN_CXX=g++-3.4
# $COMMON-gcc-4.0.1,EIGEN_CXX=g++-4.0.1
@@ -141,7 +141,7 @@ endif(NOT EIGEN_MODE)
if(NOT EIGEN_NO_UPDATE)
SET (CTEST_CVS_COMMAND "hg")
- SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen2 \"${CTEST_SOURCE_DIRECTORY}\"")
+ SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen \"${CTEST_SOURCE_DIRECTORY}\"")
SET(CTEST_BACKUP_AND_RESTORE TRUE) # the backup is CVS related ...
endif(NOT EIGEN_NO_UPDATE)
diff --git a/test/triangular.cpp b/test/triangular.cpp
index 2a583710d..111774b75 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -24,7 +24,9 @@
#include "main.h"
-template<typename MatrixType> void triangular(const MatrixType& m)
+
+
+template<typename MatrixType> void triangular_square(const MatrixType& m)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
@@ -51,8 +53,8 @@ template<typename MatrixType> void triangular(const MatrixType& m)
v2 = VectorType::Random(rows),
vzero = VectorType::Zero(rows);
- MatrixType m1up = m1.template triangularView<Eigen::UpperTriangular>();
- MatrixType m2up = m2.template triangularView<Eigen::UpperTriangular>();
+ MatrixType m1up = m1.template triangularView<UpperTriangular>();
+ MatrixType m2up = m2.template triangularView<UpperTriangular>();
if (rows*cols>1)
{
@@ -66,83 +68,197 @@ template<typename MatrixType> void triangular(const MatrixType& m)
// test overloaded operator+=
r1.setZero();
r2.setZero();
- r1.template triangularView<Eigen::UpperTriangular>() += m1;
+ r1.template triangularView<UpperTriangular>() += m1;
r2 += m1up;
VERIFY_IS_APPROX(r1,r2);
// test overloaded operator=
m1.setZero();
- m1.template triangularView<Eigen::UpperTriangular>() = m2.transpose() + m2;
+ m1.template triangularView<UpperTriangular>() = m2.transpose() + m2;
m3 = m2.transpose() + m2;
- VERIFY_IS_APPROX(m3.template triangularView<Eigen::LowerTriangular>().transpose().toDense(), m1);
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().transpose().toDenseMatrix(), m1);
// test overloaded operator=
m1.setZero();
- m1.template triangularView<Eigen::LowerTriangular>() = m2.transpose() + m2;
- VERIFY_IS_APPROX(m3.template triangularView<Eigen::LowerTriangular>().toDense(), m1);
+ m1.template triangularView<LowerTriangular>() = m2.transpose() + m2;
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().toDenseMatrix(), m1);
m1 = MatrixType::Random(rows, cols);
for (int i=0; i<rows; ++i)
- while (ei_abs2(m1(i,i))<1e-3) m1(i,i) = ei_random<Scalar>();
+ while (ei_abs2(m1(i,i))<1e-1) m1(i,i) = ei_random<Scalar>();
Transpose<MatrixType> trm4(m4);
// test back and forward subsitution with a vector as the rhs
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Eigen::LowerTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Eigen::UpperTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(v2.isApprox(m3 * (m1.template triangularView<Eigen::UpperTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Eigen::LowerTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<LowerTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<UpperTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(v2.isApprox(m3 * (m1.template triangularView<UpperTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<LowerTriangular>().solve(v2)), largerEps));
// test back and forward subsitution with a matrix as the rhs
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Eigen::LowerTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Eigen::UpperTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(m2.isApprox(m3 * (m1.template triangularView<Eigen::UpperTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Eigen::LowerTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<LowerTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<UpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<UpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<LowerTriangular>().solve(m2)), largerEps));
// check M * inv(L) using in place API
m4 = m3;
+<<<<<<< local
m3.transpose().template triangularView<Eigen::UpperTriangular>().solveInPlace(trm4);
VERIFY(m4.cwiseAbs().isIdentity(test_precision<RealScalar>()));
+=======
+ m3.transpose().template triangularView<UpperTriangular>().solveInPlace(trm4);
+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
+>>>>>>> other
// check M * inv(U) using in place API
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
+ m3 = m1.template triangularView<UpperTriangular>();
m4 = m3;
+<<<<<<< local
m3.transpose().template triangularView<Eigen::LowerTriangular>().solveInPlace(trm4);
VERIFY(m4.cwiseAbs().isIdentity(test_precision<RealScalar>()));
+=======
+ m3.transpose().template triangularView<LowerTriangular>().solveInPlace(trm4);
+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
+>>>>>>> other
// check solve with unit diagonal
- m3 = m1.template triangularView<Eigen::UnitUpperTriangular>();
- VERIFY(m2.isApprox(m3 * (m1.template triangularView<Eigen::UnitUpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UnitUpperTriangular>();
+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<UnitUpperTriangular>().solve(m2)), largerEps));
-// VERIFY(( m1.template triangularView<Eigen::UpperTriangular>()
-// * m2.template triangularView<Eigen::UpperTriangular>()).isUpperTriangular());
+// VERIFY(( m1.template triangularView<UpperTriangular>()
+// * m2.template triangularView<UpperTriangular>()).isUpperTriangular());
// test swap
m1.setOnes();
m2.setZero();
- m2.template triangularView<Eigen::UpperTriangular>().swap(m1);
+ m2.template triangularView<UpperTriangular>().swap(m1);
m3.setZero();
- m3.template triangularView<Eigen::UpperTriangular>().setOnes();
+ m3.template triangularView<UpperTriangular>().setOnes();
VERIFY_IS_APPROX(m2,m3);
}
+
+template<typename MatrixType> void triangular_rect(const MatrixType& m)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
+ typedef Matrix<Scalar, Rows, 1> VectorType;
+ typedef Matrix<Scalar, Rows, Rows> RMatrixType;
+
+
+ int rows = m.rows();
+ int cols = m.cols();
+
+ MatrixType m1 = MatrixType::Random(rows, cols),
+ m2 = MatrixType::Random(rows, cols),
+ m3(rows, cols),
+ m4(rows, cols),
+ r1(rows, cols),
+ r2(rows, cols),
+ mzero = MatrixType::Zero(rows, cols),
+ mones = MatrixType::Ones(rows, cols);
+ RMatrixType identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
+ ::Identity(rows, rows),
+ square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
+ ::Random(rows, rows);
+ VectorType v1 = VectorType::Random(rows),
+ v2 = VectorType::Random(rows),
+ vzero = VectorType::Zero(rows);
+
+ MatrixType m1up = m1.template triangularView<UpperTriangular>();
+ MatrixType m2up = m2.template triangularView<UpperTriangular>();
+
+ if (rows*cols>1)
+ {
+ VERIFY(m1up.isUpperTriangular());
+ VERIFY(m2up.transpose().isLowerTriangular());
+ VERIFY(!m2.isLowerTriangular());
+ }
+
+ // test overloaded operator+=
+ r1.setZero();
+ r2.setZero();
+ r1.template triangularView<UpperTriangular>() += m1;
+ r2 += m1up;
+ VERIFY_IS_APPROX(r1,r2);
+
+ // test overloaded operator=
+ m1.setZero();
+ m1.template triangularView<UpperTriangular>() = 3 * m2;
+ m3 = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<UpperTriangular>().toDenseMatrix(), m1);
+
+
+ m1.setZero();
+ m1.template triangularView<LowerTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().toDenseMatrix(), m1);
+
+ m1.setZero();
+ m1.template triangularView<StrictlyUpperTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyUpperTriangular>().toDenseMatrix(), m1);
+
+
+ m1.setZero();
+ m1.template triangularView<StrictlyLowerTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyLowerTriangular>().toDenseMatrix(), m1);
+ m1.setRandom();
+ m2 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ VERIFY(!m2.isLowerTriangular());
+ m2 = m1.template triangularView<StrictlyUpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<UnitUpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ m2.diagonal().cwise() -= Scalar(1);
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ VERIFY(!m2.isUpperTriangular());
+ m2 = m1.template triangularView<StrictlyLowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<UnitLowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ m2.diagonal().cwise() -= Scalar(1);
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ // test swap
+ m1.setOnes();
+ m2.setZero();
+ m2.template triangularView<UpperTriangular>().swap(m1);
+ m3.setZero();
+ m3.template triangularView<UpperTriangular>().setOnes();
+ VERIFY_IS_APPROX(m2,m3);
+}
+
void test_triangular()
{
- for(int i = 0; i < g_repeat ; i++) {
- CALL_SUBTEST_1( triangular(Matrix<float, 1, 1>()) );
- CALL_SUBTEST_2( triangular(Matrix<float, 2, 2>()) );
- CALL_SUBTEST_3( triangular(Matrix3d()) );
- CALL_SUBTEST_4( triangular(MatrixXcf(4, 4)) );
- CALL_SUBTEST_5( triangular(Matrix<std::complex<float>,8, 8>()) );
- CALL_SUBTEST_6( triangular(MatrixXcd(17,17)) );
- CALL_SUBTEST_7( triangular(Matrix<float,Dynamic,Dynamic,RowMajor>(5, 5)) );
+ for(int i = 0; i < g_repeat ; i++)
+ {
+ EIGEN_UNUSED int r = ei_random<int>(2,20);
+ EIGEN_UNUSED int c = ei_random<int>(2,20);
+
+ CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );
+ CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );
+ CALL_SUBTEST_3( triangular_square(Matrix3d()) );
+ CALL_SUBTEST_4( triangular_square(Matrix<std::complex<float>,8, 8>()) );
+ CALL_SUBTEST_5( triangular_square(MatrixXcd(r,r)) );
+ CALL_SUBTEST_6( triangular_square(Matrix<float,Dynamic,Dynamic,RowMajor>(r, r)) );
+
+ CALL_SUBTEST_7( triangular_rect(Matrix<float, 4, 5>()) );
+ CALL_SUBTEST_8( triangular_rect(Matrix<double, 6, 2>()) );
+ CALL_SUBTEST_9( triangular_rect(MatrixXcf(r, c)) );
+ CALL_SUBTEST_5( triangular_rect(MatrixXcd(r, c)) );
+ CALL_SUBTEST_6( triangular_rect(Matrix<float,Dynamic,Dynamic,RowMajor>(r, c)) );
}
}
diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp
index 2b819417e..85a83b7b5 100644
--- a/test/unalignedassert.cpp
+++ b/test/unalignedassert.cpp
@@ -87,6 +87,7 @@ void construct_at_boundary(int boundary)
_buf += (16 - (_buf % 16)); // make 16-byte aligned
_buf += boundary; // make exact boundary-aligned
T *x = ::new(reinterpret_cast<void*>(_buf)) T;
+ x[0].setZero(); // just in order to silence warnings
x->~T();
}
#endif
diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp
index 71214485c..5d86df7b3 100644
--- a/test/vectorization_logic.cpp
+++ b/test/vectorization_logic.cpp
@@ -26,17 +26,18 @@
#include <typeinfo>
template<typename Dst, typename Src>
-bool test_assign(const Dst&, const Src&, int vectorization, int unrolling)
+bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
{
- return ei_assign_traits<Dst,Src>::Vectorization==vectorization
+ ei_assign_traits<Dst,Src>::debug();
+ return ei_assign_traits<Dst,Src>::Traversal==traversal
&& ei_assign_traits<Dst,Src>::Unrolling==unrolling;
}
template<typename Xpr>
-bool test_redux(const Xpr&, int vectorization, int unrolling)
+bool test_redux(const Xpr&, int traversal, int unrolling)
{
typedef ei_redux_traits<ei_scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;
- return traits::Vectorization==vectorization && traits::Unrolling==unrolling;
+ return traits::Traversal==traversal && traits::Unrolling==unrolling;
}
void test_vectorization_logic()
@@ -45,61 +46,67 @@ void test_vectorization_logic()
#ifdef EIGEN_VECTORIZE
VERIFY(test_assign(Vector4f(),Vector4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cwiseProduct(Vector4f()),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cast<float>(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f()+Matrix4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f().cwiseProduct(Matrix4f()),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,16,16>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
- InnerVectorization,InnerUnrolling));
+ InnerVectorizedTraversal,InnerUnrolling));
VERIFY(test_assign(Matrix<float,16,16,DontAlign>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
- NoVectorization,InnerUnrolling));
+ LinearTraversal,NoUnrolling));
+
+ VERIFY(test_assign(Matrix<float,2,2,DontAlign>(),Matrix<float,2,2>()+Matrix<float,2,2>(),
+ LinearTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,6,2>(),Matrix<float,6,2>().cwiseQuotient(Matrix<float,6,2>()),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,17,17>(),Matrix<float,17,17>()+Matrix<float,17,17>(),
- NoVectorization,InnerUnrolling));
+ LinearTraversal,NoUnrolling));
+
+ VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
+ LinearTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,4,4>(),Matrix<float,17,17>().block<4,4>(2,3)+Matrix<float,17,17>().block<4,4>(10,4),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
- SliceVectorization,NoUnrolling));
+ SliceVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(VectorXf(10),
- LinearVectorization,NoUnrolling));
+ LinearVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(Matrix<float,5,2>(),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,6,2>(),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,16,16>(),
- LinearVectorization,NoUnrolling));
+ LinearVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(Matrix<float,16,16>().block<4,4>(1,2),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,16,16>().block<8,1>(1,2),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<double,7,3>(),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
#endif // EIGEN_VECTORIZE