MathGroup Archive 2002

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

Search the Archive

Re: Operating on every k-th element of list?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg37100] Re: [mg37080] Operating on every k-th element of list?
  • From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
  • Date: Wed, 9 Oct 2002 05:25:57 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

Let's first consider your original problem and take a small list as an 
example:

mylist = {a, b, c, d, e, f, g};

As you pointed out there is a rather obvious and natural way to do it 
using the Do loop.

In[5]:=
Do[mylist[[3*i + 1]] = k*mylist[[3*i]] + mylist[[3*i + 1]],
    {i, 1, Length[mylist]/3}]; mylist

Out[5]=
{a, b, c, d + c*k, e, f, g + f*k}


One can also do it using something like your second approach. Notice 
the need to re-set mylist which got changed by the Do loop:

In[6]:=
mylist={a,b,c,d,e,f,g};

In[7]:=
RotateRight[Table[If[Mod[i,3]==0,k,
           0],{i,1,Length[mylist]}]*mylist]+mylist


Out[7]=
{a,b,c,d+c k,e,f,g+f k}

There is an ambiguity that appears if the length of the list is exactly 
divisible by 3. In that case k times the last element should be added 
to the next element. In this case the first approach (using Do) will 
produce an error message while the second will interpret "the next 
element" to mean the first element of the list. One can fix that but I 
shan't bother to do so and assume that the length of the list is not 
divisible by 3.

Now let's take a large list and compare the performance of the two 
approaches:

In[8]:=
k = 2;

In[9]:=
mylist = Table[Random[Integer, {1, 9}], {10000}];

In[11]:=
mylist1 = mylist;

In[12]:=
Timing[list1 = (Do[mylist[[3*i + 1]] = k*mylist[[3*i]] +
         mylist[[3*i + 1]], {i, 1, Length[mylist]/3}];
      mylist); ]

Out[12]=
{0.21999999999999997*Second, Null}

In[13]:=
mylist = mylist1;

In[14]:=
Timing[list2 = RotateRight[Table[If[Mod[i, 3] == 0, k, 0],
         {i, 1, Length[mylist]}]*mylist] + mylist; ]

Out[14]=
{0.020000000000000018*Second, Null}

In[15]:=
list1 == list2

Out[15]=
True

So you were right, at least in this implementation the second approach 
turns out to be much faster. Note also however, that when you change 
the problem to the one that you originally stated the two approaches 
will no longer give the same answer. The reason is that your statement 
is ambiguous: "apply a function to every  k-th  element of a long list 
and add the result to the  k+1  element" can either mean that you want 
to take the original k-th element of the original list, multiply by a 
constant and add to the next one, or do the same with the already 
altered  k-th element (by the previous step of the procedure). The Do 
loop approach will do the latter and the other the former.


Andrzej Kozlowski
Yokohama, Japan
http://www.mimuw.edu.pl/~akoz/
http://platon.c.u-tokyo.ac.jp/andrzej/



On Tuesday, October 8, 2002, at 08:17 PM, AES wrote:

> I want to apply a function to every  k-th  element of a long list and
> add the result to the  k+1  element.
>
> [Actually  k = 3  and I just want to multiply  myList[[k]]  by a
> constant (independent of k)  and add the result to  myList[[k+1]]  for
> every value of  k  that's divisible by 3.]
>
> Is there a way to do this -- or in general to get at every  k-th
> element of a list -- that's faster and more elegant than writing a 
> brute
> force  Do[]  loop or using  Mod[]  operators, and that will take
> advantage of native List operators,  but still not be too recondite?
>
> I've been thinking about multiplying a copy of  myList  by a "mask 
> list"
> {0,0,1,0,0,1,..} to generate a "masked copy" and approaches like that.
> Better ways???
>
>
>



  • Prev by Date: RE: Operating on every k-th element of list?
  • Next by Date: Re: Re: Re: Accuracy and Precision
  • Previous by thread: RE: Operating on every k-th element of list?
  • Next by thread: Re: Operating on every k-th element of list?