# Using compile to speed up evaluation of a While loop

I want to calculate a loop. For speed, I compiled my code. Even after the compilation, it is still very slow in getting the results.

Are there any further improvements that can be made to my code?

Needs["CCompilerDriver"]
c =
Compile[{{x0, _Integer}},
With[{x = x0},
pover = 0.0; t = 1.0;
While[t <= x - 1,
pover =
pover +
Total[
Table[
1.0/Sqrt[a^2 + t^2 + (100000.0 - 0.7)^2] -
1.0/Sqrt[a^2 + t^2 + (100000.0 + 0.7)^2],
{a, t + 1, 40000.0,1}]];
t++];
pover],
CompilationTarget -> "C",
Parallelization -> True,
RuntimeOptions -> "Speed"]

Timing[c[2500.0]]


The result is

{126.42, 0.0125525}


Runs in a quarter-second by reformulating as a single two-index sum:

c = Compile[{{x, _Integer}},
Sum[1/Sqrt[a^2 + t^2 + (100000 - 0.7)^2] -
1/Sqrt[a^2 + t^2 + (100000 + 0.7)^2],
{t, 1, x - 1}, {a, t + 1, 40000}],
CompilationTarget -> "C", Parallelization -> True, RuntimeOptions -> "Speed"];

c // AbsoluteTiming
(*    {0.262834, 0.0125525}    *)


If an approximation is enough for you, then we can replace the sum by an integral:

F[q_, y_, x_] =
Assuming[q > 0 && 1 <= x < y,
Integrate[1/Sqrt[a^2 + t^2 + q],
{t, 1 - 1/2, x - 1 + 1/2},
{a, t + 1 - 1/2, y + 1/2}]];

c[x_] = F[(100000 - 0.7)^2, 40000, x] - F[(100000 + 0.7)^2, 40000, x];

c // Re // RepeatedTiming
(*    {0.0000615271, 0.0125525}    *)


evaluates in 60 microseconds.

• would it possible to make it faster? – Qiankun Wang Feb 23 at 13:31
• Yes, if approximations are allowed. See update. – Roman Feb 23 at 15:39

This runs in about a second:

Needs["CCompilerDriver"]
c = Compile[{{x, _Integer}}, Block[{pover,t}, pover = 0.0; t = 1.0;
While[t <= x - 1,
pover = pover +
Total[Table[
1.0/Sqrt[a^2 + t^2 + (100000.0 - 0.7)^2] -
1.0/Sqrt[a^2 + t^2 + (100000.0 + 0.7)^2],
{a, t + 1, 40000.0,
1}]]; t++];
pover], CompilationTarget -> "C", Parallelization -> True,
RuntimeOptions -> "Speed"]
`