Guiding Sympy though trig substitutions

502 views
Skip to first unread message

Alex Clifton

unread,
Feb 7, 2014, 2:28:20 AM2/7/14
to sy...@googlegroups.com
I was wondering if there was a way to “guide” sympy in performing trig identities to get the output into a specific form? Below, I go into detail and have attached a working version of the file for reference.

In the expression of P, the coefficients D, F, G, H, and J are assumed to be real valued. I have left some commented print statements to show the different simplify options I have tried. I have performed this calculation by hand and I know there are several trig substitutions that need to be made in order to get the final expression in the form that I would like. That form is to get rid of all powers of trig functions greater than 1 by appropriate substitutions. Of course, I cannot expect sympy to know that I want things in this form so I am not surprised when the different simplify  statements do not give me that form. I was wondering what would be the best way to guide sympy in order to get the final output of P to be in the following form:

K + Lsin(x) + Mcos(x) +  Nsin(2x) + Qcos(2x) + Rsin(3x) + Scos(3x) + Tsin(4x) + Vcos(4x)

Where K, L, M, N, Q, R, S, T, and V are now combinations of the original D, F, G, H, and J.

By the way, I am not as concerned now about the coefficients as I am getting rid of the higher powers of the trig functions. Although if people would like to weigh in on that, that would be great. If more detail is needed, please let me know and I’d be happy to provide it.

full_eq.py

Matthew Rocklin

unread,
Feb 7, 2014, 11:11:22 AM2/7/14
to sy...@googlegroups.com
A few parts of sympy allow you to specify objective functions for simplification.  Pure trig simplification with the fu algorithm is one.

In [6]: fu?
Objective function example
>>> fu(sin(x)/cos(x))  # default objective function
tan(x)
>>> fu(sin(x)/cos(x), measure=lambda x: -x.count_ops()) # maximize op count
sin(x)/cos(x)

But getting rid of powers and such will also rely on other parts of sympy which may not support this kind of guided search.

The search process is powered by sympy.strategies.tree.greedy

By the way, for others listening in, this is the sort of thing that the step-by-step expression manipulation GSoC project would be able to support as a side effect.


--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.

Jacob Bayless

unread,
Feb 18, 2014, 3:27:48 AM2/18/14
to sy...@googlegroups.com
Just thought I'd mention that I'm also looking to do the same thing.

One reason this particular form of an equation is important is that it represents the equation in terms of its frequency content. It is very easy to identify the Fourier components this way, which is important for things like communication, acoustics, information processing and optics. Cross terms like sin(x)cos(2x) and nonlinear terms like sin(x)^2 hide information about the actual spectral content of the equation. I can imagine it would be highly desirable to be able to conveniently manipulate trig equations into the form described by the original poster.

Jacob

mario

unread,
Feb 18, 2014, 6:56:06 AM2/18/14
to sy...@googlegroups.com
In fu.py there are several functions to manipulate trigonometric expressions; in your example you
can use TR8  to expand products of sin-cos to sums;

```
from sympy.simplify.fu import TR8
from sympy.simplify.simplify import _mexpand
P = (D + F*sin(x) + G*cos(x) + H*sin(2*x) + J*cos(2*x))**2
r = _mexpand(TR8(_mexpand(P)))
```
what is missing is the collection of the coefficients; it is easy to write a function collecting terms,
but I suspect that there is already a simple way in SymPy to do this.

Matthew Rocklin

unread,
Feb 18, 2014, 10:22:28 AM2/18/14
to sy...@googlegroups.com
It would be nice if users didn't have to know about all of the little functions in sympy but could instead just state an objective function.

We often get the questions "I want my result in this form..."
We often give the answers  "try this function, then this one, then one of these two, whichever works best"

This works but it requires human/listhost intervention.  It would be nice if sympy could do this itself.  In Fu simplification and in a few other functions it sort of can.  Note that this would make a great GSoC project if anyone is interested.


Aaron Meurer

unread,
Feb 18, 2014, 7:39:45 PM2/18/14
to sy...@googlegroups.com
Well, having better names for the Fu functions would go a long way towards this.

It would be cool to have a "simp lookup" routine, that works like
simp_lookup(expr1, expr2) -> list of functions that take expr1 to
expr2.

Aaron Meurer

Chris Smith

unread,
Feb 19, 2014, 11:07:12 PM2/19/14
to sy...@googlegroups.com
Regarding the naming of the Fu transformations -- in keeping with the paper (and anyone else who uses the Fu method) I think it wise to leave the names alone. This doesn't preclude the use of aliases, however, and anyone doing this work can easily write their own aliases.

And don't forget to read the header to the fu.py file which, has at the top, a summary of the different methods which could be printed out.

Chris Smith

unread,
Feb 19, 2014, 11:14:11 PM2/19/14
to sy...@googlegroups.com
ALSO -- Fu, et al., have already thought a lot about trig simplification and if you just run fu(expr) you may get what you are looking for:

>>> ok = fu(P.expand()); print filldedent(ok)

D**2 + 2*D*F*sin(x) + 2*D*G*cos(x) + 2*D*H*sin(2*x) + 2*D*J*cos(2*x) +
F**2*(-cos(2*x)/2 + 1/2) + F*G*sin(2*x) + F*H*(cos(x) - cos(3*x)) +
F*J*(-sin(x) + sin(3*x)) + G**2*(cos(2*x)/2 + 1/2) + G*H*(sin(x) +
sin(3*x)) + G*J*sin(4*x)/(2*sin(x)) + H**2*(-cos(4*x)/2 + 1/2) +
H*J*sin(4*x) + J**2*(cos(4*x)/2 + 1/2)

>>> print filldedent(ok.atoms(Pow))

set([D**2, J**2, F**2, 1/sin(x), G**2, H**2])


There are no powers of trig functions except for the sin(x) in the denominator.
Reply all
Reply to author
Forward
0 new messages