Re: Modifying arguments of sub-parts of an expression (improved)
- To: mathgroup at smc.vnet.net
- Subject: [mg38888] Re: Modifying arguments of sub-parts of an expression (improved)
- From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
- Date: Fri, 17 Jan 2003 05:39:07 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
Ealier I sent a solution to Gareth Russell's problem.
He had an expression such as
Gamma[a]*Gamma[b]/Beta[a,b]*Gamma[a+b]
and wanted to make a new expression where for every subexpression
with head Gamma,
if the arguments include b, each b is replaced by b+1. I provided a
function that
would make this change. I have a much improved solution below. With
my new version you can
specify the pattern and replacement rule to use!
Here it is:
--------------------------------
In[1]:=
PatternReplaceAll::usage= "PatternReplaceAll[expr, pattern, rule] uses
ReplaceAll
to make the changes specified by rule, but the replacements are only made
to
subexpressions of expr that match pattern. PatternReplaceAll[expr,
pattern,
{rules}] uses one or more rules.";
PatternReplaceAll[expr_, pattn_, {rules:(_Rule|_RuleDelayed)..} ]:=
With[ {posn=Reverse@Sort@Position[Hold@@{expr}, pattn]},
ReleaseHold[Fold[MapAt[ Function[a, a/.{rules}], #1, #2]&,
Hold@@{expr}, posn ]]
]
PatternReplaceAll[ expr_, pattn_, SingleRule:(_Rule| _RuleDelayed) ] :=
PatternReplaceAll[ expr, pattn, {SingleRule} ]
(*-----------------------
(1) (Reverse at Sort...) ensures the later positions in (posn) still apply
even after folding several times.
(2) We can't let the replacements take effect until after Fold is done
because the
position of things may change. To solve that I use Hold@@{expr}.
(3) I don't use (rules__?OptionQ) because OptionQ[n_Integer->n+2] returns
False.
Instead I use rules:(_Rule|_RuleDelayed).
----------------------------*)
Examples:
In[4]:=
ex=b*Gamma[1+a]^2*Gamma[1+b]/Gamma[2, 4+2b]*PolyGamma[2*b]*(b+2)^2;
In[5]:=
PatternReplaceAll[ ex, _Gamma, b->bb]
Out[5]=
(b*(2 + b)^2*Gamma[1 + a]^2*Gamma[1 + bb]*PolyGamma[0, 2*b])/Gamma[2, 4 +
2*bb]
------------------
Next I use a named pattern in the replacement rule!
In[6]:=
PatternReplaceAll[ ex, _Gamma, n_Integer->n+2 ]
Out[6]:=
(b*(2 + b)^2*Gamma[3 + a]^2*Gamma[3 + b]*PolyGamma[0, 2*b])/Gamma[4, 6 +
4*b]
------------------
Next I use a list of replacement rules.
In[7]:=
PatternReplaceAll[ ex, _Gamma, { b->bb, n_Integer->n+2 } ]
Out[7]=
(b*(2 + b)^2*Gamma[3 + a]^2*Gamma[3 + bb]*PolyGamma[0, 2*b])/Gamma[4, 6 +
4*bb]
------------------------
Regards,
Ted Ersek
Download my collection of Mathematica tricks from:
http://www.verbeia.com/mathematica/tips/Tricks.html
and
http://www.verbeia.com/mathematica/tips/GraphicsTricks.html