Message Boards Message Boards

Suggestions for speeding up this plot?

GROUPS:

Consider the code:

HairyStarfish[a_, plotpts_, thickness_, imagesize_] := ParametricPlot[{
                               Sum[(2/3)^k Sin[(3/2)^k t], {k, 0, a}],
                               Sum[(-(2/3))^k Cos[(3/2)^k t], {k, 0, a}]
                               }, {t, 0, 2^(a + 1) Pi}, MaxRecursion -> 5, Axes -> False, 
                PlotPoints -> plotpts, PlotStyle -> {Thickness[thickness], Black}, 
                PlotRange -> {{-2.5, 2.5}, {-2.5, 2.5}},  ImageSize -> {imagesize, Automatic}]
                HairyStarfish[11, 15000, 0.00004, 500]

enter image description here

I want to generate this plot at a = 25 for a large art print (interesting features emerge as a gets large). Computation time increases exponentially with each increment of the value a, since PlotPoints must be doubled to keep accuracy. I've been doing it piecewise so far, breaking {t, 0, 2^(a+1) Pi} up into segments, and then combining the plots later with ImageMultiply. I'm wondering if there's an efficient way to render several segments at once with parallelization and/or GPU. Or if anyone has general comments on a smarter way to render this plot.

So far, I've tried:

  • ParallelEvaluate, generating multiple plots at once on parallel kernels. But it is not any faster.
  • Pairing different values of MaxRecursion and PlotPoints. No significant speed increase.
  • Generating only half of the plot, then combing with it's mirror (since it is symmetric). But this only cuts time by a factor of 2.

Does ParametricPlot use the graphics card as wisely as possible? My graphics card is a 980ti with 6gb of vram and 704 cores, so I figure it should be able to speed up the rendering somewhat if I utilize it properly. I just got CUDALink installed... I've been reading about it, but I'm still pretty lost on how i could apply it here, if at all.

I've also considered purchasing a cluster computing package through gridMathematica, since the computation times are so high and it is parallelizable. But I want to make sure I'm attacking the problem as intelligently as possible before I go that route.

POSTED BY: Bryan Lettner
Answer
1 year ago

Your function definition contains errors and, probably, it must be

HairyStarfish[a_, plotpts_, thickness_, imagesize_] := 
 ParametricPlot[{Sum[(2/3)^k Sin[(3/2)^k t], {k, 0, a}], 
   Sum[(-(2/3))^k Cos[(3/2)^k t], {k, 0, a}]}, {t, 0, 2^(a + 1) Pi}, 
  MaxRecursion -> 5, Axes -> False, PlotPoints -> plotpts, 
  PlotStyle -> {Thickness[thickness], Black}, 
  PlotRange -> {{-2.5, 2.5}, {-2.5, 2.5}}, 
  ImageSize -> {imagesize, Automatic}]

Am I right?

POSTED BY: Valeriu Ungureanu
Answer
1 year ago

No Errors. The code just displayed as text instead of code for some reason. Fixed.

POSTED BY: Bryan Lettner
Answer
1 year ago

You may try ListPlot with ParallelTable, after you have estimated a reasonable increment for t that does not make you lose too much detail.

POSTED BY: Gianluca Gorni
Answer
1 year ago

You also get it a bit faster by wrapping the inner bit into an Evaluate:

myHairyStarfish[a_, plotpts_, thickness_, imagesize_] := 
 ParametricPlot[
  Evaluate[{Sum[(2/3)^k Sin[(3/2)^k t], {k, 0, a}], 
    Sum[(-(2/3))^k Cos[(3/2)^k t], {k, 0, a}]}], {t, 0, 2^(a + 1) Pi},
   MaxRecursion -> 5, Axes -> False, PlotPoints -> plotpts, 
  PlotStyle -> {Thickness[thickness], Black}, 
  PlotRange -> {{-2.5, 2.5}, {-2.5, 2.5}}, 
  ImageSize -> {imagesize, Automatic}]

AbsoluteTiming[myHairyStarfish[11, 15000, 0.00004, 500]]

On my computer it goes from 5.75 secs to 2.94 secs.

Cheers,

Marco

POSTED BY: Marco Thiel
Answer
1 year ago

You should consider the following: what takes longer - rendering the figure or computing the points? If computing the points is a significant time waste then consider separating it from plotting function and use Compile with options potential CompilationTarget -> "C" and Parallelization -> True. If this is for a poster, perhaps you do not want to render in front end and then export. Use Export right away and better to a vector format such as SVG or PDF. Not sure if all this is useful, just a train of thoughts.

POSTED BY: Vitaliy Kaurov
Answer
1 year ago

Thank you. Yes, I generally Export directly to TIFF... I omitted for simplicity. Would SVG or PDF offer advantages over TIFF in this particular case? I'm new to the idea of a vector format.

Unfortunately, compilation does not appear to increase the speed. Although, I'm guessing I am doing something wrong, since I have never compiled anything before. Here is a comparison:

myHairyStarfish[a_, plotpts_, thickness_, imagesize_] := 
 ParametricPlot[
  Evaluate[{Sum[(2/3)^k Sin[(3/2)^k t], {k, 0, a}], 
    Sum[(-(2/3))^k Cos[(3/2)^k t], {k, 0, a}]}]
  , {t, 0, 2^(a + 1) Pi}, MaxRecursion -> 5, Axes -> False, 
  PlotPoints -> plotpts, PlotStyle -> {Thickness[thickness], Black}, 
  PlotRange -> {{-2.5, 2.5}, {-2.5, 2.5}}, 
  ImageSize -> {imagesize, Automatic}]

myHairyStarfish[11, 15000, 0.00004, 500]

takes 2.02 seconds.

cf = Compile[{t}, Sum[{(2/3)^k Sin[(3/2)^k t], (-(2/3))^k Cos[(3/2)^k t]}, {k, 0, 11}], 
CompilationTarget -> "C", Parallelization -> True]

ParametricPlot[
 cf[t]
 , {t, 0, 2^(11 + 1) Pi}, MaxRecursion -> 5, Axes -> False, 
 PlotPoints -> 15000, PlotStyle -> {Thickness[0.00004], Black}, 
 PlotRange -> {{-2.5, 2.5}, {-2.5, 2.5}}, 
 ImageSize -> {500, Automatic}]

takes 2.42 seconds.

But cf[t] still seems to be evaluating within ParametricPlot, so that's probably why. Is there a way to take cf[t] from cf[0] to cf[2^(a + 1) Pi] first, then plot it after?

POSTED BY: Bryan Lettner
Answer
1 year ago

Using compilation and machine real numbers may be tricky here. You are going to calculate Sin and Cos of numbers that are of the order of 10^12. Can you trust the results?

POSTED BY: Gianluca Gorni
Answer
1 year ago

Group Abstract Group Abstract