# Simplification Methods Survey

I noted that SageMath has many ways to simplify expressions, including simplify_full(), full_simplify and canonicalize_radical. Is there a survey nd usage guide available for these? In particular, I am trying to simplify an expression as in

constants=var('a1,a2,b,c')

((a1*b)^c/(a2*b)^c).simplify_full()


such that I get (a1/a2)^c, but without success.

edit retag close merge delete

There may be a simplification in Sage Maths, but it doesn't look easy to find anyway. In any case, me too I was not able to found it!

constants=var('a1,a2,b,c')

f=((a1*b)^c/(a2*b)^c)
show(f.simplify())
show(f.simplify_full())
show(f.simplify_rational(algorithm='simple'))
show(f.simplify_rational())

show(f.simplify_rational(algorithm='simple',map=True))
show(f.simplify_rational(map=True))
show(f.simplify_rational(algorithm='noexpand'))
show(f.simplify_rational(algorithm='full'))

show(f.simplify_real())
show(f.simplify_rectform())

f.simplify_rational??

( 2020-10-28 08:10:18 +0100 )edit

Sort by » oldest newest most voted

When Sage doesn't want to simplify my expressions, I do it myself.

I wrote a function to do that some time ago, and I just need to change the rules (I already used the same function to solve this other question).

Here I use the rule $a^b\to e^{b \log a}$, defined on the third line (holding the result, otherwise it immediatly goes back to $a^b$). The function will try to apply this rule everywhere, then finish with one step of log_simplify.

def custom_simplify(E):
"""Apply some rules on expression E as long as it changes, then apply some final steps."""

w = [SR.wild(i) for i in (0, .., 10)]

rules = {w[0]^w[1]: lambda f: ((exp(f[w[1]]*log(f[w[0]]), hold=True)), f[w[0]]>0),}
final_steps = ['log_simplify']

def apply_rules():
nonlocal E
for r in rules:
for e in E.find(r):
f = e.match(r)
if rules[r](f)[1]:
E = E.substitute({e: rules[r](f)[0]})
return E

while(E!=apply_rules()):
pass

for step in final_steps:
E = getattr(E, step)()

return E


It works as expected:

sage: assume(a1>0, a2>0, b>0)
sage: custom_simplify((a1*b)^c/(a2*b)^c)
(a1/a2)^c


Edit: Modified for use with assumptions for correctness, as suggested by Emmanuel Charpentier. The rules now returns a tuple, the second element being a condition that must hold for the substitution to be valid.

more

This transform is legitimate only for some cases. See for example the discussion in Sympy's documentation of powsimp... The necessary checks could be integrated in custom_simplify...

( 2020-10-28 16:28:47 +0100 )edit

You are completely right. I edited the code. The rules now contain a condition describing when it is valid. This code is getting even uglier... Well, it was supposed to be a dirty hack anyway.

( 2020-10-28 18:06:13 +0100 )edit

Thanks, that's indeed a helpful function. Experimenting with it I wonder why

from sage.symbolic.constants import Constant
constants=var('a1,a2,b,c,L')
custom_simplify((a1*b)^c/(L*a1*z+a1*b)^c)


does not work, but it is working if L is replaced by d.

( 2020-10-28 18:18:02 +0100 )edit

My initial problem was not whether there is a function that handles this specific term, but whether there is some guidance to find functions that may handle some given term, so I don't think this was overkill.

If there is no automatic selection of a simplification method, the approach to define a set of rewrite rules and apply them is helpful, preferably encapsulated in a single function which takes a term and a ruleset and applies it. https://wiki.sagemath.org/symbolics/r... is close to that, except that it has a fixed ruleset.

.

I confess that I am looking for an easy-to-use function as I am not a Sage expert.

( 2020-10-28 18:31:05 +0100 )edit

hmm, I don't really know. How do you define z? What does the import do? Did you remember to use the assumptions assume(a1>0, b>0, L>0) ?

This works for me:

sage: constants=var('a1,a2,b,c,L')
sage: assume(a1>0, a2>0, L>0, b>0)
sage: custom_simplify((a1*b)^c/(L*a1*a2+a1*b)^c)
(b/(L*a2 + b))^c

( 2020-10-28 19:30:17 +0100 )edit

Nope : without further hypotheses, neither Sage, Sympy nor Mathematica can do better than :

sage: constants=var('a1,a2,b,c')
sage: f=((a1*b)^c/(a2*b)^c)
a1^c/a2^c


Powers and logs are simple to treat in the "usual" special cases and extremely tricky in general. Hiont : think of lomplex logarithm and its branch cut...

more

I wouldn't mind if the system asks for assumptions to work (as desolve does).

( 2020-10-28 18:01:20 +0100 )edit