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> +<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 }
|