Ask Your Question

Revision history [back]

Okay, i am not sure to understand your question in whole generality. However, here is a solution that could be generalized and adapted to your needs. Let me assume that you want to rewrite the exponents of your expression and that those exponents are polynomials. Working on polynomials has the good property that instead of doing some pattern matching as in the symbolic ring, you can use quotient rings.

For example, here is what you can do in your previous example:

sage: R.<b_m,b_s> = PolynomialRing(QQ)
sage: R
Multivariate Polynomial Ring in b_m, b_s over Rational Field
sage: S = R.quotient(b_m + (b_s-b_m)^3 - b_m)
sage: S
Quotient of Multivariate Polynomial Ring in b_m, b_s over Rational Field by the ideal (-b_m^3 + 3*b_m^2*b_s - 3*b_m*b_s^2 + b_s^3)
sage: p = -b_m^3 + 3*b_m^2*b_s - 3*b_m*b_s^2 + b_s^3 + b_m
sage: p
-b_m^3 + 3*b_m^2*b_s - 3*b_m*b_s^2 + b_s^3 + b_m
sage: S(p)
sage: lift(S(p))

Now, what you have to do is to walk along the expression and apply this recipe to all exponents of the powers that are encountered. A power is a kind of arithmetic operation, so you will have to override the arithmetic method of ExpressionTreeWalker. Here is how to:

from sage.symbolic.expression_conversions import ExpressionTreeWalker
class RewritePolynomialPowers(ExpressionTreeWalker):
    def __init__(self, ring):
        self.ring = ring
    def arithmetic(self, ex, op):
        if op is operator.pow:
            base, exponent = ex.operands()
            exponent = SR(str(lift(self.ring(exponent))))
            return base ** exponent
            return reduce(op, map(self, ex.operands()))

Let us try with your example:

sage: var('a,x,b,b_s,b_m')
(a, x, b, b_s, b_m)
sage: f_m = a*x^b
sage: expr = expand(f_m.subs({b : b_m + (b_s-b_m)^3})).derivative(b_m).full_simplify()
sage: RewritePolynomialPowers(S)(expr)
-(3*a*b_m^2 - 6*a*b_m*b_s + 3*a*b_s^2 - a)*x^b_m*log(x)

Please tell if this is sufficient for your general case. Anyway, you see the TreeWalker strategy, you can also replace other kind of operators (composition, derivation, relation,...), see the (not documented)