MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Compile function and AppendTo for lists (vrs. 8.0.4)

On Tue, 24 Jan 2012 10:07:28 -0000, kris < at> wrote:

> Hi
> I have some trouble with my code and would like ask for your help. In
> general it is about appending data in form of a list to an existing
> list in a compiled function. As far as I understand Mathematica is not
> supporting what I am asking for. In order to understand the problem in
> more detail I present some "toy" code below.
> test=Compile[{{k,_Integer}},
> Module[{mat={}},
> For[i=1,i<=k,i++,
> AppendTo[mat,{1,i}];
> ];
> mat
> ]
> ];
> test[2]
> (*which produces an error*)
> Appending data in form of numbers for example works just fine but not
> with lists. Can anybody explain why Mathematica does not support
> appending lists to lists for compiled function? As an alternative I
> tried Reap and Sow, which also produces an error.

Mathematica does support what you're trying to do, but you've run into  
what I would consider a weak point of the compiler: it's difficult to  
specify variables of tensor types without using tricks. The following  

test = Compile[{{k, _Integer, 0}},
  Module[{mat = {{0, 0}}, i = 0},
   For[i = 1, i <= k, i++, AppendTo[mat, {1, i}]];

In := test[2]
Out = {{1, 1}, {1, 2}}

The trick here is that mat's type (a rank-2 integer tensor) must be  
specified, otherwise Mathematica infers it to be a scalar (and in  
Mathematica 8 an integer, but in previous versions, a real number). To do  
this properly you must assign it a suitable value initially, which in this  
case is {{0, 0}}. Also, you didn't specify that i is local to the compiled  
function or an integer scalar, nor that k is a scalar, so I added these  
specifications as well.

As a point of note, in Mathematica 8, you can define types using e.g.  
Most[{{0, 0}}], which creates an empty rank-2 integer tensor (well,  
strictly speaking, it creates a rank-2 integer tensor consisting of {{0,  
0}} and then clears it), but in previous versions it is apparently not  
possible to clear variables like this without also losing the type  
information, hence the need to return Rest[mat] above if you want your  
code to work in older versions of Mathematica and without a spurious {0,  
0} prefixed to the list of results.

Additionally, Sow and Reap cannot be compiled, and anything that seems to  
indicate they can be is just an illusion. It would certainly be nice if  
they could be, given that AppendTo is an O(N^2) operation whereas Sow is  
O(1) on average (I think). What can be compiled are the functions used  
internally to implement Sow and Reap (Internal`Bag, Internal`StuffBag,  
Internal`BagPart), although these are undocumented and complicate matters  
by introducing yet more types. However, I shan't discuss these further for  
the time being as I'm not sure whether the compiler supports bags of  
tensor type and don't have time right now to investigate.

> However, what seems funny is the following code:
> mat={};
> test=Compile[{{k,_Integer}},
> For[i=1,i<=k,i++,
> AppendTo[mat,{1,i}];
> ];
> ];
> test[2];mat
> The above code produces the result that I was looking for in a
> cumbersome way. I would like to prefer compile code which produces the
> same result without calling the list mat again.

This code only works because it is not compiled in any meaningful way (and  
therefore it will gain none of the performance one usually desires when  
compiling code). The compiled code is calling out to the interpreter to  
perform the necessary operations.

  • Prev by Date: Re: Automatically colred and indexed custom locators
  • Next by Date: Re: Difficulties with LocatorPanel
  • Previous by thread: Re: Compile function and AppendTo for lists (vrs. 8.0.4)
  • Next by thread: Re: Compile function and AppendTo for lists (vrs. 8.0.4)