result += check_normal(e, den);
}
+ // Negative exponents
+ e = (exp(2*x)-exp(-2*x))/(exp(x)-exp(-x));
+ ex en = e.normal();
+ // Either exp(x) or exp(-x) can be viewed as a "symbol" during run-time
+ // thus two different forms of the result are possible
+ ex r1 = (exp(2*x)+1)/exp(x) ;
+ ex r2 = (exp(-2*x)+1)/exp(-x);
+
+ if (!en.is_equal(r1) && !en.is_equal(r2)) {
+ clog << "normal form of " << e << " erroneously returned "
+ << en << " (should be " << r1 << " or " << r2 << ")" << endl;
+ result += 1;
+ }
+
return result;
}
e /= 2*pow(b, y/2)-3*pow(b, z/2);
d = 2*pow(b, y/2)+3*pow(b, z/2);
result += check_normal(e, d);
+
+ // Negative powers
+ e = (b -pow(b,-1));
+ e /= (pow(b, numeric(1,2)) - pow(b, numeric(-1,2)));
+ d = (b+1)*pow(b, numeric(-1,2));
+ result += check_normal(e, d);
}
return result;
normal_map_function map_normal;
int nmod = modifier.nops(); // To watch new modifiers to the replacement list
- lst result = dynallocate<lst>({replace_with_symbol(map(map_normal), repl, rev_lookup, modifier), _ex1});
+ ex result = replace_with_symbol(map(map_normal), repl, rev_lookup, modifier);
for (int imod = nmod; imod < modifier.nops(); ++imod) {
exmap this_repl;
this_repl.insert(std::make_pair(modifier.op(imod).op(0), modifier.op(imod).op(1)));
- result = ex_to<lst>(result.subs(this_repl, subs_options::no_pattern));
+ result = result.subs(this_repl, subs_options::no_pattern);
}
- return result;
+ // Sometimes we may obtain negative powers, they need to be placed to denominator
+ if (is_a<power>(result) && result.op(1).info(info_flags::negative))
+ return dynallocate<lst>({_ex1, power(result.op(0), -result.op(1))});
+ else
+ return dynallocate<lst>({result, _ex1});
}