set.seed(0) library("spray") library("stokes") options(rmarkdown.html_vignette.check_title = FALSE) knitr::opts_chunk$set(echo = TRUE) knit_print.function <- function(x, ...){dput(x)} registerS3method( "knit_print", "function", knit_print.function, envir = asNamespace("knitr") )
knitr::include_graphics(system.file("help/figures/stokes.png", package = "stokes"))
tensorprod tensorprod2
To cite the stokes
package in publications, please use
@hankin2022_stokes. Function tensorprod()
returns the tensor cross
product of any number of ktensor
objects; tensorprod2()
is a
lower-level helper function that returns the product of two such
objects. These functions use spraycross()
from the spray
package
[@hankin2022_spray].
In a memorable passage, @spivak1965 states:
Integration on chains
If $V$ is a vector space over $\mathbb{R}$, we denote the $k$-fold product $V\times\cdots\times V$ by $V^k$. A function $T\colon V^k\longrightarrow\mathbb{R}$ is called *multilinear* if for each $i$ with $1\leqslant i\leqslant k$ we have $$ T\left(v_1,\ldots, v_i + {v'}_i,\ldots, v_k\right)= T\left(v_1,\ldots,v_i,\ldots,v_k\right)+ T\left(v_1,\ldots,{v'}_i,\ldots,v_k\right),\\ T\left(v_1,\ldots,av_i,\ldots,v_k\right)=aT\left(v_1,\ldots,v_i,\ldots,v_k\right). $$ A multilinear function $T\colon V^k\longrightarrow\mathbb{R}$ is called a *$k$-tensor* on $V$ and the set of all $k$-tensors, denoted by $\mathcal{J}^k(V)$, becomes a vector space (over $\mathbb{R}$) if for $S,T\in\mathcal{J}^k(V)$ and $a\in\mathbb{R}$ we define $$ (S+T)(v_1,\ldots,v_k) = S(v_1,\ldots,v_k) + T(v_1,\ldots,v_k)\\ (aS)(v_1,\ldots,v_k) = a\cdot S(v_1,\ldots,v_k). $$ There is also an operation connecting the various spaces $\mathcal{J}(V)$. If $S\in\mathcal{J}^k(V)$ and $T\in\mathcal{J}^l(V)$, we define the *tensor product* $S\otimes T\in\mathcal{J}^{k+l}(V)$ by $$ S\otimes T(v_1,\ldots,v_k,v_{k+1},\ldots,v_{k+l})= S(v_1,\ldots,v_k)\cdot T(v_{k+1},\ldots,v_{k+l}). $$
- Michael Spivak, 1969 (Calculus on Manifolds, Perseus books). Page 75
Spivak goes on to observe that the tensor product is distributive and associative but not commutative. He then proves that the set of all $k$-fold tensor products
$$ \phi_{i_1}\otimes\cdots\otimes\phi_{i_k},\qquad 1\leqslant i_1,\ldots,i_k\leqslant n $$
[where $\phi_i(v_j)=\delta_{ij}$,$v_1,\ldots,v_k$ being a basis for
$V$] is a basis for $\mathcal{J}^k(V)$, which therefore has dimension
$n^k$. Function tensorprod()
evaluates the tensor product and I
give examples here.
(a <- ktensor(spray(matrix(c(1,1,2,1),2,2),3:4))) (b <- ktensor(spray(matrix(c(3,4,7,5,4,3),3,2),7:9)))
Thus $a=4\phi_1\otimes\phi_1+3\phi_1\otimes\phi_2$ and
$b=7\phi_3\otimes\phi_5+8\phi_4\otimes\phi_4+9\phi_7\otimes\phi_3$.
Now the cross product $a\otimes b$ is given by tensorprod()
:
tensorprod(a,b)
We can see that the product includes the term $21\phi_1\otimes\phi_2\otimes\phi_3\otimes\phi_5$ and five others.
Spivak proves that the tensor product is associative and distributive, which are demonstrated here.
S <- rtensor() T <- rtensor() U <- rtensor() c( left_distributive = S %X% (T+U) == S*T + S*U, right_distributive = (S+T) %X% U == S %X% U + T %X% U, associative = S %X% (T %X% U) == (S %X% T) %X% U )
It is interesting to note that, while the tensor product is associative, disord discipline obscures this fact. Consider the following:
x <- ktensor(spray(matrix(c(1,1,2,1),2,2),1:2)) y <- ktensor(spray(matrix(c(3,4,7,5,4,3),3,2),1:3)) z <- ktensor(spray(matrix(c(1,1,2,1),2,2),1:2)) tensorprod(x, tensorprod(y, z)) tensorprod(tensorprod(x, y), z)
The two products are algebraically identical but the terms appear in a different order.
rm(T) # tidyup
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.