vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
1.15k stars 136 forks source link

Substituting vectors from tables, extra symbols, etc. breaks contracted indices #344

Closed magv closed 4 years ago

magv commented 4 years ago

Hi, folks. When trying to substitute a vector variable using a table (or extrasymbol_), like so:

auto V p;
Table TBL(1:1);
Fill TBL(1) = pa+pb;
Local EXPR = p1.p2 + e_(p1,p2,p3,p4);
id p1 = TBL(1);
print;
.sort
.end

... the output is far from desired:

   EXPR =
      pa + pb - e_(p2,p3,p4,N1_?)*pa - e_(p2,p3,p4,N1_?)*pb;

The scalar product turned into a vector, and e_ got broken too.

The workaround I'm using at the moment is to try to undo the automatic index contraction in various ways, wrap vectors into auxiliary functions, and only perform the substitution then. Hardly ideal, in short.

A fix for this problem, or at least a better workaround would be appreciated.

tueda commented 4 years ago

You are doing, basically, the following manipulation:

V pa,pb,p1,...,p4;
S TBL;
L F = p1.p2 + e_(p1,p2,p3,p4);
id p1 = TBL;
id TBL = pa+pb;
P;
.end
   F =
      pa + pb - e_(p2,p3,p4,N1_?)*pa - e_(p2,p3,p4,N1_?)*pb;

But the indices of vectors should be also considered:

V pa,pb,p1,...,p4;
S TBL;
T t1;
I mu1;
L F = p1.p2 + e_(p1,p2,p3,p4);
totensor p1,t1;
chainout t1;
id t1(mu1?) = pa(mu1) + pb(mu1);
P;
.end
   F =
      pa.p2 + pb.p2 + e_(pa,p2,p3,p4) + e_(pb,p2,p3,p4);

So, if you want to use a table, then you can write something like:

V pa,pb,p1,...,p4;
T t1;
I mu1;
Table TBL(1:1,mu1?);
Fill TBL(1) = pa(mu1)+pb(mu1);
L F = p1.p2 + e_(p1,p2,p3,p4);
totensor p1,t1;
chainout t1;
id t1(mu1?) = TBL(1,mu1);
P;
.end
   F =
      pa.p2 + pb.p2 + e_(pa,p2,p3,p4) + e_(pb,p2,p3,p4);
tueda commented 4 years ago

Maybe FORM should warn or raise an error for illegal substitutions like

V p1;
S TBL;
id p1 = TBL;
magv commented 4 years ago

So then the recipe for substituting vectors with e.g. extrasymbol_() or anything that doesn't allow for an additional index argument (like tables do) would be to undo the index contraction via totensor, replace tensor(i?) with e.g. dummy(extrasymbol_(n), i), and then do id dummy(p?, i?) = p(i)?

tueda commented 4 years ago

Yes, the recipe seems to work even for more complicated problems:

* Store a vector-like expression into an extra symbol.

V pa,pb;
CF f;
L F = f(pa+pb);
argtoextrasymbol f;
.sort

* A complicated example.

V p,p1,...,p4;
T t;
CT t1;
CF dummy;
I mu;
Drop;

L F = p1.p2^2*p1.p1^3*e_(p1,p2,p3,p4)*t(p1,p1,p2);
totensor p1,t1;
chainout t1;
id t1(mu?) = dummy(extrasymbol_(1),mu);
id dummy(p?,mu?) = p(mu);

* The following code is to check if the result is correct.

.sort
Skip;
L G = p1.p2^2*p1.p1^3*e_(p1,p2,p3,p4)*t(p1,p1,p2);
id p1 = pa + pb;

.sort
Drop;

L Zero = F - G;
P;
.end
   Zero = 0;
vermaseren commented 4 years ago

The main problem is that tables are basically scalar-like. As Takahiro mentioned, you have to somehow pass the index, with in your example is a contracted index. Hence you could do something like: auto V p; Index i; Table TBL(1:1,i?); Fill TBL(1) = pa(i)+pb(i); Local EXPR = p1.p2 + e_(p1,p2,p3,p4); id p1 = TBL(1,?); print; .sort which will give the desired output. I do not see a simpler way to do this.