I am trying to define a function (reduce[x]) which does several substitutions, depending on the values of certain parameters. Concretely, consider an expression x, which contains an arbitrary number of terms of the type J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_}. Crucially, n1, n2 and n3 will always be numbers, while m1, m2 and m3 will always be variables (for example, m) which are either zero or greather than zero.

If n1>1 I wish to do a substitution, otherwise the expression stays the same. Not only that, the replacement will be different whenever m1, m2 and m3 are different than zero and whenever one of them is zero. Therefore, consider the following function which takes whatever expression x containing different terms of J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_} and does the following replacements

reduce[x_] := 
  x /. J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_}] /; 
    m1 != 0 /; m2 != 0 /; m3 != 0 /; n1> 1 /;n2 !=  0 /; n3 != 0 -> n1/m1 /. J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_}] /; 
    m1 = 0 /; m2 != 0 /; m3 != 0 /; n1> 1 /;n2 !=  0 /; n3 != 0 -> n2/m2 /. J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_}] /; 
    m1 != 0 /; m2 = 0 /; m3 != 0 /; n1> 1 /;n2 !=  0 /; n3 != 0 -> n3/m3 /. J[{m1_, n1_}, {m2_, n2_}, {m3_, n3_}] /; 
    m1 != 0 /; m2 != 0 /; m3 = 0 /; n1> 1 /;n2 !=  0 /; n3 != 0 -> n1+n2+n3

where I don't show the rest of replacements whenever two of the m's are zero or all three of them are zero, as hopefully it's not needed to understand my problem. My issue is that m1, m2 and m3 are not numbers, insetad they are variables (that are always equal or greater than zero), and therefore when evaluating

reduce[J[{m, 2}, {m, 1}, {m, 1}]]

The function won't work, as it doesn't know that m is different from zero. I tried defining global assumptions so that m is set to be different than zero, but it doesn't work (even after using Simplify). Therefore I am missing something, I think the issue is that the function expects m1, m2 and m3 to be numbers, and even using assumptions on m1, m2, m3 it doesn't seem to work. Any advice? I have the feeling it should have an easy solution, but I haven't been able to figure it out or find one.

  • $\begingroup$ In reduce[J[{m, 2}, {m, 1}, {m, 1}]] since m does not have a numeric value it cannot be determined to be non-zero in each of the tests for m1, m2 and m3. You would need to eliminate the constraints on m1, m2 and m3. For example, reduce[x_] := x /. (J[{m1_, n1_?(# > 1 &)}, {m2_, n2_?(# != 0 &)}, {m3_, n3_?(# != 0 &)}] :> n1) then reduce[J[{m, 2}, {m, 1}, {m, 1}]] evaluates to 2 $\endgroup$
    – Bob Hanlon
    Dec 1 '20 at 17:04
  • $\begingroup$ I agree with you and that is what I did at first, but my problem is that if one of the m's is zero, then I don't want to do such replacement, I only want it if the m's are different than zero. Otherwise, if any m is zero, another replacement is made, which I am not showing for clarity. So, since the expression x within reduce[x] might contain many J[{m1,n1},{m2,n2},{m3,n3}] with different values of m's, I need to constrain such replacement to only when all m's are different than zero. Is it therefore impossible to do in this manner because m doesn't have a numeric value? $\endgroup$
    – Jordi
    Dec 1 '20 at 17:09
  • $\begingroup$ Try reduce[x_] := x /. (J[{m1_, n1_?(# > 1 &)}, {m2_, n2_?(# != 0 &)}, {m3_, n3_?(# != 0 &)}] :> ConditionalExpression[n1, Simplify[m1 != 0 && m2 != 0 && m3 != 0]]). You could also put all of the tests into the condition for the ConditionalExpression $\endgroup$
    – Bob Hanlon
    Dec 1 '20 at 17:23
  • $\begingroup$ It seems to work, I get the output ConditionalExpression[2,m1!=0&&m2!=0&&m3!=0] for reduce[J[{m, 2}, {m, 1}, {m, 1}]]. It's not exactly what I am looking for though, I only want n1 to be the output as I need to further manipulate the expression. If I understand correctly your code returns n1 and explicitly indicates that all m's must be different than zero, but the code is not checking that they are different than zero. $\endgroup$
    – Jordi
    Dec 1 '20 at 17:32
  • $\begingroup$ With ConditionalExpression you will get Undefined when the test fails. You might instead want to look at using Piecewise No test will work if the m do not have values or you do not include assumptions to Simplify $\endgroup$
    – Bob Hanlon
    Dec 1 '20 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.