The other day, someone asked a question: Can the itensor package in Maxima calculate the Laplace-Beltrami operator applied to a scalar field in the presence of torsion?

Well, it can. But I was very happy to get this question because it allowed me to uncover some long-standing, subtle bugs in the package that prevented some essential simplifications and in some cases, even produced nonsensical results.

With these fixes, Maxima now produces a beautiful result, as evidenced by this nice newly created demo, which I am about to add to the package:

(%i1) **if get('itensor,'version) = false then load(itensor)**
(%i2) "First, we set up the basic properties of the system"
(%i3) **imetric(g)**
(%i4) "Demo is faster in 3D but works for other values of dim, too"
(%i5) **dim:3**
(%i6) "We declare symmetries of the metric and other symbols"
(%i7) **decsym(g,2,0,[sym(all)],[])**
(%i8) **decsym(g,0,2,[],[sym(all)])**
(%i9) **components(g([a],[b]),kdelta([a],[b]))**
(%i10) **decsym(levi_civita,0,dim,[],[anti(all)])**
(%i11) **decsym(itr,2,1,[anti(all)],[])**
(%i12) "It is useful to set icounter to avoid indexing conflicts"
(%i13) **icounter:100**
(%i14) "We choose the appropriate convention for exterior algebra"
(%i15) **igeowedge_flag:true**
(%i16) "Now let us calculate the Laplacian of a scalar field and simplify"
(%i17) **canform(hodge(extdiff(hodge(extdiff(f([],[]))))))**
(%i18) **contract(expand(lc2kdt(%)))**
(%i19) **ev(%,kdelta)**
(%i20) **D1:ishow(canform(%))
%1 %2 %3 %4 %1 %2 %1 %2
(%t20) (- f g g g ) + f g + f g
,%4 ,%3 %1 %2 ,%2 ,%1 ,%1 %2
**(%i21) "We can re-express the result using Christoffel symbols, too"
(%i22) **ishow(canform(conmetderiv(D1,g)))
%1 %4 %2 %5 %3 %1 %2 %3
(%t22) 2 f g g ichr2 g - f g ichr2
,%5 %1 %2 %3 %4 ,%3 %1 %2
%1 %3 %2 %1 %2
- f g ichr2 + f g
,%3 %1 %2 ,%1 %2
**(%i23) "Nice. Now let us repeat the same calculation with torsion"
(%i24) **itorsion_flag:true**
(%i25) **canform(hodge(extdiff(hodge(extdiff(f([],[]))))))**
(%i26) "Additional simplifications are now needed"
(%i27) **contract(expand(lc2kdt(%th(2))))**
(%i28) **ev(%,kdelta)**
(%i29) **canform(%)**
(%i30) **ev(%,ichr2)**
(%i31) **ev(%,ikt2)**
(%i32) **ev(%,ikt1)**
(%i33) **ev(%,g)
(%i34) ev(%,ichr1)**
(%i35) **contract(rename(expand(canform(%))))**
(%i36) **flipflag:not flipflag**
(%i37) **D2:ishow(canform(%th(2)))
%1 %2 %3 %4 %1 %2 %3 %1 %2
(%t37) (- f g g g ) + f g itr + f g
,%1 ,%2 %3 %4 ,%1 %2 %3 ,%1 ,%2
%1 %2
+ f g
,%1 %2
**(%i38) "Another clean result; can also be expressed using Christoffel symbols"
(%i39) **ishow(canform(conmetderiv(D2,g)))
%1 %2 %3 %4 %5 %1 %2 %3
(%t39) 2 f g g ichr2 g + f g itr
,%1 %2 %3 %4 %5 ,%1 %2 %3
%1 %2 %3 %2 %3 %1 %1 %2
- f g ichr2 - f g ichr2 + f g
,%1 %2 %3 ,%1 %2 %3 ,%1 %2
**(%i40) "Finally, we see that the two results differ only by torsion"
(%i41) **ishow(canform(D2-D1))
%1 %2 %3
(%t41) f g itr
,%1 %2 %3
**(%i42) "Last but not least, d^2 is not nilpotent in the presence of torsion"
(%i43) **extdiff(extdiff(f([],[])))**
(%i44) **ev(%,icc2,ikt2,ikt1)**
(%i45) **canform(%)**
(%i46) **ev(%,g)**
(%i47) **ishow(contract(%))
%3
(%t47) f itr
,%3 %275 %277
**(%i48) "Reminder: when dim = 2n, the Laplacian is -1 times these results."

The learning curve is steep and there are many pitfalls, but itensor remains an immensely powerful package.