/* * Tiny Vector Matrix Library * Dense Vector Matrix Libary of Tiny size using Expression Templates * * Copyright (C) 2001 - 2003 Olaf Petzold * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: TestUnloops.h,v 1.1 2004/04/24 11:55:15 opetzold Exp $ */ #ifndef TVMET_TEST_UNLOOPS_H #define TVMET_TEST_UNLOOPS_H #include #include #include #include #include template class TestUnloops : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( TestUnloops ); CPPUNIT_TEST( Mx ); CPPUNIT_TEST( Mtx ); CPPUNIT_TEST( MM ); // CPPUNIT_TEST( MtM ); // CPPUNIT_TEST( MMt ); // CPPUNIT_TEST( tMM ); CPPUNIT_TEST_SUITE_END(); public: TestUnloops() { } public: // cppunit interface /** cppunit hook for fixture set up. */ void setUp(); /** cppunit hook for fixture tear down. */ void tearDown(); protected: template void mv_product(const A&, const B&, C&); template void mm_product(const A&, const B&, C&); template void mtm_product(const A&, const B&, C&); template void mmt_product(const A&, const B&, C&); protected: void Mx(); void Mtx(); void MM(); void MtM(); void MMt(); void tMM(); public: typedef T value_type; private: enum { dim = 8, foo = 2 }; }; /***************************************************************************** * Implementation part I (cppunit part) ****************************************************************************/ template void TestUnloops::setUp() { } template void TestUnloops::tearDown() { } /***************************************************************************** * Implementation part II (reference loops) ****************************************************************************/ template template void TestUnloops::mv_product(const LHS& A, const RHS& B, RES& X) { assert(int(LHS::Rows) == int(RES::Size)); assert(int(LHS::Cols) == int(RHS::Size)); enum { M = LHS::Rows, N = RHS::Size // is Vector }; for (int i = 0; i < M; i++){ value_type sum(0); for (int j = 0; j < N; j++){ sum += A(i, j) * B(j); } X(i) = sum; } } template template void TestUnloops::mm_product(const LHS& A, const RHS& B, RES& X) { assert(int(LHS::Rows) == int(RES::Rows)); assert(int(LHS::Cols) == int(RHS::Rows)); assert(int(RHS::Cols) == int(RES::Cols)); enum { M = LHS::Rows, N = RHS::Cols, K = RHS::Rows }; for (int i = 0; i < M; ++i) { for (int j = 0; j < N; ++j) { value_type sum(0); for (int k = 0; k < K; ++k) { sum += A(i, k) * B(k, j); } X(i, j) = sum; } } } template template void TestUnloops::mtm_product(const LHS& A, const RHS& B, RES& X) { assert(int(LHS::Rows) == int(RHS::Rows)); assert(int(LHS::Cols) == int(RES::Rows)); assert(int(RHS::Cols) == int(RES::Cols)); enum { M = LHS::Cols, N = RHS::Cols, K = RHS::Rows }; for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ value_type sum(0); for (int k = 0; k < K; k++){ sum += A(k, i) * B(k, j); } X(i, j) = sum; } } } template template void TestUnloops::mmt_product(const LHS& A, const RHS& B, RES& X) { assert(int(LHS::Rows) == int(RES::Rows)); assert(int(LHS::Cols) == int(RHS::Cols)); assert(int(RHS::Rows) == int(RES::Cols)); enum { M = LHS::Rows, N = RHS::Rows, K = LHS::Cols }; for (int i = 0;i < N; i++){ for (int j = 0;j < N; j++){ value_type sum(0); for (int k = 0;k < N; k++){ sum += A(i, k)*A(j, k); } X(i, j) = sum; } } } /***************************************************************************** * Implementation part III ****************************************************************************/ template void TestUnloops::Mx() { using namespace tvmet; enum { Rows = dim-foo, Cols = dim+foo, }; typedef Matrix matrix1_type; typedef Vector vector1_type; typedef Vector vector2_type; matrix1_type M; vector1_type x; std::generate(M.begin(), M.end(), tvmet::util::Incrementor()); std::generate(x.begin(), x.end(), tvmet::util::Incrementor()); vector2_type r; mv_product(M, x, r); vector2_type y; y = prod(M, x); CPPUNIT_ASSERT( all_elements( y == r ) ); } template void TestUnloops::Mtx() { using namespace tvmet; enum { Rows = dim-foo, Cols = dim+foo, }; typedef Matrix matrix1_type; typedef Matrix matrix1t_type; typedef Vector vector1_type; typedef Vector vector2_type; matrix1_type M; vector1_type x; std::generate(M.begin(), M.end(), tvmet::util::Incrementor()); std::generate(x.begin(), x.end(), tvmet::util::Incrementor()); vector2_type r; matrix1t_type Mt(trans(M)); mv_product(Mt, x, r); vector2_type y; y = Mtx_prod(M, x); CPPUNIT_ASSERT( all_elements( y == r ) ); } template void TestUnloops::MM() { using namespace tvmet; enum { Rows1 = dim-foo, Cols1 = dim+foo, Cols2 = dim }; typedef Matrix matrix1_type; typedef Matrix matrix2_type; typedef Matrix matrix3_type; matrix1_type M1; matrix2_type M2; std::generate(M1.begin(), M1.end(), tvmet::util::Incrementor()); std::generate(M2.begin(), M2.end(), tvmet::util::Incrementor()); matrix3_type R; mm_product(M1, M2, R); matrix3_type M3; M3 = prod(M1, M2); CPPUNIT_ASSERT( all_elements( M3 == R ) ); } template void TestUnloops::MtM() { using namespace tvmet; enum { Rows1 = dim-foo, Cols1 = dim+foo, Cols2 = dim }; typedef Matrix matrix1_type; typedef Matrix matrix2_type; typedef Matrix matrix3_type; matrix1_type M1; matrix2_type M2; std::generate(M1.begin(), M1.end(), tvmet::util::Incrementor()); std::generate(M2.begin(), M2.end(), tvmet::util::Incrementor()); matrix3_type R; mtm_product(M1, M2, R); matrix3_type M3; M3 = MtM_prod(M1, M2); std::cout << "M1=" << M1 << std::endl; std::cout << "M2=" << M2 << std::endl; std::cout << "M3=" << M3 << std::endl; std::cout << "R=" << R << std::endl; CPPUNIT_ASSERT( all_elements( M3 == R ) ); } template void TestUnloops::MMt() { using namespace tvmet; enum { Rows1 = dim-foo, Cols1 = dim+foo, Rows2 = dim }; typedef Matrix matrix1_type; typedef Matrix matrix2_type; typedef Matrix matrix3_type; matrix1_type M1; matrix2_type M2; std::generate(M1.begin(), M1.end(), tvmet::util::Incrementor()); std::generate(M2.begin(), M2.end(), tvmet::util::Incrementor()); matrix3_type R; mmt_product(M1, M2, R); matrix3_type M3; M3 = MMt_prod(M1, M2); std::cout << "M1=" << M1 << std::endl; std::cout << "M2=" << M2 << std::endl; std::cout << "M3=" << M3 << std::endl; std::cout << "R=" << R << std::endl; CPPUNIT_ASSERT( all_elements( M3 == R ) ); } template void TestUnloops::tMM() { using namespace tvmet; enum { Rows1 = dim-foo, Cols1 = dim+foo, Cols2 = dim }; typedef Matrix matrix1_type; typedef Matrix matrix2_type; typedef Matrix matrix3_type; typedef Matrix matrix3t_type; matrix1_type M1; matrix2_type M2; std::generate(M1.begin(), M1.end(), tvmet::util::Incrementor()); std::generate(M2.begin(), M2.end(), tvmet::util::Incrementor()); matrix3_type R; matrix3t_type Rt; mm_product(M1, M2, R); Rt = trans(R); matrix3t_type M3; M3 = trans_prod(M1, M2); std::cout << "M1=" << M1 << std::endl; std::cout << "M2=" << M2 << std::endl; std::cout << "M3=" << M3 << std::endl; std::cout << "Rt=" << Rt << std::endl; CPPUNIT_ASSERT( all_elements( M3 == Rt ) ); } #endif // TVMET_TEST_UNLOOPS_H // Local Variables: // mode:C++ // End: