2009-02-12 23:18:59 +08:00
// This file is part of Eigen, a lightweight C++ template library
2009-05-23 02:25:33 +08:00
// for linear algebra.
2009-02-12 23:18:59 +08:00
//
// Copyright (C) 2008 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 matrixRedux ( const MatrixType & m )
{
2010-06-20 23:37:56 +08:00
typedef typename MatrixType : : Index Index ;
2009-02-12 23:18:59 +08:00
typedef typename MatrixType : : Scalar Scalar ;
2010-02-04 02:20:25 +08:00
typedef typename MatrixType : : RealScalar RealScalar ;
2009-02-12 23:18:59 +08:00
2010-06-20 23:37:56 +08:00
Index rows = m . rows ( ) ;
Index cols = m . cols ( ) ;
2009-02-12 23:18:59 +08:00
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 ( float ( rows * cols ) ) ) ; // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy
2010-10-25 22:15:22 +08:00
Scalar s ( 0 ) , p ( 1 ) , minc ( internal : : real ( m1 . coeff ( 0 ) ) ) , maxc ( internal : : real ( m1 . coeff ( 0 ) ) ) ;
2009-02-12 23:18:59 +08:00
for ( int j = 0 ; j < cols ; j + + )
for ( int i = 0 ; i < rows ; i + + )
{
s + = m1 ( i , j ) ;
p * = m1 ( i , j ) ;
2010-10-25 22:15:22 +08:00
minc = std : : min ( internal : : real ( minc ) , internal : : real ( m1 ( i , j ) ) ) ;
maxc = std : : max ( internal : : real ( maxc ) , internal : : real ( m1 ( i , j ) ) ) ;
2009-02-12 23:18:59 +08:00
}
2010-02-04 02:20:25 +08:00
const Scalar mean = s / Scalar ( RealScalar ( rows * cols ) ) ;
2010-01-29 19:12:02 +08:00
2009-02-12 23:18:59 +08:00
VERIFY_IS_APPROX ( m1 . sum ( ) , s ) ;
2010-01-29 19:12:02 +08:00
VERIFY_IS_APPROX ( m1 . mean ( ) , mean ) ;
2009-02-12 23:18:59 +08:00
VERIFY_IS_APPROX ( m1 . prod ( ) , p ) ;
2010-10-25 22:15:22 +08:00
VERIFY_IS_APPROX ( m1 . real ( ) . minCoeff ( ) , internal : : real ( minc ) ) ;
VERIFY_IS_APPROX ( m1 . real ( ) . maxCoeff ( ) , internal : : real ( maxc ) ) ;
2010-05-14 05:34:04 +08:00
2010-06-21 00:59:15 +08:00
// test slice vectorization assuming assign is ok
2010-10-25 22:15:22 +08:00
Index r0 = internal : : random < Index > ( 0 , rows - 1 ) ;
Index c0 = internal : : random < Index > ( 0 , cols - 1 ) ;
Index r1 = internal : : random < Index > ( r0 + 1 , rows ) - r0 ;
Index c1 = internal : : random < Index > ( c0 + 1 , cols ) - c0 ;
2010-05-14 05:34:04 +08:00
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , r1 , c1 ) . sum ( ) , m1 . block ( r0 , c0 , r1 , c1 ) . eval ( ) . sum ( ) ) ;
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , r1 , c1 ) . mean ( ) , m1 . block ( r0 , c0 , r1 , c1 ) . eval ( ) . mean ( ) ) ;
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , r1 , c1 ) . prod ( ) , m1 . block ( r0 , c0 , r1 , c1 ) . eval ( ) . prod ( ) ) ;
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , r1 , c1 ) . real ( ) . minCoeff ( ) , m1 . block ( r0 , c0 , r1 , c1 ) . real ( ) . eval ( ) . minCoeff ( ) ) ;
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , r1 , c1 ) . real ( ) . maxCoeff ( ) , m1 . block ( r0 , c0 , r1 , c1 ) . real ( ) . eval ( ) . maxCoeff ( ) ) ;
2010-07-16 20:02:20 +08:00
// test empty objects
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , 0 , 0 ) . sum ( ) , Scalar ( 0 ) ) ;
VERIFY_IS_APPROX ( m1 . block ( r0 , c0 , 0 , 0 ) . prod ( ) , Scalar ( 1 ) ) ;
2009-02-12 23:18:59 +08:00
}
template < typename VectorType > void vectorRedux ( const VectorType & w )
{
2010-06-21 02:16:45 +08:00
typedef typename VectorType : : Index Index ;
2009-02-12 23:18:59 +08:00
typedef typename VectorType : : Scalar Scalar ;
typedef typename NumTraits < Scalar > : : Real RealScalar ;
2010-06-21 02:16:45 +08:00
Index size = w . size ( ) ;
2009-02-12 23:18:59 +08:00
VectorType v = VectorType : : Random ( size ) ;
for ( int i = 1 ; i < size ; i + + )
{
Scalar s ( 0 ) , p ( 1 ) ;
2010-10-25 22:15:22 +08:00
RealScalar minc ( internal : : real ( v . coeff ( 0 ) ) ) , maxc ( internal : : real ( v . coeff ( 0 ) ) ) ;
2009-02-12 23:18:59 +08:00
for ( int j = 0 ; j < i ; j + + )
{
s + = v [ j ] ;
p * = v [ j ] ;
2010-10-25 22:15:22 +08:00
minc = std : : min ( minc , internal : : real ( v [ j ] ) ) ;
maxc = std : : max ( maxc , internal : : real ( v [ j ] ) ) ;
2009-02-12 23:18:59 +08:00
}
2010-01-05 10:24:43 +08:00
VERIFY_IS_APPROX ( s , v . head ( i ) . sum ( ) ) ;
VERIFY_IS_APPROX ( p , v . head ( i ) . prod ( ) ) ;
VERIFY_IS_APPROX ( minc , v . real ( ) . head ( i ) . minCoeff ( ) ) ;
VERIFY_IS_APPROX ( maxc , v . real ( ) . head ( i ) . maxCoeff ( ) ) ;
2009-02-12 23:18:59 +08:00
}
for ( int i = 0 ; i < size - 1 ; i + + )
{
Scalar s ( 0 ) , p ( 1 ) ;
2010-10-25 22:15:22 +08:00
RealScalar minc ( internal : : real ( v . coeff ( i ) ) ) , maxc ( internal : : real ( v . coeff ( i ) ) ) ;
2009-02-12 23:18:59 +08:00
for ( int j = i ; j < size ; j + + )
{
s + = v [ j ] ;
p * = v [ j ] ;
2010-10-25 22:15:22 +08:00
minc = std : : min ( minc , internal : : real ( v [ j ] ) ) ;
maxc = std : : max ( maxc , internal : : real ( v [ j ] ) ) ;
2009-02-12 23:18:59 +08:00
}
2010-10-25 22:15:22 +08:00
VERIFY_IS_MUCH_SMALLER_THAN ( internal : : abs ( s - v . tail ( size - i ) . sum ( ) ) , Scalar ( 1 ) ) ;
2010-01-05 10:24:43 +08:00
VERIFY_IS_APPROX ( p , v . tail ( size - i ) . prod ( ) ) ;
VERIFY_IS_APPROX ( minc , v . real ( ) . tail ( size - i ) . minCoeff ( ) ) ;
VERIFY_IS_APPROX ( maxc , v . real ( ) . tail ( size - i ) . maxCoeff ( ) ) ;
2009-02-12 23:18:59 +08:00
}
for ( int i = 0 ; i < size / 2 ; i + + )
{
Scalar s ( 0 ) , p ( 1 ) ;
2010-10-25 22:15:22 +08:00
RealScalar minc ( internal : : real ( v . coeff ( i ) ) ) , maxc ( internal : : real ( v . coeff ( i ) ) ) ;
2009-02-12 23:18:59 +08:00
for ( int j = i ; j < size - i ; j + + )
{
s + = v [ j ] ;
p * = v [ j ] ;
2010-10-25 22:15:22 +08:00
minc = std : : min ( minc , internal : : real ( v [ j ] ) ) ;
maxc = std : : max ( maxc , internal : : real ( v [ j ] ) ) ;
2009-02-12 23:18:59 +08:00
}
VERIFY_IS_APPROX ( s , v . segment ( i , size - 2 * i ) . sum ( ) ) ;
VERIFY_IS_APPROX ( p , v . segment ( i , size - 2 * i ) . prod ( ) ) ;
VERIFY_IS_APPROX ( minc , v . real ( ) . segment ( i , size - 2 * i ) . minCoeff ( ) ) ;
VERIFY_IS_APPROX ( maxc , v . real ( ) . segment ( i , size - 2 * i ) . maxCoeff ( ) ) ;
}
2010-07-16 20:02:20 +08:00
// test empty objects
VERIFY_IS_APPROX ( v . head ( 0 ) . sum ( ) , Scalar ( 0 ) ) ;
VERIFY_IS_APPROX ( v . tail ( 0 ) . prod ( ) , Scalar ( 1 ) ) ;
VERIFY_RAISES_ASSERT ( v . head ( 0 ) . mean ( ) ) ;
VERIFY_RAISES_ASSERT ( v . head ( 0 ) . minCoeff ( ) ) ;
VERIFY_RAISES_ASSERT ( v . head ( 0 ) . maxCoeff ( ) ) ;
2009-02-12 23:18:59 +08:00
}
void test_redux ( )
{
for ( int i = 0 ; i < g_repeat ; i + + ) {
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_1 ( matrixRedux ( Matrix < float , 1 , 1 > ( ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_1 ( matrixRedux ( Array < float , 1 , 1 > ( ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_2 ( matrixRedux ( Matrix2f ( ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_2 ( matrixRedux ( Array2f ( ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_3 ( matrixRedux ( Matrix4d ( ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_3 ( matrixRedux ( Array4d ( ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_4 ( matrixRedux ( MatrixXcf ( 3 , 3 ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_4 ( matrixRedux ( ArrayXXcf ( 3 , 3 ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_5 ( matrixRedux ( MatrixXd ( 8 , 12 ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_5 ( matrixRedux ( ArrayXXd ( 8 , 12 ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_6 ( matrixRedux ( MatrixXi ( 8 , 12 ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_6 ( matrixRedux ( ArrayXXi ( 8 , 12 ) ) ) ;
2009-02-12 23:18:59 +08:00
}
for ( int i = 0 ; i < g_repeat ; i + + ) {
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_7 ( vectorRedux ( Vector4f ( ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_7 ( vectorRedux ( Array4f ( ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_5 ( vectorRedux ( VectorXd ( 10 ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_5 ( vectorRedux ( ArrayXd ( 10 ) ) ) ;
2009-10-29 06:19:29 +08:00
CALL_SUBTEST_8 ( vectorRedux ( VectorXf ( 33 ) ) ) ;
2010-01-29 19:12:02 +08:00
CALL_SUBTEST_8 ( vectorRedux ( ArrayXf ( 33 ) ) ) ;
2009-02-12 23:18:59 +08:00
}
}