KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > matrixJep > MatrixPreprocessor


1 /* @author rich
2  * Created on 30-Oct-2003
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.matrixJep;
9 import org.nfunk.jep.*;
10 import org.nfunk.jep.function.*;
11 import org.lsmp.djep.djep.*;
12 import org.lsmp.djep.xjep.*;
13 import org.lsmp.djep.matrixJep.nodeTypes.*;
14 import org.lsmp.djep.vectorJep.*;
15 import org.lsmp.djep.vectorJep.function.*;
16 /**
17  * This visitor does the majority of preprocessing work.
18  * Specifically it
19  * <ul>
20  * <li>Sets the dimension of each node.
21  * <li>For assignment equations it adds an entry in the VariableTable
22  * <li>For diff opperator it calculates the derivative.
23  * <li>For the List opperator it finds the dimensions and
24  * returns a ASTTensor.
25  * <li>For the Hat opperator it finds the dimension and returns
26  * a Power or Wedge opperator.
27  * </ul>
28  * The visitor will return a new Tree.
29  *
30  * @author Rich Morris
31  * Created on 30-Oct-2003
32  */

33 public class MatrixPreprocessor implements ParserVisitor
34 {
35     private MatrixJep mjep;
36     private MatrixNodeFactory nf;
37     private MatrixOperatorSet opSet;
38     private DSymbolTable vt;
39
40     public MatrixPreprocessor() {}
41
42     /**
43      * Main entry point: preprocess a node.
44      * @param node Top node of tree.
45      * @param mdjep Reference to MatrixJep instance
46      * @return A new tree with all preprocessing carried out.
47      * @throws ParseException
48      */

49     public MatrixNodeI preprocess(Node node,MatrixJep mdjep) throws ParseException
50     {
51         this.mjep=mdjep;
52         this.nf=(MatrixNodeFactory) mdjep.getNodeFactory();
53         this.vt=(DSymbolTable) mdjep.getSymbolTable();
54         this.opSet=(MatrixOperatorSet) mdjep.getOperatorSet();
55         return (MatrixNodeI) node.jjtAccept(this,null);
56     }
57     
58     /**
59      * Returns an array of matrix nodes which are the results of visiting each child.
60      */

61     public MatrixNodeI[] visitChildrenAsArray(Node node,Object JavaDoc data) throws ParseException
62     {
63         int nchild = node.jjtGetNumChildren();
64         MatrixNodeI children[] = new MatrixNodeI[nchild];
65         for(int i=0;i<nchild;++i)
66         {
67 // System.out.println("vcaa "+i+" "+node.jjtGetChild(i));
68
MatrixNodeI no = (MatrixNodeI) node.jjtGetChild(i).jjtAccept(this,data);
69 // System.out.println("vcaa "+i+" "+node.jjtGetChild(i)+" done "+no);
70
children[i] = (MatrixNodeI) no;
71         }
72         return children;
73     }
74     
75     ////////////////////////////////////////////////////////////////////
76

77     public Object JavaDoc visit(SimpleNode node, Object JavaDoc data) { return null; }
78     public Object JavaDoc visit(ASTStart node, Object JavaDoc data) { return null; }
79
80     /** constants **/
81     public Object JavaDoc visit(ASTConstant node, Object JavaDoc data) throws ParseException
82     {
83         return nf.buildConstantNode(node.getValue());
84     }
85     /** multidimensions differentiable variables */
86     public Object JavaDoc visit(ASTVarNode node, Object JavaDoc data) throws ParseException
87     {
88         return nf.buildVariableNode(vt.getVar(node.getName()));
89     }
90
91     /** visit functions and operators **/
92     public Object JavaDoc visit(ASTFunNode node, Object JavaDoc data) throws ParseException
93     {
94         if(node.isOperator()) return visitOp(node,data);
95         if(node.getPFMC() instanceof Diff) return visitDiff(node,data);
96         if(node.getPFMC() instanceof CommandVisitorI)
97                 throw new IllegalArgumentException JavaDoc("MatrixPreprocessor: encounterd and instance of CommandVisitorI for function "+node.getName());
98         MatrixNodeI children[] = visitChildrenAsArray(node,data);
99         ASTMFunNode res = (ASTMFunNode) nf.buildFunctionNode(node,children);
100         return res;
101     }
102
103     /** operators +,-,*,/ **/
104     public Object JavaDoc visitOp(ASTFunNode node, Object JavaDoc data) throws ParseException
105     {
106         PostfixMathCommandI pfmc=node.getPFMC();
107 // if(pfmc instanceof SpecialPreProcessI)
108
// {
109
// SpecialPreProcessI spp = (SpecialPreProcessI) node.getPFMC();
110
// return spp.preprocess(node,this,mjep);
111
// }
112
MatrixNodeI children[] = visitChildrenAsArray(node,data);
113
114         if(pfmc instanceof Assign)
115         {
116             if(node.jjtGetNumChildren()!=2) throw new ParseException("Operator "+node.getOperator().getName()+" must have two elements, it has "+children.length);
117             Dimensions rhsDim = children[1].getDim();
118             MatrixVariable var = (MatrixVariable) ((ASTVarNode) children[0]).getVar();
119             var.setDimensions(rhsDim);
120             Node copy =mjep.deepCopy(children[1]);
121             Node simp = mjep.simplify(copy);
122             //Node preproc = (Node) simp.jjtAccept(this,data);
123
var.setEquation(simp);
124             return (ASTMFunNode) nf.buildOperatorNode(node.getOperator(),children,rhsDim);
125         }
126         else if(pfmc instanceof Power || pfmc instanceof MPower)
127         {
128             if(node.jjtGetNumChildren()!=2) throw new ParseException("Operator "+node.getOperator().getName()+" must have two elements, it has "+children.length);
129             Dimensions lhsDim = children[0].getDim();
130             Dimensions rhsDim = children[1].getDim();
131             if(rhsDim.equals(Dimensions.ONE))
132             {
133                 Dimensions dim = lhsDim;
134                 return (ASTMFunNode) nf.buildOperatorNode(
135                         node.getOperator(),children,dim);
136             }
137             else
138             {
139                 Operator op = opSet.getCross();
140                 PostfixMathCommandI pfmc2 = op.getPFMC();
141                 BinaryOperatorI bin = (BinaryOperatorI) pfmc2;
142                 Dimensions dim = bin.calcDim(lhsDim,rhsDim);
143                 return (ASTMFunNode) nf.buildOperatorNode(op,children,dim);
144             }
145         }
146         else if(pfmc instanceof List)
147         {
148             // What if we have x=[1,2]; y = [x,x]; or z=[[1,2],x];
149
// first check if all arguments are TENSORS
150
boolean flag=true;
151             for(int i=0;i<children.length;++i)
152             {
153                 if(children[i] instanceof ASTMFunNode)
154                 {
155                     if(((ASTMFunNode) children[i]).getOperator() != opSet.getMList())
156                     {
157                         flag=false; break;
158                     }
159                 }
160                 else
161                     flag=false; break;
162             }
163
164             if(flag)
165             {
166                 ASTMFunNode opNode1 = (ASTMFunNode) children[0];
167                 Dimensions dim = Dimensions.valueOf(children.length,opNode1.getDim());
168                 ASTMFunNode res = (ASTMFunNode) nf.buildUnfinishedOperatorNode(opSet.getMList());
169                 int k=0;
170                 res.setDim(dim);
171                 res.jjtOpen();
172                 for(int i=0;i<children.length;++i)
173                 {
174                     ASTMFunNode opNode = (ASTMFunNode) children[i];
175                     for(int j=0;j<opNode.jjtGetNumChildren();++j)
176                     {
177                         Node child = opNode.jjtGetChild(j);
178                         res.jjtAddChild(child,k++);
179                         child.jjtSetParent(res);
180                     }
181                 }
182                 res.jjtClose();
183                 return res;
184             }
185             else
186             {
187                 MatrixNodeI node1 = (MatrixNodeI) children[0];
188                 Dimensions dim = Dimensions.valueOf(children.length,node1.getDim());
189                 ASTMFunNode res = (ASTMFunNode) nf.buildOperatorNode(opSet.getMList(),children,dim);
190                 return res;
191             }
192         }
193         else if(pfmc instanceof BinaryOperatorI)
194         {
195             if(node.jjtGetNumChildren()!=2) throw new ParseException("Operator "+node.getOperator().getName()+" must have two elements, it has "+children.length);
196             BinaryOperatorI bin = (BinaryOperatorI) pfmc;
197             Dimensions dim = bin.calcDim(children[0].getDim(),children[1].getDim());
198             return (ASTMFunNode) nf.buildOperatorNode(node.getOperator(),children,dim);
199         }
200         else if(pfmc instanceof UnaryOperatorI)
201         {
202             if(children.length!=1) throw new ParseException("Operator "+node.getOperator().getName()+" must have one elements, it has "+children.length);
203             UnaryOperatorI uni = (UnaryOperatorI) pfmc;
204             Dimensions dim = uni.calcDim(children[0].getDim());
205             return (ASTMFunNode) nf.buildOperatorNode(node.getOperator(),children,dim);
206         }
207         else if(pfmc instanceof NaryOperatorI)
208         {
209             Dimensions dims[] = new Dimensions[children.length];
210             for(int i=0;i<children.length;++i)
211                 dims[i]=((MatrixNodeI) children[i]).getDim();
212             NaryOperatorI uni = (NaryOperatorI) pfmc;
213             Dimensions dim = uni.calcDim(dims);
214             return (ASTMFunNode) nf.buildOperatorNode(node.getOperator(),children,dim);
215         }
216         else
217         {
218             //throw new ParseException("Operator must be unary or binary. It is "+op);
219
Dimensions dim = Dimensions.ONE;
220             return (ASTMFunNode) nf.buildOperatorNode(node.getOperator(),children,dim);
221         }
222     }
223
224     /** the differential opperator
225      * TODO move into an MDiff function
226      * **/

227
228     public Object JavaDoc visitDiff(ASTFunNode node, Object JavaDoc data) throws ParseException
229     {
230         MatrixNodeI children[] = visitChildrenAsArray(node,data);
231         if(children.length != 2)
232             throw new ParseException("Diff opperator should have two children, it has "+children.length);
233         // TODO need to handle diff(x,[x,y])
234
if(!(children[1] instanceof ASTMVarNode))
235             throw new ParseException("rhs of diff opperator should be a variable.");
236         ASTMVarNode varNode = (ASTMVarNode) children[1];
237         Node diff = mjep.differentiate(children[0],varNode.getName());
238         return diff;
239     }
240 }
241
Popular Tags