# One-way "cross" of function between two matrices

I'm trying to create a sort of one way "cross" of a function between two matrices, such that every pair in one matrix is mapped to every pair in the other, but not the other way around; for example, given the two matrixes:

matrixA = {{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}} (* Tuples[{0, 1, 2}, 2 *)
matrixB = {{0, 0}, {0, 1}, {1, 0}, {1, 1}} (* Tuples[{0, 1}, 2] *)


I want to compute: [edited - I forgot the closing brace]

{f[{{0, 0}, {0, 0}}], f[{{0, 0}, {0, 1}}], f[{{0, 0}, {1, 0}}], f[{{0, 0}, {1, 1}}],
f[{{0, 1}, {0, 0}}], f[{{0, 1}, {0, 1}}], f[{{0, 1}, {1, 0}}], f[{{0, 1}, {1, 1}}],
f[{{1, 0}, {0, 0}}], f[{{1, 0}, {0, 1}}], f[{{1, 0}, {1, 0}}], f[{{1, 0}, {1, 1}}],
f[{{1, 1}, {0, 0}}], f[{{1, 1}, {0, 1}}], f[{{1, 1}, {1, 0}}], f[{{1, 1}, {1, 1}}]}


How do I do this? I've fiddled with Inner, Outer, MapThread, etc, but haven't been able to get what I want.

For reference, this is the snippet I'm trying to use this in:

dim = base^num + 1;
mat = ConstantArray[0, {dim, dim}];
mat[[dim, dim]] = 1;
tuples = Tuples[{0, 1}, num];
p := (frac[[1]]^Count[rev, 1] * minusfrac^Count[rev, 0])/(frac[[2]]^num);
z := MapThread[If[#2 == 0, #1, 0] &, {state[[i + 1]], rev}];
state = Tuples[Range[0, base - 1], num]
For[i = 0, i < dim - 1, i++,
Do[
mat[[i + 1, FromDigits[z, base] + 2]] += p, {rev, tuples}
]
]


I'm just trying to simplify this by pre-computing z for all values of i and rev so that I can hopefully get a step closer to doing away entirely with the for and do loops. If you find a more effective way to simplify this snippet than the route I'm trying to take [or if my reasoning is flawed], please tell me!

• Your expected result is incomplete and your code snippet has undefined symbols, so I don't really have a way to check anything. But I think you might be looking for Outer[f, matrixA, matrixB, 1]. Mar 20 at 18:30
• That doesn't match exactly, but I assume it's close enough for you to work with. Maybe you want f@*List instead of just f. And of course you can flatten it. Mar 20 at 18:31
• f /@ Tuples[{matrixA, matrixB}]?
– kglr
Mar 20 at 23:04
• also Distribute[f[matrixA, matrixB], List, f, List, f@*List]
– kglr
Mar 20 at 23:08

You can use Intersection and Tuples.

With

matrixA = Tuples[{0, 1, 2}, 2];
matrixB = Tuples[{0, 1}, 2];


Then

f /@ Tuples[Intersection[matrixA, matrixB], 2]

{f[{{0, 0}, {0, 0}}], f[{{0, 0}, {0, 1}}], f[{{0, 0}, {1, 0}}], f[{{0, 0}, {1, 1}}],
f[{{0, 1}, {0, 0}}], f[{{0, 1}, {0, 1}}], f[{{0, 1}, {1, 0}}], f[{{0, 1}, {1, 1}}],
f[{{1, 0}, {0, 0}}], f[{{1, 0}, {0, 1}}], f[{{1, 0}, {1, 0}}], f[{{1, 0}, {1, 1}}],
f[{{1, 1}, {0, 0}}], f[{{1, 1}, {0, 1}}], f[{{1, 1}, {1, 0}}], f[{{1, 1}, {1, 1}}]}


Hope this helps.

You get almost the right thing using Map and Outer, but it has an extra { } around it.

matrixA = Tuples[{0, 1, 2}, 2];
matrixB = Tuples[{0, 1}, 2];
m = Map[f, Outer[List, matrixA, matrixB, 1], {2}]


You remove the extra { } with

Flatten[m,1]


A oneliner:

Sort[(x |-> f[#, x] & /@ Select[matrixA , (Max@# < 2 &)]) /@ matrixB //
Flatten, ({10, 1} . #1[[1]] <= {10, 1} . #2[[1]] &)] // TableForm

f[{0,0},{0,0}]
f[{0,0},{0,1}]
f[{0,0},{1,0}]
f[{0,0},{1,1}]
f[{0,1},{0,0}]
f[{0,1},{0,1}]
f[{0,1},{1,0}]
f[{0,1},{1,1}]
f[{1,0},{0,0}]
f[{1,0},{0,1}]
f[{1,0},{1,0}]
f[{1,0},{1,1}]
f[{1,1},{0,0}]
f[{1,1},{0,1}]
f[{1,1},{1,0}]
f[{1,1},{1,1}]