# Down-Up Algebras#

AUTHORS:

• Travis Scrimshaw (2023-4): initial version

class sage.algebras.down_up_algebra.DownUpAlgebra(alpha, beta, gamma, base_ring)#

The down-up algebra.

Let $$R$$ be a commutative ring, and let $$\alpha, \beta, \gamma \in R$$. The down-up algebra is the associative unital algebra $$DU(\alpha, \beta, \gamma)$$ generated by $$d, u$$ with relations

\begin{split}\begin{aligned} d^2u & = \alpha dud + \beta ud^2 + \gamma d, \\ du^2 & = \alpha udu + \beta u^2d + \gamma u. \end{aligned}\end{split}

The down-up algebra has a PBW-type basis given by

$\{ u^i (du)^j d^k \mid i,j,k \in \ZZ_{\geq 0} \}.$

This algebra originates in the study of posets. For a poset $$P$$, we define operators acting on $$R[P]$$ by

$d(y) = \sum_x x \qquad\qquad u(y) = \sum_z z,$

where $$y$$ covers $$x$$ and $$z$$ covers $$y$$. For $$r$$-differential posets we have $$du - ud = r 1$$, and thus it affords a representation of a Weyl algebra. This Weyl algebra is obtained as the quotient of $$DU(0, 1, 2r)$$ by the ideal generated by $$du - ud - r$$. For a $$(q, r)$$-differential poset, we have the $$d$$ and $$u$$ operators satisfying

\begin{split}\begin{aligned} d^2u & = q(q+1) dud - q^3 ud^2 + r d, \\ du^2 & = q(q+1) udu - q^3 u^2d + r u, \end{aligned}\end{split}

or $$\alpha = q(q+1)$$, $$\beta = -q^3$$, and $$\gamma = r$$. Specializing $$q = -1$$ recovers the $$r$$-differential poset relation.

Two other noteworthy quotients are:

• the $$q$$-Weyl algebra from $$DU(0, q^2, q+1)$$ by the ideal generated by $$du - qud - 1$$, and

• the quantum plane $$R_q[d, u]$$, where $$du = qud$$, from $$DU(2q, -q^2, 0)$$ by the ideal generated by $$du - qud$$.

EXAMPLES:

We begin by constructing the down-up algebra and perform some basic computations:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: d, u = DU.gens()
sage: d * u
(d*u)
sage: u * d
u*d
sage: d^2 * u
b*u*d^2 + a*(d*u)*d + g*d
sage: d * u^2
b*u^2*d + a*u*(d*u) + g*u


We verify some examples of Proposition 3.5 in [BR1998], which states that the 0-th degree part is commutative:

sage: DU0 = [u^i * (d*u)^j * d^i for i,j in
....:        cartesian_product([range(3), range(3)])]
sage: all(x.degree() == 0 for x in DU0)
True
sage: all(x * y == y * x for x, y in cartesian_product([DU0, DU0]))
True


We verify that $$DU(2, -1, \gamma)$$ can be described as the universal enveloping algebra of the 3-dimensional Lie algebra spanned by $$x,y,z$$ satisfying $$z = [x, y]$$, $$[x, z] = \gamma x$$, and $$[z, y] = \gamma y$$:

sage: R.<g> = QQ[]
sage: L = LieAlgebra(R, {('x','y'): {'z': 1}, ('x','z'): {'x': g}, ('z','y'): {'y': g}},
....:                names='x,y,z')
sage: x, y, z = L.basis()
sage: (L[x, y], L[x, z], L[z, y])
(z, g*x, g*y)
sage: x, y, z = L.pbw_basis().gens()
sage: x^2*y - 2*x*y*x + y*x^2 == g*x
True
sage: x*y^2 - 2*y*x*y + y^2*x == g*y
True
sage: DU = algebras.DownUp(2, -1, g)
sage: d, u = DU.gens()
sage: d^2*u - 2*d*u*d + u*d^2 == g*d
True
sage: d*u^2 - 2*u*d*u + u^2*d == g*u
True


Young’s lattice is known to be a differential poset. Thus we can construct a representation of $$DU(0, 1, 2)$$ on this poset (which gives a proof that Fomin’s growth diagrams are equivalent to edge local rules or shadow lines construction for RSK()):

sage: DU = algebras.DownUp(0, 1, 2)
sage: d, u = DU.gens()
sage: d^2*u == 0*d*u*d + 1*u*d*d + 2*d
True
sage: d*u^2 == 0*u*d*u + 1*u*u*d + 2*u
True

