3
$\begingroup$

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}
$\endgroup$

2 Answers 2

8
$\begingroup$

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[2500] // 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[2500] // Re // RepeatedTiming
(*    {0.0000615271, 0.0125525}    *)

evaluates in 60 microseconds.

$\endgroup$
2
  • $\begingroup$ would it possible to make it faster? $\endgroup$
    – Q. Wang
    Feb 23, 2021 at 13:31
  • $\begingroup$ Yes, if approximations are allowed. See update. $\endgroup$
    – Roman
    Feb 23, 2021 at 15:39
6
$\begingroup$

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"]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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