A differential operator on a smooth manifold is a Leibniz operator which coincides with the primitive gradient operator on scalar fields, and for which the derivative of the gradient of a scalar field is everywhere symmetric. Any two differential operators differ by a linear map on each rank of the smooth manifold's tensor bundle. Take G and T to be the mutually dual ranks of tensor which represent gradient- and tangent-valued fields.

Each rank of the tensor bundle is characterized by a list, each entry in which is either G or T: this is a mapping ({G,T}:F|n) = [F(0),…,F(n−1)], with each F(i) in {G,T}, for some natural n, known as the length of F; the rank is obtained by combining the entries in the list using the ⊗ binary operator, which combines linear spaces; tensor(F) = bulk(⊗, F) = F(0)⊗…⊗F(n−1); a typical member of U⊗…⊗W would be a sum of terms, each of form u×…×w with u in U, … and w in W; in which × is a bilinear operator – and that'd better be enough of the underpinning of tensor algebra for here.

For any list, [U,…,W], of linear spaces we can permute the entries in
the list, shuffling their order: for each such permutation, there is a linear
map from the original list's rank to the permuted list's rank; in general, if
the entries in the list aren't all the same and the permutation replaces some
entry with a different space, the output of this linear map has different rank
from the input. Example: given u and v in U, the permutation [1,0] = (:
0←1, 1←0 :) acts on U⊗U in a way which maps u×v to
v×u; in general, a permutation (n|s|n) maps any rank, tensor(:F|n) =
F(0)⊗…⊗F(n−1), via the composite F&on;s = [F(s(0)),
…, F(s(n−1))], to the permuted rank
F(s(0))⊗…⊗F(s(n−1)); each member of tensor(F) is a
sum of terms, each of form bulk(×, (:f|n)) =
f(0)×…×f(n−1) with f(i) in F(i) for each i; even when
F(2) and F(7), say, are the same linear space, f(2) and f(7) may be distinct
members of that space; so, even when a permutation only interchanges identical
entries in the list of spaces, the way it interchanges members of a space
distinguishes the permutation operator from the identity. We can add
permutation operators in so far as we accept that the sum is restricted to only
act on ranks for which the two permutation operators produce the same rank as
output, albeit permuted in each case; we can also scale them. By averaging all
the permutations which preserve a given rank, one can obtain
a symmetrization

operator for that rank. I'll use τ(r) as the
operator associated with permutation r;

- τ = (: unite(: (: bulk(×, (U:f&on;r|n)) ← bulk(×, (U:f|n)) :tensor({U}:|n)) ← U |{linear spaces}) ← (n|s|n) |{permutations})

Manifestly, τ(r)&on;τ(s) = τ(r&on;s) for any two permutations, r and s.

Permutations also have a property called signature: this says whether one needs an odd or even number of transpositions to build up the permutation as a product of transpositions; it is +1 for a product of an even number of transpositions, −1 for odd. Composing two permutations, the result's signature is obtained by multiplying the signatures of the two permutations composed; signature is formally a mapping, sign, from a group of permutations to the group {+1,−1} under multiplication – i.e. (: (: +1← +1, −1← −1 :)← +1, (: +1← −1, −1← +1 :)← −1 :) – and the mapping respects the group structure while mapping equally many permutations to each of +1 and −1. If we multiply each permutation operator that preserves a given rank by the signature of the corresponding permutation, we can again average the results: the result is a natural antisymmetrization operator for the rank.

Some ranks only use G in their list, so are of form tensor({G}:|n), the
only free variable

being the length of the list. If we apply our
differential operator to one such rank, the output is another rank of the same
form: it just has one more G in the list. Every permutation (n||n) preserves
the rank tensor({G}:|n), so the natural symmetrization and antisymmetrization
operators for G-only ranks involve sums over all permutations of n. I'll use
the name wedge

for the antisymmetrization operator, leaving 'til later
the details of an overall scaling on it to make various sensible things work out
right.

- wedge = unite(:
- sum(: sign(s).τ(s) ←s :{permutations of n})/K(n)
- ←n |{naturals}),
for some (:K:{naturals}); to make the sum an average over all permutations, we should make K(n) the number of permutations of n, which is n!, a.k.a. factorial(n), defined by 0! = 1, (1+n)! = n!.(1+n), so yielding the sequence [1,1,2,6,24,120,720,…]. Since the same choice will, in fact, make wedge&on;wedge = wedge, I'll duly use K(n) = n!.

Composing wedge before or after a permutation operator, τ(r), which only interchanges tensor ranks to which wedge has applied itself, sign(s).τ(s) in wedge's definition becomes sign(s).τ(s&on;r) and sign(s&on;r).sign(r) is sign(s), giving sign(r).sign(s&on;r).τ(s&on;r). Now, we're averaging this over all permutations (n|s|n) for some fixed r; composing each s after r simply re-shuffles the order in which we sum over all permutations; aside from an over-all shared factor of sign(r), our sum(::)/K of sign(s&on;r).τ(s&on;r) is the sum(::)/K of sign(s).τ(s), i.e. wedge; hence wedge&on;τ(r) = sign(r).wedge. By an entirely analogous argument, τ(r)&on;wedge = sign(r).wedge.

In particular, wedge&on;wedge is a sum(::)/K of terms, each of form sign(r).wedge&on;τ(r) = sign(r).sign(r).wedge = wedge since sign(r), being either +1 or −1, is self-inverse. Thus wedge&on;wedge is just wedge times a scaling: the number of permutations of [0,…,n−1], divided by K(n); naturally, we chose to make K(n) be the number of permutations, so that wedge&on;wedge = wedge. This, in turn, lets us replace sum(::)/K with average(::):

- wedge = unite(: average(: sign(s).τ(s) ←s :{permutations of n}) ←n |{naturals})
- wedge&on;wedge = wedge, wedge&on;τ(r) = sign(r).wedge = τ(r)&on;wedge.

The typical member of tensor({G}:|n) is a sum of terms each of which is
bulk(×, (G:f|n)), for some list, f, of gradient fields; all linear actions
are defined by their action on such terms (as above for wedge on each rank) and
inferred on sums of such terms by linear extension

, i.e. by defining the
action on a sum to be the sum of the action on each term in the original
sum. Now, suppose we have a linear dependence among the entries in our list;
i.e. there is some i in n for which f(i) is sum(k.f) for some ({scalars}: k :n)
with i not in (:k|), i.e. there's no k(i).f(i) term in the sum(k.f) = sum(:
k(i).f(i) ←i :{i: i in (:f|) and i in (:g|)}). When we apply bulk(×)
to f, we get f(0)×…×f(n−1) and can substitute sum(k.f)
in place of f(i) where it appears; as × distributes over addition, we can
re-arrange the result as a sum of terms, each of form
k(j).f(0)×…×f(n−1) but with f(i) replaced by f(j);
since i isn't in (:k|), j isn't i so f(j) already appeared in the term before we
replaced f(i) with it; f(j) appears twice. There is a permutation which swaps i
and j, acting as the identity on all other members of n; this has signature
−1 (it's a transposition); composing permutations with it, it provides a
one-to-one correspondence between permutations with signatures −1 and +1;
so we can decompose wedge(: :tensor({G}:|n))'s sum over permutations of n into a
sum of two sums, one over the even permutations, ({−1}:sign|), the other
over the odd ones, ({+1}:sign|); then write each odd permutation as the i/j swap
composed after an even one; this has the same effect on our term with f(j) in
both positions as the even permutation in question, but the opposite signature;
so we can match up terms in the two sub-sums, getting the same permuted value in
each pair, but one positive the other negative; hence we can conclude that the
term in bulk(×,f)'s expansion, using f(j) in place of f(i), is mapped to
zero by wedge; linear dependence in f allows us to write it as a sum of terms
each of which wedge maps to zero, wedge must in fact map bulk(×,f) to
zero: wedge annihilates linear dependencies. Consequently, indeed, if G has
finite dimension, (| wedge :tensor({G}:|n)) will be {zero} of suitable rank for
n greater than G's dimension.

Now consider what happens when we combine wedge and D on tensor({G}:|n): we'll get (tensor({G}:|1+n): wedge&on;D :tensor({G}:|n)) respecting addition and mapping a typical member of tensor({G}:|n), u×…×w, to a sum of terms, each of which replaces one of u, …, w with D(u), … or D(w), but then applies a permutation operator to the result, along with a scaling involving the signature of the permutation. Because of the antisymmetrization, if any D(u) is symmetric, and we're passing the result to wedge, the terms in D(u) cancel one another out.

Around any location on the smooth manifold one can find a neighbourhood in
which one can define smoothly-varying scalar fields –
called coordinates

– whose gradients are linearly independent but
span the space of gradients – i.e. form a basis of G. Express the scalar
fields as a list ({scalar fields}:x|dim(G)), yielding gradients (G:dx|dim(G))
providing a basis of G. This enables us, within our neighbourhood, to write an
arbitrary tensor({G}:|n) field as a sum of terms, each having the form
a.dx(s(0))×…×dx(s(n−1)) for some (dim(G):s|n) and
scalar field a – the bulk(×, dx&on;s) provide a basis for
tensor({G}:|n) throughout our neighbourhood. Now x&on;s provides a list of n
scalar fields and we can write our typical term as a.du×…×dw
for some list [u,…,w] of n scalar fields. Applying D to this, we obtain
D(a)×du×…×dw plus a sum of terms, each involving D(du),
… or D(dw), which the definition of a differential operator says will be
symmetric, so annihilated by wedge. Since a was also a scalar field, like u,
…, w, we have D(a) = da, so wedge&on;D maps a.du×…×w
to wedge(da×du×…×dw).

Now, if a were constant, da would be zero, so a.du would be d(a.u) and
wedge&on;D would annihilate a.du×…×w; so wedge&on;D
annihilates any (finite) sum of outputs of (: bulk(×)&on;d&on;f ← f
:{lists of scalar fields}); including, in particular, every output of
wedge&on;D. At the same time, for any u = bulk(×, (G:f|n)), we have
wedge(u): can wedge&on;D distinguish between u and wedge(u) ? We're looking at
(: wedge&on;D&on;wedge :tensor({G}:|n)) and D(wedge) is zero (each permutation
operator is a constant tensor operator, wedge applies a constant scaling to each
and adds the results; so wedge is also constant); it's a sum of terms, each of
which is of form sign(s).sign(r).τ(s)&on;D&on;τ(r)/K(n)/K(1+n) with
(n|r|n) and (1+n|s|1+n) permutations, τ the mapping from permutations to
permutation operators (well, τ will also accept other things than
permutations, to do with tracing, but leave that for now) and K giving the the
rank-dependent scaling of wedge. Now each of τ's outputs is constant: so,
for a given u = bulk(×, (G:f|n)), D&on;τ(r) maps u to the result of
performing, on D(u), the permutation corresponding to r but now applied to lists
with one more entry, corresponding to D's contribution to rank, which doesn't
participate in the permutations, the rest of the list being permuted by r; so
D&on;τ(r) is τ(: 0←0, 1+r(i)←1+i :1+n)&on;D. We thus obtain
τ(s)&on;D&on;τ(r) as τ(s&on;(: 0<0, 1+r(i)←1+i :1+n))&on;D
by combining the two permutations once both are to the left of
D. The stretched

form of r has the same signature as r, hence the
composite's signature is sign(s).sign(r). Thus
sign(r).sign(s).τ(s)&on;D&on;τ(r) is just sign(q).τ(q) with q =
s&on;(: 0←0, 1+r(i)←1+i :). Now, for fixed r, every permutation
(1+n||1+n) may be obtained as q for some choice of s; for contrast, given s and
q we can only chose an r for which it works if q(0) = s(0), but for given q and
r there's always a suitable s. Thus each permutation (n|r|n) yields, in the sum
of terms making up wedge&on;D&on;wedge's restriction to tensor({G}:|n), 1/K(n)
times the sum which makes up wedge&on;D's restriction to the same domain; so
wedge&on;D&on;wedge = n!/K(n).wedge&on;D and it makes sense to chose K(n) = n!,
the number of permutations of n, computable from 0! = 1, (1+i)! = i!.(1+i),
yielding the sequence [1,1,2,6,24,120,…]; so really we are averaging,
i.e. summing over permutations then dividing by the number of permutations.

With this choice of scaling, wedge&on;D&on;wedge = wedge&on;D; in
particular, composing wedge&on;D with itself yields wedge&on;D&on;D; indeed,
bulk(&on;, ({wedge&on;D}:|n)) = wedge&on;bulk(&on;, ({D}:|n)) for any natural
n. Since we know wedge&on;D annihilates all its outputs, composing it with
itself yields the tensor operator (tensor({G}:|2+n): d0×d0×u ←
u :tensor({G}:|n)) which yields a zero of rank G⊗G higher

than the
rank of its input (any constant scalar field, k, could have been used in place
of 0 to give dk in place of d0, but 0 is perfectly good constant scalar field,
hence d0 is a zero gradient). Thus wedge&on;D&on;D maps every G-only rank of
tensor to the zero with two more Gs in its rank.

In particular, wedge&on;D = wedge&on;D&on;wedge tells us that any tensor field which is symmetric under (i.e. a fixed point of) any odd permutation's operator will be annihilated by wedge&on;D. Meanwhile wedge&on;D annihilates its outputs, all of which are sums of terms of form wedge(bulk(×, (: da(i) ←i |n)) for some list, [a(0),…,a(n−1)], of scalar fields.

Valid CSS ? Valid HTML ? Written by Eddy.