2
$\begingroup$

How can I rewrite this more efficiently taking advantage of flo, dem, and Nsup being Listable and utilize parallel computation?

MapThread[flo[#1, #2, #3] &, {Most /@ kr, Rest /@ Rk, Most /@ qsum}, 2] 

kr = Table[RandomReal[50], {10}, {5}];
Rk = Table[RandomReal[150],{10}, {5}];
qsum = Table[RandomReal[6000], {10}, {5}];

flo = 
  Compile[{{p1, _Real, 0}, {p2, _Real, 0}, {p3, _Real, 0}}, 
    Min[dem[p1], Nsup[p2, p3]], 
    Parallelization -> True, 
    RuntimeAttributes -> {Listable}, 
    CompilationOptions -> {"InlineExternalDefinitions" -> True}];

dem = 
  Compile[{{p1, _Real, 0}}, 
    Min[100 p1, 2500],
    Parallelization -> True, 
    RuntimeAttributes -> {Listable}];

Nsup = 
  Compile[{{p1, _Real, 0}, {p2, _Real, 0}}, 
    Min[(150 - p1) 100 - p2, 2500], 
    Parallelization -> True, 
    RuntimeAttributes -> {Listable}];

I am thinking it to be of the form (currently does not work)

flo1[kr, Rk, qsum];

floR1 = 
  Compile[{{p1, _Real, 0}, {p2, _Real, 0}, {p3, _Real, 0}}, 
    MapThread[Min[demR[#1], NsupR[#2, #3]] &, {Most /@ p1, Rest /@ p2, Most /@ p3}, 2], 
    Parallelization -> True, 
    RuntimeAttributes -> {Listable}, 
    CompilationOptions -> {"InlineCompiledFunctions" -> True}];

or something that avoids MapThread altogether, because I suspect MapThread does serial computation.

$\endgroup$
6
$\begingroup$

It is actually pretty simple. Just make the outmost function, i.e. flo in your case Listable, which you have already done in your first code snippet:

dem = Compile[{{p1, _Real, 0}}, Min[100 p1, 2500]];
Nsup = Compile[{{p1, _Real, 0}, {p2, _Real, 0}}, Min[(150 - p1) 100 - p2, 2500]];
flo = Compile[{{p1, _Real, 0}, {p2, _Real, 0}, {p3, _Real, 0}}, 
   Min[dem[p1], Nsup[p2, p3]], Parallelization -> True, 
   RuntimeAttributes -> {Listable}, 
   CompilationOptions -> {"InlineExternalDefinitions" -> True}];

Note that I left out the Options for dem and Nsup, because they are not needed (though setting Parallelization -> True, RuntimeAttributes -> {Listable} does not do any harm either).

The only thing you need to do then is call

flo[Most /@ kr, Rest /@ Rk, Most /@ qsum]

because Mathematica does the threading automatically for Listable functions.

BTW: You could of course use Thread first to combine your lists kr, Rk and qsum on the second level and apply a Listable function afterwards, but as stated above mathematica does that automatically, which saves you the time of calling Thread.

$\endgroup$
1
  • $\begingroup$ I was so close. Thanks for your suggestion. I am going to wait for the customary 48 hrs before accepting it as the answer. $\endgroup$
    – brama
    Jul 2 '14 at 6:03
2
$\begingroup$

I have experienced that MapThread[f, data] unpacks arrays.

Not sure if this is the case generally or just the way I use it. I always try to use Map[f, Transpose[data], {level}] to make sure arrays stay packed.

Much faster in general and especially when compiling!

$\endgroup$
3
  • 1
    $\begingroup$ Good advice, I am pretty sure you are right on that one. $\endgroup$
    – Wizard
    Jul 3 '14 at 8:40
  • $\begingroup$ +1 for agreeing with me ;) I also noticed you asked a question on this [link] (mathematica.stackexchange.com/questions/33610/…). Could this be applicable there as well? $\endgroup$
    – Sander
    Jul 3 '14 at 9:24
  • $\begingroup$ @Sander Did not know that. +1 for your suggestion. $\endgroup$
    – brama
    Jul 6 '14 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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