File: flatten_product.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 (77 lines) | stat: -rw-r--r-- 2,117 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

#include "algorithms/flatten_product.hh"
#include "properties/PartialDerivative.hh"

using namespace cadabra;


flatten_product::flatten_product(const Kernel& k, Ex& tr)
	: Algorithm(k, tr), make_consistent_only(false), is_diff(false)
	{
	}

bool flatten_product::can_apply(iterator it)
	{
	is_diff=false;
	if(*it->name!="\\prod")
		return false;

	// FIXME: acting on PartialDerivative has been disabled because
	// it really does not make sense anymore.
	//		 if(properties::get<PartialDerivative>(it)==0)
	//			  return false;
	//		 else is_diff=true;

	if(!is_diff && tr.number_of_children(it)==1) return true;
	sibling_iterator facs=tr.begin(it);
	while(facs!=tr.end(it)) {
		const PartialDerivative *pd=kernel.properties.get<PartialDerivative>(facs);
		if((is_diff && pd) || (!is_diff && *facs->name=="\\prod"))
			return true;
		if(is_diff) break;
		++facs;
		}
	return false;
	}

Algorithm::result_t flatten_product::apply(iterator& it)
	{
	//	debugout << "acting with flatten_product at " << *it->name << std::endl;
	if(!is_diff && tr.number_of_children(it)==1) {
		tr.begin(it)->fl.bracket = it->fl.bracket;
		multiply(tr.begin(it)->multiplier, *it->multiplier);
		tr.flatten(it);
		it=tr.erase(it);
		pushup_multiplier(it);
		return result_t::l_applied;
		}

	result_t ret=result_t::l_no_action;
	sibling_iterator facs=tr.begin(it);
	str_node::bracket_t btype=facs->fl.bracket;
	while(facs!=tr.end(it)) {
		const PartialDerivative *pd=kernel.properties.get<PartialDerivative>(facs);
		if((is_diff && pd) || (!is_diff && *facs->name=="\\prod")) {
			str_node::bracket_t cbtype=tr.begin(facs)->fl.bracket;
			if(!make_consistent_only || cbtype==str_node::b_none || cbtype==str_node::b_no) {
				sibling_iterator prodch=tr.begin(facs);
				while(prodch!=tr.end(facs)) {
					prodch->fl.bracket=btype;
					++prodch;
					}
				sibling_iterator tmp=facs;
				++tmp;
				tr.flatten(facs);
				multiply(it->multiplier,*facs->multiplier);
				tr.erase(facs);
				pushup_multiplier(it);
				facs=tmp;
				ret=result_t::l_applied;
				}
			else ++facs;
			}
		else ++facs;
		if(is_diff) break;
		}
	return ret;
	}