1 package net.sf.openrocket.simulation.customexpression;
3 import java.util.ArrayList;
5 import java.util.SortedMap;
6 import java.util.TreeMap;
8 import net.sf.openrocket.l10n.Translator;
9 import net.sf.openrocket.logging.LogHelper;
10 import net.sf.openrocket.startup.Application;
11 import net.sf.openrocket.util.ArrayUtils;
13 import de.congrace.exp4j.CustomFunction;
14 import de.congrace.exp4j.InvalidCustomFunctionException;
15 import de.congrace.exp4j.Variable;
18 * This is a singleton class which contains all the functions for custom expressions not provided by exp4j
20 public class Functions {
21 private static Functions instance = null;
23 private static final LogHelper log = Application.getLogger();
24 private static final Translator trans = Application.getTranslator();
26 private List<CustomFunction> allFunctions = new ArrayList<CustomFunction>();
28 public static Functions getInstance() {
29 if(instance == null) {
31 instance = new Functions();
32 } catch (InvalidCustomFunctionException e) {
33 log.error("Invalid custom function.");
39 public List<CustomFunction> getAllFunction(){
43 // A map of available operator strings (keys) and description of function (value)
44 public static final SortedMap<String, String> AVAILABLE_OPERATORS = new TreeMap<String, String>() {{
45 put("+" , trans.get("Operator.plus"));
46 put("-" , trans.get("Operator.minus"));
47 put("*" , trans.get("Operator.star"));
48 put("/" , trans.get("Operator.div"));
49 put("%" , trans.get("Operator.mod"));
50 put("^" , trans.get("Operator.pow"));
51 put("abs()" , trans.get("Operator.abs"));
52 put("ceil()" , trans.get("Operator.ceil"));
53 put("floor()" , trans.get("Operator.floor"));
54 put("sqrt()" , trans.get("Operator.sqrt"));
55 put("cbrt()" , trans.get("Operator.cbrt"));
56 put("exp()" , trans.get("Operator.exp"));
57 put("log()" , trans.get("Operator.ln"));
58 put("sin()" , trans.get("Operator.sin"));
59 put("cos()" , trans.get("Operator.cos"));
60 put("tan()" , trans.get("Operator.tan"));
61 put("asin()" , trans.get("Operator.asin"));
62 put("acos()" , trans.get("Operator.acos"));
63 put("atan()" , trans.get("Operator.atan"));
64 put("sinh()" , trans.get("Operator.hsin"));
65 put("cosh()" , trans.get("Operator.hcos"));
66 put("tanh()" , trans.get("Operator.htan"));
67 put("log10()" , trans.get("Operator.log10"));
68 put("round()" , trans.get("Operator.round"));
69 put("random()" , trans.get("Operator.random"));
70 put("expm1()" , trans.get("Operator.expm1"));
71 put("mean([:])" , trans.get("Operator.mean"));
72 put("min([:])" , trans.get("Operator.min"));
73 put("max([:])" , trans.get("Operator.max"));
74 put("var([:])" , trans.get("Operator.var"));
75 put("rms([:])" , trans.get("Operator.rms"));
76 put("stdev([:])", trans.get("Operator.stdev"));
77 put("lclip(,)" , trans.get("Operator.lclip"));
78 put("uclip(,)" , trans.get("Operator.uclip"));
79 put("binf([:],,)" , trans.get("Operator.binf"));
80 put("trapz([:])" , trans.get("Operator.trapz"));
81 put("tnear([:],)" , trans.get("Operator.tnear"));
85 protected Functions() throws InvalidCustomFunctionException {
87 CustomFunction meanFn = new CustomFunction("mean") {
89 public Variable applyFunction(List<Variable> vars) {
92 vals = vars.get(0).getArrayValue();
93 } catch (Exception e) {
94 return new Variable("Invalid");
96 return new Variable("double MEAN result, ", ArrayUtils.mean(vals));
99 allFunctions.add(meanFn);
101 CustomFunction minFn = new CustomFunction("min") {
103 public Variable applyFunction(List<Variable> vars) {
106 vals = vars.get(0).getArrayValue();
107 } catch (Exception e) {
108 return new Variable("Invalid");
110 return new Variable("double MIN result, ", ArrayUtils.min(vals));
113 allFunctions.add(minFn);
115 CustomFunction maxFn = new CustomFunction("max") {
117 public Variable applyFunction(List<Variable> vars) {
120 vals = vars.get(0).getArrayValue();
121 } catch (Exception e) {
122 return new Variable("Invalid");
124 return new Variable("double MAX result, ", ArrayUtils.max(vals));
127 allFunctions.add(maxFn);
129 CustomFunction varFn = new CustomFunction("var") {
131 public Variable applyFunction(List<Variable> vars) {
134 vals = vars.get(0).getArrayValue();
135 } catch (Exception e) {
136 return new Variable("Invalid");
138 return new Variable("double VAR result, ", ArrayUtils.variance(vals));
141 allFunctions.add(varFn);
143 CustomFunction stdevFn = new CustomFunction("stdev") {
145 public Variable applyFunction(List<Variable> vars) {
148 vals = vars.get(0).getArrayValue();
149 } catch (Exception e) {
150 return new Variable("Invalid");
152 return new Variable("double STDEV result, ", ArrayUtils.stdev(vals));
155 allFunctions.add(stdevFn);
157 CustomFunction rmsFn = new CustomFunction("rms") {
159 public Variable applyFunction(List<Variable> vars) {
162 vals = vars.get(0).getArrayValue();
163 } catch (Exception e) {
164 return new Variable("Invalid");
166 return new Variable("double RMS result, ", ArrayUtils.rms(vals));
169 allFunctions.add(rmsFn);
171 CustomFunction lclipFn = new CustomFunction("lclip",2) {
173 public Variable applyFunction(List<Variable> vars) {
176 val = vars.get(0).getDoubleValue();
177 clip = vars.get(1).getDoubleValue();
178 } catch (Exception e) {
179 return new Variable("Invalid");
184 return new Variable("double LCLIP result, ", val);
187 allFunctions.add(lclipFn);
189 CustomFunction uclipFn = new CustomFunction("uclip",2) {
191 public Variable applyFunction(List<Variable> vars) {
194 val = vars.get(0).getDoubleValue();
195 clip = vars.get(1).getDoubleValue();
196 } catch (Exception e) {
197 return new Variable("Invalid");
202 return new Variable("double UCLIP result, ", val);
205 allFunctions.add(uclipFn);
207 CustomFunction binfFn = new CustomFunction("binf", 3) {
209 public Variable applyFunction(List<Variable> vars) {
213 range = vars.get(0).getArrayValue();
214 min = vars.get(1).getDoubleValue();
215 max = vars.get(2).getDoubleValue();
216 } catch (Exception e) {
217 return new Variable("Invalid");
221 for (double x: range){
222 if (x < max && x > min){
226 return new Variable("double BINF result", (double) ins/ (double) range.length);
229 allFunctions.add(binfFn);
231 CustomFunction rombintFn = new CustomFunction("trapz") {
233 public Variable applyFunction(List<Variable> vars) {
237 range = vars.get(0).getArrayValue();
238 dt = vars.get(0).getStep();
239 } catch (Exception e) {
240 return new Variable("Invalid");
243 return new Variable("double TRAPZ result", ArrayUtils.trapz(range, dt) );
246 allFunctions.add(rombintFn);
248 CustomFunction tnearFn = new CustomFunction("tnear", 2) {
250 public Variable applyFunction(List<Variable> vars) {
256 range = vars.get(0).getArrayValue();
257 dt = vars.get(0).getStep();
258 start = vars.get(0).getStart();
259 near = vars.get(1).getDoubleValue();
260 } catch (Exception e) {
261 return new Variable("Invalid");
264 return new Variable("double TNEAR result", ArrayUtils.tnear(range, near, start, dt) );
267 allFunctions.add(tnearFn);