MathOp.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.1.0).
003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.prog.op;
021 
022 import static java.lang.Math.abs;
023 import static java.lang.Math.acos;
024 import static java.lang.Math.asin;
025 import static java.lang.Math.atan;
026 import static java.lang.Math.cbrt;
027 import static java.lang.Math.ceil;
028 import static java.lang.Math.cos;
029 import static java.lang.Math.cosh;
030 import static java.lang.Math.exp;
031 import static java.lang.Math.floor;
032 import static java.lang.Math.hypot;
033 import static java.lang.Math.log;
034 import static java.lang.Math.log10;
035 import static java.lang.Math.max;
036 import static java.lang.Math.min;
037 import static java.lang.Math.pow;
038 import static java.lang.Math.rint;
039 import static java.lang.Math.signum;
040 import static java.lang.Math.sin;
041 import static java.lang.Math.sinh;
042 import static java.lang.Math.sqrt;
043 import static java.lang.Math.tan;
044 import static java.lang.Math.tanh;
045 
046 import java.util.ArrayList;
047 import java.util.List;
048 import java.util.Optional;
049 import java.util.function.Function;
050 
051 import io.jenetics.ext.util.Tree;
052 import io.jenetics.ext.util.TreeNode;
053 
054 /**
055  * This class contains operations for performing basic numeric operations.
056  *
057  @see Math
058  *
059  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
060  @version 3.9
061  @since 3.9
062  */
063 public enum MathOp implements Op<Double> {
064 
065 
066     /* *************************************************************************
067      * Arithmetic operations
068      * ************************************************************************/
069 
070     /**
071      * Return the absolute value of a double value.
072      <em>This operation has arity 1.</em>
073      *
074      @see Math#abs(double)
075      */
076     ABS("abs"1, v -> abs(v[0])),
077 
078     /**
079      * Return the negation value of a double value.
080      <em>This operation has arity 1.</em>
081      */
082     NEG("neg"1, v -> -v[0]),
083 
084     /**
085      * Return the minimum of two values.
086      <em>This operation has arity 2.</em>
087      *
088      @see Math#min(double, double)
089      */
090     MIN("min"2, v -> min(v[0], v[1])),
091 
092     /**
093      * Return the maximum of two values
094      <em>This operation has arity 2.</em>
095      *
096      @see Math#max(double, double)
097      */
098     MAX("max"2, v -> max(v[0], v[1])),
099 
100     /**
101      * Returns the smallest (closest to negative infinity) double value that is
102      * greater than or equal to the argument and is equal to a mathematical
103      * integer.
104      <em>This operation has arity 1.</em>
105      *
106      @see Math#ceil(double)
107      */
108     CEIL("ceil"1, v -> ceil(v[0])),
109 
110     /**
111      * Returns the largest (closest to positive infinity) double value that is
112      * less than or equal to the argument and is equal to a mathematical integer.
113      <em>This operation has arity 1.</em>
114      *
115      @see Math#floor(double)
116      */
117     FLOOR("floor"1, v -> floor(v[0])),
118 
119     /**
120      * Returns the signum function of the argument; zero if the argument is
121      * zero, 1.0 if the argument is greater than zero, -1.0 if the argument is
122      * less than zero.
123      <em>This operation has arity 1.</em>
124      *
125      @see Math#signum(double)
126      */
127     SIGNUM("signum"1, v -> signum(v[0])),
128 
129     /**
130      * Returns the double value that is closest in value to the argument and is
131      * equal to a mathematical integer.
132      <em>This operation has arity 1.</em>
133      *
134      @see Math#rint(double)
135      */
136     RINT("rint"1, v -> rint(v[0])),
137 
138     /**
139      * Returns the sum of its arguments.
140      <em>This operation has arity 2.</em>
141      */
142     ADD("add"2, v -> v[0+ v[1]),
143 
144     /**
145      * Return the diff of its arguments.
146      <em>This operation has arity 2.</em>
147      */
148     SUB("sub"2, v -> v[0- v[1]),
149 
150     /**
151      * Returns the product of its arguments.
152      <em>This operation has arity 2.</em>
153      */
154     MUL("mul"2, v -> v[0]*v[1]),
155 
156     /**
157      * Returns the quotient of its arguments.
158      <em>This operation has arity 2.</em>
159      */
160     DIV("div"2, v -> v[0]/v[1]),
161 
162     /**
163      * Returns the modulo of its arguments.
164      <em>This operation has arity 2.</em>
165      */
166     MOD("mod"2, v -> v[0]%v[1]),
167 
168     /**
169      * Returns the value of the first argument raised to the power of the second
170      * argument.
171      <em>This operation has arity 2.</em>
172      *
173      @see Math#pow(double, double)
174      */
175     POW("pow"2, v -> pow(v[0], v[1])),
176 
177     /**
178      * Returns the square value of a given double value.
179      <em>This operation has arity 1.</em>
180      */
181     SQR("sqr"1, v -> v[0]*v[0]),
182 
183     /**
184      * Returns the correctly rounded positive square root of a double value.
185      <em>This operation has arity 1.</em>
186      *
187      @see Math#sqrt(double)
188      */
189     SQRT("sqrt"1, v -> sqrt(v[0])),
190 
191     /**
192      * Returns the cube root of a double value.
193      <em>This operation has arity 1.</em>
194      *
195      @see Math#cbrt(double)
196      */
197     CBRT("cbrt"1, v -> cbrt(v[0])),
198 
199     /**
200      * Returns sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>) without
201      * intermediate overflow or underflow.
202      <em>This operation has arity 2.</em>
203      *
204      @see Math#hypot(double, double)
205      */
206     HYPOT("hypot"2, v -> hypot(v[0], v[1])),
207 
208 
209     /* *************************************************************************
210      * Exponential/logarithmic operations
211      * ************************************************************************/
212 
213     /**
214      * Returns Euler's number e raised to the power of a double value.
215      <em>This operation has arity 1.</em>
216      *
217      @see Math#exp(double)
218      */
219     EXP("exp"1, v -> exp(v[0])),
220 
221     /**
222      * Returns the natural logarithm (base e) of a double value.
223      <em>This operation has arity 1.</em>
224      *
225      @see Math#log(double)
226      */
227     LOG("log"1, v -> log(v[0])),
228 
229     /**
230      * Returns the base 10 logarithm of a double value.
231      <em>This operation has arity 1.</em>
232      *
233      @see Math#log10(double)
234      */
235     LOG10("log10"1, v -> log10(v[0])),
236 
237 
238     /* *************************************************************************
239      * Trigonometric operations
240      * ************************************************************************/
241 
242     /**
243      * Returns the trigonometric sine of an angle.
244      <em>This operation has arity 1.</em>
245      *
246      @see Math#sin(double)
247      */
248     SIN("sin"1, v -> sin(v[0])),
249 
250     /**
251      * Returns the trigonometric cosine of an angle.
252      <em>This operation has arity 1.</em>
253      *
254      @see Math#cos(double)
255      */
256     COS("cos"1, v -> cos(v[0])),
257 
258     /**
259      * Returns the trigonometric tangent of an angle.
260      <em>This operation has arity 1.</em>
261      *
262      @see Math#tan(double)
263      */
264     TAN("tan"1, v -> tan(v[0])),
265 
266     /**
267      * Returns the arc cosine of a double value.
268      <em>This operation has arity 1.</em>
269      *
270      @see Math#acos(double)
271      */
272     ACOS("acos"1, v -> acos(v[0])),
273 
274     /**
275      * Returns the arc sine of a double value.
276      <em>This operation has arity 1.</em>
277      *
278      @see Math#asin(double)
279      */
280     ASIN("asin"1, v -> asin(v[0])),
281 
282     /**
283      * Returns the arc tangent of a value.
284      <em>This operation has arity 1.</em>
285      *
286      @see Math#atan(double)
287      */
288     ATAN("atan"1, v -> atan(v[0])),
289 
290     /**
291      * Returns the hyperbolic cosine of a double value.
292      <em>This operation has arity 1.</em>
293      *
294      @see Math#cosh(double)
295      */
296     COSH("cosh"1, v -> cosh(v[0])),
297 
298     /**
299      * Returns the hyperbolic sine of a double value.
300      <em>This operation has arity 1.</em>
301      *
302      @see Math#sinh(double)
303      */
304     SINH("sinh"1, v -> sinh(v[0])),
305 
306     /**
307      * Returns the hyperbolic tangent of a double value.
308      <em>This operation has arity 1.</em>
309      *
310      @see Math#tanh(double)
311      */
312     TANH("tanh"1, v -> tanh(v[0]));
313 
314 
315     /**
316      * The double value that is closer than any other to pi, the ratio of the
317      * circumference of a circle to its diameter. <em>This is a terminal
318      * operation.</em>
319      *
320      @see Math#PI
321      */
322     public static final Const<Double> PI = Const.of("π", Math.PI);
323 
324     /**
325      * The double value that is closer than any other to e, the base of the
326      * natural logarithms. <em>This is a terminal operation.</em>
327      *
328      @see Math#E
329      */
330     public static final Const<Double> E = Const.of("e", Math.E);
331 
332 
333     private final String _name;
334     private final int _arity;
335     private final Function<Double[], Double> _function;
336 
337     private MathOp(
338         final String name,
339         final int arity,
340         final Function<Double[], Double> function
341     ) {
342         assert name != null;
343         assert arity >= 0;
344         assert function != null;
345 
346         _name = name;
347         _function = function;
348         _arity = arity;
349     }
350 
351     @Override
352     public int arity() {
353         return _arity;
354     }
355 
356     @Override
357     public Double apply(final Double[] doubles) {
358         return _function.apply(doubles);
359     }
360 
361     @Override
362     public String toString() {
363         return _name;
364     }
365 
366 }