001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. 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
018 package org.apache.commons.math.analysis;
019
020 import org.apache.commons.math.FunctionEvaluationException;
021 import org.apache.commons.math.util.FastMath;
022
023
024 /**
025 * Base class for {@link UnivariateRealFunction} that can be composed with other functions.
026 *
027 * @since 2.1
028 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 f??vr. 2011) $
029 */
030 public abstract class ComposableFunction implements UnivariateRealFunction {
031
032 /** The constant function always returning 0. */
033 public static final ComposableFunction ZERO = new ComposableFunction() {
034 /** {@inheritDoc} */
035 @Override
036 public double value(double d) {
037 return 0;
038 }
039 };
040
041 /** The constant function always returning 1. */
042 public static final ComposableFunction ONE = new ComposableFunction() {
043 /** {@inheritDoc} */
044 @Override
045 public double value(double d) {
046 return 1;
047 }
048 };
049
050 /** The identity function. */
051 public static final ComposableFunction IDENTITY = new ComposableFunction() {
052 /** {@inheritDoc} */
053 @Override
054 public double value(double d) {
055 return d;
056 }
057 };
058
059 /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */
060 public static final ComposableFunction ABS = new ComposableFunction() {
061 /** {@inheritDoc} */
062 @Override
063 public double value(double d) {
064 return FastMath.abs(d);
065 }
066 };
067
068 /** The - operator wrapped as a {@link ComposableFunction}. */
069 public static final ComposableFunction NEGATE = new ComposableFunction() {
070 /** {@inheritDoc} */
071 @Override
072 public double value(double d) {
073 return -d;
074 }
075 };
076
077 /** The invert operator wrapped as a {@link ComposableFunction}. */
078 public static final ComposableFunction INVERT = new ComposableFunction () {
079 /** {@inheritDoc} */
080 @Override
081 public double value(double d){
082 return 1/d;
083 }
084 };
085
086 /** The {@code FastMath.sin} method wrapped as a {@link ComposableFunction}. */
087 public static final ComposableFunction SIN = new ComposableFunction() {
088 /** {@inheritDoc} */
089 @Override
090 public double value(double d) {
091 return FastMath.sin(d);
092 }
093 };
094
095 /** The {@code FastMath.sqrt} method wrapped as a {@link ComposableFunction}. */
096 public static final ComposableFunction SQRT = new ComposableFunction() {
097 /** {@inheritDoc} */
098 @Override
099 public double value(double d) {
100 return FastMath.sqrt(d);
101 }
102 };
103
104 /** The {@code FastMath.sinh} method wrapped as a {@link ComposableFunction}. */
105 public static final ComposableFunction SINH = new ComposableFunction() {
106 /** {@inheritDoc} */
107 @Override
108 public double value(double d) {
109 return FastMath.sinh(d);
110 }
111 };
112
113 /** The {@code FastMath.exp} method wrapped as a {@link ComposableFunction}. */
114 public static final ComposableFunction EXP = new ComposableFunction() {
115 /** {@inheritDoc} */
116 @Override
117 public double value(double d) {
118 return FastMath.exp(d);
119 }
120 };
121
122 /** The {@code FastMath.expm1} method wrapped as a {@link ComposableFunction}. */
123 public static final ComposableFunction EXPM1 = new ComposableFunction() {
124 /** {@inheritDoc} */
125 @Override
126 public double value(double d) {
127 return FastMath.expm1(d);
128 }
129 };
130
131 /** The {@code FastMath.asin} method wrapped as a {@link ComposableFunction}. */
132 public static final ComposableFunction ASIN = new ComposableFunction() {
133 /** {@inheritDoc} */
134 @Override
135 public double value(double d) {
136 return FastMath.asin(d);
137 }
138 };
139
140 /** The {@code FastMath.atan} method wrapped as a {@link ComposableFunction}. */
141 public static final ComposableFunction ATAN = new ComposableFunction() {
142 /** {@inheritDoc} */
143 @Override
144 public double value(double d) {
145 return FastMath.atan(d);
146 }
147 };
148
149 /** The {@code FastMath.tan} method wrapped as a {@link ComposableFunction}. */
150 public static final ComposableFunction TAN = new ComposableFunction() {
151 /** {@inheritDoc} */
152 @Override
153 public double value(double d) {
154 return FastMath.tan(d);
155 }
156 };
157
158 /** The {@code FastMath.tanh} method wrapped as a {@link ComposableFunction}. */
159 public static final ComposableFunction TANH = new ComposableFunction() {
160 /** {@inheritDoc} */
161 @Override
162 public double value(double d) {
163 return FastMath.tanh(d);
164 }
165 };
166
167 /** The {@code FastMath.cbrt} method wrapped as a {@link ComposableFunction}. */
168 public static final ComposableFunction CBRT = new ComposableFunction() {
169 /** {@inheritDoc} */
170 @Override
171 public double value(double d) {
172 return FastMath.cbrt(d);
173 }
174 };
175
176 /** The {@code FastMath.ceil} method wrapped as a {@link ComposableFunction}. */
177 public static final ComposableFunction CEIL = new ComposableFunction() {
178 /** {@inheritDoc} */
179 @Override
180 public double value(double d) {
181 return FastMath.ceil(d);
182 }
183 };
184
185 /** The {@code FastMath.floor} method wrapped as a {@link ComposableFunction}. */
186 public static final ComposableFunction FLOOR = new ComposableFunction() {
187 /** {@inheritDoc} */
188 @Override
189 public double value(double d) {
190 return FastMath.floor(d);
191 }
192 };
193
194 /** The {@code FastMath.log} method wrapped as a {@link ComposableFunction}. */
195 public static final ComposableFunction LOG = new ComposableFunction() {
196 /** {@inheritDoc} */
197 @Override
198 public double value(double d) {
199 return FastMath.log(d);
200 }
201 };
202
203 /** The {@code FastMath.log10} method wrapped as a {@link ComposableFunction}. */
204 public static final ComposableFunction LOG10 = new ComposableFunction() {
205 /** {@inheritDoc} */
206 @Override
207 public double value(double d) {
208 return FastMath.log10(d);
209 }
210 };
211
212 /** The {@code FastMath.log1p} method wrapped as a {@link ComposableFunction}. */
213 public static final ComposableFunction LOG1P = new ComposableFunction () {
214 @Override
215 public double value(double d){
216 return FastMath.log1p(d);
217 }
218 };
219
220 /** The {@code FastMath.cos} method wrapped as a {@link ComposableFunction}. */
221 public static final ComposableFunction COS = new ComposableFunction() {
222 /** {@inheritDoc} */
223 @Override
224 public double value(double d) {
225 return FastMath.cos(d);
226 }
227 };
228
229 /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */
230 public static final ComposableFunction ACOS = new ComposableFunction() {
231 /** {@inheritDoc} */
232 @Override
233 public double value(double d) {
234 return FastMath.acos(d);
235 }
236 };
237
238 /** The {@code FastMath.cosh} method wrapped as a {@link ComposableFunction}. */
239 public static final ComposableFunction COSH = new ComposableFunction() {
240 /** {@inheritDoc} */
241 @Override
242 public double value(double d) {
243 return FastMath.cosh(d);
244 }
245 };
246
247 /** The {@code FastMath.rint} method wrapped as a {@link ComposableFunction}. */
248 public static final ComposableFunction RINT = new ComposableFunction() {
249 /** {@inheritDoc} */
250 @Override
251 public double value(double d) {
252 return FastMath.rint(d);
253 }
254 };
255
256 /** The {@code FastMath.signum} method wrapped as a {@link ComposableFunction}. */
257 public static final ComposableFunction SIGNUM = new ComposableFunction() {
258 /** {@inheritDoc} */
259 @Override
260 public double value(double d) {
261 return FastMath.signum(d);
262 }
263 };
264
265 /** The {@code FastMath.ulp} method wrapped as a {@link ComposableFunction}. */
266 public static final ComposableFunction ULP = new ComposableFunction() {
267 /** {@inheritDoc} */
268 @Override
269 public double value(double d) {
270 return FastMath.ulp(d);
271 }
272 };
273
274 /** Precompose the instance with another function.
275 * <p>
276 * The composed function h created by {@code h = g.of(f)} is such
277 * that {@code h.value(x) == g.value(f.value(x))} for all x.
278 * </p>
279 * @param f function to compose with
280 * @return a new function which computes {@code this.value(f.value(x))}
281 * @see #postCompose(UnivariateRealFunction)
282 */
283 public ComposableFunction of(final UnivariateRealFunction f) {
284 return new ComposableFunction() {
285 @Override
286 /** {@inheritDoc} */
287 public double value(double x) throws FunctionEvaluationException {
288 return ComposableFunction.this.value(f.value(x));
289 }
290 };
291 }
292
293 /** Postcompose the instance with another function.
294 * <p>
295 * The composed function h created by {@code h = g.postCompose(f)} is such
296 * that {@code h.value(x) == f.value(g.value(x))} for all x.
297 * </p>
298 * @param f function to compose with
299 * @return a new function which computes {@code f.value(this.value(x))}
300 * @see #of(UnivariateRealFunction)
301 */
302 public ComposableFunction postCompose(final UnivariateRealFunction f) {
303 return new ComposableFunction() {
304 @Override
305 /** {@inheritDoc} */
306 public double value(double x) throws FunctionEvaluationException {
307 return f.value(ComposableFunction.this.value(x));
308 }
309 };
310 }
311
312 /**
313 * Return a function combining the instance and another function.
314 * <p>
315 * The function h created by {@code h = g.combine(f, combiner)} is such that
316 * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x.
317 * </p>
318 * @param f function to combine with the instance
319 * @param combiner bivariate function used for combining
320 * @return a new function which computes {@code combine.value(this.value(x), f.value(x))}
321 */
322 public ComposableFunction combine(final UnivariateRealFunction f,
323 final BivariateRealFunction combiner) {
324 return new ComposableFunction() {
325 @Override
326 /** {@inheritDoc} */
327 public double value(double x) throws FunctionEvaluationException {
328 return combiner.value(ComposableFunction.this.value(x), f.value(x));
329 }
330 };
331 }
332
333 /**
334 * Return a function adding the instance and another function.
335 * @param f function to combine with the instance
336 * @return a new function which computes {@code this.value(x) + f.value(x)}
337 */
338 public ComposableFunction add(final UnivariateRealFunction f) {
339 return new ComposableFunction() {
340 @Override
341 /** {@inheritDoc} */
342 public double value(double x) throws FunctionEvaluationException {
343 return ComposableFunction.this.value(x) + f.value(x);
344 }
345 };
346 }
347
348 /**
349 * Return a function adding a constant term to the instance.
350 * @param a term to add
351 * @return a new function which computes {@code this.value(x) + a}
352 */
353 public ComposableFunction add(final double a) {
354 return new ComposableFunction() {
355 @Override
356 /** {@inheritDoc} */
357 public double value(double x) throws FunctionEvaluationException {
358 return ComposableFunction.this.value(x) + a;
359 }
360 };
361 }
362
363 /**
364 * Return a function subtracting another function from the instance.
365 * @param f function to combine with the instance
366 * @return a new function which computes {@code this.value(x) - f.value(x)}
367 */
368 public ComposableFunction subtract(final UnivariateRealFunction f) {
369 return new ComposableFunction() {
370 @Override
371 /** {@inheritDoc} */
372 public double value(double x) throws FunctionEvaluationException {
373 return ComposableFunction.this.value(x) - f.value(x);
374 }
375 };
376 }
377
378 /**
379 * Return a function multiplying the instance and another function.
380 * @param f function to combine with the instance
381 * @return a new function which computes {@code this.value(x) * f.value(x)}
382 */
383 public ComposableFunction multiply(final UnivariateRealFunction f) {
384 return new ComposableFunction() {
385 @Override
386 /** {@inheritDoc} */
387 public double value(double x) throws FunctionEvaluationException {
388 return ComposableFunction.this.value(x) * f.value(x);
389 }
390 };
391 }
392
393 /**
394 * Return a function scaling the instance by a constant factor.
395 * @param scaleFactor constant scaling factor
396 * @return a new function which computes {@code this.value(x) * scaleFactor}
397 */
398 public ComposableFunction multiply(final double scaleFactor) {
399 return new ComposableFunction() {
400 @Override
401 /** {@inheritDoc} */
402 public double value(double x) throws FunctionEvaluationException {
403 return ComposableFunction.this.value(x) * scaleFactor;
404 }
405 };
406 }
407 /**
408 * Return a function dividing the instance by another function.
409 * @param f function to combine with the instance
410 * @return a new function which computes {@code this.value(x) / f.value(x)}
411 */
412 public ComposableFunction divide(final UnivariateRealFunction f) {
413 return new ComposableFunction() {
414 @Override
415 /** {@inheritDoc} */
416 public double value(double x) throws FunctionEvaluationException {
417 return ComposableFunction.this.value(x) / f.value(x);
418 }
419 };
420 }
421
422 /**
423 * Generates a function that iteratively apply instance function on all
424 * elements of an array.
425 * <p>
426 * The generated function behaves as follows:
427 * <ul>
428 * <li>initialize result = initialValue</li>
429 * <li>iterate: {@code result = combiner.value(result,
430 * this.value(nextMultivariateEntry));}</li>
431 * <li>return result</li>
432 * </ul>
433 * </p>
434 * @param combiner combiner to use between entries
435 * @param initialValue initial value to use before first entry
436 * @return a new function that iteratively apply instance function on all
437 * elements of an array.
438 */
439 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner,
440 final double initialValue) {
441 return new MultivariateRealFunction() {
442 /** {@inheritDoc} */
443 public double value(double[] point)
444 throws FunctionEvaluationException, IllegalArgumentException {
445 double result = initialValue;
446 for (final double entry : point) {
447 result = combiner.value(result, ComposableFunction.this.value(entry));
448 }
449 return result;
450 }
451 };
452 }
453
454 /**
455 * Generates a function that iteratively apply instance function on all
456 * elements of an array.
457 * <p>
458 * Calling this method is equivalent to call {@link
459 * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}.
460 * </p>
461 * @param combiner combiner to use between entries
462 * @return a new function that iteratively apply instance function on all
463 * elements of an array.
464 * @see #asCollector(BivariateRealFunction, double)
465 */
466 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) {
467 return asCollector(combiner, 0.0);
468 }
469
470 /**
471 * Generates a function that iteratively apply instance function on all
472 * elements of an array.
473 * <p>
474 * Calling this method is equivalent to call {@link
475 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}.
476 * </p>
477 * @param initialValue initial value to use before first entry
478 * @return a new function that iteratively apply instance function on all
479 * elements of an array.
480 * @see #asCollector(BivariateRealFunction, double)
481 * @see BinaryFunction#ADD
482 */
483 public MultivariateRealFunction asCollector(final double initialValue) {
484 return asCollector(BinaryFunction.ADD, initialValue);
485 }
486
487 /**
488 * Generates a function that iteratively apply instance function on all
489 * elements of an array.
490 * <p>
491 * Calling this method is equivalent to call {@link
492 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}.
493 * </p>
494 * @return a new function that iteratively apply instance function on all
495 * elements of an array.
496 * @see #asCollector(BivariateRealFunction, double)
497 * @see BinaryFunction#ADD
498 */
499 public MultivariateRealFunction asCollector() {
500 return asCollector(BinaryFunction.ADD, 0.0);
501 }
502
503 /** {@inheritDoc} */
504 public abstract double value(double x) throws FunctionEvaluationException;
505
506 }