KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > xjep > rewriteRules > ExpandPower


1 /* @author rich
2  * Created on 01-Oct-2004
3  *
4  * This code is covered by a Creative Commons
5  * Attribution, Non Commercial, Share Alike license
6  * <a HREF="http://creativecommons.org/licenses/by-nc-sa/1.0">License</a>
7  */

8 package org.lsmp.djep.xjep.rewriteRules;
9
10 import org.lsmp.djep.xjep.RewriteRuleI;
11 import org.nfunk.jep.*;
12 import org.lsmp.djep.xjep.*;
13
14 /**
15  * @author Rich Morris
16  * Created on 01-Oct-2004
17  */

18 public class ExpandPower implements RewriteRuleI {
19
20     private NodeFactory nf;
21     private OperatorSet opSet;
22     private TreeUtils tu;
23     private XJep xj;
24
25     /**
26      *
27      */

28     public ExpandPower(XJep xj) {
29         opSet = xj.getOperatorSet();
30         tu = xj.getTreeUtils();
31         nf = xj.getNodeFactory();
32         this.xj = xj;
33     }
34     private ExpandPower() {}
35     /* (non-Javadoc)
36      * @see org.lsmp.djep.xjep.RewriteRuleI#test(org.nfunk.jep.Node, org.nfunk.jep.Node[])
37      */

38     public boolean test(ASTFunNode node, Node[] children) {
39         if(!node.isOperator()) return false;
40         XOperator op= (XOperator) node.getOperator();
41
42         if(opSet.getPower() == op)
43         {
44             if(tu.getOperator(children[0]) == opSet.getAdd()
45              || tu.getOperator(children[0]) == opSet.getSubtract())
46             {
47                 return tu.isInteger(children[1]) && (tu.isPositive(children[1]) || tu.isZero(children[1]));
48             }
49             return false;
50         }
51         return false;
52     }
53
54     /* (non-Javadoc)
55      * @see org.lsmp.djep.xjep.RewriteRuleI#apply(org.nfunk.jep.Node, org.nfunk.jep.Node[])
56      */

57     public Node apply(ASTFunNode node, Node[] children) throws ParseException {
58         OperatorSet opSet = xj.getOperatorSet();
59         TreeUtils tu = xj.getTreeUtils();
60         
61         Operator lhsOp = tu.getOperator(children[0]);
62         int n = tu.intValue(children[1]);
63         Node sub1 = children[0].jjtGetChild(0);
64         Node sub2 = children[0].jjtGetChild(1);
65         
66         if(lhsOp == opSet.getAdd() || lhsOp == opSet.getSubtract())
67         { /* (a+b)^n --> (a^n+nC1 a^(n-1) b + ....) */
68             if(n == 0) return nf.buildConstantNode(new Double JavaDoc(1));
69             if(n == 1) return children[0];
70             
71             Node vals[] = new Node[(int) n+1];
72             /* a^n */
73             vals[0] = nf.buildOperatorNode(
74                 opSet.getPower(),
75                 xj.deepCopy(sub1),
76                 nf.buildConstantNode(new Double JavaDoc(n))
77                 );
78             if(n==2)
79             {
80                 vals[1]=nf.buildOperatorNode(
81                     opSet.getMultiply(),
82                     nf.buildConstantNode(new Double JavaDoc(2)),
83                     nf.buildOperatorNode(
84                         opSet.getMultiply(),
85                         xj.deepCopy(sub1),
86                         xj.deepCopy(sub2)));
87             }
88             else
89             {
90                 /* n * a^(n-1) * b */
91                 vals[1]=nf.buildOperatorNode(
92                     opSet.getMultiply(),
93                     nf.buildConstantNode(new Double JavaDoc(n)),
94                     nf.buildOperatorNode(
95                         opSet.getMultiply(),
96                         nf.buildOperatorNode(
97                             opSet.getPower(),
98                             xj.deepCopy(sub1),
99                             nf.buildConstantNode(new Double JavaDoc(n-1))),
100                         xj.deepCopy(sub2)));
101             }
102             /* n * a * b^(n-1) */
103             if(n>=3)
104             {
105                 vals[n-1] = nf.buildOperatorNode(
106                 opSet.getMultiply(),
107                 nf.buildConstantNode(new Double JavaDoc(n)),
108                 nf.buildOperatorNode(
109                     opSet.getMultiply(),
110                     xj.deepCopy(sub1),
111                     nf.buildOperatorNode(
112                         opSet.getPower(),
113                         xj.deepCopy(sub2),
114                         nf.buildConstantNode(new Double JavaDoc(n-1)))));
115             }
116             /* a^n */
117             vals[n] = nf.buildOperatorNode(
118                 opSet.getPower(),
119                 xj.deepCopy(sub2),
120                 nf.buildConstantNode(new Double JavaDoc(n))
121                 );
122             for(int i=2;i<n-1;++i)
123             {
124                 /* (n,i) * a^(n-i) * b^i */
125                 vals[i]=nf.buildOperatorNode(
126                     opSet.getMultiply(),
127                     nf.buildConstantNode(new Double JavaDoc(XMath.binomial(n,i))),
128                     nf.buildOperatorNode(
129                         opSet.getMultiply(),
130                         nf.buildOperatorNode(
131                             opSet.getPower(),
132                             xj.deepCopy(sub1),
133                             nf.buildConstantNode(new Double JavaDoc(n-i))),
134                         nf.buildOperatorNode(
135                             opSet.getPower(),
136                             xj.deepCopy(sub2),
137                             nf.buildConstantNode(new Double JavaDoc(i)))));
138             }
139 // for(int i=0;i<=n;++i)
140
// {
141
// System.out.print("val["+i+"] ");
142
// xj.println(vals[i]);
143
// }
144
Node sums[] = new Node[n+1];
145             sums[n]=vals[n];
146             for(int i=n-1;i>=0;--i)
147             {
148                 sums[i] = nf.buildOperatorNode(
149                     lhsOp,
150                     vals[i],
151                     sums[i+1]);
152             }
153 // xj.println(sums[0]);
154
return sums[0];
155         }
156         throw new ParseException("ExpandBrackets at least one child must be + or -");
157     }
158
159 }
160
Popular Tags