-lortensor lortensor_g(ex const & mu, ex const & nu)
-{
- return lortensor(lortensor::lortensor_g,"",mu,nu);
-}
-
-lortensor lortensor_epsilon(ex const & mu, ex const & nu, ex const & rho, ex const & sigma)
-{
- return lortensor(lortensor::lortensor_epsilon,"",mu,nu,rho,sigma);
-}
-
-lortensor lortensor_rank1(string const & n, ex const & mu)
-{
- return lortensor(lortensor::lortensor_rank1,n,mu);
-}
-
-lortensor lortensor_rank2(string const & n, ex const & mu, ex const & nu)
-{
- return lortensor(lortensor::lortensor_rank2,n,mu,nu);
-}
-
-ex simplify_lortensor_mul(ex const & m)
-{
- GINAC_ASSERT(is_ex_exactly_of_type(m,mul));
- exvector v_contracted;
-
- // collect factors in an exvector, store squares twice
- int n=m.nops();
- v_contracted.reserve(2*n);
- for (int i=0; i<n; ++i) {
- ex f=m.op(i);
- if (is_ex_exactly_of_type(f,power)&&f.op(1).is_equal(_ex2())) {
- v_contracted.push_back(f.op(0));
- v_contracted.push_back(f.op(0));
- } else {
- v_contracted.push_back(f);
- }
- }
-
- unsigned replacements;
- bool something_changed=false;
-
- exvector::iterator it=v_contracted.begin();
- while (it!=v_contracted.end()) {
- // process only lor_g objects
- if (is_ex_exactly_of_type(*it,lortensor) &&
- (ex_to_lortensor(*it).type==lortensor::lortensor_g)) {
- lortensor const & g=ex_to_lortensor(*it);
- GINAC_ASSERT(g.seq.size()==2);
- idx const & first_idx=ex_to_lorentzidx(g.seq[0]);
- idx const & second_idx=ex_to_lorentzidx(g.seq[1]);
- // g_{mu,mu} should have been contracted in lortensor::eval()
- GINAC_ASSERT(!first_idx.is_equal(second_idx));
- ex saved_g=*it; // save to restore it later
-
- // try to contract first index
- replacements=0;
- if (first_idx.is_symbolic()) {
- replacements = subs_index_in_exvector(v_contracted,
- first_idx.toggle_covariant(),second_idx);
- if (replacements==0) {
- // not contracted, restore g object
- *it=saved_g;
- } else {
- // a contracted index should occur exactly once
- GINAC_ASSERT(replacements==1);
- *it=_ex1();
- something_changed=true;
- }
- }
-
- // try second index only if first was not contracted
- if ((replacements==0)&&(second_idx.is_symbolic())) {
- // first index not contracted, *it is again the original g object
- replacements = subs_index_in_exvector(v_contracted,
- second_idx.toggle_covariant(),first_idx);
- if (replacements==0) {
- // not contracted except in itself, restore g object
- *it=saved_g;
- } else {
- // a contracted index should occur exactly once
- GINAC_ASSERT(replacements==1);
- *it=_ex1();
- something_changed=true;
- }
- }
- }
- ++it;
- }
- if (something_changed) {
- return mul(v_contracted);
- }
- return m;
-}
-
-ex simplify_lortensor(ex const & e)
-{
- // all simplification is done on expanded objects
- ex e_expanded=e.expand();
-
- // simplification of sum=sum of simplifications
- if (is_ex_exactly_of_type(e_expanded,add)) {
- ex sum=_ex0();
- for (int i=0; i<e_expanded.nops(); ++i) {
- sum += simplify_lortensor(e_expanded.op(i));
- }
- return sum;
- }
-
- // simplification of commutative product=commutative product of simplifications
- if (is_ex_exactly_of_type(e_expanded,mul)) {
- return simplify_lortensor_mul(e);
- }
-
- // cannot do anything
- return e_expanded;
+lortensor lortensor_g(const ex & mu, const ex & nu)
+{
+ return lortensor(lortensor::lortensor_g,"",mu,nu);
+}
+
+lortensor lortensor_epsilon(const ex & mu, const ex & nu, const ex & rho, const ex & sigma)
+{
+ return lortensor(lortensor::lortensor_epsilon,"",mu,nu,rho,sigma);
+}
+
+lortensor lortensor_rank1(const std::string & n, const ex & mu)
+{
+ return lortensor(lortensor::lortensor_rank1,n,mu);
+}
+
+lortensor lortensor_rank2(const std::string & n, const ex & mu, const ex & nu)
+{
+ return lortensor(lortensor::lortensor_rank2,n,mu,nu);
+}
+
+ex simplify_lortensor_mul(const ex & m)
+{
+ GINAC_ASSERT(is_ex_exactly_of_type(m,mul));
+ exvector v_contracted;
+
+ // collect factors in an exvector, store squares twice
+ int n=m.nops();
+ v_contracted.reserve(2*n);
+ for (int i=0; i<n; ++i) {
+ ex f=m.op(i);
+ if (is_ex_exactly_of_type(f,power)&&f.op(1).is_equal(_ex2())) {
+ v_contracted.push_back(f.op(0));
+ v_contracted.push_back(f.op(0));
+ } else {
+ v_contracted.push_back(f);
+ }
+ }
+
+ unsigned replacements;
+ bool something_changed=false;
+
+ exvector::iterator it=v_contracted.begin();
+ while (it!=v_contracted.end()) {
+ // process only lor_g objects
+ if (is_ex_exactly_of_type(*it,lortensor) &&
+ (ex_to_lortensor(*it).type==lortensor::lortensor_g)) {
+ const lortensor & g=ex_to_lortensor(*it);
+ GINAC_ASSERT(g.seq.size()==2);
+ const idx & first_idx=ex_to_lorentzidx(g.seq[0]);
+ const idx & second_idx=ex_to_lorentzidx(g.seq[1]);
+ // g_{mu,mu} should have been contracted in lortensor::eval()
+ GINAC_ASSERT(!first_idx.is_equal(second_idx));
+ ex saved_g=*it; // save to restore it later
+
+ // try to contract first index
+ replacements=0;
+ if (first_idx.is_symbolic()) {
+ replacements = subs_index_in_exvector(v_contracted,
+ first_idx.toggle_covariant(),second_idx);
+ if (replacements==0) {
+ // not contracted, restore g object
+ *it=saved_g;
+ } else {
+ // a contracted index should occur exactly once
+ GINAC_ASSERT(replacements==1);
+ *it=_ex1();
+ something_changed=true;
+ }
+ }
+
+ // try second index only if first was not contracted
+ if ((replacements==0)&&(second_idx.is_symbolic())) {
+ // first index not contracted, *it is again the original g object
+ replacements = subs_index_in_exvector(v_contracted,
+ second_idx.toggle_covariant(),first_idx);
+ if (replacements==0) {
+ // not contracted except in itself, restore g object
+ *it=saved_g;
+ } else {
+ // a contracted index should occur exactly once
+ GINAC_ASSERT(replacements==1);
+ *it=_ex1();
+ something_changed=true;
+ }
+ }
+ }
+ ++it;
+ }
+ if (something_changed) {
+ return mul(v_contracted);
+ }
+ return m;
+}
+
+ex simplify_lortensor(const ex & e)
+{
+ // all simplification is done on expanded objects
+ ex e_expanded=e.expand();
+
+ // simplification of sum=sum of simplifications
+ if (is_ex_exactly_of_type(e_expanded,add)) {
+ ex sum=_ex0();
+ for (unsigned i=0; i<e_expanded.nops(); ++i) {
+ sum += simplify_lortensor(e_expanded.op(i));
+ }
+ return sum;
+ }
+
+ // simplification of commutative product=commutative product of simplifications
+ if (is_ex_exactly_of_type(e_expanded,mul)) {
+ return simplify_lortensor_mul(e);
+ }
+
+ // cannot do anything
+ return e_expanded;