File: test_einstein_notation.cpp

package info (click to toggle)
boost1.90 1.90.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 593,168 kB
  • sloc: cpp: 4,190,642; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,776; makefile: 1,162; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (122 lines) | stat: -rw-r--r-- 3,615 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//  Copyright (c) 2018-2019 Cem Bassoy
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//  The authors gratefully acknowledge the support of
//  Fraunhofer and Google in producing this work
//  which started as a Google Summer of Code project.
//
//  And we acknowledge the support from all contributors.


#include <iostream>
#include <algorithm>
#include <boost/numeric/ublas/tensor.hpp>

#include <boost/test/unit_test.hpp>

#include "utility.hpp"

BOOST_AUTO_TEST_SUITE ( test_einstein_notation, * boost::unit_test::depends_on("test_multi_index") )


using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>;

//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>;

BOOST_AUTO_TEST_CASE_TEMPLATE( test_einstein_multiplication, value,  test_types )
{
	using namespace boost::numeric::ublas;
	using value_type   = typename value::first_type;
	using layout_type  = typename value::second_type;
	using tensor_type  = tensor<value_type,layout_type>;
	using namespace boost::numeric::ublas::index;

	{
		auto A = tensor_type{5,3};
		auto B = tensor_type{3,4};
		//		auto C = tensor_type{4,5,6};

		for(auto j = 0u; j < A.extents().at(1); ++j)
			for(auto i = 0u; i < A.extents().at(0); ++i)
				A.at( i,j ) = value_type(i+1);

		for(auto j = 0u; j < B.extents().at(1); ++j)
			for(auto i = 0u; i < B.extents().at(0); ++i)
				B.at( i,j ) = value_type(i+1);



		auto AB = A(_,_e) * B(_e,_);

		//		std::cout << "A = " << A << std::endl;
		//		std::cout << "B = " << B << std::endl;
		//		std::cout << "AB = " << AB << std::endl;

		for(auto j = 0u; j < AB.extents().at(1); ++j)
			for(auto i = 0u; i < AB.extents().at(0); ++i)
				BOOST_CHECK_EQUAL( AB.at( i,j ) , value_type(A.at( i,0 ) * ( B.extents().at(0) * (B.extents().at(0)+1) / 2 )) );


	}


	{
		auto A = tensor_type{4,5,3};
		auto B = tensor_type{3,4,2};

		for(auto k = 0u; k < A.extents().at(2); ++k)
			for(auto j = 0u; j < A.extents().at(1); ++j)
				for(auto i = 0u; i < A.extents().at(0); ++i)
					A.at( i,j,k ) = value_type(i+1);

		for(auto k = 0u; k < B.extents().at(2); ++k)
			for(auto j = 0u; j < B.extents().at(1); ++j)
				for(auto i = 0u; i < B.extents().at(0); ++i)
					B.at( i,j,k ) = value_type(i+1);

		auto AB = A(_d,_,_f) * B(_f,_d,_);

		//		std::cout << "A = " << A << std::endl;
		//		std::cout << "B = " << B << std::endl;
		//		std::cout << "AB = " << AB << std::endl;
		// n*(n+1)/2;
		auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 );
		auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 );

		for(auto j = 0u; j < AB.extents().at(1); ++j)
			for(auto i = 0u; i < AB.extents().at(0); ++i)
				BOOST_CHECK_EQUAL( AB.at( i,j ) ,  value_type(nf * nd) );

	}


	{
		auto A = tensor_type{4,3};
		auto B = tensor_type{3,4,2};

		for(auto j = 0u; j < A.extents().at(1); ++j)
			for(auto i = 0u; i < A.extents().at(0); ++i)
				A.at( i,j ) = value_type(i+1);

		for(auto k = 0u; k < B.extents().at(2); ++k)
			for(auto j = 0u; j < B.extents().at(1); ++j)
				for(auto i = 0u; i < B.extents().at(0); ++i)
					B.at( i,j,k ) = value_type(i+1);

		auto AB = A(_d,_f) * B(_f,_d,_);

		// n*(n+1)/2;
		auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 );
		auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 );

		for(auto i = 0u; i < AB.extents().at(0); ++i)
			BOOST_CHECK_EQUAL ( AB.at( i  ) ,  value_type(nf * nd) );

	}
}

BOOST_AUTO_TEST_SUITE_END()