Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/hartmath/initial/MathOperators.java


1   /*
2    *  MathOperators.java
3    *  Copyright (C) 2000 Klaus Hartlage
4    *
5    *  This program is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU General Public License
7    *  as published by the Free Software Foundation; either version 2
8    *  of the License, or any later version.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  package com.hartmath.initial;
20  
21  import java.lang.*;
22  
23  import com.hartmath.util.*;
24  import com.hartmath.domain.*;
25  import com.hartmath.mapping.*;
26  import com.hartmath.lib.C;
27  import com.hartmath.patternmatching.HRule;
28  import com.hartmath.patternmatching.HRuleSet;
29  import com.hartmath.expression.HObject;
30  import com.hartmath.expression.HString;
31  import com.hartmath.expression.HSymbol;
32  import com.hartmath.expression.HMultinomial;
33  import com.hartmath.expression.HComplex;
34  import com.hartmath.expression.HDoubleComplex;
35  import com.hartmath.expression.HDomainInstance;
36  import com.hartmath.expression.HFunction;
37  import com.hartmath.expression.HDouble;
38  import com.hartmath.expression.HSignedNumber;
39  import com.hartmath.expression.HFraction;
40  import com.hartmath.expression.HInteger;
41  import com.hartmath.exceptions.HThrowException;
42  import com.hartmath.lib.Session;
43  
44  /**
45   *  Class Declaration.
46   *
47   *@author     Klaus Hartlage <A HREF="mailto:khartlage@t-online.de">
48   *      khartlage@t-online.de</A>
49   *@created    16. Juli 2001
50   *@see
51   *@version    %I%, %G%
52   */
53  class EAdd extends ESMultiArg implements FunctionOpEvaluator {
54  
55    /**
56     *  Method Declaration.
57     *
58     *@param  o0
59     *@param  o1
60     *@param  session  Description of Parameter
61     *@return
62     *@see
63     */
64    public HObject e2ObjArg(HObject o0, HObject o1, Session session) {
65      if ((o0 instanceof HMultinomial) && (o1 instanceof HMultinomial)) {
66        return ((HMultinomial) o0).add((HMultinomial) o1);
67      }
68      if (o0 instanceof HDomainInstance && o1 instanceof HDomainInstance) {
69        return ObjectD.binaryCall("add", ((HDomainInstance) o0),
70            ((HDomainInstance) o1));
71      }
72      // Context ct = ((ContextThread) Thread.currentThread()).getContext();
73      if (session.getNumericFlag()) {
74        if (o0.equals(C.CD0)) {
75          return o1;
76        }
77  
78        if (o1.equals(C.CD0)) {
79          return o0;
80        }
81      }
82  
83      if (o0.equals(C.C0)) {
84        return o1;
85      }
86  
87      if (o1.equals(C.C0)) {
88        return o0;
89      }
90  
91      if (o0.equals(o1)) {
92        return C.Multiply.f(C.C2, o0);
93      }
94  
95      if (o0.head().equals(C.Multiply) && (((HFunction) o0).size() > 1)) {
96        HFunction f0 = (HFunction) o0;
97  
98        if (((HFunction) o0).get(0).isNumber()) {
99          if ((f0.size() == 2) && f0.get(1).equals(o1)) {
100           return C.Multiply.f(C.Add.f(C.C1, f0.get(0)), o1);
101         }
102 
103         if (o1.head().equals(C.Multiply) && (((HFunction) o1).size() > 1)) {
104           HFunction f1 = (HFunction) o1;
105 
106           if (f1.get(0).isNumber()) {
107             if (f0.equalsFromPosition(1, f1, 1)) {
108               HFunction result =
109                   new HFunction(f0, C.Multiply, 1, f0.size(), true);
110 
111               return C.Multiply.f(C.Add.f(f0.get(0), f1.get(0)), result);
112             }
113           }
114           else {
115             if (f0.equalsFromPosition(1, f1, 0)) {
116               HFunction result =
117                   new HFunction(f0, C.Multiply, 1, f0.size(), true);
118 
119               return C.Multiply.f(C.Add.f(C.C1, f0.get(0)), result);
120             }
121           }
122         }
123       }
124       else {
125         if (o1.head().equals(C.Multiply) && (((HFunction) o1).size() > 1)) {
126           HFunction f1 = (HFunction) o1;
127 
128           if (f1.get(0).isNumber()) {
129             if (f0.equalsFromPosition(0, f1, 1)) {
130               HFunction result =
131                   new HFunction(f1, C.Multiply, 1, f1.size(), true);
132 
133               return C.Multiply.f(C.Add.f(C.C1, f1.get(0)), result);
134             }
135           }
136         }
137       }
138     }
139 
140     if (o1.head().equals(C.Multiply) && (((HFunction) o1).size() > 1) &&
141         ((HFunction) o1).get(0).isNumber()) {
142       HFunction f1 = (HFunction) o1;
143 
144       if ((f1.size() == 2) && f1.get(1).equals(o0)) {
145         return C.Multiply.f(C.Add.f(C.C1, f1.get(0)), o0);
146       }
147     }
148 
149     return null;
150   }
151 
152 
153   /**
154    *  Description of the Method
155    *
156    *@param  d0       Description of Parameter
157    *@param  d1       Description of Parameter
158    *@param  session  Description of Parameter
159    *@return          Description of the Returned Value
160    */
161   public HObject e2DblArg(HDouble d0, HDouble d1, Session session) {
162     return d0.add(d1);
163   }
164 
165 
166   /**
167    *  Method Declaration.
168    *
169    *@param  d0
170    *@param  d1
171    *@param  session  Description of Parameter
172    *@return
173    *@see
174    */
175   public HObject e2DblComArg(HDoubleComplex d0, HDoubleComplex d1, Session session) {
176     return d0.add(d1);
177   }
178 
179 
180   /**
181    *  Method Declaration.
182    *
183    *@param  i0
184    *@param  i1
185    *@param  session  Description of Parameter
186    *@return
187    *@see
188    */
189   public HObject e2IntArg(HInteger i0, HInteger i1, Session session) {
190     return i0.add(i1);
191   }
192 
193 
194   /**
195    *  Method Declaration.
196    *
197    *@param  f0
198    *@param  f1
199    *@param  session  Description of Parameter
200    *@return
201    *@see
202    */
203   public HObject e2FraArg(HFraction f0, HFraction f1, Session session) {
204     return f0.add(f1);
205   }
206 
207 
208   /**
209    *  Method Declaration.
210    *
211    *@param  c0
212    *@param  c1
213    *@param  session  Description of Parameter
214    *@return
215    *@see
216    */
217   public HObject e2ComArg(HComplex c0, HComplex c1, Session session) {
218     return c0.add(c1);
219   }
220 
221 
222   /**
223    *  Method Declaration.
224    *
225    *@param  c0
226    *@param  i1
227    *@param  session  Description of Parameter
228    *@return
229    *@see
230    */
231   public HObject eComIntArg(HComplex c0, HInteger i1, Session session) {
232     return c0.add(new HComplex(i1, C.C0));
233   }
234 
235 
236   /**
237    *  Method Declaration.
238    *
239    *@param  fun
240    *@param  session  Description of Parameter
241    *@return
242    *@see
243    */
244   public String toOpString(HFunction fun, Session session) {
245     final int prec = C.ADD_PRECEDENCE;
246     final char ch = '+';
247     StringBuffer buf = new StringBuffer();
248     HObject temp;
249 
250     if (fun.size() <= 1) {
251       // important for tracing pattern-matching
252       buf.append("Add(");
253 
254       if (fun.size() == 1) {
255         fun.get(0).toStringBuffer(buf, session);
256       }
257 
258       buf.append(")");
259 
260       return buf.toString();
261     }
262 
263     for (int i = 0; i < fun.size(); i++) {
264       temp = fun.get(i);
265 
266       if (temp instanceof HFunction && (((HFunction) temp).size() > 0) &&
267           temp.head().equals(C.Multiply)) {
268         final int multPrec = C.MULTIPLY_PRECEDENCE;
269         final char multCh = '*';
270         boolean flag = false;
271         HFunction multFun = (HFunction) temp;
272         HObject temp1 = multFun.get(0);
273 
274         if (temp1 instanceof HSignedNumber &&
275             ((HSignedNumber) temp1).isNegative()) {
276           if (temp1.equals(C.C1)) {
277             flag = true;
278           }
279           else {
280             if (temp1.equals(C.CD1)) {
281               flag = true;
282             }
283             else {
284               if (temp1.equals(C.CN1)) {
285                 buf.append("-");
286 
287                 flag = true;
288               }
289               else {
290                 if (temp1.equals(C.CDN1)) {
291                   buf.append("-");
292 
293                   flag = true;
294                 }
295                 else {
296                   // buf.append(temp1.toString());
297                   temp1.toStringBuffer(buf, session);
298                 }
299               }
300             }
301           }
302         }
303         else {
304           if (i > 0) {
305             buf.append(ch);
306           }
307 
308           if (temp1.precedence() < multPrec) {
309             buf.append('(');
310           }
311 
312           // buf.append(temp1.toString());
313           temp1.toStringBuffer(buf, session);
314 
315           if (temp1.precedence() < multPrec) {
316             buf.append(')');
317           }
318         }
319 
320         for (int j = 1; j < multFun.size(); j++) {
321           temp1 = multFun.get(j);
322 
323           if ((j > 1) || (flag == false)) {
324             buf.append(multCh);
325           }
326 
327           if (temp1.precedence() < multPrec) {
328             buf.append('(');
329           }
330 
331           //buf.append(temp1.toString());
332           temp1.toStringBuffer(buf, session);
333 
334           if (temp1.precedence() < multPrec) {
335             buf.append(')');
336           }
337         }
338       }
339       else {
340         if (temp instanceof HSignedNumber &&
341             ((HSignedNumber) temp).isNegative()) {
342           // special case negative number:
343           //buf.append(temp.toString());
344           temp.toStringBuffer(buf, session);
345         }
346         else {
347           if (i > 0) {
348             buf.append(ch);
349           }
350 
351           if (temp.precedence() < prec) {
352             buf.append('(');
353           }
354 
355           // buf.append(temp.toString());
356           temp.toStringBuffer(buf, session);
357 
358           if (temp.precedence() < prec) {
359             buf.append(')');
360           }
361         }
362       }
363     }
364 
365     return buf.toString();
366   }
367 
368 
369   /**
370    *  Method Declaration.
371    *
372    *@return
373    *@see
374    */
375   public int precedence() {
376     return C.ADD_PRECEDENCE;
377   }
378 
379 }
380 
381 /**
382  *  Description of the Class
383  *
384  *@author     khartlage
385  *@created    16. Juli 2001
386  */
387 class EDot extends ESMultiArg implements FunctionOpEvaluator {
388 
389 
390   /**
391    *  Constructor for the EDot object
392    */
393   public EDot() {
394   }
395 
396 
397   /**
398    *  Description of the Method
399    *
400    *@param  o0       Description of Parameter
401    *@param  o1       Description of Parameter
402    *@param  session  Description of Parameter
403    *@return          Description of the Returned Value
404    */
405   public HObject e2ComArg(HComplex o0, HComplex o1, Session session) {
406     return null;
407   }
408 
409 
410   /**
411    *  Method Declaration.
412    *
413    *@param  o0
414    *@param  o1
415    *@param  session  Description of Parameter
416    *@return
417    *@see
418    */
419   public HObject e2ObjArg(HObject o0, HObject o1, Session session) {
420     if (session.EV(C.IsVector.f(o0)) == C.True) {
421       HFunction f0 = (HFunction) o0;
422       // vector
423       int v0len = f0.size();
424 
425       if (session.EV(C.IsVector.f(o1)) == C.True) {
426         HFunction f1 = (HFunction) o1;
427 
428         if (v0len != f1.size()) {
429           return null;
430         }
431 
432         HFunction res = new HFunction(C.Add);
433 
434         for (int k = 0; k < v0len; k++) {
435           res.add(C.Multiply.f(f0.get(k), f1.get(k)));
436         }
437 
438         return res;
439       }
440 
441       if (session.EV(C.IsMatrix.f(o1)) == C.True) {
442         HFunction f1 = (HFunction) o1;
443         HFunction g1 = (HFunction) f1.get(0);
444         int rowLen1 = f1.size();
445         int colLen1 = g1.size();
446 
447         if (v0len != rowLen1) {
448           return null;
449         }
450 
451         HFunction res = new HFunction(C.List);
452         HFunction rowres;
453 
454         for (int k = 0; k < colLen1; k++) {
455           rowres = new HFunction(C.Add);
456 
457           for (int i = 0; i < v0len; i++) {
458             rowres.add(C.Multiply.f(f0.get(i), f1.get(i, k)));
459           }
460 
461           res.add(rowres);
462         }
463 
464         return res;
465       }
466 
467       return null;
468     }
469 
470     if (session.EV(C.IsMatrix.f(o0)) == C.True) {
471       HFunction f0 = (HFunction) o0;
472       // matrix
473       HFunction g0 = (HFunction) f0.get(0);
474       // matrix-row
475 
476       if (session.EV(C.IsMatrix.f(o1)) == C.True) {
477         HFunction f1 = (HFunction) o1;
478         HFunction g1 = (HFunction) f1.get(0);
479 
480         // {{a,b},{c,d}}.{{e,f},{g,h}}
481         int colLen0 = g0.size();
482         int rowLen1 = f1.size();
483 
484         if (colLen0 != rowLen1) {
485           return null;
486         }
487 
488         HFunction res = new HFunction(C.List);
489 
490         res.setProperties(HFunction.MATRIXFORM);
491 
492         HFunction rowres;
493         HFunction temp;
494 
495         for (int k = 0; k < f0.size(); k++) {
496           rowres = new HFunction(C.List);
497           g0 = (HFunction) f0.get(k);
498 
499           for (int i = 0; i < g1.size(); i++) {
500             temp = new HFunction(C.Add);
501 
502             for (int j = 0; j < colLen0; j++) {
503               g1 = (HFunction) f1.get(j);
504 
505               temp.add(C.Multiply.f(g0.get(j), g1.get(i)));
506             }
507 
508             rowres.add(temp);
509           }
510 
511           res.add(rowres);
512         }
513 
514         return res;
515       }
516 
517       if (session.EV(C.IsVector.f(o1)) == C.True) {
518         HFunction f1 = (HFunction) o1;
519         int colLen1 = g0.size();
520 
521         if (f1.size() != colLen1) {
522           return null;
523         }
524 
525         HFunction res = new HFunction(C.List);
526         HFunction rowres;
527 
528         for (int k = 0; k < f0.size(); k++) {
529           rowres = new HFunction(C.Add);
530           g0 = (HFunction) f0.get(k);
531 
532           for (int i = 0; i < g0.size(); i++) {
533             rowres.add(C.Multiply.f(f1.get(i), g0.get(i)));
534           }
535 
536           res.add(rowres);
537         }
538 
539         return res;
540       }
541     }
542 
543     return null;
544   }
545 
546 
547   /**
548    *  Method Declaration.
549    *
550    *@param  fun
551    *@param  session  Description of Parameter
552    *@return
553    *@see
554    */
555   public String toOpString(HFunction fun, Session session) {
556     return E2SArg.operatorString(fun, ".", C.DOT_PRECEDENCE, session);
557   }
558 
559 
560   /**
561    *  Method Declaration.
562    *
563    *@return
564    *@see
565    */
566   public int precedence() {
567     return C.DOT_PRECEDENCE;
568   }
569 
570 }
571 
572 /**
573  *  Class Declaration.
574  *
575  *@author     Klaus Hartlage <A HREF="mailto:khartlage@t-online.de">
576  *      khartlage@t-online.de</A>
577  *@created    16. Juli 2001
578  *@see
579  *@version    %I%, %G%
580  */
581 class EMultiply extends E2SArg implements FunctionOpEvaluator {
582 
583 
584   /**
585    *  Description of the Method
586    *
587    *@param  vect     Description of Parameter
588    *@param  session  Description of Parameter
589    *@return          Description of the Returned Value
590    */
591   public HObject evaluate(HFunction vect, Session session) {
592     if (vect.size() == 2) {
593       if (vect.get(0) instanceof HSignedNumber &&
594           vect.get(1) instanceof HFunction &&
595           vect.get(1).head().equals(C.Add)) {
596         HFunction arg2 = (HFunction) vect.get(1);
597         HFunction result = C.Add.f();
598         for (int i = 0; i < arg2.size(); i++) {
599           result.add(C.Multiply.f(vect.get(0), arg2.get(i)));
600         }
601         return result;
602       }
603       return binaryOperator(vect.get(0), vect.get(1), session);
604     }
605 
606     if (vect.size() > 2) {
607       HSymbol sym = vect.head();
608       HFunction result = new HFunction(sym);
609       HObject tres;
610       HObject temp = vect.get(0);
611       boolean evaled = false;
612       int i = 1;
613 
614       while (i < vect.size()) {
615 
616         // for (int i = 1; i < vect.size(); i++) {
617         tres = binaryOperator(temp, vect.get(i), session);
618 
619         if (tres == null) {
620 
621           // kh***
622           for (int j = i + 1; j < vect.size(); j++) {
623             tres = binaryOperator(temp, vect.get(j), session);
624 
625             if (tres != null) {
626               evaled = true;
627               temp = tres;
628 
629               vect.remove(j);
630 
631               break;
632             }
633           }
634 
635           if (tres == null) {
636 
637             // kh***
638             result.add(temp);
639 
640             if (i == vect.size() - 1) {
641               result.add(vect.get(i));
642             }
643             else {
644               temp = vect.get(i);
645             }
646 
647             i++;
648           }
649         }
650         else {
651           evaled = true;
652           temp = tres;
653 
654           if (i == (vect.size() - 1)) {
655             result.add(temp);
656           }
657 
658           i++;
659         }
660       }
661 
662       if (evaled) {
663         if ((result.size() == 1)
664              && sym.checkAttributes(session, HSymbol.ONEIDENTITY)) {
665           return result.get(0);
666         }
667 
668         return result;
669       }
670     }
671 
672     return null;
673   }
674 
675 
676   /**
677    *  Method Declaration.
678    *
679    *@param  o0
680    *@param  o1
681    *@param  session  Description of Parameter
682    *@return
683    *@see
684    */
685   public HObject e2ObjArg(HObject o0, HObject o1, Session session) {
686     if ((o0 instanceof HMultinomial) && (o1 instanceof HMultinomial)) {
687       return ((HMultinomial) o0).multiply((HMultinomial) o1);
688     }
689     if (o0 instanceof HDomainInstance && o1 instanceof HDomainInstance) {
690       return ObjectD.binaryCall("multiply", ((HDomainInstance) o0),
691           ((HDomainInstance) o1));
692     }
693     // Context ct = ((ContextThread) Thread.currentThread()).getContext();
694     if (session.getNumericFlag()) {
695       if (o0.equals(C.CD0)) {
696         return C.CD0;
697       }
698 
699       if (o1.equals(C.CD0)) {
700         return C.CD0;
701       }
702 
703       if (o0.equals(C.CD1)) {
704         return o1;
705       }
706 
707       if (o1.equals(C.CD1)) {
708         return o0;
709       }
710     }
711 
712     if (o0.equals(C.C0)) {
713       return C.C0;
714     }
715 
716     if (o1.equals(C.C0)) {
717       return C.C0;
718     }
719 
720     if (o0.equals(C.C1)) {
721       return o1;
722     }
723 
724     if (o1.equals(C.C1)) {
725       return o0;
726     }
727 
728     if (o0.equals(o1)) {
729       return C.Pow.f(o0, C.C2);
730     }
731 
732     if (o0.head().equals(C.Pow) && (((HFunction) o0).size() == 2)) {
733       HFunction f0 = (HFunction) o0;
734 
735       if (f0.get(1).isNumber()) {
736         if (f0.get(0).equals(o1)) {
737           return C.Pow.f(o1, C.Add.f(C.C1, f0.get(1)));
738         }
739 
740         if (o1.head().equals(C.Pow) && (((HFunction) o1).size() == 2)) {
741           HFunction f1 = (HFunction) o1;
742 
743           if (f1.get(1).isNumber()) {
744             if (f0.get(0).equals(f1.get(0))) {
745               return C.Pow.f(f0.get(0), C.Add.f(f0.get(1), f1.get(1)));
746             }
747           }
748         }
749       }
750     }
751 
752     if (o1.head().equals(C.Pow) && (((HFunction) o1).size() == 2) &&
753         ((HFunction) o1).get(1).isNumber()) {
754       HFunction f1 = (HFunction) o1;
755 
756       if (f1.get(0).equals(o0)) {
757         return C.Pow.f(o0, C.Add.f(C.C1, f1.get(1)));
758       }
759     }
760 
761     return null;
762   }
763 
764 
765   /**
766    *  Method Declaration.
767    *
768    *@param  d0
769    *@param  d1
770    *@param  session  Description of Parameter
771    *@return
772    *@see
773    */
774   public HObject e2DblArg(HDouble d0, HDouble d1, Session session) {
775     return d0.multiply(d1);
776   }
777 
778 
779   /**
780    *  Method Declaration.
781    *
782    *@param  d0
783    *@param  d1
784    *@param  session  Description of Parameter
785    *@return
786    *@see
787    */
788   public HObject e2DblComArg(HDoubleComplex d0, HDoubleComplex d1, Session session) {
789     return d0.multiply(d1);
790   }
791 
792 
793   /**
794    *  Method Declaration.
795    *
796    *@param  i0
797    *@param  i1
798    *@param  session  Description of Parameter
799    *@return
800    *@see
801    */
802   public HObject e2IntArg(HInteger i0, HInteger i1, Session session) {
803     return i0.multiply(i1);
804   }
805 
806 
807   /**
808    *  Method Declaration.
809    *
810    *@param  f0
811    *@param  f1
812    *@param  session  Description of Parameter
813    *@return
814    *@see
815    */
816   public HObject e2FraArg(HFraction f0, HFraction f1, Session session) {
817     return f0.multiply(f1);
818   }
819 
820 
821   /**
822    *  Method Declaration.
823    *
824    *@param  c0
825    *@param  i1
826    *@param  session  Description of Parameter
827    *@return
828    *@see
829    */
830   public HObject eComIntArg(HComplex c0, HInteger i1, Session session) {
831     return c0.multiply(new HComplex(i1, C.C0));
832   }
833 
834 
835   /**
836    *  Method Declaration.
837    *
838    *@param  c0
839    *@param  c1
840    *@param  session  Description of Parameter
841    *@return
842    *@see
843    */
844   public HObject e2ComArg(HComplex c0, HComplex c1, Session session) {
845     return c0.multiply(c1);
846   }
847 
848 
849   /**
850    *  Method Declaration.
851    *
852    *@param  fun
853    *@param  session  Description of Parameter
854    *@return
855    *@see
856    */
857   public String toOpString(HFunction fun, Session session) {
858     final int prec = C.MULTIPLY_PRECEDENCE;
859     final char ch = '*';
860     StringBuffer buf = new StringBuffer();
861     HObject temp;
862 
863     if (fun.size() <= 1) {
864       // important for tracing pattern-matching
865       buf.append("Multiply(");
866 
867       if (fun.size() == 1) {
868         //    buf.append(fun.get(0).toString());
869         fun.get(0).toStringBuffer(buf, session);
870       }
871 
872       buf.append(")");
873 
874       return buf.toString();
875     }
876 
877     for (int i = 0; i < fun.size(); i++) {
878       temp = fun.get(i);
879 
880       if (temp.equals(C.CN1)) {
881         buf.append('-');
882       }
883       else {
884         if (temp.precedence() < prec) {
885           buf.append('(');
886         }
887 
888         //buf.append(temp.toString());
889         temp.toStringBuffer(buf, session);
890 
891         if (temp.precedence() < prec) {
892           buf.append(')');
893         }
894 
895         if (i != (fun.size() - 1)) {
896           buf.append(ch);
897         }
898       }
899     }
900 
901     return buf.toString();
902   }
903 
904 
905   /**
906    *  Method Declaration.
907    *
908    *@return
909    *@see
910    */
911   public int precedence() {
912     return C.MULTIPLY_PRECEDENCE;
913   }
914 
915 }
916 
917 /**
918  *  Class Declaration.
919  *
920  *@author     Klaus Hartlage <A HREF="mailto:khartlage@t-online.de">
921  *      khartlage@t-online.de</A>
922  *@created    16. Juli 2001
923  *@see
924  *@version    %I%, %G%
925  */
926 class EPow extends E2SArg implements FunctionOpEvaluator {
927 
928 
929   /**
930    *  Method Declaration.
931    *
932    *@param  o0
933    *@param  o1
934    *@param  session  Description of Parameter
935    *@return
936    *@see
937    */
938   public HObject e2ObjArg(HObject o0, HObject o1, Session session) {
939     if ((o0 instanceof HMultinomial) && (o1 instanceof HInteger)) {
940       return ((HMultinomial) o0).pow((HInteger) o1);
941     }
942     if (o0 instanceof HDomainInstance && o1 instanceof HInteger) {
943       return ObjectD.binaryCall("pow", ((HDomainInstance) o0),
944           ((HInteger) o1));
945     }
946     // Context ct = ((ContextThread) Thread.currentThread()).getContext();
947     if (session.getNumericFlag()) {
948       if (o0.equals(C.CD0)) {
949         if (o1.equals(C.CD0)) {
950           // 0^0
951           throw new HThrowException(C.UndefinedError, C.Pow,
952               new HString("0^0"));
953         }
954 
955         if (o1 instanceof HSignedNumber &&
956             ((HSignedNumber) o1).isNegative()) {
957           throw new HThrowException(C.ArithmeticError, C.Pow,
958               new HString("division by zero"));
959         }
960 
961         return C.CD0;
962       }
963 
964       if (o1.equals(C.CD0)) {
965         return C.CD1;
966       }
967 
968       if (o1.equals(C.CD1)) {
969         return o0;
970       }
971 
972       if (o0.equals(C.CD1)) {
973         return C.CD1;
974       }
975     }
976     if (o0.equals(C.C0)) {
977       if (o1.equals(C.C0)) {
978         // 0^0
979         throw new HThrowException(C.UndefinedError, C.Pow,
980             new HString("0^0"));
981       }
982 
983       if (o1 instanceof HSignedNumber &&
984           ((HSignedNumber) o1).isNegative()) {
985         throw new HThrowException(C.ArithmeticError, C.Pow,
986             new HString("division by zero"));
987       }
988 
989       return C.C0;
990     }
991 
992     if (o1.equals(C.C0)) {
993       return C.C1;
994     }
995 
996     if (o1.equals(C.C1)) {
997       return o0;
998     }
999 
1000    if (o0.equals(C.C1)) {
1001      return C.C1;
1002    }
1003
1004    if (o1.isNumber() && o0.head().equals(C.Pow)) {
1005      HFunction f0 = (HFunction) o0;
1006
1007      if ((f0.size() == 2) && f0.get(1).isNumber()) {
1008        return C.Pow.f(f0.get(0), C.Multiply.f(f0.get(1), o1));
1009      }
1010    }
1011    /*
1012     *  if (o0.head().equals(C.Multiply) && o1.isNumber()) {
1013     *  HFunction f0 = (HFunction) o0;
1014     *  if ((f0.size() > 0) && f0.get(0).isNumber()) {
1015     *  return C.Multiply.f(C.Pow.f(f0.get(0), o1),
1016     *  C.Pow.f(
1017     *  new HFunction(f0, C.Multiply, 1, f0.size(), true), o1));
1018     *  }
1019     *  }
1020     */
1021    if (o0.head().equals(C.Multiply)) {
1022      if (o1 instanceof HInteger) {
1023        // (a * b * c)^n => a^n * b^n * c^n
1024        HFunction f0 = (HFunction) o0;
1025        HFunction result = C.Multiply.f();
1026        for (int i = 0; i < f0.size(); i++) {
1027          result.add(C.Pow.f(f0.get(i), o1));
1028        }
1029        return result;
1030      }
1031      if (o1.isNumber()) {
1032        HFunction f0 = (HFunction) o0;
1033
1034        if ((f0.size() > 0) && f0.get(0).isNumber()) {
1035          return C.Multiply.f(C.Pow.f(f0.get(0), o1),
1036              C.Pow.f(
1037              new HFunction(f0, C.Multiply, 1, f0.size(), true), o1));
1038        }
1039      }
1040    }
1041    return null;
1042  }
1043
1044
1045  /**
1046   *  Method Declaration.
1047   *
1048   *@param  i0
1049   *@param  i1
1050   *@param  session  Description of Parameter
1051   *@return
1052   *@see
1053   */
1054  public HObject e2IntArg(HInteger i0, HInteger i1, Session session) {
1055    if (i0.equals(C.C0)) {
1056      // all other cases see e2ObjArg
1057      return null;
1058    }
1059
1060    if (i1.less(session, C.C0)) {
1061      return new HFraction(C.C1, i0.pow(i1.negate().intValue()));
1062    }
1063
1064    return i0.pow(i1.intValue());
1065  }
1066
1067
1068  /**
1069   *  Method Declaration.
1070   *
1071   *@param  f0
1072   *@param  f1
1073   *@param  session  Description of Parameter
1074   *@return
1075   *@see
1076   */
1077  public HObject e2FraArg(HFraction f0, HFraction f1, Session session) {
1078    if (f0.numer().equals(C.C0)) {
1079      return C.C0;
1080    }
1081
1082    if (f1.numer().equals(C.C0)) {
1083      return C.C1;
1084    }
1085
1086    // if (f0.denom().equals(C.C1) && f1.numer().equals(C.C1)) { // example: (-27)^(1/3) or 8^(1/3)
1087    if (f1.numer().equals(C.C1)) {
1088      HInteger a = f0.numer();
1089      HInteger b = f0.denom();
1090
1091      if (f1.isNegative()) {
1092        return null;
1093      }
1094      final HInteger root = f1.denom();
1095
1096      HObject new_numer = calculateRoot(a, root, session);
1097      HObject new_denom = calculateRoot(b, root, session);
1098
1099      if (new_numer != null) {
1100        if (new_denom != null) {
1101          return session.EV(C.Multiply.f(new_numer, C.Pow.f(new_denom, C.CN1)));
1102        }
1103        else {
1104          if (a.equals(C.C1)) {
1105            return null;
1106          }
1107          return session.EV(C.Multiply.f(new_numer, C.Pow.f(new HFraction(C.C1, b), f1)));
1108        }
1109      }
1110      else {
1111        if (new_denom != null) {
1112          if (b.equals(C.C1)) {
1113            return null;
1114          }
1115          return session.EV(C.Multiply.f(C.Pow.f(a, f1), C.Pow.f(new_denom, C.CN1)));
1116        }
1117      }
1118      return null;
1119    }
1120
1121    if (f1.denom().unequals(C.C1)) {
1122      return null;
1123    }
1124
1125    int iNumer;
1126    try {
1127      iNumer = f1.numer().getIntValue();
1128    }
1129    catch (IndexOutOfBoundsException iob) {
1130      return null;
1131    }
1132    return f0.pow(iNumer);
1133  }
1134
1135
1136  /**
1137   *  Method Declaration.
1138   *
1139   *@param  c0
1140   *@param  i1
1141   *@param  session  Description of Parameter
1142   *@return
1143   *@see
1144   */
1145  public HObject eComIntArg(HComplex c0, HInteger i1, Session session) {
1146    if (c0.isZero()) {
1147      return C.C0;
1148    }
1149
1150    if (i1.isZero()) {
1151      return C.C1;
1152    }
1153
1154    return c0.pow(i1.intValue());
1155  }
1156
1157
1158  /**
1159   *  Description of the Method
1160   *
1161   *@param  d0       Description of Parameter
1162   *@param  d1       Description of Parameter
1163   *@param  session  Description of Parameter
1164   *@return          Description of the Returned Value
1165   */
1166  public HObject e2DblArg(HDouble d0, HDouble d1, Session session) {
1167    HDouble res = d0.pow(d1);
1168
1169    if (res.isNaN()) {
1170      return new HDoubleComplex(d0.doubleValue()).pow(
1171          new HDoubleComplex(d1));
1172    }
1173
1174    return res;
1175  }
1176
1177
1178  /**
1179   *  Method Declaration.
1180   *
1181   *@param  d0
1182   *@param  d1
1183   *@param  session  Description of Parameter
1184   *@return
1185   *@see
1186   */
1187  public HObject e2DblComArg(HDoubleComplex d0, HDoubleComplex d1, Session session) {
1188    return d0.pow(d1);
1189  }
1190
1191
1192  /**
1193   *  Description of the Method
1194   *
1195   *@param  c0       Description of Parameter
1196   *@param  c1       Description of Parameter
1197   *@param  session  Description of Parameter
1198   *@return          Description of the Returned Value
1199   */
1200  public HObject e2ComArg(HComplex c0, HComplex c1, Session session) {
1201    return null;
1202  }
1203
1204
1205  /**
1206   *  Method Declaration.
1207   *
1208   *@param  fun
1209   *@param  session  Description of Parameter
1210   *@return
1211   *@see
1212   */
1213  public String toOpString(HFunction fun, Session session) {
1214    StringBuffer buf = new StringBuffer();
1215    HObject temp;
1216
1217    if (fun.size() > 0) {
1218      if ((fun.size() == 2) &&
1219          (fun.get(1).equals(C.CN1) ||
1220          fun.get(1).equals(C.CDN1) ||
1221          fun.get(1).equals(C.C1D2) ||
1222          fun.get(1).equals(C.CN1D2))) {
1223        temp = fun.get(0);
1224
1225        if (fun.get(1).equals(C.C1D2)) {
1226          buf.append("Sqrt(");
1227          temp.toStringBuffer(buf, session);
1228          buf.append(")");
1229        }
1230        else {
1231          buf.append("1/");
1232
1233          if (fun.get(1).equals(C.CN1D2)) {
1234            buf.append("Sqrt(");
1235            temp.toStringBuffer(buf, session);
1236            buf.append(")");
1237          }
1238          else {
1239            if (temp.precedence() < C.MULTIPLY_PRECEDENCE) {
1240              buf.append('(');
1241            }
1242
1243            //buf.append(temp.toString());
1244            temp.toStringBuffer(buf, session);
1245
1246            if (temp.precedence() < C.MULTIPLY_PRECEDENCE) {
1247              buf.append(')');
1248            }
1249          }
1250        }
1251      }
1252      else {
1253        temp = fun.get(0);
1254
1255        if (temp.precedence() < C.POW_PRECEDENCE) {
1256          buf.append('(');
1257        }
1258
1259        //buf.append(temp.toString());
1260        temp.toStringBuffer(buf, session);
1261
1262        if (temp.precedence() < C.POW_PRECEDENCE) {
1263          buf.append(')');
1264        }
1265
1266        if (fun.size() > 1) {
1267          buf.append('^');
1268        }
1269
1270        for (int i = 1; i < fun.size(); i++) {
1271          temp = fun.get(i);
1272
1273          if (temp.precedence() <= C.POW_PRECEDENCE) {
1274            buf.append('(');
1275          }
1276
1277          //buf.append(temp.toString());
1278          temp.toStringBuffer(buf, session);
1279
1280          if (temp.precedence() <= C.POW_PRECEDENCE) {
1281            buf.append(')');
1282          }
1283
1284          if (i != (fun.size() - 1)) {
1285            buf.append('^');
1286          }
1287        }
1288      }
1289    }
1290
1291    return buf.toString();
1292  }
1293
1294
1295  /**
1296   *  Method Declaration.
1297   *
1298   *@return
1299   *@see
1300   */
1301  public int precedence() {
1302    return C.POW_PRECEDENCE;
1303  }
1304
1305
1306  /**
1307   *  Description of the Method
1308   *
1309   *@param  a        Description of Parameter
1310   *@param  root     Description of Parameter
1311   *@param  session  Description of Parameter
1312   *@return          Description of the Returned Value
1313   */
1314  HObject calculateRoot(HInteger a, HInteger root, Session session) {
1315    boolean negFlag = false;
1316    HInteger result;
1317
1318    int iRoot;
1319    try {
1320      iRoot = root.getIntValue();
1321    }
1322    catch (IndexOutOfBoundsException iob) {
1323      return null;
1324    }
1325
1326    if (a.isNegative()) {
1327      if (root.isEven()) {
1328        // complex root ???
1329        a = a.negate();
1330        result = a.root(iRoot);
1331
1332        if (result.pow(iRoot).equals(a)) {
1333          if (iRoot % 4 != 0) {
1334            return session.EV(C.Multiply.f(C.CI, result));
1335          }
1336        }
1337
1338        return null;
1339      }
1340
1341      negFlag = true;
1342      a = a.negate();
1343
1344    }
1345
1346    result = a.root(iRoot);
1347
1348    if (result.pow(iRoot).equals(a)) {
1349      if (negFlag) {
1350        return result.negate();
1351      }
1352      return result;
1353    }
1354
1355    return null;
1356  }
1357
1358}
1359
1360/**
1361 *  Class Declaration.
1362 *
1363 *@author     Klaus Hartlage <A HREF="mailto:khartlage@t-online.de">
1364 *      khartlage@t-online.de</A>
1365 *@created    16. Juli 2001
1366 *@see
1367 *@version    %I%, %G%
1368 */
1369class ESqrt extends E1Arg {
1370
1371
1372  /**
1373   *  Method Declaration.
1374   *
1375   *@param  o
1376   *@return
1377   *@see
1378   */
1379  public HObject e1ObjArg(HObject o) {
1380    return C.Pow.f(o, C.C1D2);
1381  }
1382
1383}
1384
1385
1386class EReplaceAll extends SFunctionEvaluator implements FunctionOpEvaluator {
1387  /**
1388   *  Constructor for the EReplaceAll object
1389   */
1390  public EReplaceAll() {
1391  }
1392
1393
1394  /**
1395   *@param  vect     the function, which should be evaluated
1396   *@param  session  Description of Parameter
1397   *@return          <code>null</code> or the evaluated object
1398   */
1399  public HObject evaluate(HFunction vect, Session session) {
1400    if (vect.size() == 2 && vect.get(1) instanceof HFunction) {
1401      HFunction f = (HFunction) vect.get(1);
1402      HObject a0 = vect.get(0);
1403
1404      if (f.isList()) {
1405        for (int i = 0; i < f.size(); i++) {
1406          if (f.get(i) instanceof HFunction) {
1407            a0 = useRule(a0, (HFunction) f.get(i), session);
1408          }
1409        }
1410
1411        return a0;
1412      }
1413      else {
1414        return useRule(a0, f, session);
1415      }
1416    }
1417
1418    return null;
1419  }
1420
1421
1422  /**
1423   *  Method Declaration.
1424   *
1425   *@param  fun
1426   *@param  session  Description of Parameter
1427   *@return
1428   *@see
1429   */
1430  public String toOpString(HFunction fun, Session session) {
1431    return E2SArg.operatorString(fun, "/.", C.REPLACEALL_PRECEDENCE, session);
1432  }
1433
1434
1435  /**
1436   *  Method Declaration.
1437   *
1438   *@return
1439   *@see
1440   */
1441  public int precedence() {
1442    return C.REPLACEALL_PRECEDENCE;
1443  }
1444
1445
1446  /**
1447   *  Method Declaration.
1448   *
1449   *@param  a0
1450   *@param  f
1451   *@param  session  Description of Parameter
1452   *@return
1453   *@see
1454   */
1455  HObject useRule(HObject a0, HFunction f, Session session) {
1456    HObject result;
1457    HRuleSet rset;
1458
1459    if (f.size() == 2 && (f.head() == C.Rule || f.head() == C.RuleDelayed)) {
1460      rset = new HRuleSet(f.get(0).head());
1461
1462      if (f.head() == C.Rule) {
1463        rset.putDownRule(session, HRule.RULE, f.get(0), f.get(1));
1464      }
1465      else {
1466        rset.putDownRule(session, HRule.RULEDELAYED, f.get(0),
1467            f.get(1));
1468      }
1469
1470      result = rset.getDownRule(a0, session);
1471
1472      if (result != null) {
1473        return result;
1474      }
1475
1476      if (a0 instanceof HFunction) {
1477        result = ((HFunction) a0).replaceAll(rset, session);
1478
1479        if (result != null) {
1480          return result;
1481        }
1482      }
1483    }
1484
1485    return a0;
1486  }
1487
1488}
1489
1490class ERule extends SFunctionEvaluator implements FunctionOpEvaluator {
1491
1492
1493  /**
1494   *  Constructor for the ERule object
1495   */
1496  public ERule() {
1497  }
1498
1499
1500  /**
1501   *@param  vect     the function, which should be evaluated
1502   *@param  session  Description of Parameter
1503   *@return          <code>null</code> or the evaluated object
1504   */
1505  public HObject evaluate(HFunction vect, Session session) {
1506    if (vect.size() == 2) {
1507      HObject a0 = (HObject) vect.get(0);
1508      HObject arg2 = session.ELoop((HObject) vect.get(1));
1509
1510      if (a0 instanceof HSymbol) {
1511        if (arg2 == null) {
1512          return null;
1513        }
1514
1515        return C.Rule.f(a0, arg2);
1516      }
1517
1518      if (a0 instanceof HFunction) {
1519        HObject result = ((HFunction) a0).evaluateArgAttr(session);
1520
1521        if (result != null) {
1522          a0 = result;
1523
1524          if (arg2 == null) {
1525            arg2 = vect.get(1);
1526          }
1527        }
1528        else {
1529          if (arg2 == null) {
1530            return null;
1531          }
1532        }
1533
1534        return C.Rule.f(a0, arg2);
1535      }
1536    }
1537
1538    return null;
1539  }
1540
1541
1542  /**
1543   *  Method Declaration.
1544   *
1545   *@param  fun
1546   *@param  session  Description of Parameter
1547   *@return
1548   *@see
1549   */
1550  public String toOpString(HFunction fun, Session session) {
1551    return E2SArg.operatorString(fun, "->", C.RULE_PRECEDENCE, session);
1552  }
1553
1554
1555  /**
1556   *  Method Declaration.
1557   *
1558   *@return
1559   *@see
1560   */
1561  public int precedence() {
1562    return C.RULE_PRECEDENCE;
1563  }
1564
1565}
1566
1567/**
1568 *  Description of the Class
1569 *
1570 *@author     khartlage
1571 *@created    8. Oktober 2001
1572 */
1573class ERuleDelayed extends SFunctionEvaluator implements FunctionOpEvaluator {
1574
1575
1576  /**
1577   *  Constructor for the ERuleDelayed object
1578   */
1579  public ERuleDelayed() {
1580  }
1581
1582
1583  /**
1584   *@param  vect     the function, which should be evaluated
1585   *@param  session  Description of Parameter
1586   *@return          <code>null</code> or the evaluated object
1587   */
1588  public HObject evaluate(HFunction vect, Session session) {
1589    if (vect.size() == 2) {
1590      HObject a0 = (HObject) vect.get(0);
1591      HObject arg2 = (HObject) vect.get(1);
1592
1593      if (a0 instanceof HSymbol) {
1594        return C.Rule.f(a0, arg2);
1595      }
1596
1597      if (a0 instanceof HFunction) {
1598        HObject result = ((HFunction) a0).evaluateArgAttr(session);
1599
1600        if (result != null) {
1601          a0 = result;
1602        }
1603
1604        return C.Rule.f(a0, arg2);
1605      }
1606    }
1607
1608    return null;
1609  }
1610
1611
1612  /**
1613   *  Method Declaration.
1614   *
1615   *@param  fun
1616   *@param  session  Description of Parameter
1617   *@return
1618   *@see
1619   */
1620  public String toOpString(HFunction fun, Session session) {
1621    return E2SArg.operatorString(fun, ":>", C.RULEDELAYED_PRECEDENCE, session);
1622  }
1623
1624
1625  /**
1626   *  Method D