The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Function tensorprod() function in the stokes package

Robin K. S. Hankin

tensorprod
function (U, ...) 
{
    if (nargs() < 3) {
        tensorprod2(U, ...)
    }
    else {
        tensorprod2(U, Recall(...))
    }
}
tensorprod2
function (U1, U2) 
{
    if (is.empty(U1) | is.empty(U2)) {
        return(as.ktensor(cbind(index(U1)[0, ], index(U2)[0, 
            ])))
    }
    return(ktensor(spraycross(U1, U2)))
}

To cite the stokes package in publications, please use Hankin (2022b). 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 (Hankin 2022a).

The tensor cross product

In a memorable passage, Spivak (1965) 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)))
## A linear map from V^2 to R with V=R^2:
##          val
##  1 1  =    4
##  1 2  =    3
(b <- ktensor(spray(matrix(c(3,4,7,5,4,3),3,2),7:9)))
## A linear map from V^2 to R with V=R^7:
##          val
##  4 4  =    8
##  7 3  =    9
##  3 5  =    7

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)
## A linear map from V^4 to R with V=R^7:
##              val
##  1 2 3 5  =   21
##  1 2 7 3  =   27
##  1 1 7 3  =   36
##  1 1 3 5  =   28
##  1 2 4 4  =   24
##  1 1 4 4  =   32

We can see that the product includes the term \(21\phi_1\otimes\phi_2\otimes\phi_3\otimes\phi_5\) and five others.

Verification

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
  )
##  left_distributive right_distributive        associative 
##               TRUE               TRUE               TRUE

Note on associativity

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))
## A linear map from V^6 to R with V=R^7:
##                  val
##  1 1 4 4 1 1  =    8
##  1 2 3 5 1 1  =    2
##  1 1 7 3 1 1  =   12
##  1 1 3 5 1 1  =    4
##  1 2 4 4 1 2  =    2
##  1 1 4 4 1 2  =    4
##  1 2 7 3 1 2  =    3
##  1 2 7 3 1 1  =    6
##  1 1 7 3 1 2  =    6
##  1 2 4 4 1 1  =    4
##  1 2 3 5 1 2  =    1
##  1 1 3 5 1 2  =    2
tensorprod(tensorprod(x, y), z)
## A linear map from V^6 to R with V=R^7:
##                  val
##  1 1 4 4 1 2  =    4
##  1 2 4 4 1 2  =    2
##  1 1 3 5 1 2  =    2
##  1 2 7 3 1 2  =    3
##  1 1 4 4 1 1  =    8
##  1 2 3 5 1 2  =    1
##  1 2 4 4 1 1  =    4
##  1 1 3 5 1 1  =    4
##  1 1 7 3 1 1  =   12
##  1 1 7 3 1 2  =    6
##  1 2 7 3 1 1  =    6
##  1 2 3 5 1 1  =    2

The two products are algebraically identical but the terms appear in a different order.

References

Hankin, R. K. S. 2022a. “Sparse Arrays in R: The spray Package.” https://arxiv.org/abs/2210.03856; arXiv. https://doi.org/10.48550/ARXIV.2210.10848.
———. 2022b. “Stokes’s Theorem in R.” arXiv. https://doi.org/10.48550/ARXIV.2210.17008.
Spivak, M. 1965. Calculus on Manifolds. Addison-Wesley.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.