Open vsht opened 11 months ago
Hi Vlad,
I usually do a little bit more in Mathematica before creating the Fill statements. I Collect against the integral function names on the RHS of the rules, and apply something like GCoeffSimplify2
to the coefficients.
ep does not end up in the prf, which helps stop the terms becoming too big for FORM (and I will later expand in ep in FORM with a routine which acts on the "denep" denominators). If I am expanding in more symbols than just ep, I arrange that they end up in their own "den..." functions also. Then the prf functions contain only symbols which won't be expanded later.
Since performance on the Mathematica side can be an issue for large tables I split each reduction table into many parts and process each part in parallel.
(* Slightly modified, from Arnd Behring *)
crCollect[expr_,pat_,f_:Identity]:=
Module[{patalt,vars,res},
If[expr===0,
Return[f[expr]]
];
patalt=If[Head[pat]===List,Alternatives@@pat,pat];
vars=Union@Cases[expr,patalt,{0,Infinity}];
If[Length[vars]===0,
Return[f[expr]]
];
res=CoefficientRules[expr,vars];
res=Map[Apply[Times,vars^#[[1]]]*f[#[[2]]]&,res];
res=Total[res];
Return[res]
];
GCoeffSimplify2[x_] := Module[{numer,denom,coeff},
coeff = Together[x];
numer = Collect[Numerator[coeff], ep,
num
];
denom = FactorList[Denominator[coeff]];
denom = Map[
(#/.{
{a_/;ContainsAll[Variables[a],{ep}], p_}:>denep[a]^p,
{a_ /; ContainsNone[Variables[a], {ep}], p_} :> den[a]^p
})&
,
denom
];
denom = denom/.List->Times;
coeff = crCollect[numer*denom, {ep,_denep},
(prf[Numerator[#],Denominator[#]]& @ Factor[Together[#/.{num[a_]->a,den[b_]->1/b}]])&
]/.{denep[ep]->1/ep};
Return[coeff];
];
As you suggest, you can alternatively create expressions instead of fill statements (wrapping the names in [] makes life much easier here...) and process them in FORM with InParallel;
helping performance when processing many tiny expressions. Those results can be converted to fill statements with some simple regex.
Assuming your lsclD = 4-2*ep
, your second rule ends up something like:
((denep[1 + 2*ep]*prf[-45, 8*gkin^2*meta^4*u0b^4])/ep +
(denep[1 + 2*ep]*prf[-1, 4*gkin^2*meta^4*u0b^4])/ep^3 +
denep[1 + 2*ep]*prf[9, 2*gkin^2*meta^4*u0b^4] +
(denep[1 + 2*ep]*prf[17, 8*gkin^2*meta^4*u0b^4])/ep^2)*
topology1[1, 0, 1, 0, 1, 0, 0] +
((denep[1 + 2*ep]*prf[-1, gkin*meta^2*u0b^2])/ep +
(denep[1 + 2*ep]*prf[1, 4*gkin*meta^2*u0b^2])/ep^2 +
denep[1 + 2*ep]*prf[3, 4*gkin*meta^2*u0b^2])*
topology100[1, 1, 0, 0, 1, 1, 0]
Another way: : Do not construct the fill statements directly, but make an expression with the elements of the table mentioned as arguments of a function f; After that use the FillExpression statement to fill the table.
On 14 Jul 2023, at 18:21, jodavies @.***> wrote:
Hi Vlad,
I usually do a little bit more in Mathematica before creating the Fill statements. I Collect against the integral function names on the RHS of the rules, and apply something like GCoeffSimplify2 to the coefficients.
ep does not end up in the prf, which helps stop the terms becoming too big for FORM (and I will later expand in ep in FORM with a routine which acts on the "denep" denominators). If I am expanding in more symbols than just ep, I arrange that they end up in their own "den..." functions also. Then the prf functions contain only symbols which won't be expanded later.
Since performance on the Mathematica side can be an issue for large tables I split each reduction table into many parts and process each part in parallel.
( Slightly modified, from Arnd Behring ) crCollect[expr,pat,f_:Identity]:= Module[{patalt,vars,res}, If[expr===0, Return[f[expr]] ]; patalt=If[Head[pat]===List,Alternatives@@pat,pat]; @.**[expr,patalt,{0,Infinity}]; If[Length[vars]===0, Return[f[expr]] ]; res=CoefficientRules[expr,vars]; res=Map[Apply[Times,vars^#[[1]]]f[#[[2]]]&,res]; res=Total[res]; Return[res] ];
GCoeffSimplify2[x] := Module[{numer,denom,coeff}, coeff = Together[x]; numer = Collect[Numerator[coeff], ep, num ]; denom = FactorList[Denominator[coeff]]; denom = Map[ (#/.{ {a/;ContainsAll[Variables[a],{ep}], p_}:>denep[a]^p })& , denom ]; denom = denom/.List->Times;
coeff = crCollect[numer*denom, {ep,denep}, (prf[Numerator[#],Denominator[#]]& @ Factor[Together[#/.{num[a]->a,den[b_]->1/b}]])& ]/.{denep[ep]->1/ep}; Return[coeff]; ]; As you suggest, you can alternatively create expressions instead of fill statements (wrapping the names in [] makes life much easier here...) and process them in FORM with InParallel; helping performance when processing many tiny expressions. Those results can be converted to fill statements with some simple regex.
— Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/454#issuecomment-1636087391, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCEUCHV4L3KTGQXM6K3DXQFWYJANCNFSM6AAAAAA2KPXPD4. You are receiving this because you are subscribed to this thread.
Hi Vlad,
I usually do a little bit more in Mathematica before creating the Fill statements. I Collect against the integral function names on the RHS of the rules, and apply something like
GCoeffSimplify2
to the coefficients.ep does not end up in the prf, which helps stop the terms becoming too big for FORM (and I will later expand in ep in FORM with a routine which acts on the "denep" denominators). If I am expanding in more symbols than just ep, I arrange that they end up in their own "den..." functions also. Then the prf functions contain only symbols which won't be expanded later.
Since performance on the Mathematica side can be an issue for large tables I split each reduction table into many parts and process each part in parallel.
Hi Josh,
many thanks for your input. At the moment I'm using FeynCalc`s Collect2 for organizing the prefactors and my own routine for loading the tables. The source codes for both can be found in the FeynCalc repo.
However, I noticed that the Mathematica parts of my setup are the one that require most time on the cluster, so I started to think of possibilities to minimize their amount in my code. At some point I would also like to make that code public and since not all universities actually have Mma site licenses, parallelizing Mathematica scripts might not be a viable option for everyone.
But InParallel
indeed looks very interesting, I haven't really thought about that before.
Another way: : Do not construct the fill statements directly, but make an expression with the elements of the table mentioned as arguments of a function f; After that use the FillExpression statement to fill the table.
Dear Jos,
thanks a lot, this indeed sounds like an interesting solution, since somehow I overlooked fillexpression
when browsing through the manual.
I think now I've been given enough food for thought to implement something that works reasonably well, thanks again to Josh and Jos :)
Dear FORM experts,
I apologize if this has already been discussed/asked somewhere else, but I'm just wondering whether there is a straightforward way to apply
polyratfun
tofill
statements that are used to populate atablebase
.My use case is as follows: I do reduction with FIRE and employ a lightweight Mathematica script that converts the content of the reduction tables into
fill
statements. Since the rational coefficients in front of the masters can be quite complicated, I merely expand them (withDistribute
) to make sure that each coefficient can be split into a propernum
anddenom
functions. So no factorization within Mathematica takes place and this task is entirely offloaded to FORM. Here is an example of the output my script producesIn this fashion I can apply
polyratfun
only after having substituted the reduction results into my amplitude. This is obviously not very efficient and I was thinking that it would have been much better to do this in advance.On the other hand, converting each reduction rule into a local variable, applying
polyratfun
and then creating afill
statement out of it looks a bit too contrived to me. So perhaps there is a more natural way to integrate FIRE results into a FORM calculation that I'm not aware of.Cheers, Vlad