aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2016-01-09 08:30:38 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2016-01-09 08:30:38 +0100
commit8b9dc9f0dfb44c2c4ad6d02fb88ecce0986cd154 (patch)
treeb821895e79c11c8be9d2f8c4af77046eba6f7811 /test
parentf9d71a172992cfda5e2733f9f4a6e12a14b9ed73 (diff)
bug #1144: fix regression in x=y+A*x (aliasing), and move evaluator_traits::AssumeAliasing to evaluator_assume_aliasing.
Diffstat (limited to 'test')
-rw-r--r--test/product.h35
-rw-r--r--test/product_large.cpp23
-rw-r--r--test/product_notemporary.cpp6
3 files changed, 55 insertions, 9 deletions
diff --git a/test/product.h b/test/product.h
index 9dfff9303..bd92309d2 100644
--- a/test/product.h
+++ b/test/product.h
@@ -145,14 +145,31 @@ template<typename MatrixType> void product(const MatrixType& m)
VERIFY_IS_APPROX(res.col(r).noalias() = square * square.col(r), (square * square.col(r)).eval());
// inner product
- Scalar x = square2.row(c) * square2.col(c2);
- VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());
-
+ {
+ Scalar x = square2.row(c) * square2.col(c2);
+ VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());
+ }
+
// outer product
- VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
- VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose());
- VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
- VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
- VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols));
- VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols));
+ {
+ VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose());
+ VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols));
+ }
+
+ // Aliasing
+ {
+ ColVectorType x(cols); x.setRandom();
+ ColVectorType z(x);
+ ColVectorType y(cols); y.setZero();
+ ColSquareMatrixType A(cols,cols); A.setRandom();
+ // CwiseBinaryOp
+ VERIFY_IS_APPROX(x = y + A*x, A*z);
+ x = z;
+ // CwiseUnaryOp
+ VERIFY_IS_APPROX(x = Scalar(1.)*(A*x), A*z);
+ }
}
diff --git a/test/product_large.cpp b/test/product_large.cpp
index 7207973c2..98f84c53b 100644
--- a/test/product_large.cpp
+++ b/test/product_large.cpp
@@ -9,6 +9,27 @@
#include "product.h"
+template<typename T>
+void test_aliasing()
+{
+ int rows = internal::random<int>(1,12);
+ int cols = internal::random<int>(1,12);
+ typedef Matrix<T,Dynamic,Dynamic> MatrixType;
+ typedef Matrix<T,Dynamic,1> VectorType;
+ VectorType x(cols); x.setRandom();
+ VectorType z(x);
+ VectorType y(rows); y.setZero();
+ MatrixType A(rows,cols); A.setRandom();
+ // CwiseBinaryOp
+ VERIFY_IS_APPROX(x = y + A*x, A*z); // OK because "y + A*x" is marked as "assume-aliasing"
+ x = z;
+ // CwiseUnaryOp
+ VERIFY_IS_APPROX(x = T(1.)*(A*x), A*z); // OK because 1*(A*x) is replaced by (1*A*x) which is a Product<> expression
+ x = z;
+ // VERIFY_IS_APPROX(x = y-A*x, -A*z); // Not OK in 3.3 because x is resized before A*x gets evaluated
+ x = z;
+}
+
void test_product_large()
{
for(int i = 0; i < g_repeat; i++) {
@@ -17,6 +38,8 @@ void test_product_large()
CALL_SUBTEST_3( product(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
CALL_SUBTEST_4( product(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
+
+ CALL_SUBTEST_1( test_aliasing<float>() );
}
#if defined EIGEN_TEST_PART_6
diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp
index ff93cb881..5a3f3a01a 100644
--- a/test/product_notemporary.cpp
+++ b/test/product_notemporary.cpp
@@ -43,10 +43,16 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
r1 = internal::random<Index>(8,rows-r0);
VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1);
+ VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()).transpose(), 1);
VERIFY_EVALUATION_COUNT( m3.noalias() = m1 * m2.adjoint(), 0);
+ VERIFY_EVALUATION_COUNT( m3 = s1 * (m1 * m2.transpose()), 1);
+// VERIFY_EVALUATION_COUNT( m3 = m3 + s1 * (m1 * m2.transpose()), 1);
VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0);
+ VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()), 1);
+
+ VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()).transpose(), 1);
VERIFY_EVALUATION_COUNT( m3.noalias() = m3 + m1 * m2.transpose(), 0);
VERIFY_EVALUATION_COUNT( m3.noalias() += m3 + m1 * m2.transpose(), 0);
VERIFY_EVALUATION_COUNT( m3.noalias() -= m3 + m1 * m2.transpose(), 0);