sage: YL = CombinatorialFreeModule(DU.base_ring(), Partitions())
sage: def d_action(la):
....:     return YL.sum_of_monomials(la.remove_cell(*c) for c in la.removable_cells())
sage: def u_action(la):
sage: D = YL.module_morphism(on_basis=d_action, codomain=YL)
sage: U = YL.module_morphism(on_basis=u_action, codomain=YL)
sage: for la in PartitionsInBox(5, 5):
....:     b = YL.basis()[la]
....:     assert (D*D*U)(b) == 0*(D*U*D)(b) + 1*(U*D*D)(b) + 2*D(b)
....:     assert (D*U*U)(b) == 0*(U*D*U)(la) + 1*(U*U*D)(b) + 2*U(b)
....:     assert (D*U)(b) == (U*D)(b) + b  # the Weyl algebra relation


Todo

Implement the homogenized version.

REFERENCES:

algebra_generators()#

Return the algebra generators of self.

EXAMPLES:

sage: DU = algebras.DownUp(2, 3, 4)
sage: dict(DU.algebra_generators())
{'d': d, 'u': u}

degree_on_basis(m)#

Return the degree of the basis element indexed by m.

EXAMPLES:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: I = DU.indices()
sage: DU.degree_on_basis(I([0, 3, 2]))
-2
sage: DU.degree_on_basis(I([2, 3, 0]))
2
sage: DU.degree_on_basis(I([2, 0, 3]))
-1
sage: DU.degree_on_basis(I([3, 10, 3]))
0

gens()#

Return the generators of self.

EXAMPLES:

sage: DU = algebras.DownUp(2, 3, 4)
sage: DU.gens()
(d, u)

one_basis()#

Return the index of the basis element of $$1$$.

EXAMPLES:

sage: DU = algebras.DownUp(2, 3, 4)
sage: DU.one_basis()
(0, 0, 0)

product_on_basis(m1, m2)#

Return the product of the basis elements indexed by m1 and m2.

EXAMPLES:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: I = DU.indices()
sage: DU.product_on_basis(I([2,0,0]), I([4,0,0]))
u^6
sage: DU.product_on_basis(I([2,0,0]), I([0,4,0]))
u^2*(d*u)^4
sage: DU.product_on_basis(I([2,0,0]), I([0,0,4]))
u^2*d^4
sage: DU.product_on_basis(I([0,2,0]), I([0,4,0]))
(d*u)^6
sage: DU.product_on_basis(I([0,2,0]), I([0,0,4]))
(d*u)^2*d^4
sage: DU.product_on_basis(I([0,0,2]), I([0,0,4]))
d^6
sage: DU.product_on_basis(I([5,3,1]), I([1,0,4]))
u^5*(d*u)^4*d^4

sage: DU.product_on_basis(I([0,1,0]), I([1,0,0]))
b*u^2*d + a*u*(d*u) + g*u
sage: DU.product_on_basis(I([0,0,2]), I([1,0,0]))
b*u*d^2 + a*(d*u)*d + g*d
sage: DU.product_on_basis(I([0,0,1]), I([2,0,0]))
b*u^2*d + a*u*(d*u) + g*u
sage: DU.product_on_basis(I([0,0,1]), I([0,1,0]))
b*u*d^2 + a*(d*u)*d + g*d

sage: DU.product_on_basis(I([0,1,0]), I([3,0,0]))
(a^2*b+b^2)*u^4*d + (a^3+2*a*b)*u^3*(d*u) + (a^2*g+a*g+b*g+g)*u^3
sage: DU.product_on_basis(I([1,1,3]), I([0,1,1]))
(a^2*b^2+b^3)*u^3*d^6 + (a^3*b+a*b^2)*u^2*(d*u)*d^5 + (a^2*b*g+b^2*g)*u^2*d^5
+ (a^3+2*a*b)*u*(d*u)^2*d^4 + (a^2*g+a*g+b*g+g)*u*(d*u)*d^4

verma_module(la)#

Return the Verma module $$V(\lambda)$$ of self.

EXAMPLES:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: DU.verma_module(5)
Verma module of weight 5 of Down-Up algebra with parameters (a, b, g)
over Multivariate Polynomial Ring in a, b, g over Rational Field

class sage.algebras.down_up_algebra.VermaModule(DU, la)#

The Verma module $$V(\lambda)$$ of a down-up algebra.

The Verma module $$V(\lambda)$$ for the down-up algebra generated by $$d, u$$ is the span of $$\{v_n \mid n \in \ZZ_{\geq 0} \}$$ satisfying the relations

$d \cdot v_n = \lambda_{n-1} v_{n-1}, \qquad\qquad u \cdot v_n = v_{n+1},$

where $$\lambda_n = \alpha \lambda_{n-1} + \beta \lambda_{n-2} + \gamma$$ and we set $$\lambda_0 = \lambda$$ and $$\lambda_{-1} = 0$$.

By Proposition 2.4 in [BR1998], $$V(\lambda)$$ is simple if and only if $$\lambda_n \neq 0$$ for all $$n \geq 0$$. Moreover, a maximal submodule is spanned by $$\{ v_n \mid n > m \}$$, where $$m$$ is the minimal index such that $$\lambda_m = 0$$. Moreover, this is unique unless $$\gamma = \lambda = 0$$.

