5
$\begingroup$

Here is a piece of my code, in which I have a function that includes sums over the multiplication of ThreeJSymbols. I am using this function in a multiple loops to calculate potentials. Does anybody know of ways to make it way faster?

 ℓ0 = 4;
 γ = 
  Join[Table[{m, 1}, {m, -ℓ0, ℓ0}], 
  Table[{m, -1}, {m, -ℓ0, ℓ0}]]
  nstates = 2*(2 ℓ0 + 1);
  ne = 2 ℓ0 + 2;

  avec = Table[0, {ie, 1, ne}, {i, 1, nstates}];
  Do[avec[[1, i]] = 1;
  avec[[j, nstates - (i - 1)]] = 1, {i, 1, nstates/2}, {j, 2, ne}]

ParallelEvaluate[Off[ClebschGordan::phy];
ClearAll[dfxn]; 
dfxn[ℓ_, m1_, m2_, p1_, p2_] := 
N@If[m1 + p1 == m2 + p2, 
 Sum[(2 ℓ + 1)^2 (2 ℓtemp + 1)/(4 π )
    Sum[If[m1 + p1 == mval && m2 + p2 == mval, 
     ThreeJSymbol[{ℓ, m1}, {ℓ, 
        p1}, {ℓtemp, -mval}] ThreeJSymbol[{ℓ, 
        m2}, {ℓ, 
        p2}, {ℓtemp, -mval}] ThreeJSymbol[{ℓ, 
        0}, {ℓ, 0}, {ℓtemp, 0}]^2, 
     0], {mval, -ℓtemp, ℓtemp}], \
     {ℓtemp, 0, 2 ℓ}], 0];];

    vdir =(*(2 ℓ0 +1)^2*) Chop[ParallelTable[

    mpf = γ[[f, 1]];
    mk = γ[[k, 1]];
    μpf = γ[[f, 2]];
    μk = γ[[k, 2]];
    Total[   
    Table[
    Off[ClebschGordan::phy];
    μpi = γ[[i, 2]];
    μpj = γ[[j, 2]];
    pi = γ[[i, 1]]; 
    pj = γ[[j, 1]];
    If[μpi == μpj && μpf == μk, 
    N[Conjugate[avec[[ie, i]]] *avec[[ie, j]]* 
     dfxn[ ℓ0, pi, mk, mpf, pj]], 0]
   , {ie, 1, ne}, {i, 1, nstates}, {j, 1, nstates} ]
   , Infinity ] 
   , {f, 1, nstates}, {k, 1, nstates}]];
$\endgroup$
  • 2
    $\begingroup$ Your code throws errors because avec is unknown. $\endgroup$ – Henrik Schumacher Feb 24 at 20:47
  • 1
    $\begingroup$ I added avec. Thank you $\endgroup$ – Delaram Nematollahi Feb 24 at 20:56
  • 2
    $\begingroup$ A simple change gets this done in ~5 seconds on my laptop. Is that quick enough? $\endgroup$ – ciao Feb 24 at 21:40
6
$\begingroup$

I'll go ahead and post this quick speed improvement pending your reply to my question.

Replace references to ThreeJSymbol in your code with j3s, and add

ClearAll[j3s];
j3s[a_, b_, c_] := j3s[a, b, c] = ThreeJSymbol[a, b, c];

to the top of your code.

This will redefine j3s for known values as they are computed (a kind of memoization), and results in a better than order of magnitude speed increase for execution.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you Ciao, This helps but since I am looking for large ne and it's a part of a larger loop, it still take a long time and I am wondering if It can still get improved. (sorry I was in the class, couldn't reply quickly) $\endgroup$ – Delaram Nematollahi Feb 24 at 23:20
  • 1
    $\begingroup$ @DelaramNematollahi - how large? $\endgroup$ – ciao Feb 24 at 23:48
  • $\begingroup$ I have two potential functions calling the dfxn in each iteration, and I need to run it for ne>=16 in a two outer loops ( 20 iteration for the larger loop and each loop 5 inner iteration means total 100 iteration at least ) $\endgroup$ – Delaram Nematollahi Feb 24 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.