2
$\begingroup$

Please bear with the vagueness of this question's title, as my question itself has to deal with the fact that I don't know what to call the operation I'm looking for. I have a statistical operation involving groupings and permutations, and I'm not sure how to refer to the name of the operation I want. I have some déjà vu from statistics classes that what I'm trying to do is a "named mathematical operation", but I'm too rusty to remember what it might be called.

I suspect that there is a named function in Mathematica that could get me my desired results in a one-liner, but I don't even know what to search for in the manual. Unfortunately, I'm going to have to simply post an example of the desired results and some code, and hope somebody recognizes it.

The desired results are:

Given any integer n, first form the set of all integers in the range {0,n}. Call this the input to the unknown function. Then, form the set of permutations (order matters) of this set, and all possible groupings within that set of permutations. For example, for n=3, the desired results are:

{
 {{{1, 2, 3}}, {{1, 2}, {3}}, {{1}, {2, 3}}, {{1}, {2}, {3}}},
 {{{1, 3, 2}}, {{1, 3}, {2}}, {{1}, {3, 2}}, {{1}, {3}, {2}}},
 {{{2, 1, 3}}, {{2, 1}, {3}}, {{2}, {1, 3}}, {{2}, {1}, {3}}},
 {{{2, 3, 1}}, {{2, 3}, {1}}, {{2}, {3, 1}}, {{2}, {3}, {1}}},
 {{{3, 1, 2}}, {{3, 1}, {2}}, {{3}, {1, 2}}, {{3}, {1}, {2}}},
 {{{3, 2, 1}}, {{3, 2}, {1}}, {{3}, {2, 1}}, {{3}, {2}, {1}}}
}

I have been able to achieve this with the following ad-hoc function:

PermutationGroupings = Function[range,
   With[
    {
     groupings = 
      Thread@Unevaluated@Splice@*Permutations@# &@
       IntegerPartitions@range,
     perms = Permutations@Range@range
     },
    Outer[TakeList, perms, groupings, 1]
    ]];

PermutationGroupings@3

The above function relies upon what I know about list manipulation, rather than core mathematical functions. It's at least better than some earlier attempts that used Groupings and Permutations together to come up with a massive list which needed to be manipulated and pruned-down to remove duplicates. I've been binging on the reference manual, and came up with a bunch of other inefficient and half-baked alternatives involving everything from FrobeniusSolve[...] to Subsequences[...] of DeBruijnSequence[...]s, and all I've concluded is that I have a lot to learn. But I could've sworn that there is a term for what I'm trying to do, and probably a dedicated Mathematica function to do it.

Any leads? Thanks!

Again, the output looks like:

Grid[#, Frame -> All] &@
     Map[Column[#, Alignment -> Center, 
        Spacings -> {0, 0}] &, #, {2}] &@
   Map[Grid[List@#, Frame -> All] &, #, {3}] &@
 PermutationGroupings@3

enter image description here

$\endgroup$
2
  • $\begingroup$ Many times (usually?) the objective is to determine some set of summary statistics associated with the complete list of arrangements. Now that @ciao has given you something that can do what you want for at least up to $n=9$, What do you want to do with those humongous lists? The number of items in the list is n! so you're going to run out of time and memory real quick. But determining some summary statistics doesn't always need a complete enumeration. $\endgroup$
    – JimB
    Commented May 31, 2021 at 22:39
  • $\begingroup$ I first wrote the above PermutationGroupings to run some unit testing on other Mathematica code. For example, consider a function which takes level or part specifications, where you want to test it up to a reasonable level (e.g. n ==4). I keep a notebook or ten with such re-usable utility functions. ;-) $\endgroup$
    – Sean
    Commented Jun 2, 2021 at 8:59

1 Answer 1

3
$\begingroup$

I don't think there's a "name" for your operation, nor a built-in. The closest analog might be subset partitioning (as counted by the Bell polynomials), but not quite.

In any case, the following s/b a bit more time-efficient for larger values, and a bit more memory efficient (it can complete for 9 on my laptop, your code crashes the kernel w/ memory pressure):

do[l_] := Module[{v = Table[Unique[], l], f},
   f[Sequence @@ (Pattern[#, _] & /@ v)] = 
    FoldPairList[TakeDrop, v, #] & /@ 
     Join @@ Permutations /@ IntegerPartitions[l];
   f @@@ Permutations[Range@l]];
$\endgroup$
1
  • $\begingroup$ Thanks @ciao! Very lean; I like it. I'll look up some information on Bell polynomials as well. It may help "free some cache" in my brain by putting the subject to rest ;-) $\endgroup$
    – Sean
    Commented Jun 2, 2021 at 8:54

Your Answer

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

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