kform and ktensor objectsOps.RdAllows arithmetic operators to be used for \(k\)-forms and \(k\)-tensors such as addition, multiplication, etc, where defined.
# S3 method for class 'kform'
Ops(e1, e2 = NULL)
# S3 method for class 'ktensor'
Ops(e1, e2 = NULL)The functions Ops.kform() and Ops.ktensor() pass unary
and binary arithmetic operators (“+”, “-”,
“*”, “/” and “^”) to the
appropriate specialist function by coercing to spray objects.
Binary addition and subtraction, as in x+y or x-y, are
performed by spray::spray_plus_spray().
For wedge products of \(k\)-forms, use wedge() or
%^% or ^; and for tensor products of
\(k\)-tensors, use tensorprod() or %X%.
All functions documented here return an object of class
kform or ktensor.
A plain asterisk, “*” behaves differently for ktensors
and kforms.
Given two ktensors T1 and T2, then
“T1*T2” will return their tensor product,
tensorprod(T1,T2). This on the grounds that the idiom has only
one natural interpretation. But its use is discouraged (use
%X% or tensorprod() instead). An asterisk can also be
used to multiply a tensor by a scalar, as in T1*5, in which the
scalar is interpreted as a \(0\)-tensor.
Given two kforms K1 and K2, asterisks behave
differently. An asterisk cannot be used to multiply K1 and
K2: K1*K2 will return an error. Multiplication by
scalars is OK, as in K1*6.
Powers simply do not make sense for alternating forms: if we wish to
define “\(S^2\)” (that is, the “square” of \(S\)),
then the only natural interpretation of this is S^S [that is,
wedge(S,S)], but this is zero identically. In the package,
therefore, the caret (“^”) exclusively evaluates the
wedge product; note that %^% is also acceptable.
Here the caret is interpreted consistently as a wedge product, and if
one of the factors is numeric it is interpreted as a zero-form (that
is, a scalar). Thus S^2 = wedge(S,2) = 2^S = S*2 = S+S, and
indeed S^n == S*n. Caveat emptor! If S is a kform
object, it is very tempting [but incorrect] to interpret
“S^3” as something like “S to the power
3”. See also the note at Ops.clifford in the
clifford package.
Powers are not currently implemented for ktensors, but this might be implemented in the future: a ktensor to the power zero is the 0-tensor with unit coefficient.
Note that one has to take care with order of operations if we mix
^ with *. For example, dx ^ (6*dy) is perfectly
acceptable; but (dx ^ 6)*dy) will return an error, as will the
unbracketed form dx ^ 6 * dy. In the second case we attempt to
use an asterisk to multiply two k-forms, which triggers the error.
## dx_1 ^ dx_2 + 6dx_5 ^ dx_6:
as.kform(1) ^ as.kform(2) + 6*as.kform(5) ^ as.kform(6)
#> An alternating linear map from V^2 to R with V=R^6:
#> val
#> 1 2 = 1
#> 5 6 = 6
k1 <- kform_general(4, 2, rnorm(6))
k2 <- kform_general(4, 2, rnorm(6))
E <- matrix(rnorm(8), 4, 2)
as.function(k1 + k2)(E)
#> [1] 7.515684
## verify linearity, here 2*k1 + 3*k2:
as.function(2*k1 + 3*k2)(E)-(2*as.function(k1)(E) + 3*as.function(k2)(E))
#> [1] 7.105427e-15
## should be small