1 // Copyright (c) 2018-2019 Cem Bassoy
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // The authors gratefully acknowledge the support of
8 // Fraunhofer and Google in producing this work
9 // which started as a Google Summer of Code project.
11 // And we acknowledge the support from all contributors.
16 #include <boost/numeric/ublas/tensor.hpp>
18 #include <boost/test/unit_test.hpp>
20 #include "utility.hpp"
22 BOOST_AUTO_TEST_SUITE ( test_einstein_notation
, * boost::unit_test::depends_on("test_multi_index") )
25 using test_types
= zip
<int,long,float,double,std::complex<float>>::with_t
<boost::numeric::ublas::first_order
, boost::numeric::ublas::last_order
>;
27 //using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>;
29 BOOST_AUTO_TEST_CASE_TEMPLATE( test_einstein_multiplication
, value
, test_types
)
31 using namespace boost::numeric::ublas
;
32 using value_type
= typename
value::first_type
;
33 using layout_type
= typename
value::second_type
;
34 using tensor_type
= tensor
<value_type
,layout_type
>;
35 using namespace boost::numeric::ublas::index
;
38 auto A
= tensor_type
{5,3};
39 auto B
= tensor_type
{3,4};
40 // auto C = tensor_type{4,5,6};
42 for(auto j
= 0u; j
< A
.extents().at(1); ++j
)
43 for(auto i
= 0u; i
< A
.extents().at(0); ++i
)
44 A
.at( i
,j
) = value_type(i
+1);
46 for(auto j
= 0u; j
< B
.extents().at(1); ++j
)
47 for(auto i
= 0u; i
< B
.extents().at(0); ++i
)
48 B
.at( i
,j
) = value_type(i
+1);
52 auto AB
= A(_
,_e
) * B(_e
,_
);
54 // std::cout << "A = " << A << std::endl;
55 // std::cout << "B = " << B << std::endl;
56 // std::cout << "AB = " << AB << std::endl;
58 for(auto j
= 0u; j
< AB
.extents().at(1); ++j
)
59 for(auto i
= 0u; i
< AB
.extents().at(0); ++i
)
60 BOOST_CHECK_EQUAL( AB
.at( i
,j
) , value_type(A
.at( i
,0 ) * ( B
.extents().at(0) * (B
.extents().at(0)+1) / 2 )) );
67 auto A
= tensor_type
{4,5,3};
68 auto B
= tensor_type
{3,4,2};
70 for(auto k
= 0u; k
< A
.extents().at(2); ++k
)
71 for(auto j
= 0u; j
< A
.extents().at(1); ++j
)
72 for(auto i
= 0u; i
< A
.extents().at(0); ++i
)
73 A
.at( i
,j
,k
) = value_type(i
+1);
75 for(auto k
= 0u; k
< B
.extents().at(2); ++k
)
76 for(auto j
= 0u; j
< B
.extents().at(1); ++j
)
77 for(auto i
= 0u; i
< B
.extents().at(0); ++i
)
78 B
.at( i
,j
,k
) = value_type(i
+1);
80 auto AB
= A(_d
,_
,_f
) * B(_f
,_d
,_
);
82 // std::cout << "A = " << A << std::endl;
83 // std::cout << "B = " << B << std::endl;
84 // std::cout << "AB = " << AB << std::endl;
86 auto const nf
= ( B
.extents().at(0) * (B
.extents().at(0)+1) / 2 );
87 auto const nd
= ( A
.extents().at(0) * (A
.extents().at(0)+1) / 2 );
89 for(auto j
= 0u; j
< AB
.extents().at(1); ++j
)
90 for(auto i
= 0u; i
< AB
.extents().at(0); ++i
)
91 BOOST_CHECK_EQUAL( AB
.at( i
,j
) , value_type(nf
* nd
) );
97 auto A
= tensor_type
{4,3};
98 auto B
= tensor_type
{3,4,2};
100 for(auto j
= 0u; j
< A
.extents().at(1); ++j
)
101 for(auto i
= 0u; i
< A
.extents().at(0); ++i
)
102 A
.at( i
,j
) = value_type(i
+1);
104 for(auto k
= 0u; k
< B
.extents().at(2); ++k
)
105 for(auto j
= 0u; j
< B
.extents().at(1); ++j
)
106 for(auto i
= 0u; i
< B
.extents().at(0); ++i
)
107 B
.at( i
,j
,k
) = value_type(i
+1);
109 auto AB
= A(_d
,_f
) * B(_f
,_d
,_
);
112 auto const nf
= ( B
.extents().at(0) * (B
.extents().at(0)+1) / 2 );
113 auto const nd
= ( A
.extents().at(0) * (A
.extents().at(0)+1) / 2 );
115 for(auto i
= 0u; i
< AB
.extents().at(0); ++i
)
116 BOOST_CHECK_EQUAL ( AB
.at( i
) , value_type(nf
* nd
) );
121 BOOST_AUTO_TEST_SUITE_END()