<commit_before>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 <NAME> and <NAME>. 
// 
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
// 
// Xerus 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 Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org 
// or contact us at <EMAIL>.


#include<xerus.h>

#include "../../include/xerus/misc/test.h"
using namespace xerus;

UNIT_TEST(TensorNetwork, contractions_of_4_to_degree_0,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({100,1}, rnd, dist);
	Tensor B = Tensor::random({100,1}, rnd, dist);
	Tensor C = Tensor::random({100,1}, rnd, dist);
	Tensor D = Tensor::random({100,1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3,i4;
	
	
	E() = A(i1,i2) * D(i1,i2);
	double a1 = E[{}];
	E() = B(i3,i4) * C(i3,i4);
	double a2 = E[{}];
	E() = A(i1,i2) * B(i3,i2) * C(i3,i4) * D(i1,i4);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
	E() = B(i3,i2) * C(i3,i4) * D(i1,i4) * A(i1,i2);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
	E() = B(i3,i2) * D(i1,i4) * C(i3,i4) * A(i1,i2);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
)

UNIT_TEST(TensorNetwork, contractions_of_3_to_degree_0,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({1,10}, rnd, dist);
	Tensor B = Tensor::random({10,100}, rnd, dist);
	Tensor C = Tensor::random({100,1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3,i4;
	
	
	E() = A(i1,i2) * B(i2,i3) * C(i3,i1);
	double a1 = E[{}];
	E() = B(i2,i3) * C(i3,i1) * A(i1,i2);
	double a2 = E[{}];
	E() = C(i3,i1) * B(i2,i3) * A(i1,i2);
	double a3 = E[{}];
	LOG(unit_test, a1 << " " << a2 << " " << a3 << " " << a1-a2 << " " << a2-a3);
	TEST(misc::approx_equal(a1, a2, 1e-20*a1)); // effectively ==
	TEST(misc::approx_equal(a2, a3, 1e-20*a2));
)

UNIT_TEST(TensorNetwork, contraction_single_node_trace,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({1,10,10}, rnd, dist);
	Tensor B = Tensor::random({1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3;
	
 	E() = A(i1,i2,i2) * B(i1);
	TEST(std::isnormal(E[{}]));
)

UNIT_TEST(TensorNetwork, contraction_single_network_trace,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({2,2,2,2}, rnd, dist);
	TensorNetwork ATN(A);
	Tensor E;
	TensorNetwork ETN(0);
	Index i1,i2,i3,i4;
	
	ETN() = ATN(i1,i1,i2,i2);
	E = Tensor(ETN);
	TEST(std::isnormal(E[{}]));
 	E() = ATN(i1,i1,i2,i2);
	TEST(std::isnormal(E[{}]));
	
)




UNIT_TEST(TensorNetwork, triple_indices,
	std::mt19937_64 rnd;<commit_msg>added failing testcase for reshuffeling indices, relates #155<commit_after>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 <NAME> and <NAME>. 
// 
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
// 
// Xerus 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 Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org 
// or contact us at <EMAIL>.


#include<xerus.h>

#include "../../include/xerus/misc/test.h"
using namespace xerus;

UNIT_TEST(TensorNetwork, contractions_of_4_to_degree_0,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({100,1}, rnd, dist);
	Tensor B = Tensor::random({100,1}, rnd, dist);
	Tensor C = Tensor::random({100,1}, rnd, dist);
	Tensor D = Tensor::random({100,1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3,i4;
	
	
	E() = A(i1,i2) * D(i1,i2);
	double a1 = E[{}];
	E() = B(i3,i4) * C(i3,i4);
	double a2 = E[{}];
	E() = A(i1,i2) * B(i3,i2) * C(i3,i4) * D(i1,i4);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
	E() = B(i3,i2) * C(i3,i4) * D(i1,i4) * A(i1,i2);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
	E() = B(i3,i2) * D(i1,i4) * C(i3,i4) * A(i1,i2);
	TEST(misc::approx_equal(E[{}], a1 * a2, 1e-20));
)

UNIT_TEST(TensorNetwork, contractions_of_3_to_degree_0,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({1,10}, rnd, dist);
	Tensor B = Tensor::random({10,100}, rnd, dist);
	Tensor C = Tensor::random({100,1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3,i4;
	
	
	E() = A(i1,i2) * B(i2,i3) * C(i3,i1);
	double a1 = E[{}];
	E() = B(i2,i3) * C(i3,i1) * A(i1,i2);
	double a2 = E[{}];
	E() = C(i3,i1) * B(i2,i3) * A(i1,i2);
	double a3 = E[{}];
	LOG(unit_test, a1 << " " << a2 << " " << a3 << " " << a1-a2 << " " << a2-a3);
	TEST(misc::approx_equal(a1, a2, 1e-20*a1)); // effectively ==
	TEST(misc::approx_equal(a2, a3, 1e-20*a2));
)

UNIT_TEST(TensorNetwork, contraction_single_node_trace,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({1,10,10}, rnd, dist);
	Tensor B = Tensor::random({1}, rnd, dist);
	Tensor E;
	Index i1,i2,i3;
	
 	E() = A(i1,i2,i2) * B(i1);
	TEST(std::isnormal(E[{}]));
)

UNIT_TEST(TensorNetwork, contraction_single_network_trace,
	std::mt19937_64 rnd;
    std::normal_distribution<value_t> dist (0.0, 10.0);

    Tensor A = Tensor::random({2,2,2,2}, rnd, dist);
	TensorNetwork ATN(A);
	Tensor E;
	TensorNetwork ETN(0);
	Index i1,i2,i3,i4;
	
	ETN() = ATN(i1,i1,i2,i2);
	E = Tensor(ETN);
	TEST(std::isnormal(E[{}]));
 	E() = ATN(i1,i1,i2,i2);
	TEST(std::isnormal(E[{}]));
	
)


UNIT_TEST(TensorNetwork, index_reshuffle2,
		  TensorNetwork A, B;
		  Index n1,n2,n3,n4,r1,r2;
		  Tensor At({2,1,3});
		  Tensor Bt({1,4,5,1});
		  Tensor Bt2({1,6,7,1});
		  A = At;
		  B = Bt;
		  A.draw(std::string("out")+misc::to_string(0));
		  A(n1^(1), n2, r2, n3^(1), n4) = A(n1^(1), r1, n3^(1)) * B(r1, n2, n4, r2);
		  A.draw(std::string("out")+misc::to_string(1));
		  TEST(A.dimensions == std::vector<size_t>({2,4,1,3,5}));
		  B = Bt2;
		  A(n1^(2), n2, r2, n3^(2), n4) = A(n1^(2), r1, n3^(2)) * B(r1, n2, n4, r2);
		  A.draw(std::string("out")+misc::to_string(2));
		  MTEST(A.dimensions == std::vector<size_t>({2,4,6,1,3,5,7}), "found " << A.dimensions);
)


UNIT_TEST(TensorNetwork, triple_indices,
	std::mt19937_64 rnd;
{'fraction_non_alphanumeric': 0.203771460737405, 'fraction_numerical': 0.07261469180973824, 'mean_word_length': 4.264444444444444, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 23, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4489503', 'n_tokens_mistral': 3352, 'n_tokens_neox': 3112, 'n_words': 700}