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 change the rules (I already used the same function to solve this other question).
Here I use the rule ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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))}
final_steps = ['log_simplify']
def apply_rules():
nonlocal E
for r in rules:
for e in E.find(r):
f = e.match(r)
E = E.substitute({e: rules[r](f)})
return E
while(E!=apply_rules()):
pass
for step in final_steps:
E = getattr(E, step)()
return E
It works as expected:
sage: custom_simplify((a1*b)^c/(a2*b)^c)
(a1/a2)^c
![]() | 2 | No.2 Revision |
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 ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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))}
final_steps = ['log_simplify']
def apply_rules():
nonlocal E
for r in rules:
for e in E.find(r):
f = e.match(r)
E = E.substitute({e: rules[r](f)})
return E
while(E!=apply_rules()):
pass
for step in final_steps:
E = getattr(E, step)()
return E
It works as expected:
sage: custom_simplify((a1*b)^c/(a2*b)^c)
(a1/a2)^c
![]() | 3 | No.3 Revision |
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 ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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))}
final_steps = ['log_simplify']
def apply_rules():
nonlocal E
for r in rules:
for e in E.find(r):
f = e.match(r)
E = E.substitute({e: rules[r](f)})
return E
while(E!=apply_rules()):
pass
for step in final_steps:
E = getattr(E, step)()
return E
It works as expected:
sage: custom_simplify((a1*b)^c/(a2*b)^c)
(a1/a2)^c
Edit: It's extremely overkill here, since canonicalize_radical
does the work fine.
![]() | 4 | No.4 Revision |
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 ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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"""
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))}
((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)})
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: It's extremely overkill here, since canonicalize_radical
does the work fine.
![]() | 5 | No.5 Revision |
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 ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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 contain a tuple, the second element being a condition that must hold for the substitution to be valid.
![]() | 6 | No.6 Revision |
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 ab→ebloga, defined on the third line (holding the result, otherwise it immediatly goes back to ab). 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 contain returns a tuple, the second element being a condition that must hold for the substitution to be valid.