From: Matthias Fripp on 24 Jun 2010 04:27 I am having trouble using ReplaceAll to replace symbols that already have a delayed assignment. e.g., this input: In[287]:= a := A c b := B c a /. {a -> x, b -> y} b /. {a -> x, b -> y} a + b /. {a -> x, b -> y} a * b /. {a -> x, b -> y} gives this output: Out[289]= x Out[290]= y Out[291]= x + y Out[292]= A B c^2 All of this works as expected except for the final term. I would have expected to get the result "x y". Is there any way to force Mathematica to produce that result? If on the other hand the original assignment is a := A + c and b := B + c, I get an unexpected output for the sum, but the expected output (x y) for the product. If I insert d instead of one of the c's, I get various other (unpredictable) kinds of result. My first guess is that Mathematica is doing a sort of "double ReplaceAll", where it first tries the pattern given in the delayed assignment, and any symbols matched by that are not tested against the explicit ReplaceAll. But that doesn't explain why the sum works and not the product. Am I thinking about this the wrong way? Thanks for any help you can give! Matthias Fripp
From: Albert Retey on 25 Jun 2010 07:24 Am 24.06.2010 10:27, schrieb Matthias Fripp: > I am having trouble using ReplaceAll to replace symbols that already > have a delayed assignment. > > e.g., this input: > > In[287]:= > a := A c > b := B c > a /. {a -> x, b -> y} > b /. {a -> x, b -> y} > a + b /. {a -> x, b -> y} > a * b /. {a -> x, b -> y} > > gives this output: > > Out[289]= x > > Out[290]= y > > Out[291]= x + y > > Out[292]= A B c^2 > > All of this works as expected except for the final term. I would have > expected to get the result "x y". Is there any way to force > Mathematica to produce that result? > > If on the other hand the original assignment is a := A + c and b := B > + c, I get an unexpected output for the sum, but the expected output > (x y) for the product. If I insert d instead of one of the c's, I get > various other (unpredictable) kinds of result. > > My first guess is that Mathematica is doing a sort of "double > ReplaceAll", where it first tries the pattern given in the delayed > assignment, and any symbols matched by that are not tested against the > explicit ReplaceAll. But that doesn't explain why the sum works and > not the product. Am I thinking about this the wrong way? No, what actually happens is that a and b are evaluated to A*c and B*c respectively, even before the ReplaceAll sees them. Then the ReplaceAll sees A*c+B*c /. {A*c -> x, B*c -> y} A*B*c^2 /. {A*c -> x, B*c -> y} where it will find matches in the first case but not in the second and so does nothing. There are two things you need to understand: first is the evaluation order, second is the fact that replacement rules work on structure, not on mathematical relations. Both are topics that you will a lot of information in the documentation and in the archive of this group. I would recommend to search for "evaluation order" and "pattern matching" in the documentation and read, well as much as you want to learn... hth, albert
From: Bill Rowe on 25 Jun 2010 07:25 On 6/24/10 at 4:27 AM, mfripp(a)gmail.com (Matthias Fripp) wrote: >I am having trouble using ReplaceAll to replace symbols that already >have a delayed assignment. >e.g., this input: >In[287]:= >a := A c >b := B c >a /. {a -> x, b -> y} >b /. {a -> x, b -> y} >a + b /. {a -> x, b -> y} >a * b /. {a -> x, b -> y} >gives this output: >Out[289]= x >Out[290]= y >Out[291]= x + y >Out[292]= A B c^2 >All of this works as expected except for the final term. I would >have expected to get the result "x y". Is there any way to force >Mathematica to produce that result? In[10]:= a := A c b := B c In[12]:= a*b /. {A -> x/c, B -> y/c} Out[12]= x y The reason this needs to be different than the others is due to the way Mathematica's evaluator works. In everyone of your examples a,b are replaced by A c and B c when Mathematica encounters them as expected by using SetDelayed. After the replacement occurs, then evaluation of the specified operations on the left hand side of /. occurs. In each case except for the last, this leaves an expression with in terms of A c and B c. So, in those cases when a,b on the right hand side get evaluated, they match something on the left hand side and the replacement occurs as you want. But in the last case, the multiplication operation yields the result (in FullForm) of Times[A, B, Power[c,2]] Since nothing in this matches either Times[A, c] or Times[B, c], the replacement you are looking for does not occur. My work around does what you want since there is a match for A and B. >If on the other hand the original assignment is a := A + c and b := >B + c, I get an unexpected output for the sum, but the expected >output (x y) for the product. If I insert d instead of one of the >c's, I get various other (unpredictable) kinds of result. This fails for the same reason a * b /. {a -> x, b -> y} failed. That is, with these assignments, a + b will evaluate to (in FullForm) Plus[A, B, Times[2, c]] Again, there will be nothing to match either A+c or B+c and the replacement fails. >My first guess is that Mathematica is doing a sort of "double >ReplaceAll", where it first tries the pattern given in the delayed >assignment, and any symbols matched by that are not tested against >the explicit ReplaceAll. But that doesn't explain why the sum works >and not the product. Am I thinking about this the wrong way? Yes, your thinking here is incorrect. Note you can verify what occurs by using Trace. For example, In[18]:= a + b /. {a -> x, b -> y} // Trace Out[18]= {{{a,A+c},{b,B+c},(A+c)+(B+c),A+c+B+c,A+B+c+c,A+B+2 c},{{{a,A+c},A+c->x,A+c->x},{{b,B+c},B+c->y,B+c->y},{A+c->x,B+c->y}},A+B+2= c/.{A+c->x,B+c->y},A+B+2 c} Here you can see the evaluation of a+b to A+B+2c occurs before the replacement rule evaluates as I described above. The consequence is, there is no match for either A+c or B+c. A key point about replacement rules is these are implemented as literal replacements. There is no mathematic operation being by the replacement rules. Any mathematics is done on the left hand side before the replacement. Further mathematics may be done after the replacement depending on the nature of the replacement. But the replacement itself does not do mathematic operations.
From: Leonid Shifrin on 25 Jun 2010 07:26 Hi Matthias, the problem is that in all rules you used, symbols <a> and <b> evaluated to their respective values A*c and B*c before any rule substitution took place, both in the rules and in the expressions to which you apply the rules. This can be easily tracked by using Trace: In[1]:= a:=A c b:=B c In[3]:= Trace[a/.{a->x,b->y},ReplaceAll] Out[3]= {A c/.{A c->x,B c->y},x} In[4]:= Trace[b/.{a->x,b->y},ReplaceAll] Out[4]= {B c/.{A c->x,B c->y},y} In[5]:= Trace[a+b/.{a->x,b->y},ReplaceAll] Out[5]= {A c+B c/.{A c->x,B c->y},x+y} In[6]:= Trace[a*b/.{a->x,b->y},ReplaceAll] Out[6]= {A B c^2/.{A c->x,B c->y},A B c^2} So you see, the actual expressions used by ReplaceAll are not at all those you started with, hence the results. Presumably, you wanted to prevent evaluation of both expressions and rules, at least until the rule applies. You can use Unevaluated and HoldPattern for this purpose: In[7]:= Unevaluated[a] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} Out[7]= x In[8]:= Unevaluated[b] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} Out[8]= y In[9]:= Unevaluated[a + b] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} Out[9]= x + y In[10]:= Unevaluated[a*b] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} Out[10]= x y You can use Trace as above to see that now the actual expressions used in ReplaceAll are what you probably had in mind. However, if you have a choice, I wouldn't make the assignments to <a> and <b> in the first place, or make them local rules and apply after all other rules have been applied. Hope this helps. Regards, Leonid On Thu, Jun 24, 2010 at 1:27 AM, Matthias Fripp <mfripp(a)gmail.com> wrote: > I am having trouble using ReplaceAll to replace symbols that already > have a delayed assignment. > > e.g., this input: > > In[287]:= > a := A c > b := B c > a /. {a -> x, b -> y} > b /. {a -> x, b -> y} > a + b /. {a -> x, b -> y} > a * b /. {a -> x, b -> y} > > gives this output: > > Out[289]= x > > Out[290]= y > > Out[291]= x + y > > Out[292]= A B c^2 > > All of this works as expected except for the final term. I would have > expected to get the result "x y". Is there any way to force > Mathematica to produce that result? > > If on the other hand the original assignment is a := A + c and b := B > + c, I get an unexpected output for the sum, but the expected output > (x y) for the product. If I insert d instead of one of the c's, I get > various other (unpredictable) kinds of result. > > My first guess is that Mathematica is doing a sort of "double > ReplaceAll", where it first tries the pattern given in the delayed > assignment, and any symbols matched by that are not tested against the > explicit ReplaceAll. But that doesn't explain why the sum works and > not the product. Am I thinking about this the wrong way? > > Thanks for any help you can give! > > Matthias Fripp > >
From: Matthias Fripp on 25 Jun 2010 07:26 Hi Leonid, Thanks -- your explanation is very helpful. The descriptions of the Trace, Unevaluated and HoldPattern functions are also very useful. It would have taken me a while to find them on my own! I'm surprised to see that Mathematica evaluates the main expression as far as possible before applying any replacement rules. It would seem more "natural" to me to apply the replacements first, then go to work on the expression. But I suppose there's a certain logic to this. At least now I know how to apply the rules before the expression is evaluated (which will be useful in other situations as well). I'm equally surprised that Mathematica applies the delayed assignment (a := A c) to the left hand side of the ReplaceAll rule (a -> x). But at least now I know what to watch out for and how to work around it! Thanks very much for your help. Matthias On Jun 24, 2010, at 12:59 PM, Leonid Shifrin wrote: > Hi Matthias, > > the problem is that in all rules you used, symbols <a> and <b> > evaluated to their respective values A*c and B*c before any rule > substitution took place, both in the rules and in the expressions to > which you apply the rules. This can be easily tracked by using Trace: > > In[1]:= > a:=A c > b:=B c > > In[3]:= Trace[a/.{a->x,b->y},ReplaceAll] > > Out[3]= {A c/.{A c->x,B c->y},x} > > In[4]:= Trace[b/.{a->x,b->y},ReplaceAll] > > Out[4]= {B c/.{A c->x,B c->y},y} > > In[5]:= Trace[a+b/.{a->x,b->y},ReplaceAll] > > Out[5]= {A c+B c/.{A c->x,B c->y},x+y} > > In[6]:= Trace[a*b/.{a->x,b->y},ReplaceAll] > > Out[6]= {A B c^2/.{A c->x,B c->y},A B c^2} > > So you see, the actual expressions used by ReplaceAll are not at > all those you started with, hence the results. Presumably, you > wanted to prevent evaluation of both expressions and rules, at least > until the rule applies. You can use Unevaluated and HoldPattern for > this purpose: > > In[7]:= > Unevaluated[a] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} > > Out[7]= x > > In[8]:= Unevaluated[b] /. {HoldPattern[a] -> x, HoldPattern[b] -> y} > > Out[8]= y > > In[9]:= Unevaluated[a + b] /. {HoldPattern[a] -> x, > HoldPattern[b] -> y} > > Out[9]= x + y > > In[10]:= Unevaluated[a*b] /. {HoldPattern[a] -> x, HoldPattern[b] -> > y} > > Out[10]= x y > > You can use Trace as above to see that now the actual expressions > used in ReplaceAll are what you probably had in mind. However, if > you have a choice, I wouldn't make the assignments to <a> and <b> > in the first place, or make them local rules and apply after all > other rules have been applied. > > Hope this helps. > > Regards, > Leonid > > > > > > On Thu, Jun 24, 2010 at 1:27 AM, Matthias Fripp <mfripp(a)gmail.com> > wrote: > I am having trouble using ReplaceAll to replace symbols that already > have a delayed assignment. > > e.g., this input: > > In[287]:= > a := A c > b := B c > a /. {a -> x, b -> y} > b /. {a -> x, b -> y} > a + b /. {a -> x, b -> y} > a * b /. {a -> x, b -> y} > > gives this output: > > Out[289]= x > > Out[290]= y > > Out[291]= x + y > > Out[292]= A B c^2 > > All of this works as expected except for the final term. I would have > expected to get the result "x y". Is there any way to force > Mathematica to produce that result? > > If on the other hand the original assignment is a := A + c and b := B > + c, I get an unexpected output for the sum, but the expected output > (x y) for the product. If I insert d instead of one of the c's, I get > various other (unpredictable) kinds of result. > > My first guess is that Mathematica is doing a sort of "double > ReplaceAll", where it first tries the pattern given in the delayed > assignment, and any symbols matched by that are not tested against the > explicit ReplaceAll. But that doesn't explain why the sum works and > not the product. Am I thinking about this the wrong way? > > Thanks for any help you can give! > > Matthias Fripp > >
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Export 3D graphics to Web page (a la LiveGraphics3D) Next: ContourStyle Question |