# Revision history [back]

Here is a function to produce the desired quotient algebra.

Given generator names, a maximum degree, and a base ring, it builds the free algebra on the generators with the requested names over the requested ring, and outputs the quotient modulo terms of degree higher than the specified maximum degree.

def my_algebra(gen_names, max_degree=2, base_ring=QQ):
r"""
Return the quotient of the free algebra on these generators
by terms of degree max_degree + 1.

EXAMPLES::

sage: G = my_algebra(['a', 'b'], max_degree=2, base_ring=QQ)
sage: G.inject_variables()
sage: (a * b + a) * b
ab
sage: gens = (G.one(),) + G.gens()
sage: prods = [[x * y for y in gens] for x in gens]
sage: hr = gens
sage: hc = ('*',) + gens
*  | 1    a    b    aa   ab   ba   bb
+----+----+----+----+----+----+----+----+
1  | 1    a    b    aa   ab   ba   bb
a  | a    aa   ab   0    0    0    0
b  | b    ba   bb   0    0    0    0
aa | aa   0    0    0    0    0    0
ab | ab   0    0    0    0    0    0
ba | ba   0    0    0    0    0    0
bb | bb   0    0    0    0    0    0
"""
n = max_degree
R = base_ring
words = [w for W in [Words(gen_names, j) for j in range(n + 1)] for w in W]
names = [str(w) for w in words[1:]]
F = FreeAlgebra(R, names=names)
FM = F.monoid()
gens = FM.gens()
mons = (FM.one(),) + gens
r = len(mons)
M = MatrixSpace(R, r)
def row(m, mm):
if len(m) + len(mm) > n:
return [0] * r
res = [0] * r
res[words.index(mm * m)] = 1
return res
mats = [M([row(m, mm) for mm in words]) for m in words[1:]]
return FreeAlgebraQuotient(F, mons, mats, names=names)


Here is a function to produce the desired quotient algebra.

Given generator names, a maximum degree, and a base ring, it builds the free algebra on the generators with the requested names over the requested ring, and outputs the quotient modulo terms of degree higher than the specified maximum degree.

The following function works with one-letter generators.

def my_algebra(gen_names, max_degree=2, base_ring=QQ):
r"""
Return the quotient of the free algebra on these generators
by terms of degree max_degree + 1.

EXAMPLES::

sage: G = my_algebra(['a', 'b'], max_degree=2, base_ring=QQ)
sage: G.inject_variables()
sage: (a * b + a) * b
ab
sage: gens = (G.one(),) + G.gens()
sage: prods = [[x * y for y in gens] for x in gens]
sage: hr = gens
sage: hc = ('*',) + gens
*  | 1    a    b    aa   ab   ba   bb
+----+----+----+----+----+----+----+----+
1  | 1    a    b    aa   ab   ba   bb
a  | a    aa   ab   0    0    0    0
b  | b    ba   bb   0    0    0    0
aa | aa   0    0    0    0    0    0
ab | ab   0    0    0    0    0    0
ba | ba   0    0    0    0    0    0
bb | bb   0    0    0    0    0    0
"""
n = max_degree
R = base_ring
words = [w for W in [Words(gen_names, j) for j in range(n + 1)] for w in W]
names = [str(w) for w in words[1:]]
F = FreeAlgebra(R, names=names)
FM = F.monoid()
gens = FM.gens()
mons = (FM.one(),) + gens
r = len(mons)
M = MatrixSpace(R, r)
def row(m, mm):
if len(m) + len(mm) > n:
return [0] * r
res = [0] * r
res[words.index(mm * m)] = 1
return res
mats = [M([row(m, mm) for mm in words]) for m in words[1:]]
return FreeAlgebraQuotient(F, mons, mats, names=names)


This variant accepts multicharacter generator names:

def my_algebra(gen_names, max_degree=2, base_ring=QQ):
r"""
Return the quotient of the free algebra on these generators
by terms of degree max_degree + 1.
"""
n = max_degree
R = base_ring
word_options = dict(WordOptions())
WordOptions(letter_separator='')
words = [w for W in [Words(gen_names, j) for j in range(n + 1)] for w in W]
names = [str(w) for w in words[1:]]
F = FreeAlgebra(R, names=names)
FM = F.monoid()
gens = FM.gens()
mons = (FM.one(),) + gens
r = len(mons)
M = MatrixSpace(R, r)
def row(m, mm):
if len(m) + len(mm) > n:
return [0] * r
res = [0] * r
res[words.index(mm * m)] = 1
return res
mats = [M([row(m, mm) for mm in words]) for m in words[1:]]
WordOptions(**word_options)
return FreeAlgebraQuotient(F, mons, mats, names=names)


This function gives the multiplication table:

def algebra_table(G):
gens = (G.one(),) + G.gens()
prods = [[x * y for y in gens] for x in gens]
hr = gens
hc = ('*',) + gens


Some trials in the Sage REPL:

sage: G = my_algebra(['a', 'b'], max_degree=2, base_ring=QQ)
sage: a, b = G.gen(0), G.gen(1)
sage: (a * b + a) * b
ab

sage: algebra_table(G)
*  | 1    a    b    aa   ab   ba   bb
+----+----+----+----+----+----+----+----+
1  | 1    a    b    aa   ab   ba   bb
a  | a    aa   ab   0    0    0    0
b  | b    ba   bb   0    0    0    0
aa | aa   0    0    0    0    0    0
ab | ab   0    0    0    0    0    0
ba | ba   0    0    0    0    0    0
bb | bb   0    0    0    0    0    0

sage: G = my_algebra(['x1', 'x2'], max_degree=2, base_ring=QQ)
sage: a, b = G.gen(0), G.gen(1)
sage: (a * b + a) * b
x1x2

sage: algebra_table(G)
*    | 1      x1     x2     x1x1   x1x2   x2x1   x2x2
+------+------+------+------+------+------+------+------+
1    | 1      x1     x2     x1x1   x1x2   x2x1   x2x2
x1   | x1     x1x1   x1x2   0      0      0      0
x2   | x2     x2x1   x2x2   0      0      0      0
x1x1 | x1x1   0      0      0      0      0      0
x1x2 | x1x2   0      0      0      0      0      0
x2x1 | x2x1   0      0      0      0      0      0
x2x2 | x2x2   0      0      0      0      0      0

sage: G = my_algebra(['x_1', 'x_2'], max_degree=2, base_ring=QQ)
sage: a, b = G.gen(0), G.gen(1)
sage: (a * b + a) * b
x_1x_2

sage: algebra_table(G)
*      | 1        x_1      x_2      x_1x_1   x_1x_2   x_2x_1   x_2x_2
+--------+--------+--------+--------+--------+--------+--------+--------+
1      | 1        x_1      x_2      x_1x_1   x_1x_2   x_2x_1   x_2x_2
x_1    | x_1      x_1x_1   x_1x_2   0        0        0        0
x_2    | x_2      x_2x_1   x_2x_2   0        0        0        0
x_1x_1 | x_1x_1   0        0        0        0        0        0
x_1x_2 | x_1x_2   0        0        0        0        0        0
x_2x_1 | x_2x_1   0        0        0        0        0        0
x_2x_2 | x_2x_2   0        0        0        0        0        0


In Jupyter, latexing is off for names such as x1x2 or x_1x_2. Not sure how to fix that.