redux.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #include "main.h"
00026 
00027 template<typename MatrixType> void matrixRedux(const MatrixType& m)
00028 {
00029   typedef typename MatrixType::Index Index;
00030   typedef typename MatrixType::Scalar Scalar;
00031   typedef typename MatrixType::RealScalar RealScalar;
00032 
00033   Index rows = m.rows();
00034   Index cols = m.cols();
00035 
00036   MatrixType m1 = MatrixType::Random(rows, cols);
00037 
00038   VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1));
00039   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
00040   Scalar s(0), p(1), minc(internal::real(m1.coeff(0))), maxc(internal::real(m1.coeff(0)));
00041   for(int j = 0; j < cols; j++)
00042   for(int i = 0; i < rows; i++)
00043   {
00044     s += m1(i,j);
00045     p *= m1(i,j);
00046     minc = std::min(internal::real(minc), internal::real(m1(i,j)));
00047     maxc = std::max(internal::real(maxc), internal::real(m1(i,j)));
00048   }
00049   const Scalar mean = s/Scalar(RealScalar(rows*cols));
00050 
00051   VERIFY_IS_APPROX(m1.sum(), s);
00052   VERIFY_IS_APPROX(m1.mean(), mean);
00053   VERIFY_IS_APPROX(m1.prod(), p);
00054   VERIFY_IS_APPROX(m1.real().minCoeff(), internal::real(minc));
00055   VERIFY_IS_APPROX(m1.real().maxCoeff(), internal::real(maxc));
00056 
00057   // test slice vectorization assuming assign is ok
00058   Index r0 = internal::random<Index>(0,rows-1);
00059   Index c0 = internal::random<Index>(0,cols-1);
00060   Index r1 = internal::random<Index>(r0+1,rows)-r0;
00061   Index c1 = internal::random<Index>(c0+1,cols)-c0;
00062   VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).sum(), m1.block(r0,c0,r1,c1).eval().sum());
00063   VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).mean(), m1.block(r0,c0,r1,c1).eval().mean());
00064   VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).prod(), m1.block(r0,c0,r1,c1).eval().prod());
00065   VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff());
00066   VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff());
00067   
00068   // test empty objects
00069   VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(),   Scalar(0));
00070   VERIFY_IS_APPROX(m1.block(r0,c0,0,0).prod(),  Scalar(1));
00071 }
00072 
00073 template<typename VectorType> void vectorRedux(const VectorType& w)
00074 {
00075   typedef typename VectorType::Index Index;
00076   typedef typename VectorType::Scalar Scalar;
00077   typedef typename NumTraits<Scalar>::Real RealScalar;
00078   Index size = w.size();
00079 
00080   VectorType v = VectorType::Random(size);
00081   for(int i = 1; i < size; i++)
00082   {
00083     Scalar s(0), p(1);
00084     RealScalar minc(internal::real(v.coeff(0))), maxc(internal::real(v.coeff(0)));
00085     for(int j = 0; j < i; j++)
00086     {
00087       s += v[j];
00088       p *= v[j];
00089       minc = std::min(minc, internal::real(v[j]));
00090       maxc = std::max(maxc, internal::real(v[j]));
00091     }
00092     VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.head(i).sum()), Scalar(1));
00093     VERIFY_IS_APPROX(p, v.head(i).prod());
00094     VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff());
00095     VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff());
00096   }
00097 
00098   for(int i = 0; i < size-1; i++)
00099   {
00100     Scalar s(0), p(1);
00101     RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
00102     for(int j = i; j < size; j++)
00103     {
00104       s += v[j];
00105       p *= v[j];
00106       minc = std::min(minc, internal::real(v[j]));
00107       maxc = std::max(maxc, internal::real(v[j]));
00108     }
00109     VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.tail(size-i).sum()), Scalar(1));
00110     VERIFY_IS_APPROX(p, v.tail(size-i).prod());
00111     VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff());
00112     VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff());
00113   }
00114 
00115   for(int i = 0; i < size/2; i++)
00116   {
00117     Scalar s(0), p(1);
00118     RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
00119     for(int j = i; j < size-i; j++)
00120     {
00121       s += v[j];
00122       p *= v[j];
00123       minc = std::min(minc, internal::real(v[j]));
00124       maxc = std::max(maxc, internal::real(v[j]));
00125     }
00126     VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.segment(i, size-2*i).sum()), Scalar(1));
00127     VERIFY_IS_APPROX(p, v.segment(i, size-2*i).prod());
00128     VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff());
00129     VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff());
00130   }
00131   
00132   // test empty objects
00133   VERIFY_IS_APPROX(v.head(0).sum(),   Scalar(0));
00134   VERIFY_IS_APPROX(v.tail(0).prod(),  Scalar(1));
00135   VERIFY_RAISES_ASSERT(v.head(0).mean());
00136   VERIFY_RAISES_ASSERT(v.head(0).minCoeff());
00137   VERIFY_RAISES_ASSERT(v.head(0).maxCoeff());
00138 }
00139 
00140 void test_redux()
00141 {
00142   for(int i = 0; i < g_repeat; i++) {
00143     CALL_SUBTEST_1( matrixRedux(Matrix<float, 1, 1>()) );
00144     CALL_SUBTEST_1( matrixRedux(Array<float, 1, 1>()) );
00145     CALL_SUBTEST_2( matrixRedux(Matrix2f()) );
00146     CALL_SUBTEST_2( matrixRedux(Array2f()) );
00147     CALL_SUBTEST_3( matrixRedux(Matrix4d()) );
00148     CALL_SUBTEST_3( matrixRedux(Array4d()) );
00149     CALL_SUBTEST_4( matrixRedux(MatrixXcf(3, 3)) );
00150     CALL_SUBTEST_4( matrixRedux(ArrayXXcf(3, 3)) );
00151     CALL_SUBTEST_5( matrixRedux(MatrixXd(8, 12)) );
00152     CALL_SUBTEST_5( matrixRedux(ArrayXXd(8, 12)) );
00153     CALL_SUBTEST_6( matrixRedux(MatrixXi(8, 12)) );
00154     CALL_SUBTEST_6( matrixRedux(ArrayXXi(8, 12)) );
00155   }
00156   for(int i = 0; i < g_repeat; i++) {
00157     CALL_SUBTEST_7( vectorRedux(Vector4f()) );
00158     CALL_SUBTEST_7( vectorRedux(Array4f()) );
00159     CALL_SUBTEST_5( vectorRedux(VectorXd(10)) );
00160     CALL_SUBTEST_5( vectorRedux(ArrayXd(10)) );
00161     CALL_SUBTEST_8( vectorRedux(VectorXf(33)) );
00162     CALL_SUBTEST_8( vectorRedux(ArrayXf(33)) );
00163   }
00164 }


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:33:18