File: lr_tensor.cc

package info (click to toggle)
cadabra2 2.4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 78,732 kB
  • sloc: ansic: 133,450; cpp: 92,064; python: 1,530; javascript: 203; sh: 184; xml: 182; objc: 53; makefile: 51
file content (154 lines) | stat: -rw-r--r-- 3,512 bytes parent folder | download | duplicates (3)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

#include "Cleanup.hh"
#include "algorithms/lr_tensor.hh"
#include "properties/Tableau.hh"
#include "properties/FilledTableau.hh"

using namespace cadabra;

lr_tensor::lr_tensor(const Kernel& k, Ex& tr)
	: tab_basics(k, tr)
	{
	}

bool lr_tensor::can_apply(iterator it)
	{
	if(*it->name=="\\prod") {
		sibling_iterator sib=tr.begin(it);
		tab1=tr.end(it);
		tab2=tr.end(it);
		while(sib!=tr.end(it)) {
			if(kernel.properties.get<Tableau>(sib)) {
				// FIXME: test that tab2 has the same dimension!
				if(tab1==tr.end(it))
					tab1=sib;
				else {
					tab2=sib;
					break;
					}
				}
			++sib;
			}
		if(tab2!=tr.end(it)) return true;

		sib=tr.begin(it);
		tab1=tr.end(it);
		tab2=tr.end(it);
		while(sib!=tr.end(it)) {
			if(kernel.properties.get<FilledTableau>(sib)) {
				if(tab1==tr.end(it))
					tab1=sib;
				else {
					tab2=sib;
					break;
					}
				}
			++sib;
			}
		if(tab2!=tr.end(it)) return true;
		}
	return false;
	}

Algorithm::result_t lr_tensor::apply(iterator& it)
	{
	const Tableau       *t1=kernel.properties.get<Tableau>(tab1);
	const FilledTableau *f1=kernel.properties.get<FilledTableau>(tab1);
	
	if(t1) do_tableau(it, t1->dimension);
	else   do_filledtableau(it, f1->dimension);

	return result_t::l_applied;
	}

// The format is \ftab{a,b,c}{d,e}{f}.
//
void lr_tensor::do_filledtableau(iterator& it, int dimension)
	{
	bool even_only=false;
	bool singlet_rules=false;

	// FIXME: put arguments back
	//	if(has_argument("EvenOnly"))
	//		 even_only=true;
	//	if(has_argument("SingletRules"))
	//		 singlet_rules=true;

	uinttab_t one, two;

	// For efficiency we store integers in the tableaux, not the actual
	// Ex objects.
	uinttabs_t prod;

	num_to_it.clear();
	tree_to_numerical_tab(tab1, one);
	tree_to_numerical_tab(tab2, two);

	yngtab::LR_tensor(one,two,dimension,prod.get_back_insert_iterator());

	Ex rep;
	iterator top=rep.set_head(str_node("\\sum"));

	if(singlet_rules) tabs_to_singlet_rules(prod, top);
	else              tabs_to_tree(prod, top, tab1, even_only);

	sibling_iterator sib=rep.begin(top);
	while(sib!=rep.end(top)) {
		sib->fl.bracket=str_node::b_round;
		++sib;
		}

	tr.replace(tab1, rep.begin());
	tr.erase(tab2);
	cleanup_dispatch(kernel, tr, it);
	}

void lr_tensor::do_tableau(iterator& it, int dimension)
	{
	bool even_only=false;
	// FIXME: put arguments back in
	//	if(has_argument("EvenOnly"))
	//		 even_only=true;

	yngtab::tableau one, two;
	yngtab::tableaux<yngtab::tableau> prod;

	sibling_iterator sib=tr.begin(tab1);
	while(sib!=tr.end(tab1)) {
		one.add_row(to_long(*sib->multiplier));
		++sib;
		}
	sib=tr.begin(tab2);
	while(sib!=tr.end(tab2)) {
		two.add_row(to_long(*sib->multiplier));
		++sib;
		}
	yngtab::LR_tensor(one,two,dimension,prod.get_back_insert_iterator());

	Ex rep;
	iterator top=rep.set_head(str_node("\\sum"));
	iterator tt;
	yngtab::tableaux<yngtab::tableau>::tableau_container_t::iterator tabit=prod.storage.begin();
	while(tabit!=prod.storage.end()) {
		// Keep only the diagrams which lead to a singlet if requested.
		if(even_only)
			for(unsigned int r=0; r<(*tabit).number_of_rows(); ++r)
				if((*tabit).row_size(r)%2!=0)
					goto next_tab;

		tt=tr.append_child(top, str_node(tab1->name));
		multiply(tt->multiplier, tabit->multiplicity);
		for(unsigned int r=0; r<(*tabit).number_of_rows(); ++r)
			multiply(tr.append_child(tt, str_node("1"))->multiplier, (*tabit).row_size(r));

next_tab:
		++tabit;
		}

	tr.replace(tab1, rep.begin());
	tr.erase(tab2);
	cleanup_dispatch(kernel, tr, it);
	}