# Parallel Computation

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

• We cannot run this code without CoMat. Where exactly did you use ParallelDo? Commented Nov 9, 2018 at 7:56
• @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. Commented Nov 9, 2018 at 8:16
• Did you try to substitute only the outer Do? Commented Nov 9, 2018 at 8:23
• Yes, I did; Both outer Do' separately. Commented Nov 9, 2018 at 8:25
• 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? Commented Nov 9, 2018 at 8:26

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 = DeveloperToPackedArray[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 = {
{CompileGetElement[MAT, 2 i - 1, 2 i - 1], CompileGetElement[MAT, 2 i - 1, 2 i]},
{CompileGetElement[MAT, 2 i, 2 i - 1], CompileGetElement[MAT, 2 i, 2 i]}
};
B = {
{CompileGetElement[MAT, 2 j - 1, 2 j - 1], CompileGetElement[MAT, 2 j - 1, 2 j]},
{CompileGetElement[MAT, 2 j, 2 j - 1], CompileGetElement[MAT, 2 j, 2 j]}
};
F = {
{CompileGetElement[MAT, 2 i - 1, 2 j - 1], CompileGetElement[MAT, 2 i - 1, 2 j]},
{CompileGetElement[MAT, 2 i, 2 j - 1], CompileGetElement[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 = DeveloperToPackedArray[
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