001: package com.teamkonzept.lib.math;
002:
003: public class MathFunction extends UnaryOperator {
004:
005: final static int LOG = 0; // requests extra parameter
006: final static int ABS = 1;
007: final static int ACOS = 2;
008: final static int ASIN = 3;
009: final static int ATAN = 4;
010: final static int CEIL = 5;
011: final static int COSH = 6;
012: final static int COS = 7;
013: final static int COTAN = 8;
014: final static int EXP = 9;
015: final static int FAC = 10;
016: final static int FLOOR = 11;
017: final static int FPART = 12;
018: final static int LN = 13;
019: final static int ROUND = 14;
020: final static int SFAC = 15;
021: final static int SINH = 16;
022: final static int SIN = 17;
023: final static int SQRT = 18;
024: final static int TANH = 19;
025: final static int TAN = 20;
026:
027: int type;
028:
029: // default base for log function
030: double extraOperand = 10.0;
031:
032: public MathFunction(int type, int parenlevel, int position)
033: throws UnsupportedOperatorException {
034: super (parenlevel, getPriority(type, position), position);
035: this .type = type;
036: }
037:
038: public MathFunction(int type, int parenlevel, int position,
039: Double extraOperand) {
040: super (parenlevel, MATH_FUNCTION_PRIORITY, position);
041: this .type = type;
042: this .extraOperand = extraOperand.doubleValue();
043: }
044:
045: /**
046: * evaluates this function to the operand
047: * returns the result of type Double
048: */
049: public Object evaluate(Object operand)
050: throws BadOperandTypeException {
051: if (!(operand instanceof Double))
052: throw new BadOperandTypeException(operand, "Double");
053: double d = ((Double) operand).doubleValue();
054: switch (type) {
055: case LOG:
056: return new Double(Math.log(d) / Math.log(extraOperand));
057: case ABS:
058: return new Double(Math.abs(d));
059: case ACOS:
060: return new Double(Math.acos(d));
061: case ASIN:
062: return new Double(Math.asin(d));
063: case ATAN:
064: return new Double(Math.atan(d));
065: case CEIL:
066: return new Double(Math.ceil(d));
067: case COSH:
068: return new Double((Math.exp(d) + Math.exp(0.0 - d)) / 2.0);
069: case COS:
070: return new Double(Math.cos(d));
071: case COTAN:
072: return new Double(1.0 / Math.tan(d));
073: case EXP:
074: return new Double(Math.exp(d));
075: case FAC:
076: if (Math.ceil(d) != d)
077: throw new BadOperandTypeException(operand, "Integer");
078: return new Double(computeFaculty((int) d));
079: case FLOOR:
080: return new Double(Math.floor(d));
081: case FPART:
082: return new Double(d - Math.floor(d));
083: case LN:
084: return new Double(Math.log(d));
085: case ROUND:
086: return new Double(Math.round(d));
087: case SFAC:
088: if (Math.ceil(d) != d)
089: throw new BadOperandTypeException(operand, "Integer");
090: return new Double(computeSemiFaculty((int) d));
091: case SINH:
092: return new Double((Math.exp(d) - Math.exp(0.0 - d)) / 2.0);
093: case SIN:
094: return new Double(Math.sin(d));
095: case SQRT:
096: return new Double(Math.sqrt(d));
097: case TANH:
098: double d1 = Math.exp(d);
099: double d2 = Math.exp(0.0 - d);
100: return new Double((d1 - d2) / (d1 + d2));
101: case TAN:
102: return new Double(Math.tan(d));
103: }
104: return null;
105: }
106:
107: static int getPriority(int op, int position)
108: throws UnsupportedOperatorException {
109: if (op < 0 || op > 20)
110: throw new UnsupportedOperatorException(MathFunction.class,
111: op, position);
112: return MATH_FUNCTION_PRIORITY;
113: }
114:
115: static long computeFaculty(int value) {
116: long res = 1;
117: for (int i = 2; i <= value; i++)
118: res = res * i;
119: return res;
120: }
121:
122: static long computeSemiFaculty(int value) {
123: long res = 1;
124: for (int i = value; i > 1; i = i - 2)
125: res = res * i;
126: return res;
127: }
128: }
|