Re: RE: split a list
- To: mathgroup at smc.vnet.net
- Subject: [mg40633] Re: [mg40557] RE: [mg40515] split a list
- From: Dr Bob <majort at cox-internet.com>
- Date: Fri, 11 Apr 2003 02:05:20 -0400 (EDT)
- References: <200304100737.DAA24168@smc.vnet.net>
- Reply-to: majort at cox-internet.com
- Sender: owner-wri-mathgroup at wolfram.com
That's really amazing! It's nice that we can get the advantage of compiled code while still using a high level, interpreted language with symbolic capabilities, etc. Mathematica rules. cutList = Compile[{{ r, _Real, 1}, {m, _Real}}, Module[{tmp, u, v, i, j = 0, k = 0}, u = v = Table[0., {Length[r]}]; For[i = 1, i â?¤ Length[r], ++i, If[(tmp = r[[i]]) > m, u[[++j]] = tmp, v[[++k]] = tmp]]; xj = j; xk = k; {u, v}]]; hartmut = Block[{u, v, xj, xk}, {u, v} = cutList[#1, #2]; {Take[v, xk], Take[u, xj]} ] &; (I had to reverse u and v to get the same answer as other solutions.) test = trial@5000; brambilla @@ test == kuska @@ test == treat @@ test == treat3 @@ test == treat5 @@ test == hartmut @@ test True test = trial@500000; Timing[treat @@ test;] Timing[kuska @@ test;] Timing[treat2 @@ test;] Timing[treat3 @@ test;] Timing[treat5 @@ test;] Timing[hartmut @@ test;] {3.75 Second,Null} {3.938 Second,Null} {3.703 Second,Null} {3.765 Second,Null} {16.672 Second,Null} {0.516 Second,Null} test = trial@2000000; Timing[kuska @@ test;] Timing[treat @@ test;] Timing[treat2 @@ test;] Timing[hartmut @@ test;] Timing[kuska @@ test;] Timing[treat3 @@ test;] {15.843 Second,Null} {15.406 Second,Null} {15.657 Second,Null} {2.61 Second,Null} {16.797 Second,Null} {16. Second,Null} Bobby Display all headersDate: Thu, 10 Apr 2003 03:37:08 -0400 (EDT)From: "Wolf, To: mathgroup at smc.vnet.net Hartmut" <Hartmut.Wolf at t-systems.com>To: mathgroup at smc.vnet.netSubject: [mg40633] [mg40557] RE: [mg40515] split a list > -----Original Message----- > From: Roberto Brambilla [mailto:rlbrambilla at cesi.it] To: mathgroup at smc.vnet.net > Sent: Wednesday, April 09, 2003 7:31 AM > To: mathgroup at smc.vnet.net > Subject: [mg40633] [mg40557] [mg40515] split a list > [...] > I have a list (very long, thousands, and unsorted) of numbers > r={n1,n2...} > and for a given a number m I want to split it in the two sublists > (unsorted, same order) u={elements<m], v={elements>m}. > Now I use this *old-style* method: > > u = v = {}; > For[i = 1, i <= Length[r], i++, > tmp = r[[i]]; > If[tmp > m , AppendTo[u, tmp], AppendTo[v, tmp]]; > ] > Any suggestion for a more efficient (and elegant) method? > Also oneliners are well accepted. > > Many thanks, Roberto > > Roberto Brambilla > [...] Roberto, observe In[8]:= r = Table[Random[], {10000}]; In[9]:= m = .5; In[10]:= u = v = {}; For[i = 1, i <= Length[r], i++, tmp = r[[i]]; If[tmp > m, AppendTo[u, tmp], AppendTo[v, tmp]]] // Timing Out[11]= {8.583 Second, Null} In[12]:= Length /@ {u, v} Out[12]= {4981, 5019} In[13]:= ({u, v} = Through[{Cases, DeleteCases}[r, e_ /; e > m]]); // Timing Out[13]= {0.51 Second, Null} In[14]:= Length /@ {u, v} Out[14]= {4981, 5019} What is even more problematic with your program is its time complexity which is O[n^2]. Such I would not like to wait for: In[19]:= r = Table[Random[], {100000}]; In[20]:= u = v = {}; For[i = 1, i <= Length[r], i++, tmp = r[[i]]; If[tmp > m, AppendTo[u, tmp], AppendTo[v, tmp]]] // Timing Out[21]= $Aborted In[22]:= ({u, v} = Through[{Cases, DeleteCases}[r, e_ /; e > m]]); // Timing Out[22]= {5.037 Second, Null} In[23]:= Length /@ {u, v} Out[23]= {50129, 49871} Select is even a bit faster for this benchmark: In[24]:= ({u, v} = Select[r, #] & /@ {# > m &, # <= m &}); // Timing Out[24]= {3.796 Second, Null} In[25]:= Length /@ {u, v} Out[25]= {50129, 49871} You may however fix up (make O[n]) your "old-fashioned" algorithm: In[33]:= (u = v = {}; For[i = 1, i <= Length[r], i++, If[(tmp = r[[i]]) > m, u = {u, tmp}, v = {v, tmp}]]; {u, v} = Flatten /@ {u, v}); // Timing Out[33]= {6.71 Second, Null} In[34]:= Length /@ {u, v} Out[34]= {50129, 49871} Another idea would be to compile: In[57]:= cutList = Compile[{{r, _Real, 1}, {m, _Real}}, Module[{tmp, u, v, i, j = 0, k = 0}, u = v = Table[0., {Length[r]}]; For[i = 1, i <= Length[r], ++i, If[(tmp = r[[i]]) > m, u[[++j]] = tmp, v[[++k]] = tmp]]; xj = j; xk = k; {u, v}]]; In[58]:= ({uu, vv} = cutList[r, .5]); // Timing Out[58]= {0.57 Second, Null} In[59]:= {xj, xk} Out[59]= {50129, 49871} In[62]:= {u, v} = {Take[uu, xj], Take[vv, xk]}; // Timing Out[62]= {0.05 Second, Null} In[63]:= Length /@ {u, v} Out[63]= {50129, 49871} This is by far the best timing. Regard how I transferred the result u and v as a tensor objekt, but the effective resulting Lengths via global variables! - Hartmut Wolf
- References:
- RE: split a list
- From: "Wolf, Hartmut" <Hartmut.Wolf@t-systems.com>
- RE: split a list