2
\$\begingroup\$

Thie programs is written in Sympy 1.9 and it should find a polynomial g of degree dim for a given polynomial f such that f o g = g o f as described here, where I already posted program written in Maxima. This is my first program in SymPy so I am interested in your feedback on this program except on the algorithm itself.

from sympy import symbols, pprint, expand, Poly, IndexedBase, Idx,Eq,solve
from sympy.abc import x,f,g,i
fg,gf,d=symbols('fg gf d')
f=x**3+3*x # a polynomial g exists
#f=x**3+4*x # a polynomial g does not exist
dim=5
a=IndexedBase('a')
i=Idx('i',dim)
# create a polynomial of degree dim 
# with unknown coefficients,
# but the coefficient of the highest power is 1
# an the lowest power is 1
g=a[0]+x**dim
for i in range(1,dim):
 g+=x**i*a[i]
# calculate fg = f o g 
# and gf = g o f
fg=f
gf=g
fg=expand(f.subs(x,g))
gf=expand(g.subs(x,f))
# calculate the difference d=(f o g) - (g o f)
# and check how to choose the coefficients of g
# such that it will become 0
difference=(fg-gf).as_poly(x)
candidates=solve(difference.all_coeffs()[:dim],[a[i] for i in range(dim)])
replacements=[(a[i],candidates[0][i]) for i in range(dim)]
if (difference.subs(replacements)==0):
 pprint(g.subs(replacements))
else:
 print("no solution exists")
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Dec 24, 2021 at 6:53
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Turning into a Function

I would advise turning your program into a function. This allows people to use your function in other Python scripts. That is:

def poly_commute(f, dim):
 a=IndexedBase('a')
 i=Idx('i',dim)
 g=a[0]+x**dim
 for i in range(1,dim):
 g+=x**i*a[i]
 # calculate fg = f o g 
 # and gf = g o f
 fg=f
 gf=g
 fg=expand(f.subs(x,g))
 gf=expand(g.subs(x,f))
 # calculate the difference d=(f o g) - (g o f)
 # and check how to choose the coefficients of g
 # such that it will become 0
 difference=(fg-gf).as_poly(x)
 candidates=solve(difference.all_coeffs()[:dim],[a[i] for i in range(dim)])
 replacements=[(a[i],candidates[0][i]) for i in range(dim)]
 if (difference.subs(replacements)==0):
 return g.subs(replacements)
 else:
 return None
 

Also, you should add some documentation so others can understand what your function does.

Related: Removing Global Variables

Managing state can be a pain. Keeping track of what can be in which state can be a headache. It isn't of course unmanageable in this case, but it would be useful to get rid of the state. To do so, I would add a main function.

def main():
 f = x**3 + 3*x
 dim = 5
 g = poly_commute(f, dim)
 if g:
 pprint(g)
 else:
 print("No solution exists.")
if __name__ == '__main__':
 main()

PEP 8:

There is some spacing of equations that seem to be off. This is explained in "Other recommendations" of PEP 8:

If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator:

# Correct:
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# Wrong:
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
answered Dec 25, 2021 at 18:37
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.