MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: functions: compiled vs. uncompiled version

  • To: mathgroup at smc.vnet.net
  • Subject: [mg94114] Re: [mg94089] functions: compiled vs. uncompiled version
  • From: Daniel Lichtblau <danl at wolfram.com>
  • Date: Fri, 5 Dec 2008 05:30:55 -0500 (EST)
  • References: <200812041217.HAA27808@smc.vnet.net>

Diego Guadagnoli wrote:
> Hi All,
> 
> I am performing mathematica calculations involving
> many nested sums of the kind
> FUN = Sum[term[i,j,k], {i,6},{j,6},{k,2} ] or similar,
> where term[__] returns a complex number.
> 
> Since I have many those sums, Timing is really long.
> Therefore I thought to implement both term[__] and FUN
> as compiled functions. I noticed however than in both 
> cases Timing is not improved, actually it is worse in the 
> compiled version.
> 
> An example of the code is reported below as plain text.
> There are a "Needed input" and a "Functions" part. In "Functions", 
> an example of term[__] is provided by the VUUS function, which is 
> implemented in uncompiled (VUUS[i_, j_, k_]) and compiled form (VUUSc).
> This function is then called in the repeated sum "fun" (uncompiled) or 
> respectively "func" (compiled).
> 
> As you can see, the Timing in func is actually worse than in fun.
> 
> Any suggestion for improving my code without translating it in FORTRAN 
> would be very appreciated.
> 
> Cheers,
> D
> 
> 
> %%%%%Please copy the content below to a mathematica notebook
> 
> (*NEEDED INPUT*)
> 
> BR[i_] := v[1] ZR[[1, i]] - v[2] ZR[[2, i]];
> 
> {g1, sW, v[1], v[2], yuRos[1], yuRos[2], yuRos[3]} = 
>   Table[Random[], {i, 7}];
> 
> AuRos = Table[RandomComplex[], {i, 3}, {j, 3}];
> 
> ZR = Table[Random[], {i, 2}, {j, 2}];
> 
> ZU = Table[RandomComplex[], {i, 6}, {j, 6}];
> 
> \[Mu]Ros = 300;
> 
> 
> 
> (*FUNCTIONS*)
> 
> VUUS[i_, j_, 
>    k_] := -(g1^2/3)*BR[k] (KroneckerDelta[i, j] + (3 - 8 sW^2)/(4 sW^2) 
>        Sum[Conjugate[ZU[[I, i]]] ZU[[I, j]], {I, 1, 3}]) - 
>    Sum[v[2] (yuRos[I])^2 
>      ZR[[2, k]] (Conjugate[ZU[[I, i]]] ZU[[I, j]] + 
>        Conjugate[ZU[[I + 3, i]]] ZU[[I + 3, j]]), {I, 1, 3}] + 
>    Sum[1/Sqrt[2] 
>      ZR[[2, k]] (Conjugate[AuRos[[I, J]]] Conjugate[ZU[[I, i]]] 
>         ZU[[J + 3, j]] + 
>        AuRos[[I, J]] ZU[[I, j]] Conjugate[ZU[[J + 3, i]]]), {I, 1, 
>      3}, {J, 1, 3}] + 
>    Sum[1/Sqrt[2] yuRos[I] 
>      ZR[[1, k]] (Conjugate[\[Mu]Ros] ZU[[I, j]] 
>         Conjugate[ZU[[I + 3, i]]] + \[Mu]Ros Conjugate[ZU[[I, i]]] 
>         ZU[[I + 3, j]]), {I, 1, 3}];
> 
> VUUSc = Compile[{{i, _Integer}, {j, _Integer}, {k, _Integer}},
>    sum1 = 0. + 0. I; 
>    Do[sum1 = sum1 + Conjugate[ZU[[ii, i]]] ZU[[ii, j]], {ii, 1, 3}];
>    sum2 = 0. + 0. I; 
>    Do[sum2 = 
>      sum2 + v[2] (yuRos[ii])^2 
>        ZR[[2, k]] (Conjugate[ZU[[ii, i]]] ZU[[ii, j]] + 
>          Conjugate[ZU[[ii + 3, i]]] ZU[[ii + 3, j]]), {ii, 1, 3}];
>    sum3 = 0. + 0. I; 
>    Do[sum3 = 
>      sum3 + 1/Sqrt[2] 
>        ZR[[2, k]] (Conjugate[AuRos[[ii, J]]] Conjugate[ZU[[ii, i]]] 
>           ZU[[J + 3, j]] + 
>          AuRos[[ii, J]] ZU[[ii, j]] Conjugate[ZU[[J + 3, i]]]), {ii, 
>      1, 3}, {J, 1, 3}];
>    sum4 = 0. + 0. I; 
>    Do[sum4 = 
>      sum4 + 1/Sqrt[2] yuRos[ii] 
>        ZR[[1, k]] (Conjugate[\[Mu]Ros] ZU[[ii, j]] 
>           Conjugate[ZU[[ii + 3, i]]] + \[Mu]Ros Conjugate[
>            ZU[[ii, i]]] ZU[[ii + 3, j]]), {ii, 1, 3}];
>    -(g1^2/3) 
>      BR[k] (KroneckerDelta[i, j] + (3 - 8 sW^2)/(4 sW^2) sum1) - 
>     sum2 + sum3 + sum4,
>    {{BR[_], _Real}, {ZU, _Complex, 
>      6}, {v[_], _Real}, {yuRos[_], _Real}, {ZR, _Real, 
>      2}, {AuRos, _Complex, 3}, {\[Mu]Ros, _Complex}}];
> 
> fun = Compile[{{k, _Integer}},
>    sum1 = 0. + 0. I; 
>    Do[sum1 = sum1 + VUUS[l, m, k], {l, 1, 6}, {m, 1, 6}];
>    -sum1, {{VUUS[__], _Complex}}
>    ];
> 
> func = Compile[{{k, _Integer}},
>    sum1 = 0. + 0. I; 
>    Do[sum1 = sum1 + VUUSc[l, m, k], {l, 1, 6}, {m, 1, 6}];
>    -sum1, {{VUUS[__], _Complex}}
>    ];
> 
> VUUS[1, 1, 1] // Timing
> 
> VUUSc[1, 1, 1] // Timing
> 
> fun[1] // Timing
> 
> func[1] // Timing

