Sunday, April 15, 2012

Cyclically Selecting Parts Using Mod with Offset = 1

The Doc Center notes this usage of the offset feature in Mod to cyclically select Parts. Setting offset to 1 means Part will cycle from Part #1 through the value of n instead of the expression itself (i.e. Part #0) tbrough n - 1. However I have not seen a useful application of this idiom.

In[1]:= {a, b, c}[[Mod[Range[10], 3, 1]]]

Out[1]= {a, b, c, a, b, c, a, b, c, a}


The usage of Mod is straightforward, but by "offset" the Doc Center means shifting the cycle of remainders over by the offset along the number line. Normally Mod[m,n] is equivalent to the typical infix mathematical notation m mod n, i.e. it gives the remainder of m/x  (where x is a positive integer) as cycling from 0 through n-1. Offset rotates the cycle on the number line by its value. Here is the usage with default offset of 0:

In[149]:= Mod[Range@7, 3]

Out[149]= {1, 2, 0, 1, 2, 0, 1}

Now using an offset of 1, instead of cycling through {0,1,2}, the remainder cycles through {1,2,3}:

In[151]:= Mod[Range@7, 3, 1]

Out[151]= {1, 2, 3, 1, 2, 3, 1}

Using an offset of 2, instead of cycling between 0 and 2, the remainder cycles through {2,3,4}:

In[152]:= Mod[Range@7, 3, 2]

Out[152]= {4, 2, 3, 4, 2, 3, 4}

So what should happen if we use an offset of -1? The remainder should cycle through {-1,0,1}.

In[153]:= Mod[Range@7, 3, -1]

Out[153]= {1, -1, 0, 1, -1, 0, 1}

Capturing the Remnant of a Partitioned List

When partitioning, you usually don't want to just lose the leftover part at the end of the partitions. Mathematica provides ways to overlap Lists and pad them, but often you just want to capture the remnant leftover elements at the end. Here are two ways to do that. First, we define a function to capture the remnant and then Append it to the partitioned list, for instance in a TableForm usage.

In[77]:= TableForm@Partition[Range@11, 3]

We lost 10 and 11. Let's get them back.

In[78]:= listOfNumbers = Range@11;

remnant[listOfNumbers, 3]

Out[79]= {10, 11}

In[74]:= remnant[aList_List, partitionLength_Integer] :=
 Take[aList, -Mod[Length@aList, partitionLength]]

The most compact way to write a function that requires another short function, such as remnant, is to just protect the variable name and define the function at the same time within Module's local scope list.

In[80]:= unevenListTable[aList_List, partitionLength_Integer] :=
 Module[{remnant = Take[aList, -Mod[Length@aList, partitionLength]]},
  Partition[aList, partitionLength] // Append[#, remnant] & // TableForm]

In[81]:= unevenListTable[Range@11, 3]


There is also a way using a particular Partition syntax. What this says is, "Partition the list into sublists of length 4, take them in blocks of 4 (i.e. do not overlap them), start the first element of the first list at position 1 of the first sublist, and do not pad the last uneven list (i.e. pad it with the empty set)."

In[83]:= Partition[listOfNumbers, 3, 3, 1, {}] // TableForm


To get a glimpse of how this syntax works, by way of contrast, note what happens when we tell Partition to start the first element at position 3 of the first sublist. Since the sublists are only length 3, the first element takes that third slot and then Partition creates sublists of length 3 until it runs into too few elements to do that—the remnant, which is 11—and ignores them.

In[84]:= Partition[Range@11, 3, 3, 3, {}]

Out[84]= {{1}, {2, 3, 4}, {5, 6, 7}, {8, 9, 10}}