On Tue, Mar 10, 2009 at 2:31 PM, Fabian Seoane <fab...@fseoane.net> wrote:
>
> Ondrej Certik wrote:
>> Hi,
>>
>> sending a trivial patch to remove hacks from trigsimp.
>>
>
> removing hacks is always good news, but I do not agree that
> sin(x)**2/cos(x)**2 is a valid answer.
> By definition, trigsimp will try to return the simplest possible
> expression, and although 'the simplest possible
> expression' is a rather vague term, imho tan**2 is a better answer than
> sin(x)**2/cos(x)**2
>
> Related to this,  I would expect the following to return True:
>
> In [2]: trigsimp(tan(x)) == trigsimp(sin(x)/cos(x))
> Out[2]: False

All of this is fixed in the attached patch. Please review.

Ondrej

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy-patches" group.
To post to this group, send email to sympy-patches@googlegroups.com
To unsubscribe from this group, send email to 
sympy-patches+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sympy-patches?hl=en
-~----------~----~----~----~------~----~------~--~---

From bddf677be04b62d450229a622c8e8bd73d92e38d Mon Sep 17 00:00:00 2001
From: Ondrej Certik <ond...@certik.cz>
Date: Tue, 24 Mar 2009 21:13:59 -0700
Subject: [PATCH] trigsimp() two hacks removed and done right

Previously trigsimp() failed to simplify sin(x)/cos(x) to tan(x) and similar
things and also it required an ugly hack. Many of those are now fixed and tests
written.

Signed-off-by: Ondrej Certik <ond...@certik.cz>
---
 sympy/simplify/simplify.py            |   46 ++++++++++++++++++++++++--------
 sympy/simplify/tests/test_simplify.py |   18 ++++++++++++-
 2 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py
index 2ab5cf3..1c0c42e 100644
--- a/sympy/simplify/simplify.py
+++ b/sympy/simplify/simplify.py
@@ -764,15 +764,39 @@ def trigsimp(expr, deep=False, recursive=False):
         >>> trigsimp(log(e), deep=True)
         log(2)
     """
+    from sympy.core.basic import S
+    sin, cos, tan, cot = C.sin, C.cos, C.tan, C.cot
     if recursive:
         w, g = cse(expr)
         g = trigsimp_nonrecursive(g[0])
         for sub in reversed(w):
             g = g.subs(sub[0], sub[1])
             g = trigsimp_nonrecursive(g)
-        return(g)
+        result = g
     else:
-        return trigsimp_nonrecursive(expr, deep)
+        result = trigsimp_nonrecursive(expr, deep)
+
+    # do some final simplifications like sin/cos -> tan:
+    a,b,c = map(Wild, 'abc')
+    matchers = (
+            (a*sin(b)**c/cos(b)**c, a*tan(b)**c),
+    )
+    for pattern, simp in matchers:
+        res = result.match(pattern)
+        if res is not None:
+            # if c is missing or zero, do nothing:
+            if (not c in res) or res[c] == 0:
+                continue
+            # if "a" contains the argument of sin/cos "b", skip the
+            # simplification:
+            if res[a].has(res[b]):
+                continue
+            # simplify and finish:
+            result = simp.subs(res)
+            break
+
+    return result
+
 
 def trigsimp_nonrecursive(expr, deep=False):
     """
@@ -796,28 +820,26 @@ def trigsimp_nonrecursive(expr, deep=False):
         >>> e = 2*sin(x)**2 + 2*cos(x)**2
         >>> trigsimp(e)
         2
-        >>> trigsimp(log(e))
+        >>> trigsimp_nonrecursive(log(e))
         log(2*cos(x)**2 + 2*sin(x)**2)
-        >>> trigsimp(log(e), deep=True)
+        >>> trigsimp_nonrecursive(log(e), deep=True)
         log(2)
     """
     from sympy.core.basic import S
     sin, cos, tan, cot = C.sin, C.cos, C.tan, C.cot
 
-    #XXX this stopped working:
-    if expr == 1/cos(Symbol("x"))**2 - 1:
-        return tan(Symbol("x"))**2
-
     if expr.is_Function:
         if deep:
-            return expr.func( trigsimp(expr.args[0], deep) )
+            return expr.func( trigsimp_nonrecursive(expr.args[0], deep) )
     elif expr.is_Mul:
         ret = S.One
         for x in expr.args:
-            ret *= trigsimp(x, deep)
+            ret *= trigsimp_nonrecursive(x, deep)
+
         return ret
     elif expr.is_Pow:
-        return Pow(trigsimp(expr.base, deep), trigsimp(expr.exp, deep))
+        return Pow(trigsimp_nonrecursive(expr.base, deep),
+                trigsimp_nonrecursive(expr.exp, deep))
     elif expr.is_Add:
         # TODO this needs to be faster
 
@@ -832,7 +854,7 @@ def trigsimp_nonrecursive(expr, deep=False):
         # Scan for the terms we need
         ret = S.Zero
         for term in expr.args:
-            term = trigsimp(term, deep)
+            term = trigsimp_nonrecursive(term, deep)
             res = None
             for pattern, result in matchers:
                 res = term.match(pattern)
diff --git a/sympy/simplify/tests/test_simplify.py b/sympy/simplify/tests/test_simplify.py
index b62ea40..b45ef5e 100644
--- a/sympy/simplify/tests/test_simplify.py
+++ b/sympy/simplify/tests/test_simplify.py
@@ -33,7 +33,7 @@ def test_ratsimp_X2():
     assert e != 1
     assert ratsimp(e) == 1
 
-def test_trigsimp():
+def test_trigsimp1():
     x, y = symbols('x y')
 
     assert trigsimp(1 - sin(x)**2) == cos(x)**2
@@ -53,11 +53,27 @@ def test_trigsimp():
     assert trigsimp(cos(0.12345)**2 + sin(0.12345)**2) == 1
     e = 2*sin(x)**2 + 2*cos(x)**2
     assert trigsimp(log(e), deep=True) == log(2)
+
+def test_trigsimp2():
+    x, y = symbols('x y')
     assert trigsimp(cos(x)**2*sin(y)**2 + cos(x)**2*cos(y)**2 + sin(x)**2,
             recursive=True) == 1
     assert trigsimp(sin(x)**2*sin(y)**2 + sin(x)**2*cos(y)**2 + cos(x)**2,
             recursive=True) == 1
 
+def test_trigsimp3():
+    x, y = symbols('x y')
+    assert trigsimp(sin(x)/cos(x)) == tan(x)
+    assert trigsimp(sin(x)**2/cos(x)**2) == tan(x)**2
+    assert trigsimp(sin(x)**3/cos(x)**3) == tan(x)**3
+    assert trigsimp(sin(x)**10/cos(x)**10) == tan(x)**10
+
+    assert trigsimp(cos(x)/sin(x)) == 1/tan(x)
+    assert trigsimp(cos(x)**2/sin(x)**2) == 1/tan(x)**2
+    assert trigsimp(cos(x)**10/sin(x)**10) == 1/tan(x)**10
+
+    assert trigsimp(tan(x)) == trigsimp(sin(x)/cos(x))
+
 @XFAIL
 def test_factorial_simplify():
     # There are more tests in test_factorials.py. These are just to
-- 
1.6.0.4

Reply via email to