vermaseren / form

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

renumber 1 does not seem to catch all cases #401

Open johanbijnens opened 2 years ago

johanbijnens commented 2 years ago

symbol d; dimension d; index mu1,...,mu5; cfunction nn(symmetric),f(symmetric);

L X = +f(nn,nn(mu1,mu2,mu3))f(nn(mu1),nn(mu2,mu3)) +f(nn,nn(mu1,mu2,mu3))f(nn(mu2),nn(mu1,mu3)) +f(nn,nn(mu1,mu2,mu3))*f(nn(mu3),nn(mu1,mu2)); .sort sum mu1,mu2,mu3; renumber 1; .sort argument; argument;

do i=3,1,-1

id Ni'_? = mui';

enddo

endargument; endargument; print +s; .end

produces the output: FORM 4.2.1 (Nov 10 2020, v4.2.1-30-gb0e72a8) 64-bits Run: Tue Dec 7 17:31:54 2021 X =

Since both f and nn are symmetric these terms are really the same. I had expected that summing and renumber 1 would catch these cases but it does not seem to. This is the simplest example of the behaviour I could find (was of course discovered in a much more complicated setting), I'm fully aware that it is virtually impossible to catch all of these cases but a warning in the description of the renumber command that it tries all permutations but might still miss some equivalences might be useful to add. Unless it turns out that it is easy to change the code to include this case which has a symmetric function inside a symmetric function.

The last module is simply to make the output more legible than for the Ni_? notation.

I had this behaviour earlier already but in that project it only showed up in very complicated cases and I did not find a simple example that had it, then it was with traces (i.e. cyclically symmetric functions) and many more objects, so submitting a report didn't seem useful.

With best regards, Hans

tueda commented 2 years ago

I guess a 19-year-old (at least) comment of FullRenumber applies: https://github.com/vermaseren/form/blob/b0e72a834eb5d1d057e91202201ff21013838be4/sources/reshuf.c#L320-L321

The following example also shows that Renumber does not work for dummy indices in nested functions.

S d;
Dimension d;
I mu1,...,mu3;
CF f,f1(symmetric),f2(symmetric),f3(symmetric);

* Dummy indices in nested functions. The Renumber statement fails to simplify them.
L X =
  + f(f1(mu1,mu2,mu3) * f2(mu1) * f3(mu2,mu3))
  + f(f1(mu1,mu2,mu3) * f2(mu2) * f3(mu1,mu3))
  + f(f1(mu1,mu2,mu3) * f2(mu3) * f3(mu1,mu2))
;

* Dummy indices in single-level functions. The Renumber statement does simplify them.
L Y =
  + f1(mu1,mu2,mu3) * f2(mu1) * f3(mu2,mu3)
  + f1(mu1,mu2,mu3) * f2(mu2) * f3(mu1,mu3)
  + f1(mu1,mu2,mu3) * f2(mu3) * f3(mu1,mu2)
;

P +s;
.sort

sum mu1,mu2,mu3;
P +s;
.sort

renumber 1;
P +s;
.sort

multiply replace_(<N1_?,mu1>,...,<N3_?,mu3>);
P +s;
.end
   X =
       + f(f1(mu1,mu2,mu3)*f2(mu1)*f3(mu2,mu3))
       + f(f1(mu1,mu2,mu3)*f2(mu2)*f3(mu1,mu3))
       + f(f1(mu1,mu2,mu3)*f2(mu3)*f3(mu1,mu2))
      ;

   Y =
       + 3*f1(mu1,mu2,mu3)*f2(mu1)*f3(mu2,mu3)
      ;

Depending on your problem, you may be able to work around it by temporarily flattening the structure of your expressions. For example:

S d;
Dimension d;
I mu1,...,mu3;
CF nn(symmetric),f(symmetric);

CF f1(symmetric),f2(symmetric);
CF ff1,ff2,nnn;  * non-symmetric versions

L X =
  +f(nn,nn(mu1,mu2,mu3)) * f(nn(mu1),nn(mu2,mu3))
  +f(nn,nn(mu1,mu2,mu3)) * f(nn(mu2),nn(mu1,mu3))
  +f(nn,nn(mu1,mu2,mu3)) * f(nn(mu3),nn(mu1,mu2))
;
sum mu1,mu2,mu3;

* Flatten the terms.
multiply replace_(nn,nnn);  * for argument field wildcard substitution
#do i=1,2
  id once,f(nnn(?a),nnn(?b)) = f`i'(?a) * f`i'(?b);
#enddo

renumber 1;
multiply replace_(<N1_?,mu1>,...,<N3_?,mu3>);