Making this fast is indeed a bit tricky. First thing to realize is if 
VUUSc[[4]] shows function evaluations, you'll have trouble.

I changed slightly your definitions so that I could use vectors rather 
than indexed symbols (things like vvec[[j]] rather than v[j]). I'm not 
sure this was really necessary. Anyway, here is what I use.

BR[i_] := v[1] ZR[[1, i]] - v[2] ZR[[2, i]];
{g1, sW, v[1], v[2], yuRos[1], yuRos[2], yuRos[3]} =
   Table[Random[], {i, 7}];
yuRosvec = {yuRos[1], yuRos[2], yuRos[3]};
vvec = {v[1], v[2]};
AuRos = Table[RandomComplex[], {i, 3}, {j, 3}];
ZR = Table[Random[], {i, 2}, {j, 2}];
ZU = Table[RandomComplex[], {i, 6}, {j, 6}];
\[Mu]Ros = 300;

In order to get a good compiled version, we now insert that actual 
arrays into the Compile. This can be done using With, as below.

VUUSc = With[{ZU = ZU, ZR = ZR, yuRosvec = yuRosvec, AuRos = AuRos,
     g1 = g1, sW = sW, vvec = vvec, \[Mu]Ros = \[Mu]Ros},
    Compile[{{i, _Integer}, {j, _Integer}, {k, _Integer}},
     Module[{sum1, sum2, sum3, sum4},
      sum1 = 0. + 0. I;
      Do[sum1 = sum1 + Conjugate[ZU[[ii, i]]] ZU[[ii, j]], {ii, 1,
        3}];
      sum2 = 0. + 0. I;
      Do[sum2 =
        sum2 + Evaluate[
           vvec[[2]]] (yuRosvec[[ii]])^2 ZR[[2,
            k]] (Conjugate[ZU[[ii, i]]] ZU[[ii, j]] +
            Conjugate[ZU[[ii + 3, i]]] ZU[[ii + 3, j]]), {ii, 1, 3}];
      sum3 = 0. + 0. I;
      Do[sum3 =
        sum3 + 1/
           Sqrt[2] ZR[[2,
            k]] (Conjugate[AuRos[[ii, J]]] Conjugate[
              ZU[[ii, i]]] ZU[[J + 3, j]] +
            AuRos[[ii, J]] ZU[[ii, j]] Conjugate[ZU[[J + 3, i]]]), {ii,
         1, 3}, {J, 1, 3}];
      sum4 = 0. + 0. I;
      Do[sum4 =
        sum4 + 1/
           Sqrt[2] yuRosvec[[ii]] ZR[[1,
            k]] (Conjugate[\[Mu]Ros] ZU[[ii, j]] Conjugate[
              ZU[[ii + 3, i]]] + \[Mu]Ros Conjugate[
              ZU[[ii, i]]] ZU[[ii + 3, j]]), {ii, 1, 3}];
      -(g1^2/3) Evaluate[
         BR[k] ] (If[i == j, 1, 0] + (3 - 8 sW^2)/(4 sW^2) sum1) -
       sum2 + sum3 + sum4], {{BR[_], _Real}}]];

Finally we fix func so that it declares VUUSc rather than VUUS as it's 
complex evaluated function (took me quite a while to see this was one of 
the problems).

func = Compile[{{k, _Integer}},
    -Total[
      Flatten[Table[
        VUUSc[l, m, k], {l, 1, 6}, {m, 1,
         6}]]], {{VUUSc[__], _Complex}}];

Now compare results in speed.

In[223]:= fun[1] // Timing
Out[223]= {0.013998, -4438.04 + 2.13163*10^-14 I}

In[224]:= func[1] // Timing
Out[224]= {0.002, -4438.04 + 2.13163*10^-14 I}

In[229]:= Do[fun[1], {100}] // Timing
Out[229]= {1.10383, Null}

In[230]:= Do[func[1], {100}] // Timing
Out[230]= {0.155976, Null}


Daniel Lichtblau
Wolfram Research


  • Prev by Date: Re: functions: compiled vs. uncompiled version
  • Next by Date: RE: Rearranging expressions in a user-defined form
  • Previous by thread: functions: compiled vs. uncompiled version
  • Next by thread: Re: functions: compiled vs. uncompiled version