Revise the function called by Outer command

See my following usage of Outer:

 In[395]:= Outer[f, {a, b}, #1, 1] &@{x, y}

Out[395]= {{f[a, x], f[a, y]}, {f[b, x], f[b, y]}}

But, in my case, the desired result is as follows:

{{f[a, x, myarg], f[a, y, myarg]}, {f[b, x, myarg], f[b, y, myarg]}}

So, how can I revise the function called by Outer to meet this specific requirement?

Regards,
Zhao

Check this:

Outer[f, {a, b}, {x, y}, {myarg}] // Flatten[#, {1, 3}] &

Yes. It does the trick. But I still don’t understand Flatten’s complex level specification. Can you explain the execution logic of the above example? Or, more generally, is there any way to let me check the execution process of the code in detail to get an intuitive understanding?

Zhao, I have no good answers. In this case I just work from experience and intuition. Guessing, in other words. TreeForm can help in this process. So I leave it to others to explain how Flatten actually handles the level specification {1, 3}.

Thank you for your comment and explanation.

Hi Hans,

In fact, I want to keep all the sublists in their original form, i.e., without been flattened. So, I just tweaked your above idea a bit as follows:

In[224]:= 
Join[{x}, Flatten[Outer[f, {a, b}, {x}, {myarg}, 1], 2]]
% /. {x -> Array[x, {2, 2}], a -> Array[a, {1, 2}]}

Out[224]= {x, f[a, x, myarg], f[b, x, myarg]}

Out[225]= {{{x[1, 1], x[1, 2]}, {x[2, 1], x[2, 2]}}, 
 f[{{a[1, 1], a[1, 2]}}, {{x[1, 1], x[1, 2]}, {x[2, 1], x[2, 2]}}, 
  myarg], f[b, {{x[1, 1], x[1, 2]}, {x[2, 1], x[2, 2]}}, myarg]}

This is an alternative:

Outer[OperatorApplied[f, {2, 3, 1}][myarg], {a, b}, {x, y}]

I tried your method, but it seemed that the expected results could not be produced:

M1={{0,0,1,1/4},{1,0,0,1/4},{0,-1,0,1/4},{0,0,0,1}};
M2={{0,0,-1,0},{0,-1,0,0},{1,0,0,0},{0,0,0,1}};
mod=1
gens={M1,M2};

This is your method:

In[42]:= Union[Join[#1, 
          Flatten[Outer[OperatorApplied[f, {2, 3, 1}][mod], gens, #1], 2]
          (*Flatten[Outer[ AffModOneDotOnLeft, gens, #1, {mod}, 1], 2]*)
          ]] &@{AffineTransform[{IdentityMatrix[3],ConstantArray[0, 3]}]//TransformationMatrix}

Out[42]= {{{{f[-1, 1, 1], f[-1, 0, 1], f[-1, 0, 1], 
    f[-1, 0, 1]}, {f[-1, 0, 1], f[-1, 1, 1], f[-1, 0, 1], 
    f[-1, 0, 1]}, {f[-1, 0, 1], f[-1, 0, 1], f[-1, 1, 1], 
    f[-1, 0, 1]}, {f[-1, 0, 1], f[-1, 0, 1], f[-1, 0, 1], 
    f[-1, 1, 1]}}}, {{{f[0, 1, 1], f[0, 0, 1], f[0, 0, 1], 
    f[0, 0, 1]}, {f[0, 0, 1], f[0, 1, 1], f[0, 0, 1], 
    f[0, 0, 1]}, {f[0, 0, 1], f[0, 0, 1], f[0, 1, 1], 
    f[0, 0, 1]}, {f[0, 0, 1], f[0, 0, 1], f[0, 0, 1], 
    f[0, 1, 1]}}}, {{{f[1/4, 1, 1], f[1/4, 0, 1], f[1/4, 0, 1], 
    f[1/4, 0, 1]}, {f[1/4, 0, 1], f[1/4, 1, 1], f[1/4, 0, 1], 
    f[1/4, 0, 1]}, {f[1/4, 0, 1], f[1/4, 0, 1], f[1/4, 1, 1], 
    f[1/4, 0, 1]}, {f[1/4, 0, 1], f[1/4, 0, 1], f[1/4, 0, 1], 
    f[1/4, 1, 1]}}}, {{{f[1, 1, 1], f[1, 0, 1], f[1, 0, 1], 
    f[1, 0, 1]}, {f[1, 0, 1], f[1, 1, 1], f[1, 0, 1], 
    f[1, 0, 1]}, {f[1, 0, 1], f[1, 0, 1], f[1, 1, 1], 
    f[1, 0, 1]}, {f[1, 0, 1], f[1, 0, 1], f[1, 0, 1], 
    f[1, 1, 1]}}}, {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 
   0, 1}}}

This is the desired result:

In[44]:= Union[Join[#1, 
              (*Flatten[Outer[OperatorApplied[f, {2, 3, 1}][mod], 
    gens, #1], 2]*)
              Flatten[Outer[ f, gens, #1, {mod}, 1], 2]
              ]] &@{AffineTransform[{IdentityMatrix[3], 
     ConstantArray[0, 3]}] // TransformationMatrix}

Out[44]= {f[{{0, 0, -1, 0}, {0, -1, 0, 0}, {1, 0, 0, 0}, {0, 0, 0, 
    1}}, {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}, 1],
  f[{{0, 0, 1, 1/4}, {1, 0, 0, 1/4}, {0, -1, 0, 1/4}, {0, 0, 0, 
    1}}, {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}, 
  1], {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}