4
$\begingroup$

Somewhat related to a previous question, I'm experimenting with ReplaceList to get the list of all possible transformations we can obtain by applying a rule to an expression. But I don't manage to make it work as expected:

expr := 1+Cos[ω t - π/4 + 3π/4]
rule := Cos[a_ + b_] -> X[a,b]
ReplaceList[expr,{ rule }]

I expected the result:

>     { 1+X[ω t - π/4, 3π/4], 1+X[ω t, -π/4 + 3π/4] }

But instead, I obtain:

{}

Why is Mathematica unable to apply rule on expr? How should I fix my code to obtain the expected result?


As an extra requirement, I missed the fact that ReplaceAll like Replace "does not map down to subparts".

I'm probably looking for a mix between ReplaceList and Cases (?)


As per comment, to avoid Mathematica to rewrite the expression as a sinus, I tried wrapping it inside various Hold* functions--in no case, the rule is applied.

expr := Hold[1+Cos[ω t - π/4 + 3π/4]]
expr := HoldForm[1+Cos[ω t - π/4 + 3π/4]]
expr := HoldComplete[1+Cos[ω t - π/4 + 3π/4]]
$\endgroup$
  • 2
    $\begingroup$ because mathematica automatically rewrites expr as Sin[t \[Omega]] $\endgroup$ – Nasser Dec 13 '19 at 22:38
  • 1
    $\begingroup$ Because expr evaluates to -Sin[t ω], which does not contain any expression with Cos head, so nothing in it matches the left-hand side of your rule? I also find your rule definition using SetDelayed somewhat odd, so I wonder whether there might not be a misunderstanding there. Why should it matter that rule is evaluated every time it is called? $\endgroup$ – MarcoB Dec 13 '19 at 22:39
  • $\begingroup$ Thanks both of you for the comments. @Nasser, I tried wrapping the expression definition in Hold, HoldForm and HoldComplete. It prevents rewriting the expression as as sinus--but the rule still doesn't apply. $\endgroup$ – Sylvain Leroux Dec 13 '19 at 22:44
  • $\begingroup$ @Marco "I also find your rule definition using SetDelayed somewhat odd, so I wonder whether there might not be a misunderstanding there." Indeed. What would be the consequences of using SetDelayed instead of Set? $\endgroup$ – Sylvain Leroux Dec 13 '19 at 22:45
  • 1
    $\begingroup$ @Sylvain I think you might want RuleDelayed (:>) rather than SetDelayed, i.e. you would want to delay the evaluation of the right-hand side of the rule until a and b have been given values. I have put the rest in an answer cause it was getting too long for comments. $\endgroup$ – MarcoB Dec 13 '19 at 22:51
2
$\begingroup$

As discussed in comments, you have to somehow prevent MMA from rewriting your Cos expression, which you can accomplish with a Hold function. I am still not sure that I understand the intended outcome, but I wonder if this is what you are after:

Clear[expr, rule]
expr = HoldForm@Cos[ω t - π/4 + 3 π/4]
rule = HoldForm@Cos[a_ + b_] :> X[a, b]
ReplaceList[expr, rule]

(* Out: 
{X[t ω, π/2], X[-(π/4), (3 π)/4 + t ω], 
 X[(3 π)/4, -(π/4) + t ω], 
 X[-(π/4) + t ω, (3 π)/4], 
 X[(3 π)/4 + t ω, -(π/4)], X[π/2, t ω]}
*)
| improve this answer | |
$\endgroup$
  • $\begingroup$ Yes, that's what I was looking for. One question though: why in another answer given by @ChrisDegnen he has to use ReleaseHold whereas you don't need it? I also notice in his answer - π/4 + 3 π/4 was replaced by -π/2 (something I don't want). Is that related to ReleaseHold? $\endgroup$ – Sylvain Leroux Dec 13 '19 at 22:56
  • $\begingroup$ Ouch: I failed to notice that ReplaceAll does not apply to subparts. I've edited the question accordingly. Sorry for having wasted your time. $\endgroup$ – Sylvain Leroux Dec 13 '19 at 23:20
2
$\begingroup$

Try this instead

expr := Hold[Cos[ω t - π/4 + 3 π/4]]
rule := Cos[a_ + b_] :> X[a, b]
ReleaseHold[ReplaceAll[expr, {rule}]]
X[t ω, π/2]

In reply to the comment

expr := Hold[Cos[ω t - π/4 + 3 π/4]]
rule := Cos[a_] :> (a /. List -> X)
ReleaseHold[ReplaceAll[expr /. Plus -> List, {rule}]]
X[t ω, -(π/4), (3 π)/4]

I'm sure there is a simpler way.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks, @Chris. Is there a way to prevent - π/4 + 3 π/4 to be reduced to -π/2? $\endgroup$ – Sylvain Leroux Dec 13 '19 at 22:58
  • $\begingroup$ I failed to notice that ReplaceAll does not apply to subparts. I've edited the question accordingly. Sorry @Chris for having wasted your time. $\endgroup$ – Sylvain Leroux Dec 13 '19 at 23:20
1
$\begingroup$

You may be trying to solve the wrong problem. It is better to define a rule that applies to all the forms in which your expression might appear. For example

expr = Cos[ω t - π/4 + (3 π)/4]
(* -Sin[t ω] *)

rule = {Cos[a_ + b_.] -> X[a, b], Sin[a_ + b_.] -> X[a, -(π/2) + b]};

expr /. rule
(* -X[t ω, -(π/2)] *)
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thnaks @mikado. I don't have checked your answer yet--but I wanted to warn you ASAP I've edited the question because I failed to notice initially Replace was not replacing down to subexpressions. Sorry for that. $\endgroup$ – Sylvain Leroux Dec 13 '19 at 23:22
1
$\begingroup$

Perhaps this approach is more in keeping with your coding style.

expr = Inactivate[1 + Cos[ω t - π/4 + 3 π/4], Cos]
rule = Inactive[Cos][Plus[args__]] -> X[args]
ReplaceAll[expr, rule]

1 + X[π/2 + t ω]

Notes

  • Personally, I prefer the short form
    expr /. rule
    
    to using ReplaceAll.
  • The revised rule you see above was written after I inspected
    expr // FullForm
    

    Plus[1, Inactive[Cos][Plus[Times[Rational[1, 2], Pi], Times[t, ω]]]]

| improve this answer | |
$\endgroup$

Your Answer

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

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