1
$\begingroup$

How can I modify this code in order to run in parallel? (It's some part of my main code)

LogNeg = {};
Do[LNeg = 0;
Do[Do[
  A = {{CoMat[[2*i - 1, 2*i - 1]], 
    CoMat[[2*i - 1, 2*i]]}, {CoMat[[2*i, 2*i - 1]], 
    CoMat[[2*i, 2*i]]}};

  B = {{CoMat[[2*j - 1, 2*j - 1]], 
    CoMat[[2*j - 1, 2*j]]}, {CoMat[[2*j, 2*j - 1]], 
    CoMat[[2*j, 2*j]]}};

  F = {{CoMat[[2*i - 1, 2*j - 1]], 
    CoMat[[2*i - 1, 2*j]]}, {CoMat[[2*i, 2*j - 1]], 
    CoMat[[2*i, 2*j]]}};

  S = ArrayFlatten[{{A, F}, {Transpose[F], B}}];

  v = eta /. 
   Solve[eta^4 - (Det[A] + Det[B] - 2*Det[F])*eta^2 + Det[S] == 0];

  LNeg += -Log2[Min[Abs[v], 1]], {j, i + 1, M}], {i, 1, M}];

  AppendTo[LogNeg, LNeg], {t, 0, tMax}];

I've used ParallelDo[], but It doesn't work. Main code: https://ufile.io/cmjj6

Thank you in advance

$\endgroup$
  • 1
    $\begingroup$ We cannot run this code without CoMat. Where exactly did you use ParallelDo? $\endgroup$ – J42161217 Nov 9 '18 at 7:56
  • $\begingroup$ @J42161217 CoMat is a 2M*2M square matrix of interpolating Functions. It's made by solving ODEs. The code is a big one, anyway, It's what I embedded above. $\endgroup$ – Ghaem Nov 9 '18 at 8:16
  • $\begingroup$ Did you try to substitute only the outer Do? $\endgroup$ – J42161217 Nov 9 '18 at 8:23
  • $\begingroup$ Yes, I did; Both outer Do' separately. $\endgroup$ – Ghaem Nov 9 '18 at 8:25
  • 1
    $\begingroup$ What exactly do you mean by "it doesn't work"? Could you add the exact code you tried and the error it produced to the question? $\endgroup$ – Lukas Lang Nov 9 '18 at 8:26
1
$\begingroup$

Still not parallelized, but tremendously faster. Most important are:

  • The matrix CoMat is evaluated only once for each t. Inparticular, CoMat2[t] is explicitly defined as a function t to gai control over evaluation; and it returns the matrix CoMat already nicely partitioned for easy access.
  • The function sol which solves the symbolic equation once and the time of definition.

This makes the execution ten times faster.

CoMat2[t_] = Partition[
   First[Cov[t] /. 
     NDSolve[{Join[DiffEq, InitialCond]}, Cov[t], {t, 0, tMax}]],
   {2, 2}, {2, 2}];
sol[p_, q_] = N[η /. Solve[η^4 - p η^2 + q == 0, η]];
result = Table[
     Mat = Developer`ToPackedArray[CoMat2[t]];
     Block[{A, detA, B, F, S},
      Sum[
       A = Mat[[i, i]];
       detA = Det[A];
       Sum[
        B = Mat[[j, j]];
        F = Mat[[i, j]];
        S = ArrayFlatten[{{A, F}, {Transpose[F], B}}];
        -Log2[Min[Abs[sol[(detA + Det[B] - 2*Det[F]), Det[S]]], 1]],
        {j, i + 1, M}],
       {i, 1, M}]
      ],
     {t, 0., tMax}]; // AbsoluteTiming // First

0.327722

Edit

I cannot speed up the InterpolatingFunctions, but the rest can be made much faster (and parallelized) with Compile:

Block[{MAT, i, j, A, B, F, S, vcode},
  A = {
    {Compile`GetElement[MAT, 2 i - 1, 2 i - 1], Compile`GetElement[MAT, 2 i - 1, 2 i]},
    {Compile`GetElement[MAT, 2 i, 2 i - 1], Compile`GetElement[MAT, 2 i, 2 i]}
    };
  B = {
    {Compile`GetElement[MAT, 2 j - 1, 2 j - 1], Compile`GetElement[MAT, 2 j - 1, 2 j]},
    {Compile`GetElement[MAT, 2 j, 2 j - 1], Compile`GetElement[MAT, 2 j, 2 j]}
    };
  F = {
    {Compile`GetElement[MAT, 2 i - 1, 2 j - 1], Compile`GetElement[MAT, 2 i - 1, 2 j]},
    {Compile`GetElement[MAT, 2 i, 2 j - 1], Compile`GetElement[MAT, 2 i, 2 j]}
    };
  S = ArrayFlatten[{{A, F}, {Transpose[F], B}}];
  vcode = sol[(Det[A] + Det[B] - 2*Det[F]), Det[S]];

  cf = With[{code = vcode},
    Compile[{{MAT, _Real, 2}, {M, _Integer}},
     Block[{LNeg = 0.},
      Do[Do[
        LNeg -= Log2[Min[Abs[code], 1.]],
        {j, i + 1, M}], {i, 1, M}];
      LNeg
      ],
     CompilationTarget -> "C",
     RuntimeAttributes -> {Listable},
     Parallelization -> True,
     RuntimeOptions -> "Speed"
     ]
    ]
  ];

Now the computations:

CoMat[t_] = 
  First[Cov[t] /. 
    NDSolve[{Join[DiffEq, InitialCond]}, Cov[t], {t, 0, tMax}]];
Mat = Developer`ToPackedArray[
    Table[CoMat[t], {t, 0., tMax}]]; // AbsoluteTiming
result2 = cf[Mat, M]; // AbsoluteTiming // First
Max[Abs[result - result2]]

0.123596

0.000423

6.24386*10^-11

$\endgroup$

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.