MathGroup Archive 2001

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

Search the Archive

Re: Appending to Lists

  • To: mathgroup at smc.vnet.net
  • Subject: [mg27064] Re: [mg27045] Appending to Lists
  • From: "Carl K. Woll" <carlw at u.washington.edu>
  • Date: Sat, 3 Feb 2001 04:58:58 -0500 (EST)
  • References: <200102010800.DAA04717@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

James,

Probably the reason your functions are so slow is because you use AppendTo
to create large lists. Using AppendTo to create lists is among the slowest
possible techniques. This is because creating a list and then removing and
adding parts to it is a very slow process in Mathematica. Here is a faster
technique to create your a) list:

getlist[particle_, x_] := Module[{vecs, veclist},
    vecs = Union[particle];
    veclist = Flatten[Position[particle, #]] & /@ vecs;
    x[[#]] & /@ veclist]

For your example we have

In[39]:=
data = {.2, .6, 1.2, -.2, .5, .3, .7, -.2, -.6};
particle = {1, 2, 3, 1, 2, 1, 2, 1, 1};
getlist[particle, data]

Out[41]=
{{0.2, -0.2, 0.3, -0.2, -0.6}, {0.6, 0.5, 0.7}, {1.2}}

which is only different from what you had because there was an error in your
output.

For a longer example, we could have

In[42]:=
particle = Table[Random[Integer, {1, 3}], {100000}];
data = Table[Random[], {100000}];
getlist[particle, data]; // Timing

Out[44]=
{2.407 Second, Null}

So, 2 1/2 seconds on a 200MHz machine doesn't seem too bad.

As far as your second question goes, take a look at PadRight.

In[45]:=
?PadRight

PadRight[list, n] makes a list of length n by padding list with zeros on the
   right. PadRight[list, n, x] pads by repeating the element x.
   PadRight[list, n, {x1, x2, ... }] pads by cyclically repeating the
   elements xi. PadRight[list, n, padding, m] leaves a margin of m elements
   of padding on the left. PadRight[list, {n1, n2, ... }] makes a nested
   list with length ni at level i.

This function should work much more quickly than your second function.

Carl Woll
Physics Dept
U of Washington

P.S. If you have many vectors, rather than the 3 in your example, it
probably will be better to use a different algorithm based on the idea of
using the functions Split and Sort.

----- Original Message -----
From: "James Jones" <j.k.jones at dl.ac.uk>
To: mathgroup at smc.vnet.net
Subject: [mg27064] [mg27045] Appending to Lists


> Hi,
>
> I have a function that creates a list (a) from another list (b). The list
> elements are re-grouped in the new list according to a third list (c). A
> Position command is applied to list (c) for an element, then with this
> output the list (a) is created from list (b) at positions given by the
> element position data, list (c). This is repeated for the large number of
> elements in the original lists.
> The Position command is necessary as different elements appear in the list
a
> different number of times.
> However, with the large number of elements in the lists (approx 50,000 for
a
> simple list), this method is _very_ slow.
> If any one can give me help in speeding this process up I would be very
> grateful.
>
> The data sets would look like this
>
>       b                       c
>
>     0.2                      1
>     0.6                      2
>     1.2                      3
>     -0.2                     1
>     0.5                       2
>     0.3                       1
>     0.7                       2
>    -0.2                      1
>    -0.6                      1
>
> A List would then be created from this data ( the list (a) ) containing
> vectors for 1, 2 and 3. The data in (b) is not important, and the order in
> which elements in (c) drop out is not set.
> In this case the (a) list should look like
>
> a = { { 0.2, -0.2, -0.2, -0.6} , {0.6, 0.5, 0.7} , { 1.2 } }
>
> My current function looks like this
>
> Do[AppendTo[xfinal,
>       Flatten[Part[X, #] & /@
>           Position[Global`PARTICLE, i]]], {i, 1,
>       Max[PARTICLE]}];
>
> where xfinal is an (a) list, i.e. to be created.
>           X is the (b) list , i.e. to be addressed, and
>           PARTICLE is the (c) list. It is referenced by number.
>
> and it is very slow!
>
> Also, after producing this list, the different vector elements need to be
> made the same length, and so 0.0 are added to the ends of all vector
> elements shorter than the longest. My current function for doing this
looks
> like
>
> table = Table[0.0, {Length[First[long]]}]; Print["Table Created!"];
>
> Do[If[Length[Part[xfinal, i]] < Length[First[long]],
>       AppendTo[Part[xfinal, i],
>         Drop[table, (Length[Part[xfinal, i]])] ]], {i, 2,
>       Length[xfinal]}];
>
> where list (long) just sorts the list elements according to length.
>
> This function is also very slow, and I was wondering, again, if anyone
knew
> a faster way of implementing this. Is the production of a table, once, and
> then dropping bits off and appending the fastest method? Of course this
> needs to be done tens of thousands of times per set of data so any small
> speed increase would be very helpful ;->
>
> Again, any help much appreciated,
>
> James Jones
> Daresbury Laboratory
>
>



  • Prev by Date: Re: Appending to Lists
  • Next by Date: Problems rendering Graphics3D with RealTime3D
  • Previous by thread: Appending to Lists
  • Next by thread: Re: Appending to Lists