2
x[t_] = Sin[t] + Cos[t];
y[t_] = Sin[t] + Sin[2 t];
i = 
  NIntegrate[Sqrt[(x'[t])^2 + (y'[t])^2], {t, 0, 1}, 
    AccuracyGoal -> 8, MaxPoints -> 10000, MaxRecursion -> 100];
XS = 
  Quiet[
    Timing[
      ParallelTable[
        FindRoot[
          NIntegrate[Sqrt[(x'[t])^2 + (y'[t])^2], {t, 0, X}, 
            AccuracyGoal -> 8, MaxPoints -> 10000, MaxRecursion -> 100] == i/k, 
          {X, 0}], 
        {k, 100, 1, -1}]]]

Even though I put Quiet after ParallelTable, it doesn't supress kernel warnings, which are present in large amounts. If I replace ParallelTable with Table, the code works, though. How can I get the same behavior from ParallelTable?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Vsevolod A.
  • 959
  • 5
  • 15
  • This isn't exactly what you were asking for, but: why not use NDSolve[] to evaluate your arclength function? NDSolveValue[{s'[t] == Sqrt[x'[t]^2 + y'[t]^2], s[0] == 0}, s, {t, 0, 1}] – J. M.'s missing motivation Mar 07 '18 at 12:06
  • @J.M. because I need not arclength but points where arclength is fixed, i.e. 1/10, 2/10 and so on. – Vsevolod A. Mar 07 '18 at 12:12
  • 1
    Not too hard. Using the same definitions above: arclen = NDSolveValue[{s'[t] == Sqrt[x'[t]^2 + y'[t]^2], s[0] == 0}, s, {t, 0, 1}]; i = arclen[1]; Table[FindRoot[arclen[X] == i/k, {X, 0}], {k, 100, 1, -1}]. Have you seen this, BTW? – J. M.'s missing motivation Mar 07 '18 at 12:21
  • @J.M. this works well, however my concern is precision, which I can control directly when using NIntegrate. NDSolve inevitably using integration procedure, so I would avoid nesting one entity into another for no particular reason. – Vsevolod A. Mar 07 '18 at 13:24

1 Answers1

3

There seems to indeed be a problem with Quiet and messages issued on the parallel kernels: it simply doesn't suppress them which might be a consequence of the special mechanisms necessary to forward those messages from the parallel kernels to the master in the first place.

A workaround would be to use Off[NIntegrate::nlim] on the parallel kernels (and probably switch it On after the computations are finished, of course).

Even better is to avoid the messages in the first place, which would in your example be as easy as:

lhs[X_?NumericQ] := NIntegrate[
  Sqrt[(x'[t])^2 + (y'[t])^2], {t, 0, X},
  AccuracyGoal -> 8, MaxPoints -> 10000, MaxRecursion -> 100
]

XS = AbsoluteTiming[
  ParallelTable[FindRoot[lhs[X] == i/k, {X, 0}], {k, 10, 1, -1}]]

the trick (which is well known and described in further detail in other answers) is to avoid evaluation of the NIntegrate unless the argument is indeed a number. To compare runtimes for a parallel program to the sequential versions you would rather use AbsoluteTiming as Timing will only measure the cpu time on the master, which typically is nearly nothing...

Albert Retey
  • 23,585
  • 60
  • 104
  • Thanks. Does TimeUsed[] calculate this properly? – Vsevolod A. Mar 07 '18 at 16:00
  • honestly, I don't know. That function is relatively new and has not made it into my consciousness and I have no experience with it. From the documentation I would guess it does not (as external processes are not covered), but that is as often not entirely clear. I would go ahead and just try with examples. If you want to get collected CPU times I think you would have to run it on every kernel and collect+sum the result... – Albert Retey Mar 07 '18 at 18:33