A mathematical software for manipulating trigonometric polynomials

161 Views Asked by At

I am looking for recommendations for math software that can do manipulations with trigonometric polynomials. Basically, I have a bunch of trigonometric expressions like $$K \cos{\left(\alpha + \chi_1 - \chi_2 - \phi_1 + \phi_2 \right)} + K \cos{\left(\alpha - \phi_1 + \phi_2 - \psi_1 + \psi_2 \right)} .$$ Here $K$, $r$ and $\alpha$ are parameters and $\phi_1, \phi_2, \psi_1, \psi_2, \chi_1, \chi_2$ are variables. A quite usual approach to my further analysis would be to expand it into products of sines and cosines of variables and group terms with the same powers. For example, $K \cos{\left(\alpha + \chi_1 - \chi_2 - \phi_1 + \phi_2 \right)}$ expands to $$K \sin{\left(\alpha \right)} \sin{\left(\chi_1 \right)} \sin{\left(\chi_2 \right)} \sin{\left(\phi_1 \right)} \cos{\left(\phi_2 \right)} - K \sin{\left(\alpha \right)} \sin{\left(\chi_1 \right)} \sin{\left(\chi_2 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\phi_1 \right)} - K \sin{\left(\alpha \right)} \sin{\left(\chi_1 \right)} \sin{\left(\phi_1 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\chi_2 \right)} - K \sin{\left(\alpha \right)} \sin{\left(\chi_1 \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_1 \right)} \cos{\left(\phi_2 \right)} + K \sin{\left(\alpha \right)} \sin{\left(\chi_2 \right)} \sin{\left(\phi_1 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\chi_1 \right)} + K \sin{\left(\alpha \right)} \sin{\left(\chi_2 \right)} \cos{\left(\chi_1 \right)} \cos{\left(\phi_1 \right)} \cos{\left(\phi_2 \right)} + K \sin{\left(\alpha \right)} \sin{\left(\phi_1 \right)} \cos{\left(\chi_1 \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_2 \right)} - K \sin{\left(\alpha \right)} \sin{\left(\phi_2 \right)} \cos{\left(\chi_1 \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_1 \right)} + K \sin{\left(\chi_1 \right)} \sin{\left(\chi_2 \right)} \sin{\left(\phi_1 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\alpha \right)} + K \sin{\left(\chi_1 \right)} \sin{\left(\chi_2 \right)} \cos{\left(\alpha \right)} \cos{\left(\phi_1 \right)} \cos{\left(\phi_2 \right)} + K \sin{\left(\chi_1 \right)} \sin{\left(\phi_1 \right)} \cos{\left(\alpha \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_2 \right)} - K \sin{\left(\chi_1 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\alpha \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_1 \right)} - K \sin{\left(\chi_2 \right)} \sin{\left(\phi_1 \right)} \cos{\left(\alpha \right)} \cos{\left(\chi_1 \right)} \cos{\left(\phi_2 \right)} + K \sin{\left(\chi_2 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\alpha \right)} \cos{\left(\chi_1 \right)} \cos{\left(\phi_1 \right)} + K \sin{\left(\phi_1 \right)} \sin{\left(\phi_2 \right)} \cos{\left(\alpha \right)} \cos{\left(\chi_1 \right)} \cos{\left(\chi_2 \right)} + K \cos{\left(\alpha \right)} \cos{\left(\chi_1 \right)} \cos{\left(\chi_2 \right)} \cos{\left(\phi_1 \right)} \cos{\left(\phi_2 \right)}.$$

This is a simple example, however it already shows that coefficients of these polynomials are not just integers: they are also symbolic expressions, like $K \sin \alpha$. For example, if expressions are more complex, simple expansion won't help, I have to group up terms for further analysis.

