# HG changeset patch
# User Michael Orlitzky
# Date 1368329943 14400
# Node ID 7eab31faf93c1719f0f60f583f9de315f0e7d366
# Parent 16768eaa774a10ee080f972ed1a80ab32baeaad9
Trac #14630: Add Expression.simplify_real() method.
The new simplify_real() method allows the user to declare that his
expression is real, and allows the otherwise unavailable
simplification of sqrt(x^2) to abs(x). It does this by,
1. Temporarily sets the Maxima simplification domain to 'real'
(as opposed to the default of 'complex').
2. Assumes all variables in the expression are real using the
assume() facility.
3. Calls simplify() on the expression.
4. Restores the domain and forgets the approproate assumptions.
diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
--- a/sage/symbolic/expression.pyx
+++ b/sage/symbolic/expression.pyx
@@ -7349,7 +7349,8 @@
:meth:`simplify_full`, :meth:`simplify_trig`,
:meth:`simplify_rational`, :meth:`simplify_radical`,
- :meth:`simplify_factorial`, :meth:`simplify_log`
+ :meth:`simplify_factorial`, :meth:`simplify_log`,
+ :meth:`simplify_real`
EXAMPLES::
@@ -7405,6 +7406,95 @@
full_simplify = simplify_full
+
+ def simplify_real(self):
+ r"""
+ Simplify the given expression over the real numbers. This allows
+ the simplification of `\sqrt{x^{2}}` into `\left|x\\right|`.
+
+ INPUT:
+
+ - ``self`` -- the expression to convert.
+
+ OUTPUT:
+
+ A new expression, equivalent to the original one under the
+ assumption that the variables involved are real.
+
+ EXAMPLES::
+
+ sage: f = sqrt(x^2)
+ sage: f.simplify_real()
+ abs(x)
+
+ TESTS:
+
+ We set the Maxima ``domain`` variable to 'real' before we call
+ out to Maxima. When we return, however, we should set the
+ ``domain`` back to what it was, rather than assuming that it
+ was 'complex'.
+
+ sage: from sage.calculus.calculus import maxima
+ sage: maxima('domain: real;')
+ real
+ sage: x.simplify_real()
+ x
+ sage: maxima('domain;')
+ real
+ sage: maxima('domain: complex;')
+ complex
+
+ We forget the assumptions that our variables are real after
+ simplification; make sure we don't forget an assumption that
+ existed before we were called::
+
+ sage: assume(x, 'real')
+ sage: x.simplify_real()
+ x
+ sage: assumptions()
+ [x is real]
+ sage: forget()
+
+ No new assumptions should exist after the call::
+
+ sage: assumptions()
+ []
+ sage: x.simplify_real()
+ x
+ sage: assumptions()
+ []
+
+ """
+ from sage.symbolic.assumptions import assume, assumptions, forget
+ from sage.calculus.calculus import maxima
+ original_domain = maxima.eval('domain')
+ original_assumptions = assumptions()
+
+ maxima.eval('domain: real$')
+
+ # We might as well go all the way and tell Maxima to assume
+ # that all variables are real. Since we're setting the
+ # simplification domain (and it's indiscriminate), you'd
+ # better not call this unless your variables really are real
+ # anyway.
+ for v in self.variables():
+ assume(v, 'real');
+
+ result = self.simplify();
+
+ # Set the domain back to what it was before we were called.
+ maxima.eval('domain: %s$' % original_domain)
+
+ # Forget all assumptions, and restore the ones that existed
+ # when we were called. This is much simpler than the bookkeeping
+ # necessary otherwise.
+ forget()
+ for assumption in original_assumptions:
+ assume(assumption);
+
+ return result
+
+
def simplify_trig(self,expand=True):
r"""
Optionally expands and then employs identities such as