* Deflatten the terms back.
#do i=1,2
  multiply replace_(f`i',ff`i');  * for argument field wildcard substitution
  id once,ff`i'(?a) * ff`i'(?b) = f(nn(?a),nn(?b));
#enddo

P +s;
.end
   X =
       + 3*f(nn,nn(mu1,mu2,mu3))*f(nn(mu1),nn(mu2,mu3))
      ;
johanbijnens commented 2 years ago

Thanks, the flattening we had already tried and did not work, at least it did not catch all cases of the more complicated cases I was working on, where many more of these possibilities for permutations can show up (i.e. even longer ones of these connected chains). I did it in a slightly different way though so maybe your version will work better. I'll try, also for the more complicated cases.

The workaround we used is more complicated by finding the problem cases by explicitly adding all permutations, and then using #write and python to produce code that took care of the equality.

The code that identified the equal cases is included, if a bracketed term has more than one ope it means that those are really equal.

Yes, the 19 year old comment applies. Unfortunately that presumably means it will not be that easy to fix.

with best regards, Hans

On 2021-12-08 13:10, Takahiro Ueda wrote:

I guess a 19-year-old (at least) comment of |FullRenumber| applies: https://github.com/vermaseren/form/blob/b0e72a834eb5d1d057e91202201ff21013838be4/sources/reshuf.c#L320-L321 https://github.com/vermaseren/form/blob/b0e72a834eb5d1d057e91202201ff21013838be4/sources/reshuf.c#L320-L321

The following example also shows that |Renumber| does not work for dummy indices in nested functions.

|S d; Dimension d; I mu1,...,mu3; CF f,f1(symmetric),f2(symmetric),f3(symmetric); Dummy indices in nested functions. The Renumber statement fails to simplify them. L X = + f(f1(mu1,mu2,mu3) f2(mu1) f3(mu2,mu3)) + f(f1(mu1,mu2,mu3) f2(mu2)

  • f3(mu1,mu3)) + f(f1(mu1,mu2,mu3) f2(mu3) f3(mu1,mu2)) ; Dummy indices in single-level functions. The Renumber statement does simplify them. L Y = + f1(mu1,mu2,mu3) f2(mu1) * f3(mu2,mu3) + f1(mu1,mu2,mu3)
  • f2(mu2) f3(mu1,mu3) + f1(mu1,mu2,mu3) f2(mu3) * f3(mu1,mu2) ; P +s; .sort sum mu1,mu2,mu3; P +s; .sort renumber 1; P +s; .sort multiply replace(<N1?,mu1>,...,<N3_?,mu3>); P +s; .end |

|X = + f(f1(mu1,mu2,mu3)f2(mu1)f3(mu2,mu3)) + f(f1(mu1,mu2,mu3)f2(mu2)f3(mu1,mu3)) + f(f1(mu1,mu2,mu3)f2(mu3)f3(mu1,mu2)) ; Y = + 3f1(mu1,mu2,mu3)f2(mu1)*f3(mu2,mu3) ; |

Depending on your problem, you may be able to work around it by temporarily flattening the structure of your expressions. For example:

|S d; Dimension d; I mu1,...,mu3; CF nn(symmetric),f(symmetric); CF f1(symmetric),f2(symmetric); CF ff1,ff2,nnn; non-symmetric versions L X = +f(nn,nn(mu1,mu2,mu3)) f(nn(mu1),nn(mu2,mu3)) +f(nn,nn(mu1,mu2,mu3)) f(nn(mu2),nn(mu1,mu3)) +f(nn,nn(mu1,mu2,mu3)) f(nn(mu3),nn(mu1,mu2)) ; sum mu1,mu2,mu3; Flatten the terms. multiply replace_(nn,nnn); for argument field wildcard substitution #do i=1,2 id once,f(nnn(?a),nnn(?b)) = fi'(?a) * fi'(?b); #enddo renumber 1; multiply replace(<N1?,mu1>,...,<N3?,mu3>); * Deflatten the terms back. #do i=1,2 multiply replace(fi',ffi'); for argument field wildcard substitution id once,ff`i'(?a) ff`i'(?b) = f(nn(?a),nn(?b));

enddo P +s; .end |

|X = + 3f(nn,nn(mu1,mu2,mu3))f(nn(mu1),nn(mu2,mu3)) ; |

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/401#issuecomment-988757217, or unsubscribe https://github.com/notifications/unsubscribe-auth/AW2FNMMHDUC42SNJ7RUUYQDUP5DLFANCNFSM5JRWVHPA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Johan Bijnens Department of Astronomy and Theoretical Physics, Lund University Box 43, SE 221 00 Lund, Sweden Email: @.*** Homepage: https://atp.lu.se/~bijnens Tel: +46-46-2220447 Fax: +46-46-2229686 symbol d; dimension d; index mu1,...,mu5,nu1,...,nu5; cfunction nn(symmetric),f(symmetric),ope;

L X = +f(nn,nn(mu1,mu2,mu3))f(nn(mu1),nn(mu2,mu3)) +f(nn,nn(mu1,mu2,mu3))f(nn(mu2),nn(mu1,mu3)) +f(nn,nn(mu1,mu2,mu3))*f(nn(mu3),nn(mu1,mu2)); .sort sum mu1,mu2,mu3; renumber 1; .sort argument; argument;

do i=3,1,-1

id Ni'_? = mui';

enddo

endargument; endargument; .sort now for the code that finds that they are equal (i.e. two ope for the same term means that the orginal term was the same)

$a=0;

$a = $a+1; multiply ope($a); print +s; .sort multiply perm(ope,nu1,nu2,nu3); id ope(nu1?,nu2?,nu3?) = replace(<mu1,nu1>,...,<mu3,nu3>); b f; print +s; .end