MathGroup Archive 1999

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

Search the Archive

Re: Partitioning lists

  • To: mathgroup at smc.vnet.net
  • Subject: [mg20530] Re: [mg20439] Partitioning lists
  • From: "Wolf, Hartmut" <hwolf at debis.com>
  • Date: Sat, 30 Oct 1999 00:13:50 -0400
  • Organization: debis Systemhaus
  • References: <199910260433.AAA05986@smc.vnet.net.>
  • Sender: owner-wri-mathgroup at wolfram.com

DIAMOND Mark schrieb:
> 
> I would like a function f to split a list as follows
> 
> a={1,2,3,4,5,6}
> f[a] =
>   {
>     {{1},{2,3,4,5,6}},
>     {{1,2},{3,4,5,6}},
>     {{1,2,3},{4,5,6}},
>     {{1,2,3,4},{5,6}},
>     {{1,2,3,4,5},{6}}
>   }
> 
> I can do this as
> 
>       Table[{Take[a, i], Drop[a, i]}, {i, 1, Length[a] - 1}]
> 
> but it *looks* as though it is very inefficient. Is it?
> It also looks as though there should be a way of using Partition simply to
> chop a list between positions i and i+1, but
> I cannot see how to do it. Any suggestions?
> 
> mark diamond

Hello Mark,

I think your first approach is perfectly right, Take and Drop are thee
_Mathematica_ functions to do that (Partition has quite another use).

As to what matters performance, there is *only* one way to judge on
that, namely measument.

In[1]:= n = 1000;
In[2]:= a = Range[n]; // Timing
Out[2]= {0. Second, Null}

Your method:

In[3]:= Table[{Take[a, i], Drop[a, i]}, {i, 1, Length[a] - 1}]; //
Timing
Out[3]= {0.37 Second, Null}

and I think that's pretty fast.

A fundamentally different approach would be to build an index structure
and mapping thereover an array of your application:

In[4]:= b = Table[{Range[i], Range[i + 1, n]}, {i, 1, n - 1}]; // Timing
Out[4]= {0.351 Second, Null}

Compare this time with that one above. Does this prove that your way is
indeed the fastes possible? I think so, but we can't be shure, observe:

In[5]:= anArray = Array[c, {n}]; // Timing
Out[5]= {0.02 Second, Null}

(Just a model for our application array.) Now

In[6]:= Map[Part[anArray, #] & , b, {3}]; // Timing
Out[6]= {43.162 Second, Null}

In[7]:= Map[Extract[anArray, #] & , b, {3}]; // Timing
Out[7]= {50.032 Second, Null}

That takes some time (to map and to form a new structure composed of a
million leave elements!) However 

In[8]:= d = Map[anArray[[#]] & , b, {2}]; // Timing
Out[8]= {3.175 Second, Null}

Astonishing, isn't it? But observe

In[11]:= e = d[[555, 1]]; // Timing
Out[11]= {1.082 Second, Null}

Much time to access these elements, but 

In[12]:= e; // Timing
Out[12]= {0. Second, Null}

is short (of course). Now, what made Out[11] that fast? First I concede,
I don't know, but I might speculate: Out[11] did only part of the work
as specified
"expr[[{i1,i2,...}] gives a list of the parts i1, i2,... of expression", 
i.e. it did it lazy, the list wasn't really build up. Only thereafter,
when beginning to use that object d[[{1,2,3,...,555}]] it will be
evaluated and the list is then being build (and of course it's then that
you have to pay for it).
Of course this is a clever scheme which avoids spoiling computational
resources for intermediate parts of your calculation which are not
explicitly used.

Yet for us it's more difficult to judge on the performance of the
primitives, let even by looking.

Kind regards, hw



  • Prev by Date: Re: entering stuff using escape
  • Next by Date: Re: ScientificForm with NotebookWrite
  • Previous by thread: Partitioning lists
  • Next by thread: Re: Partitioning lists