Before I was using Python's SymPy to do expansions and term rewriting. However, I haven't found a way to collect terms as I want. For example, in a simplest expression $$ A \cos{\left(\alpha \right)} + B \sin{\left(\alpha \right)} \cos{\left(\alpha \right)} + C \cos{\left(\alpha \right)} $$ I expect terms to be gathered like this $$ (A+C) \cos{\left(\alpha \right)} + B \sin{\left(\alpha \right)} \cos{\left(\alpha \right)} ,$$ but using sympy.collect(expr, [sympy.cos(alpha), sympy.sin(alpha)]) or sympy.collect(expr, [sympy.cos(alpha), sympy.sin(alpha)], sympy.factor) leads to $$ \left(A + B \sin{\left(\alpha \right)} + C\right) \cos{\left(\alpha \right)},$$ which is not desirable. Exactly the same happens to regular polynomials too: collecting terms is greedy. The trigonometric problem could be converted to a problem of ordinary multivariate polynomials by substituting $\cos \theta = \frac{1-T^2}{1+T^2}$ and $\sin \theta = \frac{2T}{1+T^2}$, so I am okay with software that can group polynomials in the way that I need.

I would be glad to hear what are the alternatives to SymPy or how that could be done in SymPy if you've encountered this problem. Thanks in advance!

P.S. Special thanks if you know an open-source solution for this or can point to a tutorial where it is shown that a software can do this!

P.P.S. I also have big hopes for open-source software like Maxima, Reduce, Axiom. I'm currently skimming their tutorials, but haven't found if they can do what I'm asking.

2

There are 2 best solutions below

3
On

In Wolfram Mathematica 12.0 writing:

Factor[a Cos[x] + b Sin[x] Cos[x] + c Cos[x]]

you get:

Cos[x] (a + c + b Sin[x])

since this is the standard factorization rule present in practically every CAS.

On the other hand, not all CAS have a function like:

Collect[a Cos[x] + b Sin[x] Cos[x] + c Cos[x], {Sin[x], Cos[x]}]

through which to obtain:

(a + c) Cos[x] + b Cos[x] Sin[x]

also applicable to more complicated cases:

expr = Expand[x^2 - x y + y^2 - 2 y - 3 x - 1 /. {x -> a1 + a2 Cos[t] + a3 Sin[t], 
                                                  y -> a4 + a5 Cos[t] + a6 Sin[t]}];
Collect[expr, {Cos[t], Sin[t], Cos[t] Sin[t]}]

-1 - 3 a1 + a1^2 - 2 a4 - a1 a4 + a4^2 + (-3 a2 + 2 a1 a2 - a2 a4 - 2 a5 - a1 a5 + 2 a4 a5) Cos[t] + (a2^2 - a2 a5 + a5^2) Cos[t]^2 + (-3 a3 + 2 a1 a3 - a3 a4 - 2 a6 - a1 a6 + 2 a4 a6) Sin[t] + (2 a2 a3 - a3 a5 - a2 a6 + 2 a5 a6) Cos[t] Sin[t] + (a3^2 - a3 a6 + a6^2) Sin[t]^2

But perhaps the most interesting thing is to be able to introduce custom rules like:

rule = Log[expr_] :> Log[Abs[expr]];

Integrate[(2 x^2 + 2 x + 1)/(x + 1), x]
Integrate[(2 x^2 + 2 x + 1)/(x + 1), x] /. rule

-1 + x^2 + Log[1 + x]

-1 + x^2 + Log[Abs[1 + x]]

Of course, it takes some time to get enough confidence.

2
On

We can split $K$ by the usage of trigexpand:

(%i12) K:cos(alpha+xi1-xi2-phi1+phi2);
(%o12)               cos(xi2 - xi1 - phi2 + phi1 - alpha)
(%i13) trigexpand(K);
(%o13) cos(alpha) sin(phi1) sin(phi2) sin(xi1) sin(xi2)
 - sin(alpha) cos(phi1) sin(phi2) sin(xi1) sin(xi2)
 + sin(alpha) sin(phi1) cos(phi2) sin(xi1) sin(xi2)
 + cos(alpha) cos(phi1) cos(phi2) sin(xi1) sin(xi2)
 + sin(alpha) sin(phi1) sin(phi2) cos(xi1) sin(xi2)
 + cos(alpha) cos(phi1) sin(phi2) cos(xi1) sin(xi2)
 - cos(alpha) sin(phi1) cos(phi2) cos(xi1) sin(xi2)
 + sin(alpha) cos(phi1) cos(phi2) cos(xi1) sin(xi2)
 - sin(alpha) sin(phi1) sin(phi2) sin(xi1) cos(xi2)
 - cos(alpha) cos(phi1) sin(phi2) sin(xi1) cos(xi2)
 + cos(alpha) sin(phi1) cos(phi2) sin(xi1) cos(xi2)
 - sin(alpha) cos(phi1) cos(phi2) sin(xi1) cos(xi2)
 + cos(alpha) sin(phi1) sin(phi2) cos(xi1) cos(xi2)
 - sin(alpha) cos(phi1) sin(phi2) cos(xi1) cos(xi2)
 + sin(alpha) sin(phi1) cos(phi2) cos(xi1) cos(xi2)
 + cos(alpha) cos(phi1) cos(phi2) cos(xi1) cos(xi2)

