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