mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge
This commit is contained in:
@@ -104,16 +104,18 @@ ei_add_test(cwiseop)
|
||||
ei_add_test(unalignedcount)
|
||||
ei_add_test(redux)
|
||||
ei_add_test(visitor)
|
||||
ei_add_test(block)
|
||||
ei_add_test(product_small)
|
||||
ei_add_test(product_large)
|
||||
ei_add_test(product_extra)
|
||||
ei_add_test(diagonalmatrices)
|
||||
ei_add_test(adjoint)
|
||||
ei_add_test(submatrices)
|
||||
ei_add_test(diagonal)
|
||||
ei_add_test(miscmatrices)
|
||||
ei_add_test(commainitializer)
|
||||
ei_add_test(smallvectors)
|
||||
ei_add_test(map)
|
||||
ei_add_test(mapstride)
|
||||
ei_add_test(array)
|
||||
ei_add_test(array_for_matrix)
|
||||
ei_add_test(array_replicate)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2006-2010 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
|
||||
@@ -51,16 +51,18 @@ template<typename Scalar> struct CheckMinor<Scalar,1,1>
|
||||
CheckMinor(MatrixType&, int, int) {}
|
||||
};
|
||||
|
||||
template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
template<typename MatrixType> void block(const MatrixType& m)
|
||||
{
|
||||
/* this test covers the following files:
|
||||
Row.h Column.h Block.h Minor.h DiagonalCoeffs.h
|
||||
Row.h Column.h Block.h Minor.h
|
||||
*/
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
||||
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
|
||||
typedef Matrix<Scalar, Dynamic, Dynamic> DynamicMatrixType;
|
||||
typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType;
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
@@ -69,8 +71,6 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
m3(rows, cols),
|
||||
mzero = MatrixType::Zero(rows, cols),
|
||||
ones = MatrixType::Ones(rows, cols);
|
||||
SquareMatrixType identity = SquareMatrixType::Identity(rows, rows),
|
||||
square = SquareMatrixType::Random(rows, rows);
|
||||
VectorType v1 = VectorType::Random(rows),
|
||||
v2 = VectorType::Random(rows),
|
||||
v3 = VectorType::Random(rows),
|
||||
@@ -84,20 +84,19 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
int c2 = ei_random<int>(c1,cols-1);
|
||||
|
||||
//check row() and col()
|
||||
VERIFY_IS_APPROX(m1.col(c1).transpose(), m1.transpose().row(c1));
|
||||
// FIXME perhaps we should re-enable that without the .eval()
|
||||
VERIFY_IS_APPROX(m1.col(c1).dot(square.row(r1)), (square * m1.conjugate()).eval()(r1,c1));
|
||||
VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1));
|
||||
//check operator(), both constant and non-constant, on row() and col()
|
||||
m1.row(r1) += s1 * m1.row(r2);
|
||||
m1.col(c1) += s1 * m1.col(c2);
|
||||
|
||||
//check block()
|
||||
Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
|
||||
|
||||
RowVectorType br1(m1.block(r1,0,1,cols));
|
||||
VectorType bc1(m1.block(0,c1,rows,1));
|
||||
VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1));
|
||||
VERIFY_IS_APPROX(m1.row(r1), br1);
|
||||
VERIFY_IS_APPROX(m1.col(c1), bc1);
|
||||
VERIFY_IS_EQUAL(b1, m1.block(r1,c1,1,1));
|
||||
VERIFY_IS_EQUAL(m1.row(r1), br1);
|
||||
VERIFY_IS_EQUAL(m1.col(c1), bc1);
|
||||
//check operator(), both constant and non-constant, on block()
|
||||
m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);
|
||||
m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);
|
||||
@@ -105,11 +104,6 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
//check minor()
|
||||
CheckMinor<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> checkminor(m1,r1,c1);
|
||||
|
||||
//check diagonal()
|
||||
VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());
|
||||
m2.diagonal() = 2 * m1.diagonal();
|
||||
m2.diagonal()[0] *= 3;
|
||||
|
||||
const int BlockRows = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,2);
|
||||
const int BlockCols = EIGEN_ENUM_MIN(MatrixType::ColsAtCompileTime,5);
|
||||
if (rows>=5 && cols>=8)
|
||||
@@ -120,45 +114,23 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2);
|
||||
// check that fixed block() and block() agree
|
||||
Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);
|
||||
VERIFY_IS_APPROX(b, m1.block(3,3,BlockRows,BlockCols));
|
||||
VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols));
|
||||
}
|
||||
|
||||
if (rows>2)
|
||||
{
|
||||
// test sub vectors
|
||||
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));
|
||||
VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0,0,2,1));
|
||||
VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2));
|
||||
VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0,2));
|
||||
VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0));
|
||||
int i = rows-2;
|
||||
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));
|
||||
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i,0,2,1));
|
||||
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2));
|
||||
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i,2));
|
||||
VERIFY_IS_EQUAL(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));
|
||||
|
||||
enum {
|
||||
N1 = MatrixType::RowsAtCompileTime>1 ? 1 : 0,
|
||||
N2 = MatrixType::RowsAtCompileTime>2 ? -2 : 0
|
||||
};
|
||||
|
||||
// check sub/super diagonal
|
||||
m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>();
|
||||
m2.template diagonal<N1>()[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);
|
||||
|
||||
m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();
|
||||
m2.template diagonal<N2>()[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
|
||||
|
||||
m2.diagonal(N1) = 2 * m1.diagonal(N1);
|
||||
m2.diagonal(N1)[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);
|
||||
|
||||
m2.diagonal(N2) = 2 * m1.diagonal(N2);
|
||||
m2.diagonal(N2)[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);
|
||||
VERIFY_IS_EQUAL(v1.segment(i,2), v1.template segment<2>(i));
|
||||
}
|
||||
|
||||
// stress some basic stuffs with block matrices
|
||||
@@ -167,6 +139,49 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
||||
|
||||
VERIFY(ei_real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));
|
||||
VERIFY(ei_real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));
|
||||
|
||||
// now test some block-inside-of-block.
|
||||
|
||||
// expressions with direct access
|
||||
VERIFY_IS_EQUAL( (m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , (m1.block(r2,c2,rows-r2,cols-c2)) );
|
||||
VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );
|
||||
VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , (m1.col(c1).segment(r1,r2-r1+1)) );
|
||||
VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );
|
||||
VERIFY_IS_EQUAL( (m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );
|
||||
|
||||
// expressions without direct access
|
||||
VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , ((m1+m2).block(r2,c2,rows-r2,cols-c2)) );
|
||||
VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );
|
||||
VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , ((m1+m2).col(c1).segment(r1,r2-r1+1)) );
|
||||
VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );
|
||||
VERIFY_IS_EQUAL( ((m1+m2).transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );
|
||||
|
||||
// evaluation into plain matrices from expressions with direct access (stress MapBase)
|
||||
DynamicMatrixType dm;
|
||||
DynamicVectorType dv;
|
||||
dm.setZero();
|
||||
dm = m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2);
|
||||
VERIFY_IS_EQUAL(dm, (m1.block(r2,c2,rows-r2,cols-c2)));
|
||||
dm.setZero();
|
||||
dv.setZero();
|
||||
dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0).transpose();
|
||||
dv = m1.row(r1).segment(c1,c2-c1+1);
|
||||
VERIFY_IS_EQUAL(dv, dm);
|
||||
dm.setZero();
|
||||
dv.setZero();
|
||||
dm = m1.col(c1).segment(r1,r2-r1+1);
|
||||
dv = m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0);
|
||||
VERIFY_IS_EQUAL(dv, dm);
|
||||
dm.setZero();
|
||||
dv.setZero();
|
||||
dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0);
|
||||
dv = m1.row(r1).segment(c1,c2-c1+1);
|
||||
VERIFY_IS_EQUAL(dv, dm);
|
||||
dm.setZero();
|
||||
dv.setZero();
|
||||
dm = m1.row(r1).segment(c1,c2-c1+1).transpose();
|
||||
dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);
|
||||
VERIFY_IS_EQUAL(dv, dm);
|
||||
}
|
||||
|
||||
|
||||
@@ -176,18 +191,30 @@ void compare_using_data_and_stride(const MatrixType& m)
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
int size = m.size();
|
||||
int stride = m.stride();
|
||||
int innerStride = m.innerStride();
|
||||
int outerStride = m.outerStride();
|
||||
int rowStride = m.rowStride();
|
||||
int colStride = m.colStride();
|
||||
const typename MatrixType::Scalar* data = m.data();
|
||||
|
||||
for(int j=0;j<cols;++j)
|
||||
for(int i=0;i<rows;++i)
|
||||
VERIFY_IS_APPROX(m.coeff(i,j), data[(MatrixType::Flags&RowMajorBit) ? i*stride+j : j*stride + i]);
|
||||
VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);
|
||||
|
||||
if(!MatrixType::IsVectorAtCompileTime)
|
||||
{
|
||||
for(int j=0;j<cols;++j)
|
||||
for(int i=0;i<rows;++i)
|
||||
VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)
|
||||
? i*outerStride + j*innerStride
|
||||
: j*outerStride + i*innerStride]);
|
||||
}
|
||||
|
||||
if(MatrixType::IsVectorAtCompileTime)
|
||||
{
|
||||
VERIFY_IS_APPROX(stride, int((&m.coeff(1))-(&m.coeff(0))));
|
||||
VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));
|
||||
for (int i=0;i<size;++i)
|
||||
VERIFY_IS_APPROX(m.coeff(i), data[i*stride]);
|
||||
VERIFY(m.coeff(i) == data[i*innerStride]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,19 +238,21 @@ void data_and_stride(const MatrixType& m)
|
||||
compare_using_data_and_stride(m1.col(c1).transpose());
|
||||
}
|
||||
|
||||
void test_submatrices()
|
||||
void test_block()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1( submatrices(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( submatrices(Matrix4d()) );
|
||||
CALL_SUBTEST_3( submatrices(MatrixXcf(3, 3)) );
|
||||
CALL_SUBTEST_4( submatrices(MatrixXi(8, 12)) );
|
||||
CALL_SUBTEST_5( submatrices(MatrixXcd(20, 20)) );
|
||||
CALL_SUBTEST_6( submatrices(MatrixXf(20, 20)) );
|
||||
CALL_SUBTEST_1( block(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( block(Matrix4d()) );
|
||||
CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
|
||||
CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
|
||||
CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
|
||||
CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
|
||||
|
||||
CALL_SUBTEST_8( submatrices(Matrix<float,Dynamic,4>(3, 4)) );
|
||||
CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
|
||||
|
||||
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||
CALL_SUBTEST_6( data_and_stride(MatrixXf(ei_random(5,50), ei_random(5,50))) );
|
||||
CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(ei_random(5,50), ei_random(5,50))) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
|
||||
{
|
||||
LLT<SquareMatrixType,Lower> chollo(symmLo);
|
||||
VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
|
||||
VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
|
||||
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,Upper> cholup(symmUp);
|
||||
VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
|
||||
VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());
|
||||
vecX = cholup.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = cholup.solve(matB);
|
||||
@@ -119,8 +119,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
|
||||
{
|
||||
LDLT<SquareMatrixType> ldlt(symm);
|
||||
// TODO(keir): This doesn't make sense now that LDLT pivots.
|
||||
//VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());
|
||||
VERIFY_IS_APPROX(symm, ldlt.reconstructedMatrix());
|
||||
vecX = ldlt.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = ldlt.solve(matB);
|
||||
|
||||
81
test/diagonal.cpp
Normal file
81
test/diagonal.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2010 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 MatrixType> void diagonal(const MatrixType& m)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
||||
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
MatrixType m1 = MatrixType::Random(rows, cols),
|
||||
m2 = MatrixType::Random(rows, cols);
|
||||
|
||||
//check diagonal()
|
||||
VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());
|
||||
m2.diagonal() = 2 * m1.diagonal();
|
||||
m2.diagonal()[0] *= 3;
|
||||
|
||||
if (rows>2)
|
||||
{
|
||||
enum {
|
||||
N1 = MatrixType::RowsAtCompileTime>1 ? 1 : 0,
|
||||
N2 = MatrixType::RowsAtCompileTime>2 ? -2 : 0
|
||||
};
|
||||
|
||||
// check sub/super diagonal
|
||||
m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>();
|
||||
m2.template diagonal<N1>()[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);
|
||||
|
||||
m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();
|
||||
m2.template diagonal<N2>()[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
|
||||
|
||||
m2.diagonal(N1) = 2 * m1.diagonal(N1);
|
||||
m2.diagonal(N1)[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);
|
||||
|
||||
m2.diagonal(N2) = 2 * m1.diagonal(N2);
|
||||
m2.diagonal(N2)[0] *= 3;
|
||||
VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_diagonal()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1( diagonal(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( diagonal(Matrix4d()) );
|
||||
CALL_SUBTEST_2( diagonal(MatrixXcf(3, 3)) );
|
||||
CALL_SUBTEST_2( diagonal(MatrixXi(8, 12)) );
|
||||
CALL_SUBTEST_2( diagonal(MatrixXcd(20, 20)) );
|
||||
CALL_SUBTEST_1( diagonal(MatrixXf(21, 19)) );
|
||||
CALL_SUBTEST_1( diagonal(Matrix<float,Dynamic,4>(3, 4)) );
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ template<typename Scalar, int Mode> void transformations(void)
|
||||
Matrix3 matrot1, m;
|
||||
|
||||
Scalar a = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||
Scalar s0 = ei_random<Scalar>();
|
||||
|
||||
VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
|
||||
VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);
|
||||
@@ -234,6 +235,16 @@ template<typename Scalar, int Mode> void transformations(void)
|
||||
t1 = Matrix3(q1) * (AlignedScaling3(v0) * Translation3(v0));
|
||||
VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
|
||||
|
||||
|
||||
t0.setIdentity();
|
||||
t0.scale(s0).translate(v0);
|
||||
t1 = Scaling(s0) * Translation3(v0);
|
||||
VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
|
||||
t0.prescale(s0);
|
||||
t1 = Scaling(s0) * t1;
|
||||
VERIFY_IS_APPROX(t0.matrix(), t1.matrix());
|
||||
|
||||
|
||||
t0.setIdentity();
|
||||
t0.prerotate(q1).prescale(v0).pretranslate(v0);
|
||||
// translation * aligned scaling and transformation * mat
|
||||
|
||||
@@ -42,7 +42,7 @@ template<typename MatrixType> void inverse(const MatrixType& m)
|
||||
m2(rows, cols),
|
||||
mzero = MatrixType::Zero(rows, cols),
|
||||
identity = MatrixType::Identity(rows, rows);
|
||||
createRandomMatrixOfRank(rows,rows,rows,m1);
|
||||
createRandomPIMatrixOfRank(rows,rows,rows,m1);
|
||||
m2 = m1.inverse();
|
||||
VERIFY_IS_APPROX(m1, m2.inverse() );
|
||||
|
||||
|
||||
93
test/lu.cpp
93
test/lu.cpp
@@ -29,6 +29,7 @@ using namespace std;
|
||||
template<typename MatrixType> void lu_non_invertible()
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
/* this test covers the following files:
|
||||
LU.h
|
||||
*/
|
||||
@@ -51,39 +52,46 @@ template<typename MatrixType> void lu_non_invertible()
|
||||
cols2 = cols = MatrixType::ColsAtCompileTime;
|
||||
}
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime
|
||||
};
|
||||
typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType;
|
||||
typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> DynamicMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime>
|
||||
typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime>
|
||||
CMatrixType;
|
||||
typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime>
|
||||
RMatrixType;
|
||||
|
||||
int rank = ei_random<int>(1, std::min(rows, cols)-1);
|
||||
|
||||
// The image of the zero matrix should consist of a single (zero) column vector
|
||||
VERIFY((MatrixType::Zero(rows,cols).fullPivLu().image(MatrixType::Zero(rows,cols)).cols() == 1));
|
||||
|
||||
|
||||
MatrixType m1(rows, cols), m3(rows, cols2);
|
||||
CMatrixType m2(cols, cols2);
|
||||
createRandomMatrixOfRank(rank, rows, cols, m1);
|
||||
createRandomPIMatrixOfRank(rank, rows, cols, m1);
|
||||
|
||||
FullPivLU<MatrixType> lu;
|
||||
|
||||
// The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank
|
||||
// of singular values are either 0 or 1.
|
||||
// So it's not clear at all that the epsilon should play any role there.
|
||||
lu.setThreshold(RealScalar(0.01));
|
||||
lu.compute(m1);
|
||||
|
||||
MatrixType u(rows,cols);
|
||||
u = lu.matrixLU().template triangularView<Upper>();
|
||||
RMatrixType l = RMatrixType::Identity(rows,rows);
|
||||
l.block(0,0,rows,std::min(rows,cols)).template triangularView<StrictlyLower>()
|
||||
= lu.matrixLU().block(0,0,rows,std::min(rows,cols));
|
||||
|
||||
FullPivLU<MatrixType> lu(m1);
|
||||
// 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);
|
||||
|
||||
VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
|
||||
VERIFY(rank == lu.rank());
|
||||
VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
|
||||
VERIFY(!lu.isInjective());
|
||||
@@ -91,9 +99,8 @@ template<typename MatrixType> void lu_non_invertible()
|
||||
VERIFY(!lu.isSurjective());
|
||||
VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
|
||||
VERIFY(m1image.fullPivLu().rank() == rank);
|
||||
DynamicMatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
|
||||
sidebyside << m1, m1image;
|
||||
VERIFY(sidebyside.fullPivLu().rank() == rank);
|
||||
VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);
|
||||
|
||||
m2 = CMatrixType::Random(cols,cols2);
|
||||
m3 = m1*m2;
|
||||
m2 = CMatrixType::Random(cols,cols2);
|
||||
@@ -107,20 +114,19 @@ template<typename MatrixType> void lu_invertible()
|
||||
/* this test covers the following files:
|
||||
LU.h
|
||||
*/
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
int size = ei_random<int>(1,200);
|
||||
|
||||
MatrixType m1(size, size), m2(size, size), m3(size, size);
|
||||
m1 = MatrixType::Random(size,size);
|
||||
FullPivLU<MatrixType> lu;
|
||||
lu.setThreshold(0.01);
|
||||
do {
|
||||
m1 = MatrixType::Random(size,size);
|
||||
lu.compute(m1);
|
||||
} while(!lu.isInvertible());
|
||||
|
||||
if (ei_is_same_type<RealScalar,float>::ret)
|
||||
{
|
||||
// let's build a matrix more stable to inverse
|
||||
MatrixType a = MatrixType::Random(size,size*2);
|
||||
m1 += a * a.adjoint();
|
||||
}
|
||||
|
||||
FullPivLU<MatrixType> lu(m1);
|
||||
VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
|
||||
VERIFY(0 == lu.dimensionOfKernel());
|
||||
VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector
|
||||
VERIFY(size == lu.rank());
|
||||
@@ -134,6 +140,23 @@ template<typename MatrixType> void lu_invertible()
|
||||
VERIFY_IS_APPROX(m2, lu.inverse()*m3);
|
||||
}
|
||||
|
||||
template<typename MatrixType> void lu_partial_piv()
|
||||
{
|
||||
/* this test covers the following files:
|
||||
PartialPivLU.h
|
||||
*/
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
int rows = ei_random<int>(1,4);
|
||||
int cols = rows;
|
||||
|
||||
MatrixType m1(cols, rows);
|
||||
m1.setRandom();
|
||||
PartialPivLU<MatrixType> plu(m1);
|
||||
|
||||
VERIFY_IS_APPROX(m1, plu.reconstructedMatrix());
|
||||
}
|
||||
|
||||
template<typename MatrixType> void lu_verify_assert()
|
||||
{
|
||||
MatrixType tmp;
|
||||
@@ -169,21 +192,23 @@ void test_lu()
|
||||
|
||||
CALL_SUBTEST_2( (lu_non_invertible<Matrix<double, 4, 6> >()) );
|
||||
CALL_SUBTEST_2( (lu_verify_assert<Matrix<double, 4, 6> >()) );
|
||||
|
||||
|
||||
CALL_SUBTEST_3( lu_non_invertible<MatrixXf>() );
|
||||
CALL_SUBTEST_3( lu_invertible<MatrixXf>() );
|
||||
CALL_SUBTEST_3( lu_verify_assert<MatrixXf>() );
|
||||
|
||||
|
||||
CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_invertible<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() );
|
||||
CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() );
|
||||
|
||||
|
||||
CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() );
|
||||
CALL_SUBTEST_5( lu_invertible<MatrixXcf>() );
|
||||
CALL_SUBTEST_5( lu_verify_assert<MatrixXcf>() );
|
||||
|
||||
|
||||
CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_invertible<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() );
|
||||
CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() );
|
||||
|
||||
CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() ));
|
||||
|
||||
61
test/main.h
61
test/main.h
@@ -95,6 +95,7 @@ namespace Eigen
|
||||
#define ei_assert(a) \
|
||||
if( (!(a)) && (!no_more_assert) ) \
|
||||
{ \
|
||||
std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
|
||||
Eigen::no_more_assert = true; \
|
||||
throw Eigen::ei_assert_exception(); \
|
||||
} \
|
||||
@@ -126,6 +127,7 @@ namespace Eigen
|
||||
if( (!(a)) && (!no_more_assert) ) \
|
||||
{ \
|
||||
Eigen::no_more_assert = true; \
|
||||
std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
|
||||
throw Eigen::ei_assert_exception(); \
|
||||
}
|
||||
|
||||
@@ -148,7 +150,7 @@ namespace Eigen
|
||||
|
||||
#define EIGEN_INTERNAL_DEBUGGING
|
||||
#define EIGEN_NICE_RANDOM
|
||||
#include <Eigen/QR> // required for createRandomMatrixOfRank
|
||||
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
|
||||
|
||||
|
||||
#define VERIFY(a) do { if (!(a)) { \
|
||||
@@ -157,6 +159,7 @@ namespace Eigen
|
||||
exit(2); \
|
||||
} } while (0)
|
||||
|
||||
#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
|
||||
#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
|
||||
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b))
|
||||
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b))
|
||||
@@ -342,8 +345,59 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m)
|
||||
return m.isUnitary(test_precision<typename ei_traits<Derived>::Scalar>());
|
||||
}
|
||||
|
||||
template<typename Derived1, typename Derived2,
|
||||
bool IsVector = bool(Derived1::IsVectorAtCompileTime) && bool(Derived2::IsVectorAtCompileTime) >
|
||||
struct test_is_equal_impl
|
||||
{
|
||||
static bool run(const Derived1& a1, const Derived2& a2)
|
||||
{
|
||||
if(a1.size() != a2.size()) return false;
|
||||
// we evaluate a2 into a temporary of the shape of a1. this allows to let Assign.h handle the transposing if needed.
|
||||
typename Derived1::PlainObject a2_evaluated(a2);
|
||||
for(int i = 0; i < a1.size(); ++i)
|
||||
if(a1.coeff(i) != a2_evaluated.coeff(i)) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2>
|
||||
struct test_is_equal_impl<Derived1, Derived2, false>
|
||||
{
|
||||
static bool run(const Derived1& a1, const Derived2& a2)
|
||||
{
|
||||
if(a1.rows() != a2.rows()) return false;
|
||||
if(a1.cols() != a2.cols()) return false;
|
||||
for(int j = 0; j < a1.cols(); ++j)
|
||||
for(int i = 0; i < a1.rows(); ++i)
|
||||
if(a1.coeff(i,j) != a2.coeff(i,j)) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2>
|
||||
bool test_is_equal(const Derived1& a1, const Derived2& a2)
|
||||
{
|
||||
return test_is_equal_impl<Derived1, Derived2>::run(a1, a2);
|
||||
}
|
||||
|
||||
bool test_is_equal(const int actual, const int expected)
|
||||
{
|
||||
if (actual==expected)
|
||||
return true;
|
||||
// false:
|
||||
std::cerr
|
||||
<< std::endl << " actual = " << actual
|
||||
<< std::endl << " expected = " << expected << std::endl << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Creates a random Partial Isometry matrix of given rank.
|
||||
*
|
||||
* A partial isometry is a matrix all of whose singular values are either 0 or 1.
|
||||
* This is very useful to test rank-revealing algorithms.
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
|
||||
void createRandomPIMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
|
||||
{
|
||||
typedef typename ei_traits<MatrixType>::Scalar Scalar;
|
||||
enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
|
||||
@@ -360,7 +414,8 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
|
||||
|
||||
if(desired_rank == 1)
|
||||
{
|
||||
m = VectorType::Random(rows) * VectorType::Random(cols).transpose();
|
||||
// here we normalize the vectors to get a partial isometry
|
||||
m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
14
test/map.cpp
14
test/map.cpp
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2006-2010 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
|
||||
@@ -42,8 +42,8 @@ template<typename VectorType> void map_class_vector(const VectorType& m)
|
||||
VectorType ma1 = Map<VectorType, Aligned>(array1, size);
|
||||
VectorType ma2 = Map<VectorType, Aligned>(array2, size);
|
||||
VectorType ma3 = Map<VectorType>(array3unaligned, size);
|
||||
VERIFY_IS_APPROX(ma1, ma2);
|
||||
VERIFY_IS_APPROX(ma1, ma3);
|
||||
VERIFY_IS_EQUAL(ma1, ma2);
|
||||
VERIFY_IS_EQUAL(ma1, ma3);
|
||||
VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size)));
|
||||
|
||||
ei_aligned_delete(array1, size);
|
||||
@@ -70,9 +70,9 @@ template<typename MatrixType> void map_class_matrix(const MatrixType& m)
|
||||
Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
|
||||
MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
|
||||
MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
|
||||
VERIFY_IS_APPROX(ma1, ma2);
|
||||
VERIFY_IS_EQUAL(ma1, ma2);
|
||||
MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
|
||||
VERIFY_IS_APPROX(ma1, ma3);
|
||||
VERIFY_IS_EQUAL(ma1, ma3);
|
||||
|
||||
ei_aligned_delete(array1, size);
|
||||
ei_aligned_delete(array2, size);
|
||||
@@ -97,8 +97,8 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
|
||||
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);
|
||||
VERIFY_IS_EQUAL(ma1, ma2);
|
||||
VERIFY_IS_EQUAL(ma1, ma3);
|
||||
|
||||
ei_aligned_delete(array1, size);
|
||||
ei_aligned_delete(array2, size);
|
||||
|
||||
139
test/mapstride.cpp
Normal file
139
test/mapstride.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2010 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 VectorType> void map_class_vector(const VectorType& m)
|
||||
{
|
||||
typedef typename VectorType::Scalar Scalar;
|
||||
|
||||
int size = m.size();
|
||||
|
||||
VectorType v = VectorType::Random(size);
|
||||
|
||||
int arraysize = 3*size;
|
||||
|
||||
Scalar* array = ei_aligned_new<Scalar>(arraysize);
|
||||
|
||||
{
|
||||
Map<VectorType, Aligned, InnerStride<3> > map(array, size);
|
||||
map = v;
|
||||
for(int i = 0; i < size; ++i)
|
||||
{
|
||||
VERIFY(array[3*i] == v[i]);
|
||||
VERIFY(map[i] == v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2));
|
||||
map = v;
|
||||
for(int i = 0; i < size; ++i)
|
||||
{
|
||||
VERIFY(array[2*i] == v[i]);
|
||||
VERIFY(map[i] == v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ei_aligned_delete(array, arraysize);
|
||||
}
|
||||
|
||||
template<typename MatrixType> void map_class_matrix(const MatrixType& _m)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
|
||||
int rows = _m.rows(), cols = _m.cols();
|
||||
|
||||
MatrixType m = MatrixType::Random(rows,cols);
|
||||
|
||||
int arraysize = 2*(rows+4)*(cols+4);
|
||||
|
||||
Scalar* array = ei_aligned_new<Scalar>(arraysize);
|
||||
|
||||
// test no inner stride and some dynamic outer stride
|
||||
{
|
||||
Map<MatrixType, Aligned, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1));
|
||||
map = m;
|
||||
VERIFY(map.outerStride() == map.innerSize()+1);
|
||||
for(int i = 0; i < m.outerSize(); ++i)
|
||||
for(int j = 0; j < m.innerSize(); ++j)
|
||||
{
|
||||
VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
|
||||
VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
|
||||
}
|
||||
}
|
||||
|
||||
// test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices,
|
||||
// this allows to hit the special case where it's vectorizable.
|
||||
{
|
||||
enum {
|
||||
InnerSize = MatrixType::InnerSizeAtCompileTime,
|
||||
OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4
|
||||
};
|
||||
Map<MatrixType, Aligned, OuterStride<OuterStrideAtCompileTime> >
|
||||
map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4));
|
||||
map = m;
|
||||
VERIFY(map.outerStride() == map.innerSize()+4);
|
||||
for(int i = 0; i < m.outerSize(); ++i)
|
||||
for(int j = 0; j < m.innerSize(); ++j)
|
||||
{
|
||||
VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
|
||||
VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
|
||||
}
|
||||
}
|
||||
|
||||
// test both inner stride and outer stride
|
||||
{
|
||||
Map<MatrixType, Aligned, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2));
|
||||
map = m;
|
||||
VERIFY(map.outerStride() == 2*map.innerSize()+1);
|
||||
VERIFY(map.innerStride() == 2);
|
||||
for(int i = 0; i < m.outerSize(); ++i)
|
||||
for(int j = 0; j < m.innerSize(); ++j)
|
||||
{
|
||||
VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j));
|
||||
VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
|
||||
}
|
||||
}
|
||||
|
||||
ei_aligned_delete(array, arraysize);
|
||||
}
|
||||
|
||||
void test_mapstride()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( map_class_vector(Vector4d()) );
|
||||
CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
|
||||
CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );
|
||||
CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );
|
||||
|
||||
CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );
|
||||
CALL_SUBTEST_3( map_class_matrix(Matrix<float,3,5>()) );
|
||||
CALL_SUBTEST_3( map_class_matrix(Matrix<float,4,8>()) );
|
||||
CALL_SUBTEST_4( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) );
|
||||
CALL_SUBTEST_5( map_class_matrix(MatrixXi(5,5)));//ei_random<int>(1,10),ei_random<int>(1,10))) );
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,9 @@ template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)
|
||||
|
||||
// check dot product
|
||||
vf.dot(vf);
|
||||
#if 0 // we get other compilation errors here than just static asserts
|
||||
VERIFY_RAISES_ASSERT(vd.dot(vf));
|
||||
#endif
|
||||
VERIFY_RAISES_ASSERT(vcf.dot(vf)); // yeah eventually we should allow this but i'm too lazy to make that change now in Dot.h
|
||||
// especially as that might be rewritten as cwise product .sum() which would make that automatic.
|
||||
|
||||
@@ -125,8 +127,8 @@ void mixingtypes_large(int size)
|
||||
VERIFY_RAISES_ASSERT(mcd*md);
|
||||
VERIFY_RAISES_ASSERT(mf*vcf);
|
||||
VERIFY_RAISES_ASSERT(mcf*vf);
|
||||
VERIFY_RAISES_ASSERT(mcf *= mf);
|
||||
// VERIFY_RAISES_ASSERT(vcd = md*vcd); // does not even compile (cannot convert complex to double)
|
||||
// VERIFY_RAISES_ASSERT(mcf *= mf); // does not even compile
|
||||
// VERIFY_RAISES_ASSERT(vcd = md*vcd); // does not even compile (cannot convert complex to double)
|
||||
VERIFY_RAISES_ASSERT(vcf = mcf*vf);
|
||||
|
||||
// VERIFY_RAISES_ASSERT(mf*md); // does not even compile
|
||||
|
||||
@@ -32,7 +32,10 @@ template<typename T> T ei_negate(const T& x) { return -x; }
|
||||
template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)
|
||||
{
|
||||
for (int i=0; i<size; ++i)
|
||||
if (!ei_isApprox(a[i],b[i])) return false;
|
||||
if (!ei_isApprox(a[i],b[i])) {
|
||||
std::cout << "a[" << i << "]: " << a[i] << ", b[" << i << "]: " << b[i] << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
|
||||
typedef PermutationMatrix<Cols> RightPermutationType;
|
||||
typedef Matrix<int, Cols, 1> RightPermutationVectorType;
|
||||
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
@@ -72,7 +72,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
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());
|
||||
|
||||
@@ -86,6 +86,23 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
|
||||
identityp.setIdentity(rows);
|
||||
VERIFY_IS_APPROX(m_original, identityp*m_original);
|
||||
|
||||
// check inplace permutations
|
||||
m_permuted = m_original;
|
||||
m_permuted = lp.inverse() * m_permuted;
|
||||
VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = m_permuted * rp.inverse();
|
||||
VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = lp * m_permuted;
|
||||
VERIFY_IS_APPROX(m_permuted, lp*m_original);
|
||||
|
||||
m_permuted = m_original;
|
||||
m_permuted = m_permuted * rp;
|
||||
VERIFY_IS_APPROX(m_permuted, m_original*rp);
|
||||
|
||||
if(rows>1 && cols>1)
|
||||
{
|
||||
lp2 = lp;
|
||||
@@ -114,7 +131,7 @@ void test_permutationmatrices()
|
||||
CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
|
||||
CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
|
||||
CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
|
||||
CALL_SUBTEST_5( permutationmatrices(Matrix<double,4,6>()) );
|
||||
CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
|
||||
CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
|
||||
CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
|
||||
}
|
||||
|
||||
@@ -109,9 +109,11 @@ void test_product_symm()
|
||||
for(int i = 0; i < g_repeat ; i++)
|
||||
{
|
||||
CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_2(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_3(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
|
||||
CALL_SUBTEST_3(( symm<float,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_4(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_4(( symm<float,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_5(( symm<double,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST_6(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ void test_product_syrk()
|
||||
s = ei_random<int>(10,320);
|
||||
CALL_SUBTEST_1( syrk(MatrixXf(s, s)) );
|
||||
s = ei_random<int>(10,320);
|
||||
CALL_SUBTEST_2( syrk(MatrixXcd(s, s)) );
|
||||
CALL_SUBTEST_2( syrk(MatrixXd(s, s)) );
|
||||
s = ei_random<int>(10,320);
|
||||
CALL_SUBTEST_3( syrk(MatrixXcd(s, s)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,12 +79,13 @@ void test_product_trsolve()
|
||||
{
|
||||
// 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))));
|
||||
CALL_SUBTEST_2((trsolve<double,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320))));
|
||||
CALL_SUBTEST_3((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>()));
|
||||
CALL_SUBTEST_4((trsolve<std::complex<double>,Dynamic,1>(ei_random<int>(1,320))));
|
||||
CALL_SUBTEST_5((trsolve<float,1,1>()));
|
||||
CALL_SUBTEST_6((trsolve<float,1,2>()));
|
||||
CALL_SUBTEST_7((trsolve<std::complex<float>,4,1>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ void test_qr()
|
||||
CALL_SUBTEST_3(( qr_fixedsize<Matrix<float,3,4>, 2 >() ));
|
||||
CALL_SUBTEST_4(( qr_fixedsize<Matrix<double,6,2>, 4 >() ));
|
||||
CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,2,5>, 7 >() ));
|
||||
CALL_SUBTEST_11( qr(Matrix<float,1,1>()) );
|
||||
}
|
||||
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
|
||||
@@ -36,7 +36,7 @@ template<typename MatrixType> void qr()
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
|
||||
MatrixType m1;
|
||||
createRandomMatrixOfRank(rank,rows,cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,rows,cols,m1);
|
||||
ColPivHouseholderQR<MatrixType> qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
|
||||
@@ -64,7 +64,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
int rank = ei_random<int>(1, std::min(int(Rows), int(Cols))-1);
|
||||
Matrix<Scalar,Rows,Cols> m1;
|
||||
createRandomMatrixOfRank(rank,Rows,Cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,Rows,Cols,m1);
|
||||
ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(Cols - qr.rank() == qr.dimensionOfKernel());
|
||||
|
||||
@@ -35,7 +35,7 @@ template<typename MatrixType> void qr()
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
|
||||
MatrixType m1;
|
||||
createRandomMatrixOfRank(rank,rows,cols,m1);
|
||||
createRandomPIMatrixOfRank(rank,rows,cols,m1);
|
||||
FullPivHouseholderQR<MatrixType> qr(m1);
|
||||
VERIFY_IS_APPROX(rank, qr.rank());
|
||||
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
|
||||
|
||||
@@ -147,6 +147,9 @@ endif(NOT EIGEN_NO_UPDATE)
|
||||
|
||||
# which ctest command to use for running the dashboard
|
||||
SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE}")
|
||||
if($ENV{EIGEN_CTEST_ARGS})
|
||||
SET (CTEST_COMMAND "${CTEST_COMMAND} $ENV{EIGEN_CTEST_ARGS}")
|
||||
endif($ENV{EIGEN_CTEST_ARGS})
|
||||
# what cmake command to use for configuring this dashboard
|
||||
SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_LEAVE_TEST_IN_ALL_TARGET=ON")
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ void check_unalignedassert_good()
|
||||
delete[] y;
|
||||
}
|
||||
|
||||
#if EIGEN_ALIGN
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
template<typename T>
|
||||
void construct_at_boundary(int boundary)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ void construct_at_boundary(int boundary)
|
||||
|
||||
void unalignedassert()
|
||||
{
|
||||
#if EIGEN_ALIGN
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
construct_at_boundary<Vector2f>(4);
|
||||
construct_at_boundary<Vector3f>(4);
|
||||
construct_at_boundary<Vector4f>(16);
|
||||
@@ -124,7 +124,7 @@ void unalignedassert()
|
||||
check_unalignedassert_good<TestNew6>();
|
||||
check_unalignedassert_good<Depends<true> >();
|
||||
|
||||
#if EIGEN_ALIGN
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8));
|
||||
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define EIGEN_DEBUG_ASSIGN
|
||||
#include "main.h"
|
||||
#include <typeinfo>
|
||||
|
||||
@@ -33,6 +34,14 @@ bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
|
||||
&& ei_assign_traits<Dst,Src>::Unrolling==unrolling;
|
||||
}
|
||||
|
||||
template<typename Dst, typename Src>
|
||||
bool test_assign(int traversal, int unrolling)
|
||||
{
|
||||
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 traversal, int unrolling)
|
||||
{
|
||||
@@ -86,6 +95,15 @@ void test_vectorization_logic()
|
||||
VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
|
||||
SliceVectorizedTraversal,NoUnrolling));
|
||||
|
||||
VERIFY((test_assign<
|
||||
Map<Matrix<float,4,8>, Aligned, OuterStride<12> >,
|
||||
Matrix<float,4,8>
|
||||
>(InnerVectorizedTraversal,CompleteUnrolling)));
|
||||
|
||||
VERIFY((test_assign<
|
||||
Map<Matrix<float,4,8>, Aligned, InnerStride<12> >,
|
||||
Matrix<float,4,8>
|
||||
>(DefaultTraversal,CompleteUnrolling)));
|
||||
|
||||
VERIFY(test_redux(VectorXf(10),
|
||||
LinearVectorizedTraversal,NoUnrolling));
|
||||
|
||||
Reference in New Issue
Block a user