Operating on Level Subparts of an Expression
- To: mathgroup at smc.vnet.net
- Subject: [mg36303] Operating on Level Subparts of an Expression
- From: "David Park" <djmp at earthlink.net>
- Date: Fri, 30 Aug 2002 01:19:31 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Yesterday I posted a question on using named patterns in a rule. I received a number of useful replies and thank all those who responded. Today I have a question that actually generated yesterday's question. I am using a new subject heading to reflect the actual nature of the question. What is the best way in Mathematica to operate on some, but not all, level parts of an expression or subexpression? Suppose I have the following expression... expr = f1[a]f2[b]f3[c]f4[d]; and I want to do an operation, op, separately on f1[a]f3[c] and f2[b]f4[d]. The operation must be done on the given pairs and not on all four factors at once. One method is to use explicit exact substitution rules. expr /. f1[a]f3[c] :> op[f1[a]f3[c]] /. f2[b]f4[d] :> op[f2[b]f4[d]] op[f1[a] f3[c]] op[f2[b] f4[d]] If a,b,c,d were long expressions, we might not want to type or copy them in. This raised my question of using named patterns. Hartmut Wolf pointed out that each factor must be named to create a match with flat expressions. So we could use... expr /. (a : f1[_])(b : f3[_])(c : f2[_])(d : f4[_]) :> op[a b]op[c d] op[f1[a] f3[c]] op[f2[b] f4[d]] Andrzej Kozlowski suggested a method using Take, but using Part works better here, so we could use... expr /. a_ :> op[a[[{1, 3}]]]*op[a[[{2, 4}]]] op[f1[a] f3[c]] op[f2[b] f4[d]] All of the above methods use rules. Is it possible to do it with ReplacePart? I don't think so, but maybe somebody knows how to do it. How about using MapAt? I don't think that works either in regular Mathematica. Ted Ersek and I did a package, Algebra`ExpressionManipulation` at my web site, that implements extended positions. An extended position gives the position of an expression and a list of the desired subparts and is packaged in a header eP. So the extended position of a + c in f[a + b + c + d] is eP[{1},{1,3}]. The package modifies MapAt to accept extended positions. Then we can use... MapAt[op, expr, {eP[{}, {1, 3}], eP[{}, {2, 4}]}] op[f1[a] f3[c]] op[f2[b] f4[d]] However, I don't always like to drag in the package just to do that. I think that operating on selected level parts of a subexpression is not all that uncommon. Here is another example. 1 - Cos[x]^2 % // TrigFactor 1 - Cos[x]^2 Sin[x]^2 But... 1 - a - Cos[x]^2 % // TrigFactor 1 - a - Cos[x]^2 (1/2)*(1 - 2*a - Cos[2*x]) I was hoping for -a + Sin[x]^2. What are the best methods for handling this kind of problem in regular Mathematica? David Park djmp at earthlink.net http://home.earthlink.net/~djmp/ David Park djmp at earthlink.net http://home.earthlink.net/~djmp/