# Writing this loop in Mathematica

OK, so I've never had to write a line of Mathematica code (except for using it interactively as a calculator), but for this it looks like I have to. If someone could provide me with the code for the following, then I can edit it to do what I'm actually trying to accomplish. I need to do the following:

1. Input is a set $S$ of integers and some positive integers $n,m$

2. I want to generate all the possible vectors $X$ and $Y$, where $X$ has length $n$ and $Y$ has length $m$ and the elements of each vector belong to the set $S$.

3. I need to loop over all the possible values of $X$ and $Y$.

Something like this would be trivial to write down in, say, Haskell using list comprehensions, but having flipped through the Mathematica language reference for an hour, I couldn't figure out an easy way to do this.

The values of $n$ and $m$ are such that there are about 300 million possible combinations. Therefore, it's not possible to just take Cartesian products of $S$ and then iterate over the set, unless there's a way of generating the elements in a lazy way. Otherwise the machine would run out of memory.

• Welcome to the world of Mathematica programming! Unfortunately I don't have the time this morning to address this question in full. You are correct that Mathematica doesn't have Haskell's list comprehensions. Usually the fastest non-compiled approach is to process in chunks. See (21584) for a few ideas there. It may help if you explain what you are doing with each X and Y pair. Sep 21, 2014 at 10:34
• There ARE For loops. Which are slow, but if you generate partial cartesian product (with Outer) and finish with a single For loop (if your set has cardinality, say, 10) that should address both the memory and the speed problems. Sep 21, 2014 at 10:34
• In the actual problem I have four of these vectors that I need to independently generate, but I only need two as an example to extrapolate from the code. I compute $X^tY$ for a bunch of these vectors to form a matrix, compute left and right kernels, check whether they intersect certain subspaces. What I need to find is values for these vectors, where the matrix and its kernel satisfies a bunch of constraints... and I hope it exists and I don't need to search the whole space.
– eof
Sep 21, 2014 at 10:38
• I'm also expecting that an exhaustive search can take a week or so, but it's OK, since what I'm doing is searching for a counterexample.
– eof
Sep 21, 2014 at 10:43

Mathematica has no built-in notion of Haskell-like lazy computation. Although there have been attempts to simulate it, I would probably tackle this problem with a simple imperative loop.

Let's start with an example generator set, which we will call $s: $s = Array[Prime, 20]
(* {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71} *)


We will now define a helper function s that can return a vector of any rank using elements from that set:

s[i__] := $s[[{i}]]  So now: s[3, 7] (* {5, 17} *) s[12, 9, 15] (* {37, 23, 47} *)  This enables us to write a simple Do loop to scan over pairs of vectors of any size. Here is an example that scans pairs of 2-vectors and 3-vectors to find the first such pair with a nonsense property: Module[{c = Length @$s, x, y}
, Do[
x = s[x0, x1]
; y = s[y0, y1, y2]
; If[Total[x] - Total[y] == 39, Return[{x, y}]]
, {x0, c}, {x1, c}
, {y0, c}, {y1, c}, {y2, c}
]
]

(* {{2, 43}, {2, 2, 2}} *)

• Yes, just having the lambda operator in the language makes it possible to simulate lazynes, but doing so would be a pain. Your method is to be able to do this without that much boilerplate code. Thanks.
– eof
Sep 21, 2014 at 16:48