A short investigation of compositions and partitions in Sage. More details can be found in the documentation for compositions and partitions.
Requirements: None
# The compositions of a fixed integer n can be easily manipulated using Sage
C = Compositions(10)
print("The class [{}] has {} elements".format(C,C.cardinality()))
print("A random element of [{}] is {}".format(C,C.random_element()))
The class [Compositions of 10] has 512 elements A random element of [Compositions of 10] is [1, 1, 1, 1, 5, 1]
# The paritions of a fixed integer behave similarly
P = Partitions(20)
print("The class [{}] has {} elements".format(P,P.cardinality()))
print("A random element of [{}] is {}".format(P,P.random_element()))
The class [Partitions of the integer 20] has 627 elements A random element of [Partitions of the integer 20] is [8, 3, 2, 2, 2, 1, 1, 1]
# Partitions can be displayed graphically by their Ferrers diagram
p = P.random_element()
print("The partition {} has Ferrers diagram ".format(p))
show(p.ferrers_diagram())
The partition [5, 3, 3, 3, 2, 1, 1, 1, 1] has Ferrers diagram
# We can impose various constraints on the partitions
# Here we count partitions of 20 with at most 5 summands, each of size at most 10
Pbox = Partitions(20, max_part=10, max_length=5)
print("The class [{}] has {} elements".format(Pbox,Pbox.cardinality()))
print("A random element in this class is {}".format(Pbox.random_element()))
The class [Partitions of the integer 20 satisfying constraints max_length=5, max_part=10] has 121 elements A random element in this class is [7, 7, 2, 2, 2]
# The generating function of compositions is a geometric series
# Whether or not there is a composition of size zero is a matter of convention
var('z')
C = z/(1-2*z)
print(C.series(z,10).list()) # Series coefficients of geometric series
print([Compositions(k).cardinality() for k in range(10)]) # Actual count of compositions
[0, 1, 2, 4, 8, 16, 32, 64, 128, 256] [1, 1, 2, 4, 8, 16, 32, 64, 128, 256]
# The generating function of partitions is an infinite product, but only a finite number of terms determine a fixed number of initial terms
var('z')
def partition_series(N):
return mul([1/(1-z^k) for k in range(1,N+1)]).series(z,N)
print(partition_series(10).list())
print([Partitions(k).cardinality() for k in range(10)]) # Actual count of partitions
[1, 1, 2, 3, 5, 7, 11, 15, 22, 30] [1, 1, 2, 3, 5, 7, 11, 15, 22, 30]