KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > io > MathMLExpression


1 package JSci.io;
2
3 import java.lang.Comparable JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Map JavaDoc;
6 import java.util.ArrayList JavaDoc;
7 import JSci.maths.*;
8 import JSci.maths.matrices.*;
9 import JSci.maths.vectors.*;
10 import JSci.maths.groups.AbelianGroup;
11 import JSci.maths.algebras.*;
12 import JSci.maths.fields.*;
13
14 /**
15 * The MathMLExpression class is used by the MathMLParser to
16 * encapsulate math expressions described by the <code>&lt;apply&gt;</code> tag.
17 * @version 0.8
18 * @author Mark Hale
19 */

20 public final class MathMLExpression extends Object JavaDoc {
21         private String JavaDoc operation;
22         private List JavaDoc args=new ArrayList JavaDoc();
23
24         /**
25         * Constructs a MathML expression.
26         */

27         public MathMLExpression() {}
28         /**
29         * Set the operation to be applied to the arguments.
30         * @param op a MathML tag name
31         * (<code>plus</code>, <code>minus</code>, <code>times</code>, <code>divide</code>, etc).
32         */

33         public void setOperation(String JavaDoc op) {
34                 operation=op;
35         }
36         /**
37         * Returns the operation to be applied to the arguments.
38         * @return a MathML tag name.
39         */

40         public String JavaDoc getOperation() {
41                 return operation;
42         }
43         /**
44         * Adds an argument to this expression.
45         */

46         public void addArgument(Object JavaDoc obj) {
47                 args.add(obj);
48         }
49         /**
50         * Returns an argument from this expression.
51         */

52         public Object JavaDoc getArgument(int n) {
53                 return args.get(n);
54         }
55         /**
56         * Returns the number of arguments.
57         */

58         public int length() {
59                 return args.size();
60         }
61         /**
62         * Substitutes a value for a variable in this expression.
63         * @param var the variable to substitute for.
64         * @param value the value of the variable.
65         * @return the expression after substitution.
66         */

67         public MathMLExpression substitute(String JavaDoc var,Object JavaDoc value) {
68                 MathMLExpression subExpr=new MathMLExpression();
69                 subExpr.operation=operation;
70                 Object JavaDoc arg;
71                 for(int i=0;i<length();i++) {
72                         arg=getArgument(i);
73                         if(arg instanceof MathMLExpression)
74                                 arg=((MathMLExpression)arg).substitute(var,value);
75                         else if(arg.equals(var))
76                                 arg=value;
77                         subExpr.addArgument(arg);
78                 }
79                 return subExpr;
80         }
81         /**
82         * Substitutes several values for variables in this expression.
83         * @param vars a hashtable of variables and values to substitute.
84         * @return the expression after substitution.
85         */

86         public MathMLExpression substitute(Map JavaDoc vars) {
87                 MathMLExpression subExpr=new MathMLExpression();
88                 subExpr.operation=operation;
89                 Object JavaDoc arg;
90                 for(int i=0;i<length();i++) {
91                         arg=getArgument(i);
92                         if(arg instanceof MathMLExpression)
93                                 arg=((MathMLExpression)arg).substitute(vars);
94                         else if(vars.containsKey(arg))
95                                 arg=vars.get(arg);
96                         subExpr.addArgument(arg);
97                 }
98                 return subExpr;
99         }
100         /**
101         * Evaluates this expression.
102         */

103         public Object JavaDoc evaluate() {
104                 if(length()==1)
105                         return unaryEvaluate();
106                 else if(length()==2)
107                         return binaryEvaluate();
108                 else
109                         return nAryEvaluate();
110         }
111         /**
112         * Evaluates unary expressions.
113         */

114         private Object JavaDoc unaryEvaluate() {
115                 Object JavaDoc value=getArgument(0);
116                 if(value instanceof MathMLExpression)
117                         value=((MathMLExpression)value).evaluate();
118                 if(operation.equals("abs")) {
119                         if(value instanceof MathDouble)
120                                 value=new MathDouble(Math.abs(((MathDouble)value).value()));
121                         else if(value instanceof Complex)
122                                 value=new MathDouble(((Complex)value).mod());
123                 } else if(operation.equals("arg")) {
124                         if(value instanceof MathDouble) {
125                                 if(((MathDouble)value).value()>=0.0)
126                                         value=RealField.ZERO;
127                                 else
128                                         value=RealField.PI;
129                         } else if(value instanceof Complex)
130                                 value=new MathDouble(((Complex)value).arg());
131                 } else if(operation.equals("real")) {
132                         if(value instanceof Complex)
133                                 value=new MathDouble(((Complex)value).real());
134                         else if(value instanceof AbstractComplexVector)
135                                 value=((AbstractComplexVector)value).real();
136                         else if(value instanceof AbstractComplexMatrix)
137                                 value=((AbstractComplexMatrix)value).real();
138                 } else if(operation.equals("imaginary")) {
139                         if(value instanceof Complex)
140                                 value=new MathDouble(((Complex)value).imag());
141                         else if(value instanceof AbstractComplexVector)
142                                 value=((AbstractComplexVector)value).imag();
143                         else if(value instanceof AbstractComplexMatrix)
144                                 value=((AbstractComplexMatrix)value).imag();
145                 } else if(operation.equals("conjugate")) {
146                         if(value instanceof Complex)
147                                 value=((Complex)value).conjugate();
148                         else if(value instanceof AbstractComplexVector)
149                                 value=((AbstractComplexVector)value).conjugate();
150                         else if(value instanceof AbstractComplexMatrix)
151                                 value=((AbstractComplexMatrix)value).conjugate();
152                 } else if(operation.equals("transpose")) {
153                         if(value instanceof Matrix)
154                                 value=((Matrix)value).transpose();
155                 } else if(operation.equals("exp")) {
156                         if(value instanceof MathDouble)
157                                 value=MathDouble.exp((MathDouble)value);
158                         else if(value instanceof Complex)
159                                 value=Complex.exp((Complex)value);
160                 } else if(operation.equals("ln")) {
161                         if(value instanceof MathDouble)
162                                 value=MathDouble.log((MathDouble)value);
163                         else if(value instanceof Complex)
164                                 value=Complex.log((Complex)value);
165                 } else if(operation.equals("sin")) {
166                         if(value instanceof MathDouble)
167                                 value=MathDouble.sin((MathDouble)value);
168                         else if(value instanceof Complex)
169                                 value=Complex.sin((Complex)value);
170                 } else if(operation.equals("cos")) {
171                         if(value instanceof MathDouble)
172                                 value=MathDouble.cos((MathDouble)value);
173                         else if(value instanceof Complex)
174                                 value=Complex.cos((Complex)value);
175                 } else if(operation.equals("tan")) {
176                         if(value instanceof MathDouble)
177                                 value=MathDouble.tan((MathDouble)value);
178                         else if(value instanceof Complex)
179                                 value=Complex.tan((Complex)value);
180                 } else if(operation.equals("arcsin")) {
181                         if(value instanceof MathDouble)
182                                 value=MathDouble.asin((MathDouble)value);
183                         else if(value instanceof Complex)
184                                 value=Complex.asin((Complex)value);
185                 } else if(operation.equals("arccos")) {
186                         if(value instanceof MathDouble)
187                                 value=MathDouble.acos((MathDouble)value);
188                         else if(value instanceof Complex)
189                                 value=Complex.acos((Complex)value);
190                 } else if(operation.equals("arctan")) {
191                         if(value instanceof MathDouble)
192                                 value=MathDouble.atan((MathDouble)value);
193                         else if(value instanceof Complex)
194                                 value=Complex.atan((Complex)value);
195                 } else if(operation.equals("sinh")) {
196                         if(value instanceof MathDouble)
197                                 value=MathDouble.sinh((MathDouble)value);
198                         else if(value instanceof Complex)
199                                 value=Complex.sinh((Complex)value);
200                 } else if(operation.equals("cosh")) {
201                         if(value instanceof MathDouble)
202                                 value=MathDouble.cosh((MathDouble)value);
203                         else if(value instanceof Complex)
204                                 value=Complex.cosh((Complex)value);
205                 } else if(operation.equals("tanh")) {
206                         if(value instanceof MathDouble)
207                                 value=MathDouble.tanh((MathDouble)value);
208                         else if(value instanceof Complex)
209                                 value=Complex.tanh((Complex)value);
210                 } else if(operation.equals("factorial")) {
211                         if(value instanceof MathDouble)
212                                 value=new MathDouble(ExtraMath.factorial(((MathDouble)value).value()));
213                 } else if(operation.equals("not")) {
214                         if(value instanceof Boolean JavaDoc)
215                                 value=new Boolean JavaDoc(!((Boolean JavaDoc)value).booleanValue());
216                 }
217                 return value;
218         }
219         /**
220         * Evaluates binary expressions.
221         */

222         private Object JavaDoc binaryEvaluate() {
223                 Object JavaDoc value=getArgument(0);
224                 if(value instanceof MathMLExpression)
225                         value=((MathMLExpression)value).evaluate();
226                 Object JavaDoc next=getArgument(1);
227                 if(next instanceof MathMLExpression)
228                         next=((MathMLExpression)next).evaluate();
229                 if(operation.equals("minus")) {
230                         if(value instanceof AbelianGroup.Member)
231                                 value=((AbelianGroup.Member)value).subtract((AbelianGroup.Member)next);
232                 } else if(operation.equals("divide")) {
233                         if(next instanceof Field.Member) {
234                                 if(value instanceof Field.Member)
235                                         value=((Field.Member)value).divide((Field.Member)next);
236                                 else if(value instanceof VectorSpace.Member)
237                                         value=((VectorSpace.Member)value).scalarDivide((Field.Member)next);
238                         }
239                 } else if(operation.equals("scalarproduct")) {
240                         if(value instanceof AbstractDoubleVector)
241                                 value=new MathDouble(((AbstractDoubleVector)value).scalarProduct((AbstractDoubleVector)next));
242                         else if(value instanceof AbstractComplexVector)
243                                 value=((AbstractComplexVector)value).scalarProduct((AbstractComplexVector)next);
244                 } else if(operation.equals("vectorproduct")) {
245                         if(value instanceof Double3Vector)
246                                 value=((Double3Vector)value).multiply((Double3Vector)next);
247                         else if(value instanceof Complex3Vector)
248                                 value=((Complex3Vector)value).multiply((Complex3Vector)next);
249                 } else if(operation.equals("power")) {
250                         if(value instanceof MathDouble)
251                                 value=new MathDouble(Math.pow(((MathDouble)value).value(),((MathDouble)next).value()));
252                 } else if(operation.equals("neq")) {
253                         value=new Boolean JavaDoc(!value.equals(next));
254                 } else
255                         return nAryEvaluate();
256                 return value;
257         }
258         /**
259         * Evaluates n-ary expressions.
260         */

261         private Object JavaDoc nAryEvaluate() {
262                 Object JavaDoc value=getArgument(0);
263                 if(value instanceof MathMLExpression)
264                         value=((MathMLExpression)value).evaluate();
265                 if(operation.equals("plus")) {
266                         if(value instanceof AbelianGroup.Member) {
267                                 AbelianGroup.Member ans=(AbelianGroup.Member)value;
268                                 for(int i=1;i<length();i++) {
269                                         Object JavaDoc next=getArgument(i);
270                                         if(next instanceof MathMLExpression)
271                                                 next=((MathMLExpression)next).evaluate();
272                                         if(next instanceof AbelianGroup.Member)
273                                                 ans=ans.add((AbelianGroup.Member)next);
274                                 }
275                                 value=ans;
276                         }
277                 } else if(operation.equals("times")) {
278                         if(value instanceof Ring.Member) {
279                                 for(int i=1;i<length();i++) {
280                                         Object JavaDoc next=getArgument(i);
281                                         if(next instanceof MathMLExpression)
282                                                 next=((MathMLExpression)next).evaluate();
283                                         if(next instanceof Ring.Member)
284                                                 value=((Ring.Member)value).multiply((Ring.Member)next);
285                                         else if(next instanceof Module.Member)
286                                                 value=((Module.Member)next).scalarMultiply((Ring.Member)value);
287                                 }
288                         }
289                 } else if(operation.equals("min")) {
290                         Comparable JavaDoc ans=(Comparable JavaDoc)value;
291                         for(int i=1;i<length();i++) {
292                                 Object JavaDoc next=getArgument(i);
293                                 if(next instanceof MathMLExpression)
294                                         next=((MathMLExpression)next).evaluate();
295                                 if(ans.compareTo(next)>0)
296                                         ans=(Comparable JavaDoc)next;
297                         }
298                         value=ans;
299                 } else if(operation.equals("max")) {
300                         Comparable JavaDoc ans=(Comparable JavaDoc)value;
301                         for(int i=1;i<length();i++) {
302                                 Object JavaDoc next=getArgument(i);
303                                 if(next instanceof MathMLExpression)
304                                         next=((MathMLExpression)next).evaluate();
305                                 if(ans.compareTo(next)<0)
306                                         ans=(Comparable JavaDoc)next;
307                         }
308                         value=ans;
309                 } else if(operation.equals("mean")) {
310                         value=new MathDouble(mean());
311                 } else if(operation.equals("sdev")) {
312                         value=new MathDouble(Math.sqrt(variance()));
313                 } else if(operation.equals("var")) {
314                         value=new MathDouble(variance());
315                 } else if(operation.equals("median")) {
316                         double nums[]=new double[length()];
317                         nums[0]=((MathDouble)value).value();
318                         for(int i=1;i<nums.length;i++) {
319                                 Object JavaDoc next=getArgument(i);
320                                 if(next instanceof MathMLExpression)
321                                         next=((MathMLExpression)next).evaluate();
322                                 nums[i]=((MathDouble)next).value();
323                         }
324                         value=new MathDouble(ArrayMath.median(nums));
325                 } else if(operation.equals("union")) {
326                         if(value instanceof MathSet) {
327                                 MathSet ans=(MathSet)value;
328                                 for(int i=1;i<length();i++) {
329                                         Object JavaDoc next=getArgument(i);
330                                         if(next instanceof MathMLExpression)
331                                                 next=((MathMLExpression)next).evaluate();
332                                         if(next instanceof MathSet)
333                                                 ans=ans.union((MathSet)next);
334                                 }
335                                 value=ans;
336                         }
337                 } else if(operation.equals("intersect")) {
338                         if(value instanceof MathSet) {
339                                 MathSet ans=(MathSet)value;
340                                 for(int i=1;i<length();i++) {
341                                         Object JavaDoc next=getArgument(i);
342                                         if(next instanceof MathMLExpression)
343                                                 next=((MathMLExpression)next).evaluate();
344                                         if(next instanceof MathSet)
345                                                 ans=ans.intersect((MathSet)next);
346                                 }
347                                 value=ans;
348                         }
349                 } else if(operation.equals("and")) {
350                         if(value instanceof Boolean JavaDoc) {
351                                 boolean ans=((Boolean JavaDoc)value).booleanValue();
352                                 for(int i=1;i<length();i++) {
353                                         Object JavaDoc next=getArgument(i);
354                                         if(next instanceof MathMLExpression)
355                                                 next=((MathMLExpression)next).evaluate();
356                                         if(next instanceof Boolean JavaDoc)
357                                                 ans&=((Boolean JavaDoc)next).booleanValue();
358                                 }
359                                 value=new Boolean JavaDoc(ans);
360                         }
361                 } else if(operation.equals("or")) {
362                         if(value instanceof Boolean JavaDoc) {
363                                 boolean ans=((Boolean JavaDoc)value).booleanValue();
364                                 for(int i=1;i<length();i++) {
365                                         Object JavaDoc next=getArgument(i);
366                                         if(next instanceof MathMLExpression)
367                                                 next=((MathMLExpression)next).evaluate();
368                                         if(next instanceof Boolean JavaDoc)
369                                                 ans|=((Boolean JavaDoc)next).booleanValue();
370                                 }
371                                 value=new Boolean JavaDoc(ans);
372                         }
373                 } else if(operation.equals("xor")) {
374                         if(value instanceof Boolean JavaDoc) {
375                                 boolean ans=((Boolean JavaDoc)value).booleanValue();
376                                 for(int i=1;i<length();i++) {
377                                         Object JavaDoc next=getArgument(i);
378                                         if(next instanceof MathMLExpression)
379                                                 next=((MathMLExpression)next).evaluate();
380                                         if(next instanceof Boolean JavaDoc)
381                                                 ans^=((Boolean JavaDoc)next).booleanValue();
382                                 }
383                                 value=new Boolean JavaDoc(ans);
384                         }
385                 } else if(operation.equals("eq")) {
386                         Object JavaDoc arg1=value;
387                         boolean ans=true;
388                         for(int i=1;i<length();i++) {
389                                 Object JavaDoc arg2=getArgument(i);
390                                 if(arg2 instanceof MathMLExpression)
391                                         arg2=((MathMLExpression)arg2).evaluate();
392                                 ans&=arg1.equals(arg2);
393                                 arg1=arg2;
394                         }
395                         value=new Boolean JavaDoc(ans);
396                 } else if(operation.equals("lt")) {
397                         if(value instanceof Comparable JavaDoc) {
398                                 Comparable JavaDoc arg1=(Comparable JavaDoc)value;
399                                 boolean ans=true;
400                                 for(int i=1;i<length();i++) {
401                                         Object JavaDoc arg2=getArgument(i);
402                                         if(arg2 instanceof MathMLExpression)
403                                                 arg2=((MathMLExpression)arg2).evaluate();
404                                         ans&=arg1.compareTo(arg2)<0;
405                                         if(arg2 instanceof Comparable JavaDoc)
406                                                 arg1=(Comparable JavaDoc)arg2;
407                                 }
408                                 value=new Boolean JavaDoc(ans);
409                         }
410                 } else if(operation.equals("leq")) {
411                         if(value instanceof Comparable JavaDoc) {
412                                 Comparable JavaDoc arg1=(Comparable JavaDoc)value;
413                                 boolean ans=true;
414                                 for(int i=1;i<length();i++) {
415                                         Object JavaDoc arg2=getArgument(i);
416                                         if(arg2 instanceof MathMLExpression)
417                                                 arg2=((MathMLExpression)arg2).evaluate();
418                                         ans&=arg1.compareTo(arg2)<=0;
419                                         if(arg2 instanceof Comparable JavaDoc)
420                                                 arg1=(Comparable JavaDoc)arg2;
421                                 }
422                                 value=new Boolean JavaDoc(ans);
423                         }
424                 } else if(operation.equals("gt")) {
425                         if(value instanceof Comparable JavaDoc) {
426                                 Comparable JavaDoc arg1=(Comparable JavaDoc)value;
427                                 boolean ans=true;
428                                 for(int i=1;i<length();i++) {
429                                         Object JavaDoc arg2=getArgument(i);
430                                         if(arg2 instanceof MathMLExpression)
431                                                 arg2=((MathMLExpression)arg2).evaluate();
432                                         ans&=arg1.compareTo(arg2)>0;
433                                         if(arg2 instanceof Comparable JavaDoc)
434                                                 arg1=(Comparable JavaDoc)arg2;
435                                 }
436                                 value=new Boolean JavaDoc(ans);
437                         }
438                 } else if(operation.equals("geq")) {
439                         if(value instanceof Comparable JavaDoc) {
440                                 Comparable JavaDoc arg1=(Comparable JavaDoc)value;
441                                 boolean ans=true;
442                                 for(int i=1;i<length();i++) {
443                                         Object JavaDoc arg2=getArgument(i);
444                                         if(arg2 instanceof MathMLExpression)
445                                                 arg2=((MathMLExpression)arg2).evaluate();
446                                         ans&=arg1.compareTo(arg2)>=0;
447                                         if(arg2 instanceof Comparable JavaDoc)
448                                                 arg1=(Comparable JavaDoc)arg2;
449                                 }
450                                 value=new Boolean JavaDoc(ans);
451                         }
452                 }
453                 return value;
454         }
455         /**
456         * Calculates the mean for this expression.
457         */

458         private double mean() {
459                 double sum=((MathDouble)getArgument(0)).value();
460                 for(int i=1;i<length();i++) {
461                         Object JavaDoc next=getArgument(i);
462                         if(next instanceof MathMLExpression)
463                                 next=((MathMLExpression)next).evaluate();
464                         sum+=((MathDouble)next).value();
465                 }
466                 return sum/length();
467         }
468         /**
469         * Calculates the variance for this expression.
470         */

471         private double variance() {
472                 final double m=mean();
473                 double num=((MathDouble)getArgument(0)).value();
474                 double ans=(num-m)*(num-m);
475                 for(int i=1;i<length();i++) {
476                         Object JavaDoc next=getArgument(i);
477                         if(next instanceof MathMLExpression)
478                                 next=((MathMLExpression)next).evaluate();
479                         num=((MathDouble)next).value();
480                         ans+=(num-m)*(num-m);
481                 }
482                 return ans/(length()-1);
483         }
484 }
485
486
Popular Tags