1

Defining rules seems to be quite troublesome, because whatever rule I make has to have the exact syntax ordering of the expression I want to modify.

For example,

take this differential form

(Dt[t2 t3]) . (Dt[t1 t3]) . (Dt[t1 t2]) 
expr = Distribute[%, Plus, Dot]

(I used Dothere rather than Wedgebecause I thought Mathematica would have more inbuilt rules to help simplify it.): This returns:

(t3 Dt[t2]) . (t3 Dt[t1]) . (t2 Dt[t1]) + (t3 Dt[t2]) . (t3 Dt[
     t1]) . (t1 Dt[t2]) + (t3 Dt[t2]) . (t1 Dt[t3]) . (t2 Dt[
     t1]) + (t3 Dt[t2]) . (t1 Dt[t3]) . (t1 Dt[t2]) + (t2 Dt[
     t3]) . (t3 Dt[t1]) . (t2 Dt[t1]) + (t2 Dt[t3]) . (t3 Dt[
     t1]) . (t1 Dt[t2]) + (t2 Dt[t3]) . (t1 Dt[t3]) . (t2 Dt[
     t1]) + (t2 Dt[t3]) . (t1 Dt[t3]) . (t1 Dt[t2])

Then I want to define a rule to make the t's factor out. Naively I'd want to do something like:

Simplify[%, ( a_ Dt[b_]) . (c_ Dt[d_]) == a c (Dt[b_] . Dt[d_])]

Unfortunately that doesn't work, so instead I had to examine FullForm[expr] while repeatedly making new rules trying to match parts of the expression. The list of rules I ended up creating were:

% //. Dot[x_, y_*z_Dt] :> y (x . z)
% //. Dot[t_ * dot_Dot, other___] :> t Dot[dot, other]
% //. Dot[y_*z_Dt, other___] :> y Dot[z, other]

Which eventually managed to factor out the t's as I wanted. i.e. it returned:

t2 t3^2 Dt[t2] . Dt[t1] . Dt[t1] + t1 t3^2 Dt[t2] . Dt[t1] . Dt[t2] + 
 t1 t2 t3 Dt[t2] . Dt[t3] . Dt[t1] + 
 t1^2 t3 Dt[t2] . Dt[t3] . Dt[t2] + t2^2 t3 Dt[t3] . Dt[t1] . Dt[t1] +
  t1 t2 t3 Dt[t3] . Dt[t1] . Dt[t2] + 
 t1 t2^2 Dt[t3] . Dt[t3] . Dt[t1] + t1^2 t2 Dt[t3] . Dt[t3] . Dt[t2]

Continued Example

Then I wanted to make a rule to make repeated differentials 0. Such as $dx*dy*dx = 0$ because dx is repeated.

Here's my naive code:

% //. Dot[ ___, Dt[x_], ___, Dt[x_], ___ ] -> 0

Which did nothing.

Finally I gave up and deleted terms by hand:

t1 t2 t3 Dt[t2] . Dt[t3] . Dt[t1] + t1 t2 t3 Dt[t3] . Dt[t1] . Dt[t2];

Questions

I realize there's packages out there that do differential forms, (and I would be open to hearing suggestions about which ones are good. However, my question is how I would be able to make rules like this, because in other settings, there may not be a package that does what I want.

  1. How would I define rules like this that work without being so picky about the exact syntax of FullForm[expr]
  2. How would I do this with other techniques? Can I get a simplify with assumptions to work?
ions me
  • 881
  • 5
  • 11
  • Do you know "NonCommutativeMultiply" ? – Daniel Huber Oct 04 '23 at 09:09
  • Could check methods in 1 2 3 4 5 – Daniel Lichtblau Oct 04 '23 at 14:23
  • @DanielHuber, I tried NonCommutativeMultiply originally. To see if it was better, I then switched to dot , but it behaved similarly. If you think it's worth going back, I'll take another look at it. – ions me Oct 05 '23 at 13:45
  • @DanielLichtblau Thanks for the references, I'll take some time to digest them. – ions me Oct 05 '23 at 13:49
  • To use Dot is an severe error, because its specialized to contract tensor products and has other features by abuse of notation mixing scalar products and linear combinations where commuativity is implied . For differential forms use Wedge, that can be expanded readily by TensorExpand, if all symbols are declared correctly with their tensor rank types. Don't use Dt[x], because it cannot used with Patterns directly. – Roland F Oct 06 '23 at 06:13
  • @RolandF If I don't use Dt[x], how do I do d(t1 t2), besides explicitly doing the derivatives myself, or using Dt, and then making a bunch of rules to turn Dt[t1] into dt1. – ions me Oct 08 '23 at 01:39
  • Any implementation of exterior calculus needs a fixed base of differential 1-forms and tangent vectors. So there is no way around to code a $\mathbb d$ in that basis. One can use Dt, but for pattern matching always use HoldPattern[Dt[x_]] in order to prevent evaluation as $$dx \text{Pattern}^{(1,0)}(x,_)$$ – Roland F Oct 08 '23 at 01:59

0 Answers0