#include "algorithms/flatten_sum.hh" using namespace cadabra; flatten_sum::flatten_sum(const Kernel& k, Ex& tr) : Algorithm(k, tr), make_consistent_only(false) { } bool flatten_sum::can_apply(iterator it) { if(*it->name!="\\sum") return false; if(tr.number_of_children(it)==1 || tr.number_of_children(it)==0) return true; sibling_iterator facs=tr.begin(it); while(facs!=tr.end(it)) { if(*(*facs).name=="\\sum") return true; ++facs; } return false; } Algorithm::result_t flatten_sum::apply(iterator &it) { result_t ret=result_t::l_no_action; assert(*it->name=="\\sum"); long num=tr.number_of_children(it); if(num==1 && ! tr.begin(it)->is_range_wildcard() ) { multiply(tr.begin(it)->multiplier, *it->multiplier); tr.flatten(it); it=tr.erase(it); ret=result_t::l_applied; } else if(num==0) { node_zero(it); ret=result_t::l_applied; } else { sibling_iterator facs=tr.begin(it); str_node::bracket_t btype_par=facs->fl.bracket; while(facs!=tr.end(it)) { if(facs->fl.bracket!=str_node::b_none) btype_par=facs->fl.bracket; ++facs; } facs=tr.begin(it); while(facs!=tr.end(it)) { if(*facs->name=="\\sum") { sibling_iterator terms=tr.begin(facs); str_node::bracket_t btype=terms->fl.bracket; if(!make_consistent_only || btype==str_node::b_none || btype==str_node::b_no) { ret=result_t::l_applied; sibling_iterator tmp=facs; ++tmp; while(terms!=tr.end(facs)) { multiply(terms->multiplier,*facs->multiplier); terms->fl.bracket=btype_par; // if(terms->fl.bracket==str_node::b_none) // terms->fl.bracket=facs->fl.bracket; ++terms; } tr.flatten(facs); tr.erase(facs); facs=tmp; } else ++facs; } else ++facs; } } return ret; }