Showing posts with label sow. Show all posts
Showing posts with label sow. Show all posts

Sunday, March 31, 2013

Leveraging Sow to Simplify Loops

One of Mathematica's coolest list manipulation techniques is the Reap/Sow pattern. Using these functions together allows you to build up multiple collections at once in a decoupled manner.

To understand this idea and when it might make a difference, consider how you would sort a list of integers by divisor. What I mean is, given the list \[\{12,13,14,15,21,24,28,41,47,49,55\}\] sort it into the following lists based on divisor: \[\begin{align} 2 &\rightarrow \{12,14,24,28\} \\ 3 &\rightarrow \{12,15,21,24\} \\ 5 &\rightarrow \{15,55\} \end{align}\] (and here it's okay if one item shows up in two lists)

You might think to do it by using a for-loop and storing each item in a named list depending on what it matches. But if you want a variable list of divisors? In this case, managing the list of results can get a little tricky.

The Reap/Sow pattern presents a different approach: when important values are computed inside a function they can be "sown" with Sow, which means they bubble up the call stack until a matching Reap expression is encountered. You can use a Reap expression to process or discard sown values as you see fit.

An implementation of the divisor sorting algorithm using Reap and Sow might look something like this:

SortByDivisors[numbers_,divisors_]:=Reap[
  For[i=1, i \(\leq\) Length[numbers], i++,
    For[j=1, j \(\leq\) Length[divisors],j++
      n = numbers[[i]];
      d = divisors[[i]];
      If[Mod[n,d] == 0, Sow[n,d]];
    ];
  ];, n_, Rule][[2]]; 


And it will return a collection of Rules, each of which has a divisor as the key and a corresponding list of multiples as the value.