File: tab_basics.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 (119 lines) | stat: -rw-r--r-- 2,995 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

#include "algorithms/tab_basics.hh"

using namespace cadabra;

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

unsigned int tab_basics::find_obj(const Ex& other)
	{
	for(unsigned int i=0; i<num_to_it.size(); ++i) {
		if(tree_exact_equal(&kernel.properties, num_to_it[i], other))
			return i;
		}
	throw std::logic_error("internal error in tab_basics::find_obj");
	}

void tab_basics::tree_to_numerical_tab(iterator tab1, uinttab_t& one)
	{
	unsigned int prevsize=num_to_it.size();

	// First determine the sort order of the children of tab1.
	sibling_iterator sib=tr.begin(tab1);
	while(sib!=tr.end(tab1)) {
		if(*sib->name=="\\comma") {
			sibling_iterator sib2=tr.begin(sib);
			while(sib2!=tr.end(sib)) {
				num_to_it.push_back(sib2);
				++sib2;
				}
			}
		else {
			num_to_it.push_back(sib);
			}
		++sib;
		}

	tree_exact_less_obj cmp(&kernel.properties);
	std::vector<Ex::iterator>::iterator startit=num_to_it.begin();
	startit+=prevsize;
	std::sort(startit, num_to_it.end(), cmp);

	// Now fill the uinttab.
	sib=tr.begin(tab1);
	unsigned int currow=0;
	while(sib!=tr.end(tab1)) {
		if(*sib->name=="\\comma") {
			sibling_iterator sib2=tr.begin(sib);
			while(sib2!=tr.end(sib)) {
				one.add_box(currow, find_obj(Ex(sib2)) );
				++sib2;
				}
			}
		else {
			one.add_box(currow, find_obj(Ex(sib)) );
			}
		++sib;
		++currow;
		}
	}

void tab_basics::tabs_to_singlet_rules(uinttabs_t& tabs, iterator top)
	{
	uinttabs_t::tableau_container_t::iterator tabit=tabs.storage.begin();

	while(tabit!=tabs.storage.end()) {
		// Keep only the diagrams which lead to a singlet.
		iterator tprod;
		for(unsigned int r=0; r<(*tabit).number_of_rows(); ++r)
			if((*tabit).row_size(r)%2!=0)
				goto next_tab;

		tprod=tr.append_child(top, str_node("\\prod"));
		for(unsigned int r=0; r<(*tabit).number_of_rows(); ++r) {
			for(unsigned int c=0; c<(*tabit).row_size(r); ++c) {
				iterator tt=tr.append_child(tprod, str_node("\\delta"));
				tr.append_child(tt, num_to_it[(*tabit)(r,c++)]);
				tr.append_child(tt, num_to_it[(*tabit)(r,c)]);
				}
			}

next_tab:
		++tabit;
		}
	}


void tab_basics::tabs_to_tree(uinttabs_t& tabs, iterator top, iterator tabpat, bool even_only)
	{
	uinttabs_t::tableau_container_t::iterator tabit=tabs.storage.begin();

	while(tabit!=tabs.storage.end()) {
		// Keep only the diagrams which lead to a singlet if requested.
		iterator tt;
		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(tabpat->name));
		multiply(tt->multiplier, tabit->multiplicity);
		for(unsigned int r=0; r<(*tabit).number_of_rows(); ++r) {
			unsigned int rs=(*tabit).row_size(r);
			if(rs==1)
				tr.append_child(tt, num_to_it[(*tabit)(r,0)]);
			else {
				iterator tmp=tr.append_child(tt, str_node("\\comma"));
				for(unsigned int c=0; c<rs; ++c)
					tr.append_child(tmp, num_to_it[(*tabit)(r,c)]);
				}
			}

next_tab:
		++tabit;
		}
	}