0

I want to do a replacements such that: f[P1,P2,P3] goes to P1[a]P2[b]P3[c] g[a,b,c] where I want the a,b,c to be unique.

More general, I want products like f[P1,P2,P3] f[Q1,Q2,Q3] to go to P1[a1]P2[b1]P3[c1] g[a1,b1,c1] Q1[a2]Q2[b2]Q3[c2] g[a2,b2,c2] where again a1,a2,b1,b2,c1,c2 are guaranteed to be unique non conflicting characters.

Kvothe
  • 4,419
  • 9
  • 28
  • 1
    This looks awfully like an XY problem. What are you actually trying to do here? – J. M.'s missing motivation Jul 26 '17 at 13:14
  • @J.M. Sure I will update the question in a minute and include X (XY problem), but does that mean that there is no very simple solution to this question itself? (Since you seem to think the underlying problem is easier to solve in a different way.). I would think that this is a very fundamental operation that would have way more applications than the specific problem I am trying to solve right now. – Kvothe Jul 26 '17 at 13:20
  • Local replacement can be done through ReplacePart[], but this seems like a very unwieldy way of doing what you want here. – J. M.'s missing motivation Jul 26 '17 at 13:22
  • @Carl, great, hadn't found that one. I agree that is the same question. This should be marked a duplicate (can't do that myself right?). – Kvothe Jul 26 '17 at 13:52
  • Or you can change your question to what you actually want to do. Something like f[P1, P2, P3] /. f[a__] :> With[{v = Table[Unique[], Length[{a}]]}, Inner[Compose, {a}, v, Times] g @@ v] would work. – Carl Woll Jul 26 '17 at 13:54
  • Maybe it would be possible to solve your problem using build-in tensor algebra functions. – K.J. Jul 26 '17 at 13:59
  • We can reopen if you can refocus your question as Carl suggested. – J. M.'s missing motivation Jul 26 '17 at 14:00
  • @Carl, thanks you very much. You gave me both the practical answer and led me to the one that let me satisfy my curiosity. I will change the question to focus on the real problem so that your comment is the appropriate answer. I should have kept looking for the right replacement rule a bit longer. You have great skills that you saw the solution instantly (but I guess you have quite some experience with Mathematica, seeing how the documentation says Compose was superseded by Composition in 1991). – Kvothe Jul 26 '17 at 14:28

1 Answers1

4

You can use the following replacement rule to achieve what you want:

f[P1, P2, P3] /. f[a__] :> With[{v=Table[Unique[],Length[{a}]]},
    Inner[Compose, {a}, v, Times] g@@v
]

g[\$9, \$10, \$11] P1[\$9] P2[\$10] P3[\$11]

Note that Compose is a deprecated function that still works, and I like it. You can replace Compose with #1[#2]& if you prefer to use non-deprecated functions.

Also, as @KJ says, you could consider using the built-in tensor algebra functions. For example, you could represent your output as:

TensorContract[
    TensorProduct[P1, P2, P3, g],
    {{1,4}, {2,5}, {3,6}}
]

This representations avoids the need to create dummy indices.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355