1
$\begingroup$

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!

$\endgroup$
4
  • 2
    $\begingroup$ 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]. $\endgroup$
    – lericr
    Mar 20 at 18:30
  • 1
    $\begingroup$ 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. $\endgroup$
    – lericr
    Mar 20 at 18:31
  • 1
    $\begingroup$ f /@ Tuples[{matrixA, matrixB}]? $\endgroup$
    – kglr
    Mar 20 at 23:04
  • $\begingroup$ also Distribute[f[matrixA, matrixB], List, f, List, f@*List] $\endgroup$
    – kglr
    Mar 20 at 23:08

3 Answers 3

1
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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]
$\endgroup$
0
$\begingroup$

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}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.