X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Findexed.cpp;h=12561cf1d88f0557ef41c2f3e486a590361e80db;hb=09f37bdbd46f469b3a8a902a43d0f795c41a89bf;hp=bc474f3d41e5db31c0ed31859fd281911497c9b4;hpb=fbdd5eefb7188778ca9c04b5bee08223609b880f;p=ginac.git diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index bc474f3d..12561cf1 100644 --- a/ginac/indexed.cpp +++ b/ginac/indexed.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's indexed expressions. */ /* - * GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2002 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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; @@ -274,24 +273,6 @@ ex indexed::eval(int level) const return ex_to(base).eval_indexed(*this); } -int indexed::degree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -int indexed::ldegree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -ex indexed::coeff(const ex & s, int n) const -{ - if (is_equal(ex_to(s))) - return n==1 ? _ex1 : _ex0; - else - return n==0 ? ex(*this) : _ex0; -} - ex indexed::thisexprseq(const exvector & v) const { return indexed(ex_to(symtree), v); @@ -306,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]; @@ -338,17 +319,18 @@ 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); - if (first || cur_covariant != covariant) { + 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) - c.s << "}"; + c.s << "}{}"; covariant = cur_covariant; if (covariant) c.s << "_{"; @@ -381,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); } @@ -539,7 +521,6 @@ static ex rename_dummy_indices(const ex & e, exvector & global_dummy_indices, ex } it++; } - shaker_sort(global_dummy_indices.begin(), global_dummy_indices.end(), ex_is_less(), ex_swap()); // If this is the first set of local indices, do nothing if (old_global_size == 0) @@ -554,6 +535,7 @@ static ex rename_dummy_indices(const ex & e, exvector & global_dummy_indices, ex shaker_sort(local_syms.begin(), local_syms.end(), ex_is_less(), ex_swap()); for (unsigned i=0; i(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)); @@ -590,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); @@ -623,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); @@ -662,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 @@ -690,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()); @@ -726,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; @@ -741,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); @@ -750,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(); @@ -766,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; @@ -778,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 @@ -886,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)