diff --git a/Eigen/src/Core/CMakeLists.txt b/Eigen/src/Core/CMakeLists.txt index fb745a252..761e8c3f5 100644 --- a/Eigen/src/Core/CMakeLists.txt +++ b/Eigen/src/Core/CMakeLists.txt @@ -6,4 +6,4 @@ INSTALL(FILES ) ADD_SUBDIRECTORY(util) -ADD_SUBDIRECTORY(arch) \ No newline at end of file +ADD_SUBDIRECTORY(arch) diff --git a/Eigen/src/Core/Sum.h b/Eigen/src/Core/Sum.h index 6c7280800..3b073b95e 100644 --- a/Eigen/src/Core/Sum.h +++ b/Eigen/src/Core/Sum.h @@ -201,12 +201,11 @@ struct ei_sum_impl const int alignedEnd = alignedStart + alignedSize; Scalar res; - if(Derived::SizeAtCompileTime>=2*packetSize && alignedSize >= 2*packetSize) + if(alignedSize) { - PacketScalar packet_res = mat.template packet(alignedStart, alignedStart); + PacketScalar packet_res = mat.template packet(alignedStart); for(int index = alignedStart + packetSize; index < alignedEnd; index += packetSize) packet_res = ei_padd(packet_res, mat.template packet(index)); - res = ei_predux(packet_res); } else // too small to vectorize anything. @@ -215,7 +214,7 @@ struct ei_sum_impl res = Scalar(0); } - for(int index = alignedEnd; index < size; index++) + for(int index = 0; index < alignedStart; index++) res += mat.coeff(index); for(int index = alignedEnd; index < size; index++) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 31d2049b3..30fe3e755 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -89,6 +89,7 @@ EI_ADD_TEST(nomalloc) EI_ADD_TEST(basicstuff) EI_ADD_TEST(linearstructure) EI_ADD_TEST(cwiseop) +EI_ADD_TEST(sum) EI_ADD_TEST(product_small) EI_ADD_TEST(product_large ${EI_OFLAG}) EI_ADD_TEST(adjoint) diff --git a/test/sum.cpp b/test/sum.cpp new file mode 100644 index 000000000..5a55e5a35 --- /dev/null +++ b/test/sum.cpp @@ -0,0 +1,86 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Benoit Jacob +// +// 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 . + +#include "main.h" + +template void matrixSum(const MatrixType& m) +{ + typedef typename MatrixType::Scalar Scalar; + + int rows = m.rows(); + int cols = m.cols(); + + MatrixType m1 = MatrixType::Random(rows, cols); + + VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1)); + VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(rows*cols)); + Scalar x = Scalar(0); + for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) x += m1(i,j); + VERIFY_IS_APPROX(m1.sum(), x); +} + +template void vectorSum(const VectorType& w) +{ + typedef typename VectorType::Scalar Scalar; + int size = w.size(); + + VectorType v = VectorType::Random(size); + for(int i = 1; i < size; i++) + { + Scalar s = Scalar(0); + for(int j = 0; j < i; j++) s += v[j]; + VERIFY_IS_APPROX(s, v.start(i).sum()); + } + + for(int i = 0; i < size-1; i++) + { + Scalar s = Scalar(0); + for(int j = i; j < size; j++) s += v[j]; + VERIFY_IS_APPROX(s, v.end(size-i).sum()); + } + + for(int i = 0; i < size/2; i++) + { + Scalar s = Scalar(0); + for(int j = i; j < size-i; j++) s += v[j]; + VERIFY_IS_APPROX(s, v.block(i, size-2*i).sum()); + } +} + +void test_sum() +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( matrixSum(Matrix()) ); + CALL_SUBTEST( matrixSum(Matrix2f()) ); + CALL_SUBTEST( matrixSum(Matrix4d()) ); + CALL_SUBTEST( matrixSum(MatrixXcf(3, 3)) ); + CALL_SUBTEST( matrixSum(MatrixXf(8, 12)) ); + CALL_SUBTEST( matrixSum(MatrixXi(8, 12)) ); + } + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( vectorSum(VectorXf(5)) ); + CALL_SUBTEST( vectorSum(VectorXd(10)) ); + CALL_SUBTEST( vectorSum(VectorXf(100)) ); + } +}