File: split_gamma.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 (81 lines) | stat: -rw-r--r-- 2,071 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

#include "Cleanup.hh"
#include "algorithms/split_gamma.hh"
#include "algorithms/join_gamma.hh"

using namespace cadabra;

split_gamma::split_gamma(const Kernel& k, Ex& e, bool ob)
	: Algorithm(k, e), on_back(ob)
	{
	}

bool split_gamma::can_apply(iterator it)
	{
	if(kernel.properties.get<GammaMatrix>(it))
		if(tr.number_of_children(it)>1) {
			return true;
			}
	return false;
	}

Algorithm::result_t split_gamma::apply(iterator& it)
	{
	// Make a new expression which is the 'join' of the result which we want.
	Ex work;
	work.set_head(str_node("\\expression"));
	iterator prodnode=work.append_child(work.begin(), str_node("\\prod"));
	iterator firstgam, secondgam;
	if(on_back) {
		firstgam =work.append_child(prodnode, it);
		secondgam=work.append_child(prodnode, *it);
		}
	else {
		secondgam=work.append_child(prodnode, *it);
		firstgam =work.append_child(prodnode, it);
		}
	sibling_iterator specind;
	if(on_back) {
		specind=work.end(firstgam);
		--specind;
		}
	else specind=work.begin(firstgam);
	work.append_child(secondgam, (iterator)(specind));
	work.erase(specind);

	join_gamma jn(kernel, tr, true, true);
	const GammaMatrix *gm1=kernel.properties.get<GammaMatrix>(it);
	jn.gm1=gm1;
	jn.apply(prodnode);

	// Replace maximally-antisymmetric gamma with the product
	// in which one gamma is back-split.
	iterator maxgam=work.begin(prodnode);
	if(on_back) {
		specind=work.end(maxgam);
		--specind;
		}
	else specind=work.begin(maxgam);
	iterator newprod=work.insert(maxgam, str_node("\\prod"));
	sibling_iterator fr=maxgam, to=fr;
	++to;
	maxgam=work.reparent(newprod, fr, to);
	iterator splitgam;
	if(on_back) splitgam=work.append_child(newprod, *maxgam);
	else        splitgam=work.insert(maxgam, *maxgam);
	work.append_child(splitgam,(iterator)(specind));
	work.erase(specind);

	// Flip signs on all other terms.
	sibling_iterator other=work.begin(prodnode);
	++other;
	while(other!=work.end(prodnode)) {
		flip_sign(other->multiplier);
		++other;
		}
	it=tr.replace(it, prodnode);

	cleanup_dispatch(kernel, tr, it);
	return result_t::l_applied;
	}