EXAMPLES:

sage: R.<a,b> = QQ[]
sage: DU = algebras.DownUp(0, b, 1)
sage: d, u = DU.gens()
sage: V = DU.verma_module(a)
sage: list(V.weights()[:6])
[a, 1, a*b + 1, b + 1, a*b^2 + b + 1, b^2 + b + 1]
sage: v = V.basis()
sage: d^2 * v
a*v
sage: d * (d * v)
a*v


The weight is computed by looking at the scalars associated to the action of $$du$$ and $$ud$$:

sage: d*u * v
(b+1)*v
sage: u*d * v
(a*b+1)*v
sage: v.weight()
(b + 1, a*b + 1)


An $$U(\mathfrak{sl}_2)$$ example:

sage: DU = algebras.DownUp(2, -1, -2)
sage: d, u = DU.gens()
sage: V = DU.verma_module(5)
sage: list(V.weights()[:10])
[5, 8, 9, 8, 5, 0, -7, -16, -27, -40]
sage: v6 = V.basis()
sage: d * v6
0
sage: [V.basis()[i].weight() for i in range(6)]
[(5, 0), (8, 5), (9, 8), (8, 9), (5, 8), (0, 5)]


Note that these are the same $$\mathfrak{sl}_2$$ weights from the usual construction of the irreducible representation $$V(5)$$ (but they are different as $$\mathfrak{gl}_2$$ weights):

sage: B = crystals.Tableaux(['A',1], shape=)
sage: [b.weight() for b in B]
[(5, 0), (4, 1), (3, 2), (2, 3), (1, 4), (0, 5)]


An example with periodic weights (see Theorem 2.13 of [BR1998]):

sage: k.<z6> = CyclotomicField(6)
sage: al = z6 + 1
sage: (al - 1)^6 == 1
True
sage: DU = algebras.DownUp(al, 1-al, 0)
sage: V = DU.verma_module(5)
sage: list(V.weights()[:8])
[5, 5*z6 + 5, 10*z6, 10*z6 - 5, 5*z6 - 5, 0, 5, 5*z6 + 5]

class Element#

An element of a Verma module of a down-up algebra.

is_weight_vector()#

Return if self is a weight vector.

EXAMPLES:

sage: DU = algebras.DownUp(2, -1, -2)
sage: V = DU.verma_module(5)
sage: V.zero().is_weight_vector()
False
sage: B = V.basis()
sage: [B[i].weight() for i in range(6)]
[(5, 0), (8, 5), (9, 8), (8, 9), (5, 8), (0, 5)]
sage: B.is_weight_vector()
True
sage: v = B + B
sage: v.is_weight_vector()
False

sage: DU = algebras.DownUp(2, -1, 0)
sage: V = DU.verma_module(0)
sage: B = V.basis()
sage: v = sum(i*B[i] for i in range(1,5))
sage: v.is_weight_vector()
True

weight()#

Return the weight of self.

For $$v_n$$, this is the vector with the pair $$(\lambda_n, \lambda_{n-1})$$.

EXAMPLES:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: V = DU.verma_module(5)
sage: B = V.basis()
sage: B.weight()
(5, 0)
sage: B.weight()
(5*a + g, 5)
sage: B.weight()
(5*a^2 + a*g + 5*b + g, 5*a + g)

sage: V.zero().weight()
Traceback (most recent call last):
...
ValueError: the zero element does not have well-defined weight
sage: (B + B).weight()
Traceback (most recent call last):
...
ValueError: not a weight vector

highest_weight_vector()#

Return the highest weight vector of self that generates self as a down-up module.

EXAMPLES:

sage: DU = algebras.DownUp(1, 2, 3)
sage: V = DU.verma_module(5)
sage: V.highest_weight_vector()
v

weights()#

Return the sequence of weights $$(\lambda_n)_{n=0}^{\infty}$$.

EXAMPLES:

sage: R.<a,b,g> = QQ[]
sage: DU = algebras.DownUp(a, b, g)
sage: V = DU.verma_module(5)
sage: V.weights()
lazy list [5, 5*a + g, 5*a^2 + a*g + 5*b + g, ...]

sage: V = DU.verma_module(0)
sage: DU = algebras.DownUp(a, 1-a, 0)
sage: V = DU.verma_module(0)
sage: V.weights()
lazy list [0, 0, 0, ...]


We reproduce the Fibonacci numbers example from [BR1998]:

sage: R.<la> = QQ[]
sage: DU = algebras.DownUp(1, 1, 0, R)
sage: V = DU.verma_module(la)
sage: list(V.weights()[:11])
[la, la, 2*la, 3*la, 5*la, 8*la, 13*la, 21*la, 34*la, 55*la, 89*la]