X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Findexed.cpp;h=12561cf1d88f0557ef41c2f3e486a590361e80db;hb=09f37bdbd46f469b3a8a902a43d0f795c41a89bf;hp=765a07c8bf4c7a1f8be7a17411a55dbcb64311b9;hpb=3964aec42adfe5be0fff2998d92dc742e0413f56;p=ginac.git diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index 765a07c8..12561cf1 100644 --- a/ginac/indexed.cpp +++ b/ginac/indexed.cpp @@ -30,6 +30,7 @@ #include "ncmul.h" #include "power.h" #include "symmetry.h" +#include "operators.h" #include "lst.h" #include "print.h" #include "archive.h" @@ -178,7 +179,7 @@ void indexed::print(const print_context & c, unsigned level) const { GINAC_ASSERT(seq.size() > 0); - if (is_of_type(c, print_tree)) { + if (is_a(c)) { c.s << std::string(level, ' ') << class_name() << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec @@ -190,21 +191,19 @@ void indexed::print(const print_context & c, unsigned level) const } else { - bool is_tex = is_of_type(c, print_latex); + bool is_tex = is_a(c); const ex & base = seq[0]; - bool need_parens = is_ex_exactly_of_type(base, add) || is_ex_exactly_of_type(base, mul) - || is_ex_exactly_of_type(base, ncmul) || is_ex_exactly_of_type(base, power) - || is_ex_of_type(base, indexed); + + if (precedence() <= level) + c.s << (is_tex ? "{(" : "("); if (is_tex) c.s << "{"; - if (need_parens) - c.s << "("; - base.print(c); - if (need_parens) - c.s << ")"; + base.print(c, precedence()); if (is_tex) c.s << "}"; printindices(c, level); + if (precedence() <= level) + c.s << (is_tex ? ")}" : ")"); } } @@ -250,7 +249,7 @@ ex indexed::eval(int level) const return _ex0; // If the base object is a product, pull out the numeric factor - if (is_ex_exactly_of_type(base, mul) && is_ex_exactly_of_type(base.op(base.nops() - 1), numeric)) { + if (is_exactly_a(base) && is_exactly_a(base.op(base.nops() - 1))) { exvector v(seq); ex f = ex_to(base.op(base.nops() - 1)); v[0] = seq[0] / f; @@ -288,7 +287,7 @@ ex indexed::expand(unsigned options) const { GINAC_ASSERT(seq.size() > 0); - if ((options & expand_options::expand_indexed) && is_ex_exactly_of_type(seq[0], add)) { + if ((options & expand_options::expand_indexed) && is_exactly_a(seq[0])) { // expand_indexed expands (a+b).i -> a.i + b.i const ex & base = seq[0]; @@ -320,14 +319,14 @@ void indexed::printindices(const print_context & c, unsigned level) const exvector::const_iterator it=seq.begin() + 1, itend = seq.end(); - if (is_of_type(c, print_latex)) { + if (is_a(c)) { // TeX output: group by variance bool first = true; bool covariant = true; while (it != itend) { - bool cur_covariant = (is_ex_of_type(*it, varidx) ? ex_to(*it).is_covariant() : true); + bool cur_covariant = (is_a(*it) ? ex_to(*it).is_covariant() : true); if (first || cur_covariant != covariant) { // Variance changed // The empty {} prevents indices from ending up on top of each other if (!first) @@ -364,13 +363,13 @@ void indexed::validate(void) const GINAC_ASSERT(seq.size() > 0); exvector::const_iterator it = seq.begin() + 1, itend = seq.end(); while (it != itend) { - if (!is_ex_of_type(*it, idx)) + if (!is_a(*it)) throw(std::invalid_argument("indices of indexed object must be of type idx")); it++; } if (!symtree.is_zero()) { - if (!is_ex_exactly_of_type(symtree, symmetry)) + if (!is_exactly_a(symtree)) throw(std::invalid_argument("symmetry of indexed object must be of type symmetry")); const_cast(ex_to(symtree)).validate(seq.size() - 1); } @@ -559,13 +558,13 @@ ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & du { // Remember whether the product was commutative or noncommutative // (because we chop it into factors and need to reassemble later) - bool non_commutative = is_ex_exactly_of_type(e, ncmul); + bool non_commutative = is_exactly_a(e); // Collect factors in an exvector, store squares twice exvector v; v.reserve(e.nops() * 2); - if (is_ex_exactly_of_type(e, power)) { + if (is_exactly_a(e)) { // We only get called for simple squares, split a^2 -> a*a GINAC_ASSERT(e.op(1).is_equal(_ex2)); v.push_back(e.op(0)); @@ -573,10 +572,10 @@ ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & du } else { for (unsigned i=0; i(f) && f.op(1).is_equal(_ex2)) { v.push_back(f.op(0)); v.push_back(f.op(0)); - } else if (is_ex_exactly_of_type(f, ncmul)) { + } else if (is_exactly_a(f)) { // Noncommutative factor found, split it as well non_commutative = true; // everything becomes noncommutative, ncmul will sort out the commutative factors later for (unsigned j=0; j(*it1)) continue; bool first_noncommutative = (it1->return_type() != return_types::commutative); @@ -606,7 +605,7 @@ try_again: exvector::iterator it2; for (it2 = it1 + 1; it2 != itend; it2++) { - if (!is_ex_of_type(*it2, indexed)) + if (!is_a(*it2)) continue; bool second_noncommutative = (it2->return_type() != return_types::commutative); @@ -645,9 +644,9 @@ try_again: if (contracted) { contraction_done: if (first_noncommutative || second_noncommutative - || is_ex_exactly_of_type(*it1, add) || is_ex_exactly_of_type(*it2, add) - || is_ex_exactly_of_type(*it1, mul) || is_ex_exactly_of_type(*it2, mul) - || is_ex_exactly_of_type(*it1, ncmul) || is_ex_exactly_of_type(*it2, ncmul)) { + || is_exactly_a(*it1) || is_exactly_a(*it2) + || is_exactly_a(*it1) || is_exactly_a(*it2) + || is_exactly_a(*it1) || is_exactly_a(*it2)) { // One of the factors became a sum or product: // re-expand expression and run again @@ -673,7 +672,7 @@ contraction_done: it1 = v.begin(); itend = v.end(); while (it1 != itend) { exvector free_indices_of_factor; - if (is_ex_of_type(*it1, indexed)) { + if (is_a(*it1)) { exvector dummy_indices_of_factor; find_free_and_dummy(ex_to(*it1).seq.begin() + 1, ex_to(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor); individual_dummy_indices.insert(individual_dummy_indices.end(), dummy_indices_of_factor.begin(), dummy_indices_of_factor.end()); @@ -709,8 +708,8 @@ contraction_done: r = rename_dummy_indices(r, dummy_indices, local_dummy_indices); // Product of indexed object with a scalar? - if (is_ex_exactly_of_type(r, mul) && r.nops() == 2 - && is_ex_exactly_of_type(r.op(1), numeric) && is_ex_of_type(r.op(0), indexed)) + if (is_exactly_a(r) && r.nops() == 2 + && is_exactly_a(r.op(1)) && is_a(r.op(0))) return ex_to(r.op(0).op(0)).scalar_mul_indexed(r.op(0), ex_to(r.op(1))); else return r; @@ -724,7 +723,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi // Simplification of single indexed object: just find the free indices // and perform dummy index renaming - if (is_ex_of_type(e_expanded, indexed)) { + if (is_a(e_expanded)) { const indexed &i = ex_to(e_expanded); exvector local_dummy_indices; find_free_and_dummy(i.seq.begin() + 1, i.seq.end(), free_indices, local_dummy_indices); @@ -733,7 +732,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi // Simplification of sum = sum of simplifications, check consistency of // free indices in each term - if (is_ex_exactly_of_type(e_expanded, add)) { + if (is_exactly_a(e_expanded)) { bool first = true; ex sum = _ex0; free_indices.clear(); @@ -749,7 +748,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi } else { if (!indices_consistent(free_indices, free_indices_of_term)) throw (std::runtime_error("simplify_indexed: inconsistent indices in sum")); - if (is_ex_of_type(sum, indexed) && is_ex_of_type(term, indexed)) + if (is_a(sum) && is_a(term)) sum = ex_to(sum.op(0)).add_indexed(sum, term); else sum += term; @@ -761,9 +760,9 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi } // Simplification of products - if (is_ex_exactly_of_type(e_expanded, mul) - || is_ex_exactly_of_type(e_expanded, ncmul) - || (is_ex_exactly_of_type(e_expanded, power) && is_ex_of_type(e_expanded.op(0), indexed) && e_expanded.op(1).is_equal(_ex2))) + if (is_exactly_a(e_expanded) + || is_exactly_a(e_expanded) + || (is_exactly_a(e_expanded) && is_a(e_expanded.op(0)) && e_expanded.op(1).is_equal(_ex2))) return simplify_indexed_product(e_expanded, free_indices, dummy_indices, sp); // Cannot do anything @@ -869,8 +868,8 @@ void scalar_products::debugprint(void) const spmapkey scalar_products::make_key(const ex & v1, const ex & v2) { // If indexed, extract base objects - ex s1 = is_ex_of_type(v1, indexed) ? v1.op(0) : v1; - ex s2 = is_ex_of_type(v2, indexed) ? v2.op(0) : v2; + ex s1 = is_a(v1) ? v1.op(0) : v1; + ex s2 = is_a(v2) ? v2.op(0) : v2; // Enforce canonical order in pair if (s1.compare(s2) > 0)