Ask Your Question
3

Simplification Methods Survey

asked 2020-10-27 13:32:18 -0600

Ingo gravatar image

updated 2020-10-27 16:11:17 -0600

tmonteil gravatar image

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 flag offensive close merge delete

Comments

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??
ortollj gravatar imageortollj ( 2020-10-28 02:10:18 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2020-10-28 08:24:11 -0600

Florentin Jaffredo gravatar image

updated 2020-10-28 12:09:36 -0600

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.

edit flag offensive delete link more

Comments

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...

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2020-10-28 10:28:47 -0600 )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.

Florentin Jaffredo gravatar imageFlorentin Jaffredo ( 2020-10-28 12:06:13 -0600 )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.

Ingo gravatar imageIngo ( 2020-10-28 12:18:02 -0600 )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.

Ingo gravatar imageIngo ( 2020-10-28 12:31:05 -0600 )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
Florentin Jaffredo gravatar imageFlorentin Jaffredo ( 2020-10-28 13:30:17 -0600 )edit
1

answered 2020-10-28 08:21:25 -0600

Emmanuel Charpentier gravatar image

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)
sage: f.canonicalize_radical()
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...

edit flag offensive delete link more

Comments

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

Ingo gravatar imageIngo ( 2020-10-28 12:01:20 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2020-10-27 13:32:18 -0600

Seen: 83 times

Last updated: Oct 28