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