Noncommutative algebras
Singular.jl allows the creation of various noncommutative algebras over any of the coefficient rings described above. The constructors of the parent objects and elements thereof are given in the following table.
Constructor | Element type | Parent type | SINGULAR kernel subsystem |
---|---|---|---|
GAlgebra | spluralg{T} | PluralRing{T} | PLURAL |
WeylAlgebra | spluralg{T} | PluralRing{T} | PLURAL |
FreeAlgebra | slpalg{T} | LPRing{T} | LETTERPLACE |
These types are parameterized by the type of elements in the coefficient ring of the algebra. All noncommutative algebra element types belong directly to the abstract type AbstractAlgebra.NCRingElem
and all the noncommuative algebra parent object types belong to the abstract type AbstractAlgebra.NCRing
. The following union types cover all of Singular polynomial rings and algebras.
const PolyRingUnion{T} = Union{PolyRing{T}, PluralRing{T}, LPRing{T}} where T <: Nemo.RingElem
const SPolyUnion{T} = Union{spoly{T}, spluralg{T}, slpalg{T}} where T <: Nemo.RingElem
Constructors
All constructors returns a tuple, $R, x$ consisting of a parent object $R$ and an array $x$ of variables from which elements of the algebra can be constructed.
For constructors taking an ordering, two orderings can be specified by symbol, one for term ordering, and a second one for ordering of module components. The first ordering can also be specified by a non-symbol as with polynomial_ring
, in which case the second ordering is ignored.
By default there will only be one parent object in the system for each combination of arguments. This is accomplished by making use of a global cache. If this is not the desired behaviour cached = false
may be passed.
GAlgebra
GAlgebra(R::PolyRing{T}, C::smatrix{spoly{T}}, D::smatrix{spoly{T}};
cached::Bool = true) where T <: Nemo.RingElem
Construct the G-algebra from a commutative polynomial ring $R$ and matrices $C$, $D$ over $R$. If the variables of $R$ are $x_1,\dots,x_n$, then the noncommutative algebra is constructed with relations $x_j x_i = c_{i,j} x_i x_j + d_{i,j}$ for $1 \le i < j \le n$. The $c_{i,j}$ must be nonzero constant polynomials and the relations $x_i x_j > \mathrm{lm}(d_{i,j})$ must hold in the monomial ordering of the ring $R$.
The entries of the matrices $C$ and $D$ on or below the main diagonal are ignored. A non-matrix argument a
for either C
or D
is turned into a matrix with all relevant entries set to a
.
The conditions that assure that multiplication is associative in the resulting algebra are currently not checked. The example below illustrates how this condition can be checked.
Examples
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]);
julia> G, (x, y) = GAlgebra(R, 2, Singular.Matrix(R, [0 x; 0 0]))
(Singular G-algebra (QQ),(x,y),(dp(2),C), spluralg{n_Q}[x, y])
julia> y*x
2*x*y + x
Associativity can be checked via Interpreter Functionality.
julia> iszero(Singular.LibNctools.ndcond(G))
true
The construction of a GR-algebra proceeds by taking the quotient of a G-algebra by a two-sided ideal. Continuing with the above example:
julia> I = Ideal(G, [x^2 + y^2], twosided = true)
Singular two-sided ideal over Singular G-algebra (QQ),(x,y),(dp(2),C) with generators (x^2 + y^2)
julia> Q, (x, y) = QuotientRing(G, std(I))
(Singular G-algebra quotient ring (QQ),(x,y),(dp(2),C), spluralg{n_Q}[x, y])
WeylAlgebra
function WeylAlgebra(R::Union{Ring, Field}, s::AbstractVector{<:VarName};
ordering = :degrevlex, ordering2::Symbol = :comp1min,
cached::Bool = true, degree_bound::Int = 0)
function WeylAlgebra(R::Union{Ring, Field}, s::AbstractMatrix{<:VarName};
ordering = :degrevlex, ordering2::Symbol = :comp1min,
cached::Bool = true, degree_bound::Int = 0)
Construct the ring of differential operators $\partial_1, \dots, \partial_n$ with coefficients in $R[x_1, \dots, x_n]$. In the first variant, the differential operators are named by simply appending the letter "d" to each of the strings in x
. The second variant takes the names of the $x_i$ from the first row of the matrix and the names of the $\partial_i$ from the second row of the matrix. Note that the functionality of this constructor can be achieved with the GAlgebra
constructor: it is provided only for convenience. Note also that due to the ordering constraint on G-algebras, the orderings :neglex
, :negdeglex
, :negdevrevlex
are excluded.
Examples
julia> R, (x, y, dx, dy) = WeylAlgebra(ZZ, ["x", "y"])
(Singular G-algebra (ZZ),(x,y,dx,dy),(dp(4),C), spluralg{n_Z}[x, y, dx, dy])
julia> (dx*x, dx*y, dy*x, dy*y)
(x*dx + 1, y*dx, x*dy, y*dy + 1)
The ideals of G-algebras are left ideals by default.
julia> R, (x1, x2, x3, d1, d2, d3) = WeylAlgebra(QQ, ["x1" "x2" "x3"; "d1" "d2" "d3"])
(Singular G-algebra (QQ),(x1,x2,x3,d1,d2,d3),(dp(6),C), spluralg{n_Q}[x1, x2, x3, d1, d2, d3])
julia> gens(std(Ideal(R, [x1^2*d2^2 + x2^2*d3^2, x1*d2 + x3])))
7-element Vector{spluralg{n_Q}}:
x1*d2 + x3
x3^2
x2*x3 - x1
x1*x3
x2^2
x1*x2
x1^2
FreeAlgebra
FreeAlgebra(R::Field, s::AbstractVector{<:VarName}, degree_bound::Int;
ordering = :degrevlex, ordering2::Symbol = :comp1min,
cached::Bool = true)
Construct the free associative algebra $R \langle x_1,\dots,x_n \rangle$. The ordering must be global.
Since this uses the LETTERPLACE backend, the degree_bound
, which is the maximum length on any monomial word in the algebra, must be specified. Multiplication is checked and throws when the resulting degree exceeds this bound.
Examples
julia> R, (x, y) = FreeAlgebra(QQ, ["x", "y"], 5)
(Singular letterplace ring (QQ),(x,y,x,y,x,y,x,y,x,y),(dp(10),C,L(3)), slpalg{n_Q}[x, y])
julia> (x*y)^2
x*y*x*y
julia> (x*y)^3
ERROR: degree bound of Letterplace ring is 5, but at least 6 is needed for this multiplication
The ideals are two-sided by default for this algebra, and there is currently no possibility of constructing one-sided ideals.
julia> R, (x, y, z) = FreeAlgebra(QQ, ["x", "y", "z"], 4)
(Singular letterplace ring (QQ),(x,y,z,x,y,z,x,y,z,x,y,z),(dp(12),C,L(3)), slpalg{n_Q}[x, y, z])
julia> gens(std(Ideal(R, [x*y + y*z, x*x + x*y - y*x - y*y])))
8-element Vector{slpalg{n_Q}}:
x*y + y*z
x^2 - y*x - y^2 - y*z
y^3 + y*z*y - y^2*z - y*z^2
y^2*x + y*z*x + y^2*z + y*z^2
y^2*z*y + y*z^2*y - y^2*z^2 - y*z^3
y*z*y^2 + y*z^2*y - y*z*y*z - y*z^3
y^2*z*x + y*z^2*x + y^2*z^2 + y*z^3
y*z*y*x + y*z^2*x + y*z*y*z + y*z^3
Term Iterators
For GAlgebra
and WeylAlgebra
, the elements can be and are represented using commutative data structures, and the function exponent_vectors
is repurposed for access to the individual exponents.
Examples
julia> R, (x, y, dx, dy) = WeylAlgebra(QQ, ["x", "y"])
(Singular G-algebra (QQ),(x,y,dx,dy),(dp(4),C), spluralg{n_Q}[x, y, dx, dy])
julia> p = (dx + dy)*(x + y)
x*dx + y*dx + x*dy + y*dy + 2
julia> show(collect(exponent_vectors(p)))
[[1, 0, 1, 0], [0, 1, 1, 0], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 0, 0]]
For FreeAlgebra
, the function exponent_vectors
is undefined on elements and replaced by exponent_words
which reads off in order the indices of the variables in a monomial. Also, the monomials for the MPolyBuildCtx
are specified by these exponent words. Other than these differences the term iterators have the same behavior as in the commutative case.
Examples
julia> R, (x, y, z) = FreeAlgebra(QQ, ["x", "y", "z"], 6)
(Singular letterplace ring (QQ),(x,y,z,x,y,z,x,y,z,x,y,z,x,y,z,x,y,z),(dp(18),C,L(3)), slpalg{n_Q}[x, y, z])
julia> p = (1 + x*z + y)^2
x*z*x*z + x*z*y + y*x*z + y^2 + 2*x*z + 2*y + 1
julia> show(collect(coefficients(p)))
n_Q[1, 1, 1, 1, 2, 2, 1]
julia> show(collect(monomials(p)))
slpalg{n_Q}[x*z*x*z, x*z*y, y*x*z, y^2, x*z, y, 1]
julia> show(collect(terms(p)))
slpalg{n_Q}[x*z*x*z, x*z*y, y*x*z, y^2, 2*x*z, 2*y, 1]
julia> show(collect(exponent_words(p)))
[[1, 3, 1, 3], [1, 3, 2], [2, 1, 3], [2, 2], [1, 3], [2], Int64[]]
julia> B = MPolyBuildCtx(R)
Builder for an element of Singular letterplace ring (QQ),(x,y,z,x,y,z,x,y,z,x,y,z,x,y,z,x,y,z),(dp(18),C,L(3))
julia> push_term!(B, QQ(2), [3,2,1,3]);
julia> push_term!(B, QQ(-1), Int[]);
julia> finish(B)
2*z*y*x*z - 1