* Implementation of GiNaC's symbolic exponentiation (basis^exponent). */
/*
- * GiNaC Copyright (C) 1999-2006 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2007 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
if (is_exactly_a<numeric>(sub_exponent)) {
const numeric & num_sub_exponent = ex_to<numeric>(sub_exponent);
GINAC_ASSERT(num_sub_exponent!=numeric(1));
- if (num_exponent->is_integer() || (abs(num_sub_exponent) - (*_num1_p)).is_negative())
+ if (num_exponent->is_integer() || (abs(num_sub_exponent) - (*_num1_p)).is_negative()) {
return power(sub_basis,num_sub_exponent.mul(*num_exponent));
+ }
}
}
if (num_exponent->is_integer() && is_exactly_a<mul>(ebasis)) {
return expand_mul(ex_to<mul>(ebasis), *num_exponent, 0);
}
-
+
+ // (2*x + 6*y)^(-4) -> 1/16*(x + 3*y)^(-4)
+ if (num_exponent->is_integer() && is_exactly_a<add>(ebasis)) {
+ const numeric icont = ebasis.integer_content();
+ const numeric& lead_coeff =
+ ex_to<numeric>(ex_to<add>(ebasis).seq.begin()->coeff).div_dyn(icont);
+
+ const bool canonicalizable = lead_coeff.is_integer();
+ const bool unit_normal = lead_coeff.is_pos_integer();
+
+ if (icont != *_num1_p) {
+ return (new mul(power(ebasis/icont, *num_exponent), power(icont, *num_exponent))
+ )->setflag(status_flags::dynallocated);
+ }
+
+ if (canonicalizable && (! unit_normal)) {
+ if (num_exponent->is_even()) {
+ return power(-ebasis, *num_exponent);
+ } else {
+ return (new mul(power(-ebasis, *num_exponent), *_num_1_p)
+ )->setflag(status_flags::dynallocated);
+ }
+ }
+ }
+
// ^(*(...,x;c1),c2) -> *(^(*(...,x;1),c2),c1^c2) (c1, c2 numeric(), c1>0)
// ^(*(...,x;c1),c2) -> *(^(*(...,x;-1),c2),(-c1)^c2) (c1, c2 numeric(), c1<0)
if (is_exactly_a<mul>(ebasis)) {
return (new add(sum))->setflag(status_flags::dynallocated | status_flags::expanded);
}
-/** Expand factors of m in m^n where m is a mul and n is and integer.
+/** Expand factors of m in m^n where m is a mul and n is an integer.
* @see power::expand */
ex power::expand_mul(const mul & m, const numeric & n, unsigned options, bool from_expand) const
{