| Title: | The Weyl Algebra |
|---|---|
| Description: | A suite of routines for Weyl algebras. Notation follows Coutinho (1995, ISBN 0-521-55119-6, "A Primer of Algebraic D-Modules"). Uses 'disordR' discipline (Hankin 2022 <doi:10.48550/arXiv.2210.03856>). To cite the package in publications, use Hankin 2022 <doi:10.48550/arXiv.2212.09230>. |
| Authors: | Robin K. S. Hankin [aut, cre] (ORCID: <https://orcid.org/0000-0001-5982-0415>) |
| Maintainer: | Robin K. S. Hankin <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.0-8 |
| Built: | 2026-05-10 20:12:11 UTC |
| Source: | https://github.com/robinhankin/weyl |
A suite of routines for Weyl algebras. Notation follows Coutinho (1995, ISBN 0-521-55119-6, "A Primer of Algebraic D-Modules"). Uses 'disordR' discipline (Hankin 2022 <doi:10.48550/arXiv.2210.03856>). To cite the package in publications, use Hankin 2022 <doi:10.48550/arXiv.2212.09230>.
The DESCRIPTION file:
| Package: | weyl |
| Type: | Package |
| Title: | The Weyl Algebra |
| Version: | 0.0-8 |
| Depends: | R (>= 4.1.0) |
| Authors@R: | person(given=c("Robin", "K. S."), family="Hankin", role = c("aut","cre"), email="[email protected]", comment = c(ORCID = "0000-0001-5982-0415")) |
| Maintainer: | Robin K. S. Hankin <[email protected]> |
| Description: | A suite of routines for Weyl algebras. Notation follows Coutinho (1995, ISBN 0-521-55119-6, "A Primer of Algebraic D-Modules"). Uses 'disordR' discipline (Hankin 2022 <doi:10.48550/arXiv.2210.03856>). To cite the package in publications, use Hankin 2022 <doi:10.48550/arXiv.2212.09230>. |
| License: | GPL (>= 2) |
| LazyData: | yes |
| Suggests: | knitr,rmarkdown,testthat,covr |
| VignetteBuilder: | knitr |
| Imports: | disordR (>= 0.0-8), freealg (>= 1.0-4), spray (>= 1.0-27), methods |
| URL: | https://github.com/RobinHankin/weyl, https://robinhankin.github.io/weyl/ |
| BugReports: | https://github.com/RobinHankin/weyl/issues |
| Config/pak/sysreqs: | libgmp3-dev libicu-dev |
| Repository: | https://robinhankin.r-universe.dev |
| Date/Publication: | 2026-03-14 18:27:58 UTC |
| RemoteUrl: | https://github.com/robinhankin/weyl |
| RemoteRef: | HEAD |
| RemoteSha: | 095d7c78cd980e6a05bfdda75b27b8596684c374 |
| Author: | Robin K. S. Hankin [aut, cre] (ORCID: <https://orcid.org/0000-0001-5982-0415>) |
Index of help topics:
coeffs Manipulate the coefficients of a weyl object
constant The constant term
degree The degree of a 'weyl' object
derivation Derivations
dim The dimension of a 'weyl' object
dot-class Class "dot"
drop Drop redundant information
grade The grade of a weyl object
horner Horner's method
identity The identity operator
ooom One over one minus
Ops Arithmetic Ops Group Methods for the Weyl
algebra
print.weyl Print methods for weyl objects
rweyl Random weyl objects
spray Create spray objects
weyl The algebra and weyl objects
weyl-class Class "weyl"
weyl-package The Weyl Algebra
x_and_d Generating elements for the first Weyl algebra
zero The zero operator
Robin K. S. Hankin [aut, cre] (ORCID: <https://orcid.org/0000-0001-5982-0415>)
Maintainer: Robin K. S. Hankin <[email protected]>
x <- rweyl(d=1) y <- rweyl(d=1) z <- rweyl(d=1) is.zero(x*(y*z) - (x*y)*z) # should be TRUEx <- rweyl(d=1) y <- rweyl(d=1) z <- rweyl(d=1) is.zero(x*(y*z) - (x*y)*z) # should be TRUE
Manipulate the coefficients of a weyl object. The coefficients are
disord objects.
coeffs(S) <- valuecoeffs(S) <- value
S |
A weyl object |
value |
Numeric |
To access coefficients of a weyl object S, use
spray::coeffs(S) [package idiom is coeffs(S)]. Similarly
to access the index matrix use index(S).
The replacement method is package-specific; use coeffs(S)
<-value.
Extraction methods return a disord object (possibly
dropped); replacement methods return a weyl object.
Robin K. S. Hankin
(a <- rweyl(9)) coeffs(a) coeffs(a)[coeffs(a)<3] <- 100 a(a <- rweyl(9)) coeffs(a) coeffs(a)[coeffs(a)<3] <- 100 a
The constant of a weyl object is the coefficient of the
term with all zeros.
constant(x, drop = TRUE) constant(x) <- valueconstant(x, drop = TRUE) constant(x) <- value
x |
Object of class |
drop |
Boolean with default |
value |
Constant value to replace existing one |
Returns a numeric or weyl object
The constant.weyl() function is somewhat awkward because it has
to deal with the difficult case where the constant is zero and
drop=FALSE.
Robin K. S. Hankin
(a <- rweyl() + 700) constant(a) constant(a, drop=FALSE) constant(a) <- 0 constant(a) constant(a, drop=FALSE) constant(a + 66) == constant(a) + 66(a <- rweyl() + 700) constant(a) constant(a, drop=FALSE) constant(a) <- 0 constant(a) constant(a, drop=FALSE) constant(a + 66) == constant(a) + 66
weyl objectThe degree of a monomial weyl object
is defined as . The degree
of a general weyl object expressed as a linear combination of
monomials is the maximum of the degrees of these monomials. Following
Coutinho we have:
deg(S)deg(S)
S |
Object of class |
Nonnegative integer (or for the zero Weyl
object)
The degree of the zero object is conventionally
.
Robin K. S. Hankin
(a <- rweyl()) deg(a) d1 <- rweyl(n=2) d2 <- rweyl(n=2) deg(d1+d2) <= deg(d1) + deg(d2) deg(d1*d2) == deg(d1) + deg(d2) deg(d1*d2 - d2*d1) <= deg(d1) + deg(d2) -2(a <- rweyl()) deg(a) d1 <- rweyl(n=2) d2 <- rweyl(n=2) deg(d1+d2) <= deg(d1) + deg(d2) deg(d1*d2) == deg(d1) + deg(d2) deg(d1*d2 - d2*d1) <= deg(d1) + deg(d2) -2
A derivation of an algebra is a linear
operator that satisfies ,
for every . If a derivation is of the form
for some fixed , we say that is an inner derivation.
Function as.der() returns a derivation with
as.der(f)(g)=fg-gf.
as.der(S)as.der(S)
S |
Weyl object |
Returns a function, a derivation
Robin K. S. Hankin
(o <- rweyl(n=2,d=2)) (f <- as.der(o)) d1 <-rweyl(n=1,d=2) d2 <-rweyl(n=2,d=2) f(d1*d2) == d1*f(d2) + f(d1)*d2 # should be TRUE(o <- rweyl(n=2,d=2)) (f <- as.der(o)) d1 <-rweyl(n=1,d=2) d2 <-rweyl(n=2,d=2) f(d1*d2) == d1*f(d2) + f(d1)*d2 # should be TRUE
weyl objectThe dimension of a weyl algebra is the number of variables
needed; it is half the spray::arity(). The dimension of
a Weyl algebra generated by
is (not ).
## S3 method for class 'weyl' dim(x)## S3 method for class 'weyl' dim(x)
x |
Object of class |
Integer
Empty spray objects give zero-dimensional weyl objects.
Robin K. S. Hankin
(a <- rweyl()) dim(a)(a <- rweyl()) dim(a)
The dot object is defined so that idiom like .[x,y] returns
the commutator, that is, xy-yx.
The dot object is generated by running script inst/dot.Rmd,
which includes some further discussion and technical documentation,
and creates file dot.rda which resides in the data/
directory.
The borcherds vignette discusses this in a more general
context.
x |
Object of any class |
i, j
|
elements to commute |
... |
Further arguments to |
Always returns an object of the same class as xy.
Robin K. S. Hankin
x <- rweyl(n=1,d=2) y <- rweyl(n=1,d=2) z <- rweyl(n=1,d=2) .[x,.[y,z]] + .[y,.[z,x]] + .[z,.[x,y]] # Jacobi identityx <- rweyl(n=1,d=2) y <- rweyl(n=1,d=2) z <- rweyl(n=1,d=2) .[x,.[y,z]] + .[y,.[z,x]] + .[z,.[x,y]] # Jacobi identity
Coerce constant weyl objects to numeric
drop(x)drop(x)
x |
Weyl object |
If its argument is a constant weyl object, coerce to numeric.
Returns either a length-one numeric vector or its argument, a weyl object
Many functions in the package take drop as an argument
which, if TRUE, means that the function returns a
dropped value.
Robin K. S. Hankin
a <- rweyl() + 67 drop(a) drop(idweyl(9)) drop(constant(a, drop=FALSE))a <- rweyl() + 67 drop(a) drop(idweyl(9)) drop(constant(a, drop=FALSE))
The grade of a homogeneous term of a Weyl algebra is the sum of
the powers. Thus the grade of
is .
The functionality documented here closely follows the equivalent in the clifford package.
Coutinho calls this the symbol map.
grade(C, n, drop=TRUE) grade(C, n) <- value grades(x)grade(C, n, drop=TRUE) grade(C, n) <- value grades(x)
C, x
|
Weyl object |
n |
Integer vector specifying grades to extract |
value |
Replacement value, a numeric vector |
drop |
Boolean, with default |
Function grades() returns an (unordered) vector specifying the
grades of the constituent terms.
Function grade(x,n) returns a Weyl object with just the
elements of grade g, where g %in% n.
Function grade<-() allows idiom such as grade(x,1:2) <- 7
to operate as expected [here to set all coefficients of terms with
grades 1 or 2 to value 7].
The zero grade term, grade(x,0), is given more naturally by
constant(C).
Integer vector or weyl object
Robin K. S. Hankin
a <- rweyl(30) grades(a) grade(a, 1:4) grade(a, 5:9) <- -99 aa <- rweyl(30) grades(a) grade(a, 1:4) grade(a, 5:9) <- -99 a
Horner's method
horner(W,v)horner(W,v)
W |
Weyl object |
v |
Numeric vector of coefficients |
Given a formal polynomial
it is possible to express in the algebraically equivalent
form
which is much more efficient for evaluation, as it requires only
multiplications and additions, and this is optimal.
Robin K. S. Hankin
horner(x, 1:5) horner(x+d, 1:3) 2+x+d |> horner(1:3) |> horner(1:2)horner(x, 1:5) horner(x+d, 1:3) 2+x+d |> horner(1:3) |> horner(1:2)
The identity operator maps any function to itself.
idweyl(d) ## S3 method for class 'weyl' as.id(S) is.id(S)idweyl(d) ## S3 method for class 'weyl' as.id(S) is.id(S)
d |
Integer specifying dimensionality of the weyl object (twice the spray arity) |
S |
A weyl object |
A weyl object corresponding to the identity operator
The identity function cannot be called “id()”
because then R would not know whether to create a
spray or a weyl object.
idweyl(7) a <- rweyl(d=5) a is.id(a) is.id(1+a-a) as.id(a) a == a*1 a == a*as.id(a)idweyl(7) a <- rweyl(d=5) a is.id(a) is.id(1+a-a) as.id(a) a == a*1 a == a*as.id(a)
Uses Taylor's theorem to give one over one minus a Weyl object
ooom(W, n)ooom(W, n)
W |
Weyl object |
n |
Order of expansion |
Robin K. S. Hankin
ooom(x+d, 4) W <- x + x*d ooom(W, 4)*(1-W) == 1-W^5ooom(x+d, 4) W <- x + x*d ooom(W, 4)*(1-W) == 1-W^5
Allows arithmetic operators such as addition, multiplication,
division, integer powers, etc. to be used for weyl objects.
Idiom such as x^2 + y*z/5 should work as expected. Addition
and subtraction, and scalar multiplication, are the same as those of
the spray package; but “*” is interpreted as
operator composition, and “^” is interpreted as
repeated composition. A number of helper functions are documented
here (which are not designed for the end-user).
## S3 method for class 'weyl' Ops(e1, e2 = NULL) weyl_prod_helper1(a,b,c,d) weyl_prod_helper2(a,b,c,d) weyl_prod_helper3(a,b,c,d) weyl_prod_univariate_onerow(S1,S2,func) weyl_prod_univariate_nrow(S1,S2) weyl_prod_multivariate_onerow_singlecolumn(S1,S2,column) weyl_prod_multivariate_onerow_allcolumns(S1,S2) weyl_prod_multivariate_nrow_allcolumns(S1,S2) weyl_power_scalar(S,n)## S3 method for class 'weyl' Ops(e1, e2 = NULL) weyl_prod_helper1(a,b,c,d) weyl_prod_helper2(a,b,c,d) weyl_prod_helper3(a,b,c,d) weyl_prod_univariate_onerow(S1,S2,func) weyl_prod_univariate_nrow(S1,S2) weyl_prod_multivariate_onerow_singlecolumn(S1,S2,column) weyl_prod_multivariate_onerow_allcolumns(S1,S2) weyl_prod_multivariate_nrow_allcolumns(S1,S2) weyl_power_scalar(S,n)
S, S1, S2, e1, e2
|
Objects of class |
a, b, c, d
|
Integers, see details |
column |
column to be multiplied |
n |
Integer power (non-negative) |
func |
Function used for products |
All arithmetic is as for spray objects, apart from * and
^. Here, * is interpreted as operator concatenation:
Thus, if and are Weyl objects, then
is defined as the operator that takes
to .
Functions such as weyl_prod_multivariate_nrow_allcolumns() are
low-level helper functions with self-explanatory names. In this
context, “univariate” means the first Weyl algebra,
generated by ,
subject to ; and
“multivariate” means the algebra generated by
where .
The product is somewhat user-customisable via option prodfunc,
which affects function weyl_prod_univariate_onerow(). Currently
the package offers three examples: weyl_prod_helper1(),
weyl_prod_helper2(), and weyl_prod_helper3(). These are
algebraically identical but occupy different positions on the
efficiency-readability scale. The option defaults to
weyl_prod_helper3(), which is the fastest but most opaque. The
vignette provides further details, motivation, and examples.
Powers, as in x^n, are defined in the usual way. Negative powers
will always return an error.
Generally, return a weyl object
Function weyl_prod_univariate_nrow() is present for
completeness, it is not used in the package
Robin K. S. Hankin
x <- rweyl(n=1,d=2) y <- rweyl(n=1,d=2) z <- rweyl(n=2,d=2) x*(y+z) == x*y + x*z is.zero(x*(y*z) - (x*y)*z)x <- rweyl(n=1,d=2) y <- rweyl(n=1,d=2) z <- rweyl(n=2,d=2) x*(y+z) == x*y + x*z is.zero(x*(y*z) - (x*y)*z)
Printing methods for weyl objects follow those for the spray package, with some additional functionality.
## S3 method for class 'weyl' print(x, ...)## S3 method for class 'weyl' print(x, ...)
x |
A weyl object |
... |
Further arguments, currently ignored |
Option polyform determines whether the object is to be printed in
matrix form or polynomial form: as in the spray package, this
option governs dispatch to either print_spray_polyform() or
print_spray_matrixform().
> a <- rweyl() > a # default print method A member of the Weyl algebra: x y z dx dy dz val 1 2 2 2 1 0 = 3 2 2 0 0 1 1 = 2 0 0 0 1 1 2 = 1 > options(polyform = TRUE) > a A member of the Weyl algebra: +3*x*y^2*z^2*dx^2*dy +2*x^2*y^2*dy*dz +dx*dy*dz^2 > options(polyform = FALSE) # restore default
Irrespective of the value of polyform, option weylvars
controls the variable names. If NULL (the default), then
sensible values are used: either [xyz] if the dimension is three
or less, or integers. But option weylvars is user-settable:
> options(weylvars=letters[18:20]) > a A member of the Weyl algebra: r s t dr ds dt val 1 2 2 2 1 0 = 3 2 2 0 0 1 1 = 2 0 0 0 1 1 2 = 1 > options(polyform=TRUE) > a A member of the Weyl algebra: +3*r*s^2*t^2*dr^2*ds +2*r^2*s^2*ds*dt +dr*ds*dt^2 > options(polyform=FALSE) ; options(weylvars=NULL)
If the user sets weylvars, the print method tries to do the Right
Thing (tm). If set to c("a","b","c"), for example, the
generators are named c(" a"," b"," c","da","db","dc") [note the
spaces]. If the algebra is univariate, the names will be something like
d and x. No checking is performed and if the length is
not equal to the dimension, undesirable behaviour may occur. For the
love of God, do not use a variable named d. Internally,
weylvars works by changing the sprayvars option in the
spray package.
Note that, as for spray objects, this option has no algebraic
significance: it only affects the print method.
Returns a weyl object.
Robin K. S. Hankin
a <- rweyl() print(a) options(polyform=TRUE) print(a)a <- rweyl() print(a) options(polyform=TRUE) print(a)
Creates random weyl objects: quick-and-dirty examples of Weyl algebra elements
rweyl(nterms = 3, vals = seq_len(nterms), dim = 3, powers = 0:2) rweyll(nterms = 15, vals = seq_len(nterms), dim = 4, powers = 0:5) rweylll(nterms = 50, vals = seq_len(nterms), dim = 8, powers = 0:7)rweyl(nterms = 3, vals = seq_len(nterms), dim = 3, powers = 0:2) rweyll(nterms = 15, vals = seq_len(nterms), dim = 4, powers = 0:5) rweylll(nterms = 50, vals = seq_len(nterms), dim = 8, powers = 0:7)
nterms |
Number of terms in output |
vals |
Values of coefficients |
dim |
Dimension of weyl object |
powers |
Set from which to sample the entries of the index matrix |
Function rweyl() creates a smallish random Weyl object;
rweyll() and rweylll() create successively more
complicated objects.
These functions use spray::rspray(), so the note there about
repeated rows in the index matrix resulting in fewer than nterms
terms applies.
Function rweyl1() returns a one-dimensional Weyl object.
Returns a weyl object
Robin K. S. Hankin
rweyl() rweyll() rweyl(d=7) options(polyform = TRUE) rweyl1() options(polyform = FALSE) # restore defaultrweyl() rweyll() rweyl(d=7) options(polyform = TRUE) rweyl1() options(polyform = FALSE) # restore default
Function spray() creates a sparse array; function
weyl() coerces a spray object to a Weyl object.
spray(M, x, addrepeats=FALSE)spray(M, x, addrepeats=FALSE)
M |
An integer-valued matrix, the index of the weyl object |
x |
Numeric vector of coefficients |
addrepeats |
Boolean, specifying whether repeated rows are to be added |
The function is discussed and motivated in the spray package.
Return a weyl or a Boolean
Robin K. S. Hankin
(W <- spray(matrix(1:36,6,6), 1:6)) weyl(W) as.weyl(15, d=3)(W <- spray(matrix(1:36,6,6), 1:6)) weyl(W) as.weyl(15, d=3)
Basic functions for weyl objects
weyl(M) is.weyl(M) as.weyl(val,d) is.ok.weyl(M)weyl(M) is.weyl(M) as.weyl(val,d) is.ok.weyl(M)
M |
A weyl or spray object |
val, d
|
Value and dimension for weyl object |
To create a weyl object, pass a spray to function weyl(), as in
weyl(M). To create a spray object to pass to weyl(),
use function spray(), which is a synonym for
spray::spray().
Function weyl() is the formal creator method; is.weyl()
tests for weyl objects and is.ok.weyl() checks for well-formed
sprays. Function as.weyl() tries (but not very hard) to infer
what the user intended and return the right thing.
Return a weyl or a Boolean
Robin K. S. Hankin
(W <- spray(matrix(1:36,6,6),1:6)) weyl(W) as.weyl(15,d=3) is.ok.weyl(spray(matrix(1:30,5,6))) ## Not run: is.ok.weyl(spray(matrix(1:30,6,5)))(W <- spray(matrix(1:36,6,6),1:6)) weyl(W) as.weyl(15,d=3) is.ok.weyl(spray(matrix(1:30,5,6))) ## Not run: is.ok.weyl(spray(matrix(1:30,6,5)))
The formal S4 class for weyls.
Objects can be created by calls of the form new("weyl",
...) but this is not encouraged. Use functions weyl() or
as.weyl() instead.
Robin K. S. Hankin
Variables x and d correspond to operator and
; they are provided for convenience. These
elements generate the one-dimensional Weyl algebra.
data(x_and_d)data(x_and_d)
Note that a similar system for multivariate Weyl algebras is not
desirable. We might want to consider the Weyl algebra generated by
and correspondingly define R variables x,y,z,dx,dy,dz. But
then variable x is ambiguous: is it a member of the first Weyl
algebra or the third?
Robin K. S. Hankin
d x .[d,x] # dx-xd==1 d^3 * x^4 (1 - d*x*d) * (x^2 - d^3)d x .[d,x] # dx-xd==1 d^3 * x^4 (1 - d*x*d) * (x^2 - d^3)
The zero operator maps any function to the zero function (which maps
anything to zero). To test for something being zero, use
spray::is.zero(); package idiom would be is.zero().
Function zero() takes a single argument which is interpreted as
the dimension of the result. So zero(dim(a)) returns
a*0 (but is faster).
zero(d)zero(d)
d |
Integer specifying dimensionality of the weyl object (twice the spray arity) |
A weyl object corresponding to the zero operator (or a Boolean
for is.zero())
(a <- rweyl(d=5)) is.zero(a) is.zero(a-a) is.zero(a*0) a == a + zero(dim(a)) zero(8)(a <- rweyl(d=5)) is.zero(a) is.zero(a-a) is.zero(a*0) a == a + zero(dim(a)) zero(8)