# How to get coefficients of a multivariate trigonometric polynomial?

I have a trigonometric polynomial which is something like this:

A = (b1+2) * sin(x) + (b2+q) * sin(x)^2cos(x) + (b3/b1+6) * sin(x)cos(x) + b4 * cos(x)^4 + b5

I want to get the coefficients of the multivariate polynomial with respect to sin(x1) and cos(x1). Please note that all other variables should be treated as coefficients, including b1, b2, b3, b4, b5 and q. I would rather do this with coefficient() command, but my only problem is that coefficient command works for univariate polynomial. I can write:

A.coefficients(sin(x))

But I can't write A.coefficients({sin(x),cos(x)}) because it given an error. What can I do?

The answer should produce something like this: coefficient,(exponent of sin(x),exponent of cos(x)); b1+1,(1,0); b2+q,(2,1); b3/b1+6,(1,1); b4,(0,1); b5,(0,0).

edit retag close merge delete

Sort by » oldest newest most voted

Here is an ad-hoc quick solution, hope it works for the special purpose needed:

def get_trigonometric_coefficients( A, x ):
"""A is the given trigonometric expression in a variable x.
We extract the corresponding coefficients in sin(x)^k * cos(x)^n
for possible k, n.
"""
data_DIC = {}
for op in A.operands():
k, n = 0, 0
# identify the type of the trigonometric expression appeared
factors = op.factor_list()
coeff   = 1
for f, mul in factors:
if f == sin(x):
k += mul
elif f == cos(x):
n += mul
else:
coeff *= f^mul
if (k,n) in data_DIC:
data_DIC[ (k,n) ] += coeff
else:
data_DIC[ (k,n) ]  = coeff
# print op, coeff, f, mul, '\n'
keys = data_DIC.keys()
keys . sort()
return [ ( data_DIC[key], key ) for key in keys ]

# test
var( 'b1 b2 q x b3 b4 b5' );
A = b4*cos(x)^4 + (b2 + q)*cos(x)*sin(x)^2 + (b3/b1 + 6)*cos(x)*sin(x) + (b1 + 2)*sin(x) + b5
print get_trigonometric_coefficients( A, x )
print get_trigonometric_coefficients( A.expand(), x )


Results:

[(b5, (0, 0)), (b4, (0, 4)), (b1 + 2, (1, 0)), ((6*b1 + b3)/b1, (1, 1)), (b2 + q, (2, 1))]
[(b5, (0, 0)), (b4, (0, 4)), (b1 + 2, (1, 0)), (b3/b1 + 6, (1, 1)), (b2 + q, (2, 1))]

more

Thanks! Can you tell me a little about what happens in this code? Thanks a log!

( 2018-03-15 11:31:19 -0600 )edit
2

I will better comment, not touching the above, sample code:

sage: A = (b4-1)*sin(x)*cos(x)^3 + 9*sin(x)
sage: A.operands()
[(b4 - 1)*cos(x)^3*sin(x), 9*sin(x)]


This splits $A$ into terms. Let op be the first term above:

sage: op = _[0]; op
(b4 - 1)*cos(x)^3*sin(x)


This is a product of factors. Let us print the factors and their powers as in the f, mul loop above:

sage: for f, mul in op.factor_list(): print "f = %s mul = %s" % (f, mul)
f = b4 - 1 mul = 1
f = cos(x) mul = 3
f = sin(x) mul = 1


Now we collect the $\sin x$, $\cos x$ parts from above, record the powers (the multiplicities). It may be that in the expression the (1, 3) signature reappears. Then the coefficient b4-1 above and the further coefficient(s) for (1,3 ...(more)

( 2018-03-15 12:51:41 -0600 )edit

Very elegant, I understand it now. Thanks a lot. How does the for loop work? Doesn't it need to specify the number of iterations for loop?

( 2018-03-16 10:38:44 -0600 )edit
1

In python there are classes with tacitly implemented iterators, for instance lists, tuples, sets, strings. In case we want to access the entries of a list, for instance, it is cumbersome to use the number of them, then to loop asking for the list entry at place 0, at place 1, at place 2, ...

There is no need for such a "pointer thinking", one can just loop as in mathematics, e.g.

sage: L = (2^20).digits()
sage: for digit in L:
....:     print digit
....:
6
7
5
8
4
0
1


In mathematics we have rather sets, not lists, but $a\in A$ translates in python as a in A. The set $\{k^2\ :\ k\in \{1,2,\dots,10\}\}$ is of course

sage: { k^2 for k in [1..10] }
{1, 4, 9, 16, 25, 36, 49, 64, 81, 100}


This parallel made sage join python...

( 2018-03-24 18:47:50 -0600 )edit