1
$\begingroup$

I have an expression a which include parts of the form A[i,j], where i,j take a range of values. What I want to do is use a replacement rule on the whole expression whenever such a term is present. Currently my code looks something like

If[(! FreeQ[a, A[i_,j_]]), ReplaceRepeated[a, {a:-> f[a, i, j]}]]

where f[a,i,j] is something that I want to depend on the specific values i,j that appear in a.

The initial check using FreeQ is working, i.e. it identifies whenever A[i_,j_] is present, for arbitrary i,j. However, I'm then not sure how to proceed, because I can't find a way to identify the specific values of i,j that match the pattern.

For example, if a=... + A[1,2] + ..., then I want the replacement a -> f[a,1,2]. My code currently would replace a -> f[a,i,j], and I can't work out how to obtain the specific values of i,j.

Edit: Some more concrete examples are

a = A[1,2]B[1,2] + C[1,2]D[1,2]
a = (A[2,4]B[2,4] + C[2,4]D[2,4])^2 (A[3,2]B[3,2] + C[3,2]D[3,2])

which I would like to turn into

f[1,2]
f[2,4]^2 f[3,2]

respectively. Essentially I know that if A[i,j] appears, then so will the B, C, D terms, and in that case I want to simplify the expressions.

In this case, the above code looks like

If[(! FreeQ[a, A[i_,j_]]), 
    ReplaceRepeated[a, {(A[i,j]B[i,j] + C[i,j]D[i,j]):-> f[a, i, j]}]]

Edit: A longer explanation about the second example. For the example

a = (A[2,4]B[2,4] + C[2,4]D[2,4])^2 (A[3,2]B[3,2] + C[3,2]D[3,2])

I am unable to directly use normal replacement rules, since the expression appears expanded, i.e. as

A[2, 4]^2 A[3, 2] B[2, 4]^2 B[3, 2] + 
 2 A[2, 4] A[3, 2] B[2, 4] B[3, 2] C[2, 4] D[2, 4] + 
 A[3, 2] B[3, 2] C[2, 4]^2 D[2, 4]^2 + 
 A[2, 4]^2 B[2, 4]^2 C[3, 2] D[3, 2] + 
 2 A[2, 4] B[2, 4] C[2, 4] C[3, 2] D[2, 4] D[3, 2] + 
 C[2, 4]^2 C[3, 2] D[2, 4]^2 D[3, 2]

When it is expanded like this, the replacement rule outlined in my code above can't be used directly.

To get around this, I have a function that factorises the expression as

(p // replacement rule) (a/p // Together)

where using e.g. p = A[2,4]B[2,4] + C[2,4]D[2,4] will give me one of the factors I want. But to do this, I need to know which labels i,j are present, so that I can let them appear in p as required. This is why I am trying to extract the labels in this way, and can't use a direct replacement.

$\endgroup$
4
  • 1
    $\begingroup$ Mathematica code usually uses squared brackets f[a,1,2] or A[[i,j]] $\endgroup$ Jan 9 at 10:58
  • $\begingroup$ Thanks, I've fixed that in the question now. $\endgroup$
    – Bedge
    Jan 9 at 11:13
  • $\begingroup$ Welcome to the Mathematica Stack Exchange. Could you please provide a few concrete test cases for a as well as the desired outputs? $\endgroup$
    – Syed
    Jan 9 at 12:02
  • $\begingroup$ I have provided some more examples, I hope that is clearer. $\endgroup$
    – Bedge
    Jan 9 at 13:56

1 Answer 1

0
$\begingroup$

Setting up test data (C and D are reserved, so just for clarity and to avoid the messages, I've slightly renamed all the heads):

test1 = Aa[1, 2] Bb[1, 2] + Cc[1, 2] Dd[1, 2];
test2 = (Aa[2, 4] Bb[2, 4] + Cc[2, 4] Dd[2, 4])^2 (Aa[3, 2] Bb[3, 2] + Cc[3, 2] Dd[3, 2]);

Here is a possible set of replacement rules:

replacements =
  {h1_[i_, j_] h2_[i_, j_] :> f[{h1, h2}, i, j],
   f[h1s_, i_, j_] + f[h2s_, i_, j_] :> f[Join[h1s, h2s], i, j]}

Try them out:

test1 //. replacements

f[{Aa, Bb, Cc, Dd}, 1, 2]

test2 //. replacements

f[{Aa, Bb, Cc, Dd}, 2, 4]^2*f[{Aa, Bb, Cc, Dd}, 3, 2]

Explanation:

First off, yes I know that's not the exact form you wanted, but I was demonstrating that you can also preserve information about the heads that ended up being "grouped". You can just get rid of that bit, but be careful, because it also helps with the arithmetic.

The arithmetic is another point. These replacements pass your two tests, but might not pass more complicated expressions.

Now, if f has a definition that you don't want to evaluate until all of the replacements have been performed, then you may want to use Inactive:

replacements =
  {h1_[i_, j_] h2_[i_, j_] :> Inactive[f][{h1, h2}, i, j],
   Inactive[f][h1s_, i_, j_] + Inactive[f][h2s_, i_, j_] :> 
     Inactive[f][Join[h1s, h2s], i, j]}

Than you can Activate:

test1 //. replacements // Activate

At this point, I'm a bit confused, because you have both f[a,i,j] and f[i,j] in your question, so I'm not sure what you're trying to end up with.

$\endgroup$
4
  • $\begingroup$ Thanks for your answer, but it doesn't quite work. The problem that I tried to explain in my second edit is that I have these objects that I want to condense the form of, but they appear expanded in longer expressions. So usual replacement rules don't work when directly implemented. However, I know that if factor of $A[i, j]$ appears, then the whole thing can be factored. In that case, my division method works, but only if I can identify the indices present in $A[i,j]$. I can do this manually, but what I want is for mathematica to be able to do this for me. Do you know if this is possible? $\endgroup$
    – Bedge
    Jan 16 at 10:42
  • $\begingroup$ Actually, I already took that into account. If it doesn't work, then you need to explain what's different, cause it looks like it works to me. My solution passes all of the tests you've provided so far (modulo the final form of f, which either takes 3 or 2 arguments and I don't understand why/which). $\endgroup$
    – lericr
    Jan 16 at 15:42
  • $\begingroup$ Apologies, I've tried to simplify a more complicated problem, but in doing so, I've made it a lot easier to solve, but with methods that don't generalise. The bottom line is, I need a method that looks like 'if an object $a$ contains an object with general form $A_[i,j]$, is there a way to identify the specific values of $i$ and $j$.' f[a,i,j] is a function I have, which does the replacement rule 'manually', but I have to feed it the correct values of $i,j$, so in that sense it is a function of the total expression a. $\endgroup$
    – Bedge
    Jan 16 at 16:21
  • $\begingroup$ Well, I pointed out that my solution might need enhancing if the arithmetic were more complicated. I don't really know how to be more general without knowing the "direction" of generalization. What I've given you is very general. What I would suggest is that you provide a comprehensive set of test cases. By "test case" I mean an input and an expected output. You could start with a specific example for which my solution doesn't work. $\endgroup$
    – lericr
    Jan 16 at 16:57

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.