5

I'm looking for a function that can do this

applyDistributed[F, Dot[a, b, c]]
= {Dot[F[a, b, c]],
  Dot[F[a, b], F[c]],
  Dot[F[a], F[b, c]],
  Dot[F[a], F[b], F[c]]}

Honestly I don't even know where to start. I can't imagine how to program in the number of arguments that F should take

bmf
  • 15,157
  • 2
  • 26
  • 63
Albercoc
  • 988
  • 3
  • 13
  • Do you mean this? applyDistributed[F_, a_, b_, c_] := {Dot[F[a, b, c]], Dot[F[a, b], F[c]], Dot[F[a], F[b, c]], Dot[F[a], F[b], F[c]]} – bill s Feb 09 '23 at 01:20

3 Answers3

6
Clear["Global`*"];

Using @bmf' s definition for the partitioning

applyDistributed[func_, x_] :=
 Module[{list = List @@ x, func2 = Head@x},
  func2 @@@ Apply[func, Internal`PartitionRagged[list, #] & /@
     Apply[Join, Permutations /@
       IntegerPartitions[Length[list]]], {2}]]

applyDistributed[F, a . b . c]

(* {F[a, b, c], F[a, b] . F[c], F[a] . F[b, c], F[a] . F[b] . F[c]} *)

applyDistributed[F, abc]

(* {F[a, b, c], F[c] F[a, b], F[a] F[b, c], F[a] F[b] F[c]} *)

applyDistributed[F, a + b + c]

(* {F[a, b, c], F[c] + F[a, b], F[a] + F[b, c], F[a] + F[b] + F[c]} *)

applyDistributed[F, a . b . c . d]

(* {F[a, b, c, d], F[a, b, c] . F[d], F[a] . F[b, c, d], F[a, b] . F[c, d], F[a, b] . F[c] . F[d], F[a] . F[b, c] . F[d], F[a] . F[b] . F[c, d], F[a] . F[b] . F[c] . F[d]} *)

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
5

One way to achieve that is to start from

list = {a, b, c};

and after you generate all the sublists

res = Internal`PartitionRagged[list, #] & /@ 
  Apply[Join, Permutations /@ IntegerPartitions[Length[list]]]

list

you can apply a function on the above result

ResourceFunction["ThroughOperator"][{foo}] @@@ res

res

As you see I have used a new resource function, available to us as of 2022 which is called ThroughOperator. This is a development thanks to @Sjoerd Smit.

It was first suggested here. In the comment section under the answer @Sjoerd Smit gives motivation for its development and subsequent use for those interested. It was further used in this thread if you want to further study it.

bmf
  • 15,157
  • 2
  • 26
  • 63
  • 2
    ThroughOperator noted, thanks! Also thank you for the references – Albercoc Feb 09 '23 at 10:20
  • 1
    @Albercoc glad I was able to help. Check the other answer by BobHanlon. It's more direct and really elegant :) – bmf Feb 09 '23 at 10:21
  • 1
    (+1) Very nice. Without being pedantic, I think (since v11.1) that TakeList could be substituted for Internal`PartitionRagged (but you probably already know that)? : res2=TakeList[list,#]&/@Apply[Join, Permutations /@ IntegerPartitions[Length[list]]] – user1066 Feb 09 '23 at 20:26
  • @user1066 you are not being pedantic at all. Indeed, TakeList should have been the go-to approach, I just like undocumented stuff. Maybe a bit too much (blushing) – bmf Feb 10 '23 at 01:52
5
alist = {a, b, c};
ReplaceList[alist, {w__, x___, y___} ->
     {F @@ {w}, F @@ {x}, F @@ {y}}
    ] /. F[] :> Nothing // DeleteDuplicates // Dot @@@ # &

{F[a] . F[b, c], F[a] . F[b] . F[c], F[a, b] . F[c], F[a, b, c]}

Syed
  • 52,495
  • 4
  • 30
  • 85