We can use the tex funtcion to generate TeX output.

I tried to mimic the simplifications of this answer in Maxima and got this when using the function facsum:

(%i1) load (facexp)$
(%i2) e:A*cos(a)+B*sin(a)*cos(a)+C*cos(a);
(%o2)                B cos(a) sin(a) + C cos(a) + A cos(a)
(%i3) facsum(e,sin(a),cos(a));
(%o3)                  B cos(a) sin(a) + (C + A) cos(a)
(%i4) expr : expand(x^2 - x *y + y^2 - 2 *y - 3 *x - 1 ),
x = a1 + a2 *cos(t) + a3 *sin(t),
y = a4 + a5 *cos(t) + a6 *sin(t)$
(%i5) facsum(expr,sin(t),cos(t));
         2             2     2
(%o5) (a6  - a3 a6 + a3 ) sin (t) + (2 a5 a6 - a2 a6 - a3 a5 + 2 a2 a3) cos(t)
 sin(t) + (2 a4 a6 - a1 a6 - 2 a6 - a3 a4 + 2 a1 a3 - 3 a3) sin(t)
      2             2     2
 + (a5  - a2 a5 + a2 ) cos (t) + (2 a4 a5 - a1 a5 - 2 a5 - a2 a4 + 2 a1 a2
                    2                    2
 - 3 a2) cos(t) + a4  - a1 a4 - 2 a4 + a1  - 3 a1 - 1

I am not aware of a documented Maxima function that extracts the coeffiecients except ratp_coeffs which does this for one variable. Or you can program your own function. But there is an undocumented function coeffsin the package coeflist that (almost) seems to do what you want

(%i1) load("coeflist")$
(%i2) expr : expand(x^2 - x *y + y^2 - 2 *y - 3 *x - 1 ),
     x = a1 + a2 *cos(t) + a3 *sin(t),
     y = a4 + a5 *cos(t) + a6 *sin(t)$
(%i13) expr2: coeffs(expr,sin(t),cos(t));
                                    2                    2
(%o13) [[%poly, sin(t), cos(t)], [a4  - a1 a4 - 2 a4 + a1  - 3 a1 - 1, 0, 0],
[2 a4 a5 - a1 a5 - 2 a5 - a2 a4 + 2 a1 a2 - 3 a2, 0, 1],
   2             2
[a5  - a2 a5 + a2 , 0, 2], [2 a4 a6 - a1 a6 - 2 a6 - a3 a4 + 2 a1 a3 - 3 a3,
                                                     2             2
1, 0], [2 a5 a6 - a2 a6 - a3 a5 + 2 a2 a3, 1, 1], [a6  - a3 a6 + a3 , 2, 0]]

demo("coeflist.demo")shows some additional function of this package.

if we want only the coefficients we skip the first element of this list and retrieve the first element of each remaining triple.

(%i10) map('first,rest(expr2));
          2                    2
(%o10) [a4  - a1 a4 - 2 a4 + a1  - 3 a1 - 1,
                                                   2             2
2 a4 a5 - a1 a5 - 2 a5 - a2 a4 + 2 a1 a2 - 3 a2, a5  - a2 a5 + a2 ,
2 a4 a6 - a1 a6 - 2 a6 - a3 a4 + 2 a1 a3 - 3 a3,
                                     2             2
2 a5 a6 - a2 a6 - a3 a5 + 2 a2 a3, a6  - a3 a6 + a3 ]

There is a postcript file (format.ps) in the directory that will contain some documentation. This documentation (in pdf format) can also be found here (Bruce R. Miller: An Expression Formatter for MACSYMA).