MyNixOS website logo
Description

The Exterior Calculus.

Provides functionality for working with tensors, alternating forms, wedge products, Stokes's theorem, and related concepts from the exterior calculus. Uses 'disordR' discipline (Hankin, 2022, <doi:10.48550/ARXIV.2210.03856>). The canonical reference would be M. Spivak (1965, ISBN:0-8053-9021-9) "Calculus on Manifolds". To cite the package in publications please use Hankin (2022) <doi:10.48550/ARXIV.2210.17008>.

The stokes package: exterior calculus in R

CRAN_Status_Badge

Overview

The stokes package provides functionality for working with the exterior calculus. It includes tensor products and wedge products and a variety of use-cases. The canonical reference would be Spivak (see references). A detailed vignette is provided in the package.

The package deals with k-tensors and k-forms. A k-tensor is a multilinear map S\colon V^k\longrightarrow\mathbb{R}, where V=\mathbb{R}^n is considered as a vector space. Given two k-tensors S,T the package can calculate their outer product S\otimes T using natural R idiom (see below and the vignette for details).

A k-form is an alternating k-tensor, that is a k-tensor \omega with the property that linear dependence of x_1,\ldots,x_n implies that \omega\left(x_1,\ldots,x_n\right)=0. Given k-forms \omega,\eta, the package provides R idiom for calculating their wedge product \omega\wedge\eta.

Installation

You can install the released version of stokes from CRAN with:

# install.packages("stokes")  # uncomment this to install the package
library("stokes")
set.seed(0)

The stokes package in use

The package has two main classes of objects, kform and ktensor. In the package, we can create a k-tensor by supplying function as.ktensor() a matrix of indices and a vector of coefficents, for example:

jj <- as.ktensor(rbind(1:3,2:4),1:2)
jj
#> A linear map from V^3 to R with V=R^4:
#>            val
#>  2 3 4  =    2
#>  1 2 3  =    1

Above, object jj is equal to dx_1\otimes dx_2\otimes dx_3 + 2dx_2\otimes dx_3\otimes dx_4 (see Spivak, p76 for details).

We can coerce tensors to a function and then evaluate it:

KT <- as.ktensor(cbind(1:4,2:5),1:4)
f <- as.function(KT)
E <- matrix(rnorm(10),5,2)
f(E)
#> [1] 11.23556

Tensor products are implemented:

KT %X% KT
#> A linear map from V^4 to R with V=R^5:
#>              val
#>  1 2 1 2  =    1
#>  2 3 1 2  =    2
#>  3 4 3 4  =    9
#>  2 3 4 5  =    8
#>  1 2 2 3  =    2
#>  1 2 4 5  =    4
#>  4 5 4 5  =   16
#>  2 3 3 4  =    6
#>  4 5 3 4  =   12
#>  1 2 3 4  =    3
#>  3 4 4 5  =   12
#>  3 4 2 3  =    6
#>  4 5 2 3  =    8
#>  3 4 1 2  =    3
#>  2 3 2 3  =    4
#>  4 5 1 2  =    4

Above we see {\mathrm KT}\otimes{\mathrm KT}.

Alternating forms

An alternating form (or k-form) is an antisymmetric k-tensor; the package can convert a general k-tensor to alternating form using the Alt() function:

Alt(KT)
#> A linear map from V^2 to R with V=R^5:
#>           val
#>  5 4  =  -2.0
#>  4 5  =   2.0
#>  4 3  =  -1.5
#>  3 2  =  -1.0
#>  2 3  =   1.0
#>  3 4  =   1.5
#>  2 1  =  -0.5
#>  1 2  =   0.5

However, the package provides a bespoke and efficient representation for k-forms as objects with class kform. Such objects may be created using the as.kform() function:


M <- matrix(c(4,2,3,1,2,4),2,3,byrow=TRUE)
M
#>      [,1] [,2] [,3]
#> [1,]    4    2    3
#> [2,]    1    2    4
KF <- as.kform(M,c(1,5))
KF
#> An alternating linear map from V^3 to R with V=R^4:
#>            val
#>  1 2 4  =    5
#>  2 3 4  =    1

Above, we see that KF is equal to dx_2\wedge dx_3\wedge dx_4 + 5dx_1\wedge dx_2\wedge dx_4. We may coerce KF to functional form:

f <- as.function(KF)
E <- matrix(rnorm(12),4,3)
f(E)
#> [1] -5.979544

Above, we evaluate KF at a point in \left({\mathbb R^4}\right)^3 [the three columns of matrix E are each interpreted as vectors in {\mathbb R}^4].

The wedge product

The wedge product of two k-forms is implemented as ^ or wedge():

KF2 <- kform_general(6:9,2,1:6)
KF2
#> An alternating linear map from V^2 to R with V=R^9:
#>          val
#>  8 9  =    6
#>  7 9  =    5
#>  6 9  =    4
#>  7 8  =    3
#>  6 8  =    2
#>  6 7  =    1
KF ^ KF2
#> An alternating linear map from V^5 to R with V=R^9:
#>                val
#>  1 2 4 6 7  =    5
#>  1 2 4 6 8  =   10
#>  2 3 4 6 8  =    2
#>  2 3 4 7 8  =    3
#>  2 3 4 6 9  =    4
#>  1 2 4 6 9  =   20
#>  2 3 4 6 7  =    1
#>  2 3 4 7 9  =    5
#>  1 2 4 7 8  =   15
#>  2 3 4 8 9  =    6
#>  1 2 4 7 9  =   25
#>  1 2 4 8 9  =   30

The package can accommodate a number of results from the exterior calculus such as elementary forms:

dx <- as.kform(1)
dy <- as.kform(2)
dz <- as.kform(3)
dx ^ dy ^ dz  # element of volume 
#> An alternating linear map from V^3 to R with V=R^3:
#>            val
#>  1 2 3  =    1

A number of useful functions from the exterior calculus are provided, such as the gradient of a scalar function:

grad(1:6)
#> An alternating linear map from V^1 to R with V=R^6:
#>        val
#>  6  =    6
#>  5  =    5
#>  4  =    4
#>  3  =    3
#>  2  =    2
#>  1  =    1

The package takes the leg-work out of the exterior calculus:

grad(1:4) ^ grad(1:6)
#> An alternating linear map from V^2 to R with V=R^6:
#>          val
#>  4 5  =   20
#>  1 5  =    5
#>  2 5  =   10
#>  3 5  =   15
#>  2 6  =   12
#>  4 6  =   24
#>  3 6  =   18
#>  1 6  =    6

References

The most concise reference is

  • Spivak 1971. Calculus on manifolds, Addison-Wesley.

But a more leisurely book would be

  • Hubbard and Hubbard 2015. Vector calculus, linear algebra, and differential forms: a unified approach. Matrix Editions

Further information

For more detail, see the package vignette

vignette("stokes")

Metadata

Version

1.2-0

License

Unknown

Platforms (75)

    Darwin
    FreeBSD 13
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd13
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd13
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows