3 Implementation¶
3.0 Implementation Notes¶
In this section some implementation details will be described. This is a ongoing process and might be improved.
3.1 Internal Representation¶
Differential forms are represented as List Record(k:EAB, c:R)
where each
basic term is represented as Record(k:EAB, c:R)
, for instance:
maps to
[[k= [0,0,1],c= h(x,y,z)],[k= [0,1,0],c= g(x,y,z)],[k= [1,0,0],c= f(x,y,z)]]
or, another example:
goes to
[[k= [0,1,1],c= c(x,y,z)],[k= [1,0,1],c= b(x,y,z)],[k= [1,1,0],c= a(x,y,z)]]
It is easily seen that for n generators \(x_1, \ldots, x_n\) the term \(d x_{j_p} \wedge \ldots \wedge d x_{j_q}\) is represented by \([k = [a_{i_1}, \ldots, a_{i_n}], c = \pm 1]\) where \(a_{i_s} \in \{ 0, 1 \}\) depending on whether \(d x_{i_s}\) is contained in the term or not. The (local) function terms sends a differential form \(\omega\) to the representation \(r (\omega)\). Note that the operations are destructive, this means that one has to copy the objects in order to get new ones (mere assignment inherits all previous changes).
- Note
- The interpreter normalizes the basic terms according to increasing
generators, i.e for example: \(d x_3 \wedge d x_2\) will be stored
as \(- d x_2 \wedge d x_3\), whereby the signum of the permutation is
calculated and transferred to the
c
-field in the record.
Example:
terms(dx3*dx2) -> [[k= [0,1,1],c= - 1]]
3.2 dot :: inner product¶
Given a (pseudo)-Riemannian metric g, the scalar product of two basic terms of the same degree is given by
whereby \(1 \leqslant k, l \leqslant p\). Note that \(g^{- 1} (i_k, j_l) = g^{i_k j_l}\) is the inverse of \(g_{i_k j_l}\) (raised indexes as usual). In other words, the scalar product is inherited from the dual vector space of the space where the coordinates \((x_1, \ldots, x_n)\) live, and is continued by linearity. By the way, terms of different degree are considered to be orthogonal to each other.
Example:
[x,y,z], G = matrix(G[i,j]) = g^{- 1},
The corresponding EAB’s are [1,1,0]
and [0,1,1]
. If we define a
function pos which gives the positions of 0 or 1 respectively, the example
tells us:
pos([1,1,0],1)=[1,2] and pos([0,1,1],1)=[2,3]
so that the direct product of the two resulting lists gives the desired minor:
[1,2]x[2,3]=[[1,2],[1,3],[2,2],[2,3]] =>
This essentially comprises the method we will use to compute the scalar product w.r.t symmetric matrices g and two basic terms of equal degree.
Local function: dot2
- compute the inverse of tmverbatim{g}.
- build the tmverbatim{pos} lists.
- build the minor and apply
determinant
.
Actually there are two functions dot1 and dot2, where the former is used when the metric g is diagonal (which is equivalent to the basis vectors being orthogonal) because the performance might be better if the dimension of the space is huge.
3.3 hodgeStar :: Hodge dual¶
In this new version we have removed the first method (3.3.1) because the performance difference is not as significant as we thought in the first place, at least not for \(n\leq 7\). However, we save the method in case someone has to deal with really high space dimensions.
3.3.1 Diagonal, non-degenerated g¶
If g is a diagonal matrix then the components of \(\star \beta\) reduce to
which implies that \((j_1, \ldots, j_{n - p})\) must be the complement of \((k_1,\ldots, k_p)\) in \(\{ 1, 2, \ldots, n \}\) and
for some (yet unknown) factor C
which must actually be equal to the right
hand side of the component formula above. When we recollect the internal
representation of \(d x_{k_1} \wedge \ldots \wedge d x_{k_p}\) as
EAB then it is easy to get the complement by flipping the
0 and 1. Define a function flip such that
then by using the Hodge formula with \(\alpha = \beta = dx_{k_1} \wedge \ldots \wedge d x_{k_p}\) we get using \(\star \alpha = C\ \mathrm{flip} (\alpha)\):
Since \(\alpha \wedge \mathrm{flip} (\alpha)\) is a n-form, the function
leadingCoefficient returns the one and only coefficient. Thus we
can calculate C
to
In SPAD syntax this looks like:
This way the interpreter saved us the tedious computation of the permutation signatures. Moreover, we have not to care whether the metric g is positive or negative definite.
3.3.2 General case¶
Let \(J\) denote an ordered multi-index and \(J_\sharp\) its dual. Then a generic p-vector may be written as
Thus by definition we obtain:
Since \(\star\beta\) is a (n-p)-form, we get:
Now the term \(e_J\wedge e_K\) is non-zero only if \(K=J_\sharp\), therefore
where \(e_J\wedge e_{J_\sharp}=\epsilon(J)\, \eta\ \) defines \(\epsilon\).
If we choose \(\beta=e_M\) we finally get
This formula will be used to compute the Hodge dual for monomials. We define a function hodgeBT, in pseudo-code:
hodgeStarBT(dx[M])= sqrt(g)*
SUM[J] {eps(dx[J])*dot(g,dx[J],dx[M])*conjBasisTerm(dx[j])}
which then allows to compute the Hodge dual of any form by simple recursion:
hodgeStar(g:SMR,x:DRC):DRC ==
x=0$DRC => x
leadingCoefficient(x) * hodgeStarBT(g,leadingBasisTerm(x)) + _
hodgeStar(g, reductum(x))
3.4 interiorProduct :: Interior product¶
In this newer version we have replaced the method which uses the Hodge operator. Instead we used the fact that the interior product is an antiderivation, actually the unique antiderivation of degree \(-1\) on the exterior algebra such that \(i_X(\alpha)=\alpha(X)\):
This also allows an easy implementation by recursion.
3.5 lieDerivative :: Lie derivative¶
Here we use Cartan’s formula (see 1.1.5), so that there is not much to say.
lieDerivative(w:Vector X,x:DRC):DRC ==
a := exteriorDifferential(interiorProduct(w,x))
b := interiorProduct(w, exteriorDifferential(x))
a+b
3.6 proj :: Projection¶
Since the elements of \(\mathtt{DeRhamComplex}\) are in
it is convenient to have a function \(\mathtt{proj}:\{ 0, \ldots,n \}\times X \rightarrow X\) which returns the projection on the homogeneous component \(\Omega^p (V)\). The implementation is straightforward when using the internals of EAB. Probably there are better ways to do this, especially by using exported functions only.
** deprecated **
proj(x,p) ==
t:List REA := x::List REA
idx := [j for j in 1..#t | #pos(t.j.k,1)=p]
s := [copy(t.j) for j in idx::List(NNI)]
convert(s)$DRC
NEW
In the new version we actually replaced the function above by the following recursive one:
proj(p,x) ==
x=0 => x
homogeneous? x and degree(x)=p => x
a:=leadingBasisTerm(x)
if degree(a)=p then
leadingCoefficient(x)*a + proj(p, reductum x)
else
proj(p, reductum x)
NOTE We have changed the order of arguments from (DRC,NNI) to (NNI,DRC) because this corresponds more to the usual nomenclature of projections.