Menu ▾ ▴

#5218 Einhil.dem seems to have index issues

None
pending
None
5
2026-09-15
2026-09-02
No

The D expression does not simplify.
This is D.
-((5g([],[%1,%2])g([],[%3,%4])g([%1,%4],[],n)g([%3,m],[],%2))/4)+(g([],[%1,%2])g([],[%3,%4])g([%1,n],[],m)g([%3,%4],[],%2))/2-(g([],[%1,%2])g([],[%3,%4])g([%2,m],[],n)g([%3,%4],[],%1))/2+(5g([],[%1,%2])g([],[%3,%4])g([%1,n],[],%4)g([%3,%2],[],m))/4-g([],[%1,%2],%2,m)g([%1,n],[])+g([],[%1,%2],%2,n)g([%1,m],[])

Is this correct? The two terms at the end should cancel due to the symmetry of g and contraction.
It needs to contract g with the derivative indices first, so the derivatives are gone, and then it can use the symmetry of g to cancel them. This term -g([],[%1,%2],%2,m) times g([%1,n],[]) needs to be -g([m,n],[]) otherwise, it becomes -g([],[],m,n), which makes no sense for symmetry.

Discussion

  • Viktor Toth

    Viktor Toth - 2026-09-03

    In the current version of einhil.dem, declaration of g's symmetry properties is deliberately delayed, precisely to show their relevance to the final result. So the fact that D does not simplify to 0 is a feature, not a bug.

     
  • Viktor Toth

    Viktor Toth - 2026-09-03
    • assigned_to: Viktor Toth
     
  • Viktor Toth

    Viktor Toth - 2026-09-03
    • status: open --> pending
     
  • Richard Gobeli

    Richard Gobeli - 2026-09-12

    I made changes to ismiplify.mac and it seems to help to cancel terms so that the result D is now zero. For some reason simpmetderiv and rename with icounter at 1 some times makes mistakes.

     
    • Viktor Toth

      Viktor Toth - 2026-09-12

      You've run into a known pathology of rename() and, generally, dummy index handling in itensor. Yes, playing with icounter or the second parameter of rename() can fix things but there's no generic solution. Setting the counter to 100 fixes some, breaks other cases. In particular, I note, your suggested code actually broke einhil.dem. I've now implemented a modified solution with isimplify() taking an optional second parameter and using that in the calls to rename(), but without invoking additional calls to rename(). Ultimately though, this is not solved without a redesign of itensor.

       
  • Richard Gobeli

    Richard Gobeli - 2026-09-13

    I found that the original code works when I added any of the following after the component lines. It only needs 1 then I get D=0 without any of them i get D with 6 terms.

    --> length(R([a,b,c,d]));
    --> length(R([a,b]));
    --> length(R([],[]));

    This is really weird.
    Build_info running inMaxima command line.

    Maxima-version: "branch_5_50_base_120_g0e708d4a2"
    Maxima build date: "2026-09-07 10:39:30"
    Host type: "x86_64-w64-mingw32"
    Lisp implementation type: "SBCL"
    Lisp implementation version: "2.6.8"
    User dir: "C:/Users/Richard/maxima"
    Temp dir: "C:/Users/Richard/AppData/Local/Temp"
    Object dir: "C:/Users/Richard/maxima/binary/branch_5_50_base_120_g0e708d4a2/sbcl/2_6_8"
    Frontend: false

     

    Last edit: Richard Gobeli 2026-09-13
  • Richard Gobeli

    Richard Gobeli - 2026-09-14

    i tried the new isimplify function with 0, 1 ,2 10, 0r 100 it does not give me D=0.

    even the --> length(R([a,b,c,d])); does not help. Even using Maxima in command line mode it does not give D=0.

     
  • Viktor Toth

    Viktor Toth - 2026-09-14

    Here:

    (%i1) batch("einhil.dem");
    (%i2) "Deriving the Einstein field equations from the Einstein-Hilbert action"
    (%i3) if get('itensor,'version) = false then load(itensor)
    (%o3)          /home/vttoth/dev/maxima/share/tensor/itensor.lisp
    (%i4) "We declare the standard metric but remove automatic contraction rules..."
    (%i5) "... that may incorporate hidden assumptions about symmetry"
    (%i6) imetric(g)
    (%o6)                                done
    (%i7) remcon(g)
    (%o7)                                 [g]
    (%i8) defcon(g,g,kdelta)
    (%o8)                                done
    (%i9) "Let us define the Riemann tensor, the Ricci tensor and the Ricci scalar"
    (%i10) components(R([a,b,c,d],[]),
                      canform(isimplify(ev(icurvature([a,b,c],[e])*g([d,e],[]),
                                           ichr2,eval))))
    (%i11) components(R([a,b],[]),
                      canform(isimplify(ev(icurvature([a,b,c],[c]),ichr2,eval))))
    (%i12) components(R([],[]),
                      canform(isimplify(ev(icurvature([a,b,c],[c])*g([],[a,b]),
                                           ichr2,eval))))
    (%i13) "This is the Einstein-Hilbert action in standard form, which we evaluate and simplify"
    (%i14) L0:ishow((1/(16*%pi*G))*(2*L+'R([],[]))*sqrt(-determinant(g)))
                           (2 L + R) sqrt(- determinant(g))
    (%t14)                 --------------------------------
                                       16 %pi G
    (%i15) L0:isimplify(ev(L0,R,eval))
    (%i16) "We now generate terms of the 2nd order Euler-Lagrange equation"
    (%i17) EL0:isimplify(diff(L0,g([],[m,n])))
    (%i18) EL1:isimplify(-idiff(diff(L0,g([],[m,n],k)),k))
    (%i19) EL2:isimplify(idiff(idiff(diff(L0,g([],[m,n],k,l)),k),l))
    (%i20) "Sum and simplify"
    (%i21) EL:isimplify(expand(((EL0+EL1+EL2)*16*%pi*G)/sqrt(-determinant(g))))
    (%i22) "Did we recover the Einstein field equation?"
    (%i23) "Let us write it down and form the difference"
    (%i24) EFE:ishow('R([m,n],[])-(1/2)*g([m,n],[])*'R([],[])+(-L)*g([m,n],[]))
                                                R g
                                                   m n
    (%t24)                      R    - L g    - ------
                                 m n      m n     2
    (%i25) EFE:isimplify(ev(EFE,R,eval))
    (%i26) D:isimplify(contract(isimplify(ev(EL,ichr2,eval))-rename(EFE)))
    (%i27) "Why is D nonzero?"
    (%i28) length(D)
    (%o28)                                40
    (%i29) "We have not yet declared the symmetry properties of the metric."
    (%i30) "Now is the time!"
    (%i31) decsym(g,2,0,[sym(all)],[])
    (%o31)                               done
    (%i32) decsym(g,0,2,[],[sym(all)])
    (%o32)                               done
    (%i33) isimplify(D)
    (%o33)                                 0
    

    Now the weird part is, when I run it with SBCL instead of GCL, I do not get the same result.

    This is not isimplify() however. This is a much deeper issue with itensor in general, how it generates dummy indices and applies contraction rules especially. Note that we had to restore defcon(g,g,kdelta) in order to achieve the desired simplification. However, defcon does not respect index ordering. It prematurely treats terms as symmetric, thus simplifying some parts and not others, often dependent I think on compiler iptimization.

    There is no easy solution for this. It is behavior I've known about ever since I became familiar with itensor and began using it in nonsymmetric theories. It's a pain but it would require a conceptual redesign of contraction rules.

    Note that, curiously, you can restore the correct behavior in SBCL (and also CLISP/CMUCL/ECL on my setup) by changing this line:

    components(R([],[]),isimplify(canform(isimplify(ev(icurvature([a,b,c],[c])*g([],[a,b]),ichr2,eval)))))$
    

    For this is where GCL deviates from the rest of them and for all I know, it may be a GCL buglet. But the underlying issues in itensor -- inconsistent contraction of nonsymmetric terms, confusion when it comes to dummy index generation -- remain valid.

     
  • Richard Gobeli

    Richard Gobeli - 2026-09-14

    Do you think claude.ai could find this bug? I got claude to fix ishow to give tensor display a stagger output. Using tensor diff and contravarinat indices like -k index can give - indices in the contravainat list. There is a one line correct for that. The other changes are only in ishow.

     

    Last edit: Richard Gobeli 2026-09-14
  • Viktor Toth

    Viktor Toth - 2026-09-15

    No, I don't think there is an easy fix, with or without AI. That's because it's not really a bug per se: the deep reasons are conceptual. The 'minus sign for covariant indices' was already a hack by yours truly, to manage index ordering for nonsymmetric tensors, but as you (and Claude) have seen, it is not a fully satisfactory solution. The problem is that T([a,-b],[]) can become T([a],[b]) which then ambiguously maps into either T([a,-b],[]) or T([-b,a],[]) and the two are very much not the same: multiply by g([b,c],[]) and you get either T([a,c],[]) or T([c,a],[]).

    The "true" solution is to basically rethink the itensor concept and instead of thinking of covariant and contravariant indices as two separate bags of indices, think of them as one bag with two types. While at it, it'd also be important to implement ordinary and covariant derivative indices both, and symmetry rules for those indices contingent on the nature of the metric. And while I am at it, I'd also want to be be able to add another user-defined index attribute, to allow, for instance, the use of indexed notation in QFT, with symbols that have both coordinate and gauge indices that should never be mixed; e.g., when I write, say, W^a_\nu in the Standard Model, g^{\mu\nu}W^a_\nu makes sense, g_{ab}W^a_\nu does not.

    This is something I've been thinking about for years, and yes, consulting also with Claude and GPT. But it's not something I'd want to do hastily. The itensor package for all its flaws is remarkably powerful, and messing with it is not something I'd do lightly.

    I looked at your itensor update. Can you give me use cases that necessitated these fixes? (I thinkI know what you were trying to accomplish, but I'd not want to just guess.) Please use e-mail if convenient, you can see my e-mail address in the mailing list.

     

Log in to post a comment.