Re: Wick like theorem and "symbolic" compilation
- To: mathgroup at smc.vnet.net
- Subject: [mg61099] Re: Wick like theorem and "symbolic" compilation
- From: Peter Pein <petsie at dordos.net>
- Date: Mon, 10 Oct 2005 02:39:59 -0400 (EDT)
- References: <diaaps$ic7$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Alexander schrieb: > Dear MathGroup! > > I wrote simple programm to perform "Wick" expanding. > Here is the code: > > (*St1 - basic function to extract couples of fields from a given list*) > > st1[x_] := If[Length[ > x] === 2, Wick[Sequence @@ x], Plus @@ > ReplaceList[List @@ (x), {e___, a_, c___, > b_, d___} -> Wick[a, b] e c d]]; > > (* Some transformation rules for this function *) > > st1[x_Wick y_] := x st1[y]; > st1[a_ + b_] := st1[a] + st1[b]; > > (* Formatting rules *) > > \!\(\(Format[Wick[x_, y_]] := \(x\ y\)\&^;\)\) > > (* Final function *) > > WickTheorem[x_] := Expand[Plus @@ FixedPointList[st1, x]] //. a_ + > b_Integer c_ -> a + c; > > Simple example, showing how it works: > > In[6]:= WickTheorem[a b c d] > > Out[6]:= \!\(\*FormBox[ > RowBox[{\(a\ b\ c\ d\), "+", > RowBox[{"c", " ", > FormBox[\(\(a\ b\)\&^\), > "TraditionalForm"], " ", "d"}], "+", > RowBox[{"b", " ", > FormBox[\(\(a\ c\)\&^\), > "TraditionalForm"], " ", "d"}], "+", > RowBox[{"a", " ", > FormBox[\(\(b\ c\)\&^\), > "TraditionalForm"], " ", "d"}], "+", > RowBox[{"b", " ", "c", " ", > FormBox[\(\(a\ d\)\&^\), > "TraditionalForm"]}], "+", > RowBox[{ > FormBox[\(\(a\ d\)\&^\), > "TraditionalForm"], " ", > FormBox[\(\(b\ c\)\&^\), > "TraditionalForm"]}], "+", > RowBox[{"a", " ", "c", " ", > FormBox[\(\(b\ d\)\&^\), > "TraditionalForm"]}], "+", > RowBox[{ > FormBox[\(\(a\ c\)\&^\), > "TraditionalForm"], " ", > FormBox[\(\(b\ d\)\&^\), > "TraditionalForm"]}], "+", > RowBox[{"a", " ", "b", " ", > FormBox[\(\(c\ d\)\&^\), > "TraditionalForm"]}], "+", > RowBox[{ > FormBox[\(\(a\ b\)\&^\), > "TraditionalForm"], " ", > FormBox[\(\(c\ d\)\&^\), > "TraditionalForm"]}]}], TraditionalForm]\) > > Maybe there is more simple and elegant realization of this theorem than > my code ??? > > Second question is about optimization. > > In current realization, on my Cleleron 1700 (with 128Mb of ram) using > Mathematica 5.1 for Windows, I have following timings: > > In[7]:= WickTheorem[a b c d e f w t] // Timing // Print["Time = ", #[[ > 1]], ", Length = ", Length[#[[2]]]] & > Out[7]:= Time = 10.688 Second, Length = 764 > > So, in final expression there was 764 terms and it takes ~10 seconds to > evaluate them. Input expression contains only 8 fields, with 9 fields > computation takes a relatively long time,about 600 seconds. > > Why so long? > And what are the ways to reduce this time ? > > I have tried to use CompileEvaluate from Experimental package, but this > doesn't reduce evaluation time greatly. > > Resuming, second question sounds like: > Should I rewrite the program in more elegant and efficient way to > reduce > evaluation time or there is "symbolic" compilation technique to do > that? > > Thanks for your help! > > Alexander. > Hi Alexander, there's only one rule necessary, because Wick[x,y] is not a symbol. Off[General::spell1]; wickrule={c___,a_Symbol,d___, b_Symbol ,e___}->{ c, d ,e,Wick[a,b]}; WickTheorem[p_Times]:= (Plus@@Times@@@Union@@ NestWhileList[Flatten[(ReplaceList[#,wickrule]&)/@#,1]&, {List@@p},{}=!=#&] )/._Integer->1 Format[Wick[x_,y_]] := OverHat[x*y]; In[5]:= WickTheorem[a*b*c*d] Out[5]= a*b*c*d + c*d*a^b + b*d*a^c + b*c*a^d + a*d*b^c + a^d*b^c + a*c*b^d + a^c*b^d + a*b*c^d + a^b*c^d On an Athlon64 3000+ at 2130 MHz under Win2k with Mathematica 5.1 and 512MB RAM, I get the following timings: In[6]:= (Timing[Length[ WickTheorem[Times @@ ToExpression["a"<>ToString[#]]&/@ Range[#]]]]&) /@ Range[10] Out[6]= {{0.*Second, 1}, {0.*Second, 2}, {0.*Second, 4}, {0.*Second, 10}, {0.*Second, 26}, {0.*Second, 76}, {0.016*Second, 232}, {0.125*Second, 764}, {0.937*Second, 2620}, {8.469*Second, 9496}} I tried a rule that transforms products (a_Symbol b_Symbol c_./;OrderedQ[a,b]->Wick[a,b] c), but it has not been as fast as this one. If you are just interested in the number of the resulting terms, Sum[(2k)!/(k! 2^k) * Binomial[n,2k],{k,0,n/2}] will give the answer almost intantly (see http://www.research.att.com/cgi-bin/access.cgi/as/njas/sequences/eisA.cgi?Anum=A000085). Peter