Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose I have an expression containing p,Subscript[p,1],Subscript[p,2],etc. I want to replace p with a numerical value while keeping the other two variables intact. How can I do it?

If I naively use /.{p->0.5} for example, I will get Subscript[0.5,1], Subscript[0.5,2] as a result.

share|improve this question
add comment

3 Answers 3

up vote 14 down vote accepted

You wish to make substitutions in all except Subscript expressions I believe. This can be done by leveraging the precedence of replacement rules, like this:

{p, Subscript[p, 1], Subscript[p, 2]} /. {x_Subscript :> x, p -> 1}
{1, Subscript[p, 1], Subscript[p, 2]}

The rule x_Subscript :> x acts first, "replacing" any expression with the head Subscript by itself. Since expressions that have already been replaced are not matched again, the second rule p -> 1 is never applied to these subexpressions.

share|improve this answer
add comment

You could also make one rule that is a bit more specific

{p, Subscript[p, 1], Subscript[p, 2]} //. 
 head_[x___, p, y___] /; head =!= Subscript :> head[x, 0.5, y]

-> {0.5, Subscript[p, 1], Subscript[p, 2]}

This does not work if p is the entire expression. i.e

p/.head_[x___, p, y___] /; head =!= Subscript :> head[x, 0.5, y]

-> p

In that case you will probably have to add another rule. Note also ReplaceRepeated in the above may make things slower than necessary.

Side remark

You could also do something with Block as follows, though this is not replacement but rather evaluation

Block[
 {p = 0.5, Subscript},
 SetAttributes[Subscript, HoldAllComplete];
 {p, Subscript[p, 1], Subscript[p, 2]}
 ]

-> {0.5, Subscript[p, 1], Subscript[p, 2]}

share|improve this answer
    
This also has a problem if p exists twice in an expression for the same reason that my answer works. For example, with expression (p + p^2)/Subscript[p, 1]. I suggest amending your answer to use //. but that can be inefficient. –  Mr.Wizard May 20 '13 at 12:55
    
@Mr.Wizard Thanks, I changed it. I guess in light of the new insights that Mathematica remembers if expressions have changed anyway, the "checking if the expression has changed" step of ReplaceRepeated must take negligable time. I suppose MMA just goes through the expression twice if use //., which is the same as in your answer where you use two rules. But then your rules are simpler, so your solution must be better in terms of speed, and I can see ever more desirable properties of your answer :). Anyway, +1 for you –  Jacob Akkerboom May 20 '13 at 13:50
    
That was silly of me. It goes through the expression much more often. Changing –  Jacob Akkerboom May 20 '13 at 13:52
1  
+1 for the Block solution! A very nice addition. –  Mr.Wizard May 20 '13 at 14:45
add comment

Another way is to use level specification in Replace :

Replace[{p, Subscript[p, 1], Subscript[p, 2]} , p -> 0.5, 1]
(* {0.5, Subscript[p, 1], Subscript[p, 2]} *)
share|improve this answer
1  
I don't think it is reasonable to assume that the replacements should happen on a particular level. Consider for example: p^2 + Subscript[p, 1] + Subscript[p, 2] –  Mr.Wizard May 20 '13 at 9:46
    
@Mr.Wizard I agree it's not the most generic solution. –  b.gatessucks May 20 '13 at 9:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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