// -*- C++ -*- #include #include "gtest/gtest.h" #include #include "multi_array_header.h" #include namespace MAT = MultiArrayTools; namespace { double xround(double arg) { return roundf(arg * 100000.) / 100000.; } using namespace MAT; template void swapFactory(std::shared_ptr& fptr, std::initializer_list ilist) { std::vector tmp = ilist; auto nptr = std::make_shared( tmp ); fptr = nptr; } template void swapFactory(std::shared_ptr& fptr, std::vector& ilist) { std::vector tmp = ilist; auto nptr = std::make_shared( tmp ); fptr = nptr; } template void swapMFactory(std::shared_ptr& fptr, const Rs&... rs) { auto nptr = std::make_shared( rs... ); fptr = nptr; } template auto mkt(Ts&&... ts) -> decltype(std::make_tuple(ts...)) { return std::make_tuple(ts...); } class OpTest_1Dim : public ::testing::Test { protected: typedef SingleRangeFactory SRF; typedef SRF::oType SRange; OpTest_1Dim() { swapFactory(rfbptr, {'a', 'l', 'f', 'g'} ); srptr = std::dynamic_pointer_cast( rfbptr->create() ); } std::shared_ptr rfbptr; std::shared_ptr srptr; std::vector v1 = { 2.917, 9.436, 0.373, 7.192 }; std::vector v2 = { 8.870, 4.790, 8.215, 5.063 }; }; class OpTest_MDim : public ::testing::Test { protected: typedef SingleRangeFactory SRF; typedef SRF::oType SRange; typedef MultiRangeFactory MRF; typedef MRF::oType MRange; OpTest_MDim() { swapFactory(rfbptr, {'x', 'l', 'f', 'g'} ); sr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); swapFactory(rfbptr, {'1', '2', '3'} ); sr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); swapFactory(rfbptr, {'a', 'b'} ); sr3ptr = std::dynamic_pointer_cast( rfbptr->create() ); swapFactory(rfbptr, {'A', 'B'} ); sr4ptr = std::dynamic_pointer_cast( rfbptr->create() ); swapMFactory(rfbptr, sr2ptr, sr3ptr); mr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); swapMFactory(rfbptr, sr2ptr, sr4ptr); mr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); } std::shared_ptr rfbptr; std::shared_ptr sr1ptr; std::shared_ptr sr2ptr; std::shared_ptr sr3ptr; std::shared_ptr sr4ptr; std::shared_ptr mr1ptr; std::shared_ptr mr2ptr; std::vector v1 = { 2.917, 9.436, 0.373 }; std::vector v2 = { 8.870, 4.790 }; std::vector v3 = { 0.353, 4.005, 1.070, 2.310, 9.243, 2.911 }; std::vector v4 = { 1.470, 2.210 }; }; class OpTest_Performance : public ::testing::Test { protected: typedef SingleRangeFactory SRF; typedef SRF::oType SRange; typedef MultiRangeFactory MRF; typedef MRF::oType MRange; OpTest_Performance() { std::vector initvec1(vs1); cv1.resize(vs1); for(size_t i = 0; i != vs1; ++i){ initvec1[i] = i; cv1[i] = sqrt( static_cast(i)*0.53 ); } std::vector initvec2(vs2); cv2.resize(vs2*vs1); for(size_t i = 0; i != vs2; ++i){ initvec2[i] = i; for(size_t j = 0; j != vs1; ++j){ cv2[i*vs1 + j] = static_cast(i) * sin(static_cast(j)*0.4); } } swapFactory(rfbptr, initvec1); sr1ptr = std::dynamic_pointer_cast(rfbptr->create()); swapFactory(rfbptr, initvec2); sr2ptr = std::dynamic_pointer_cast(rfbptr->create()); swapMFactory(rfbptr, sr2ptr, sr1ptr); mrptr = std::dynamic_pointer_cast(rfbptr->create()); } const size_t vs1 = 10000; const size_t vs2 = 1000; std::shared_ptr rfbptr; std::shared_ptr sr1ptr; std::shared_ptr sr2ptr; std::shared_ptr mrptr; std::vector cv1; std::vector cv2; }; TEST_F(OpTest_Performance, PCheck) { MultiArray ma2(mrptr, cv2); MultiArray ma1(sr1ptr, cv1); MultiArray res(mrptr); auto si1 = std::dynamic_pointer_cast( sr1ptr->index() ); auto si2 = std::dynamic_pointer_cast( sr2ptr->index() ); auto mi = std::dynamic_pointer_cast( mrptr->index() ); (*mi)(si2, si1); std::clock_t begin = std::clock(); res(mi) = ma2(mi) * ma1(si1); std::clock_t end = std::clock(); std::cout << "MultiArray time: " << static_cast( end - begin ) / CLOCKS_PER_SEC << std::endl; std::vector res2(vs1*vs2); std::clock_t begin2 = std::clock(); for(size_t i = 0; i != vs2; ++i){ for(size_t j = 0; j != vs1; ++j){ res2[i*vs1 + j] = cv1[j] * cv2[i*vs1 + j]; } } std::clock_t end2 = std::clock(); std::cout << "std::vector - for loop time: " << static_cast( end2 - begin2 ) / CLOCKS_PER_SEC << std::endl; std::cout << "ratio: " << static_cast( end - begin ) / static_cast( end2 - begin2 ) << std::endl; EXPECT_EQ( xround( res.at(mkt(7,9)) ), xround(res2[7*vs1 + 9]) ); //EXPECT_EQ( xround( res.at(mkt(700,900)) ), xround(res2[700*vs1 + 900]) ); } TEST_F(OpTest_1Dim, ExecOp) { MultiArray ma1(srptr, v1); MultiArray ma2(srptr, v2); MultiArray res(srptr); auto i = std::dynamic_pointer_cast( srptr->index() ); res(i) = ma1(i) + ma2(i); EXPECT_EQ( fabs( res.at('a') - (2.917+8.870) ) < 0.0001, true); EXPECT_EQ( fabs( res.at('l') - (9.436+4.790) ) < 0.0001, true ); EXPECT_EQ( fabs( res.at('f') - (0.373+8.215) ) < 0.0001, true ); EXPECT_EQ( fabs( res.at('g') - (7.192+5.063) ) < 0.0001, true ); } TEST_F(OpTest_MDim, ExecOp1) { MultiArray res(sr2ptr,sr4ptr); const MultiArray ma1(sr2ptr, v1); const MultiArray ma2(sr4ptr, v2); auto i1 = std::dynamic_pointer_cast( sr2ptr->index() ); auto i2 = std::dynamic_pointer_cast( sr4ptr->index() ); res(i1,i2) = ma1(i1) * ma2(i2); EXPECT_EQ( xround( res.at(mkt('1','A')) ), xround(2.917 * 8.870) ); EXPECT_EQ( xround( res.at(mkt('1','B')) ), xround(2.917 * 4.790) ); EXPECT_EQ( xround( res.at(mkt('2','A')) ), xround(9.436 * 8.870) ); EXPECT_EQ( xround( res.at(mkt('2','B')) ), xround(9.436 * 4.790) ); EXPECT_EQ( xround( res.at(mkt('3','A')) ), xround(0.373 * 8.870) ); EXPECT_EQ( xround( res.at(mkt('3','B')) ), xround(0.373 * 4.790) ); } TEST_F(OpTest_MDim, ExecContract) { MultiArray res(sr2ptr); const MultiArray ma1(sr2ptr, v1); const MultiArray ma2(sr4ptr, v2); auto i1 = std::dynamic_pointer_cast( sr2ptr->index() ); auto i2 = std::dynamic_pointer_cast( sr4ptr->index() ); res(i1) = (ma1(i1) * ma2(i2)).c(i2); EXPECT_EQ( xround( res.at('1') ), xround(2.917 * 8.870 + 2.917 * 4.790) ); EXPECT_EQ( xround( res.at('2') ), xround(9.436 * 8.870 + 9.436 * 4.790) ); EXPECT_EQ( xround( res.at('3') ), xround(0.373 * 8.870 + 0.373 * 4.790) ); } TEST_F(OpTest_MDim, ExecOp2) { MultiArray res(mr1ptr,sr4ptr); MultiArray ma1(mr1ptr, v3); MultiArray ma2(sr4ptr, v2); MultiArray ma3(sr4ptr, v4); auto i1 = std::dynamic_pointer_cast( mr1ptr->index() ); auto i2 = std::dynamic_pointer_cast( sr4ptr->index() ); res(i1,i2) = ( ma1(i1) + ma2(i2) ) - ma3(i2); EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'A')) ), xround(0.353 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'B')) ), xround(0.353 + 4.790 - 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'A')) ), xround(4.005 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'B')) ), xround(4.005 + 4.790 - 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'A')) ), xround(1.070 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'B')) ), xround(1.070 + 4.790 - 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'A')) ), xround(2.310 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'B')) ), xround(2.310 + 4.790 - 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'A')) ), xround(9.243 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'B')) ), xround(9.243 + 4.790 - 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'A')) ), xround(2.911 + 8.870 - 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 + 4.790 - 2.210) ); } TEST_F(OpTest_MDim, ExecOp3) { MultiArray res(mr1ptr,sr4ptr); MultiArray ma1(mr1ptr, v3); MultiArray ma2(sr2ptr, v1); MultiArray ma3(sr4ptr, v4); auto si1 = std::dynamic_pointer_cast( sr2ptr->index() ); auto si2 = std::dynamic_pointer_cast( sr3ptr->index() ); auto si3 = std::dynamic_pointer_cast( sr4ptr->index() ); auto mi = std::dynamic_pointer_cast( mr1ptr->index() ); mi->operator()(si1,si2); res(mi,si3) = ma1(mi) + ma2(si1) + ma3(si3); EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'A')) ), xround(0.353 + 2.917 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','a'),'B')) ), xround(0.353 + 2.917 + 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'A')) ), xround(4.005 + 2.917 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('1','b'),'B')) ), xround(4.005 + 2.917 + 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'A')) ), xround(1.070 + 9.436 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','a'),'B')) ), xround(1.070 + 9.436 + 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'A')) ), xround(2.310 + 9.436 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('2','b'),'B')) ), xround(2.310 + 9.436 + 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'A')) ), xround(9.243 + 0.373 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','a'),'B')) ), xround(9.243 + 0.373 + 2.210) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'A')) ), xround(2.911 + 0.373 + 1.470) ); EXPECT_EQ( xround( res.at(mkt(mkt('3','b'),'B')) ), xround(2.911 + 0.373 + 2.210) ); } } // anonymous namspace int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }