2 Copyright 2011 frank asseg
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
17 package de.congrace.exp4j;
19 import java.util.Stack;
22 * A {@link Token} for functions
24 * @author fas@congrace.de
27 class FunctionToken extends CalculationToken {
29 * the functionNames that can be used in an expression
35 ABS, ACOS, ASIN, ATAN, CBRT, CEIL, COS, COSH, EXP, EXPM1, FLOOR, ROUND, RANDOM, LOG, SIN, SINH, SQRT, TAN, TANH, LOG10
38 private Function function;
41 * construct a new {@link FunctionToken}
44 * the name of the function
45 * @throws UnknownFunctionException
46 * if an unknown function name is encountered
48 FunctionToken(String value) throws UnknownFunctionException {
51 function = Function.valueOf(value.toUpperCase());
52 } catch (IllegalArgumentException e) {
53 throw new UnknownFunctionException(value);
55 if (function == null) {
56 throw new UnknownFunctionException(value);
61 * apply a function to a variable
64 * the value the function should be applied to
65 * @return the result of the function
67 public Variable applyFunction(Variable var) {
69 // The names here are strictly unused, but are useful for debugging
70 String name = function.name() + " result (#"+var.hashCode()+"), ";
72 switch (var.getPrimary()) {
74 name = "double "+name;
75 double x = var.getDoubleValue();
76 return new Variable(name, applyFunction(x) );
80 double[] input = var.getArrayValue();
81 double[] result = new double[input.length];
82 for (int i = 0; i < input.length; i++){
83 result[i] = applyFunction(input[i]);
85 return new Variable(name, result);
88 return new Variable("Invalid");
93 * The actual function application on a double
95 private double applyFunction(double x){
116 return Math.expm1(x);
118 return Math.floor(x);
120 return Math.round(x);
122 return Math.random()*x;
126 return Math.log10(x);
138 return Double.NaN; // should not happen ;)
144 * get the {@link Function}
146 * @return the correspoding {@link Function}
148 Function getFunction() {
153 void mutateStackForCalculation(Stack<Variable> stack, VariableSet variableValues) {
154 stack.push(this.applyFunction(stack.pop()));
158 void mutateStackForInfixTranslation(Stack<Token> operatorStack, StringBuilder output) {
159 operatorStack.push(this);