Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to minimize the computation time of problem which is too long to post. I use compilein order to gain some speed. To increase speed I would like to use the options Parallelization -> Trueand RuntimeAttributes -> {Listable} among others. The problem is now that some built-in functions I use, such as Map, do not have the attribute Listable. Thus, it seems that my code produces an error once the input is e.g. a list instead of a real number. To gain some insights I post some toy-code.

toy=Compile[{{h1,_Real},{list,_Real,1}},
leg=Length[list];
Map[Total[{list[[#]]}]/h1&, Range[leg]],
 CompilationTarget->"C",
 Parallelization->True,
 RuntimeAttributes->{Listable},
 RuntimeOptions -> "Speed"];

What this code does is it divides each element of list by h1. Please notice that this code does not have any meaning but to show the problem of using a non-listable function within a compile function. Now, let h1 be some real and list be some random list. Then,

 h1=0.1; list=RandomReal[{-1., 1.}, 100]; toy[h1, list]

works just fine. However, if one sets

h1={0.1,0.2}; toy[h1, list] 

results in an error.

My question is whether one of you knows a simple way to make this compiled function listable.

One may use e.g. a Do-loop to get the result, but this is too slow. Thanks in advance I really appreciate it.

share|improve this question
add comment

2 Answers

After some debugging I found an answer to my question which I would like to share. I seems very basic and has to do with ragged lists that I created. These lists look e.g. like {{0,1},{1,2,3}}. Compileis not able to handle these lists. I tried to avoid this using Flattenbut this does not work. Why did I create ragged lists in the first place? To save time. I was aware that I could achieve the same results using a loop and AppendTo`, however, this function is very slow.

I found this very nice thread Internal`Bag inside Compile. It is basically an alternative to AppendTo but much much faster. Now, Compileseems more intuitive then before.

share|improve this answer
add comment

I hope your toy function is really just a toy-function because neither the Map nor the pure function is required to calculate what you want.

The problem with your code is that you did not localize leg! If you do so, the code runs fine.

toy = Compile[{{h1, _Real}, {list, _Real, 1}},
   Module[{leg = Length[list]},
    Map[Total[{list[[#]]}]/h1 &, Range[leg]]
    ]
   , CompilationTarget -> "C", Parallelization -> True, 
   RuntimeAttributes -> {Listable}, RuntimeOptions -> "Speed"];

If you don't localize all variables, Mathematica assumes you mean the global symbol led and calls the kernel from within the compiled function to evaluate it. You should therefore always check your compiled code with

<< CompiledFunctionTools`
CompilePrint[toy]

and ensure, that there are no (unwanted) MainEvaluate[..] calls in it.

share|improve this answer
1  
There is a led blinking in the text where someone's leg should be. –  István Zachar Feb 11 '13 at 10:58
    
@halirutan: Thanks for your help. Usually, I do indeed localize all variables but for some reason I get an error once I localize the relevant variable in the "non-toy" code. The error reads: "nontensor object generated". I don't know why this error occurs. –  chris Feb 11 '13 at 15:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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