• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package org.apache.commons.math.analysis;
19 
20 import org.apache.commons.math.FunctionEvaluationException;
21 import org.apache.commons.math.util.FastMath;
22 
23 
24 /**
25  * Base class for {@link UnivariateRealFunction} that can be composed with other functions.
26  *
27  * @since 2.1
28  * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
29  */
30 public abstract class ComposableFunction implements UnivariateRealFunction {
31 
32     /** The constant function always returning 0. */
33     public static final ComposableFunction ZERO = new ComposableFunction() {
34         /** {@inheritDoc} */
35         @Override
36         public double value(double d) {
37             return 0;
38         }
39     };
40 
41     /** The constant function always returning 1. */
42     public static final ComposableFunction ONE = new ComposableFunction() {
43         /** {@inheritDoc} */
44         @Override
45         public double value(double d) {
46             return 1;
47         }
48     };
49 
50     /** The identity function. */
51     public static final ComposableFunction IDENTITY = new ComposableFunction() {
52         /** {@inheritDoc} */
53         @Override
54         public double value(double d) {
55             return d;
56         }
57     };
58 
59     /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */
60     public static final ComposableFunction ABS = new ComposableFunction() {
61         /** {@inheritDoc} */
62         @Override
63         public double value(double d) {
64             return FastMath.abs(d);
65         }
66     };
67 
68     /** The - operator wrapped as a {@link ComposableFunction}. */
69     public static final ComposableFunction NEGATE = new ComposableFunction() {
70         /** {@inheritDoc} */
71         @Override
72         public double value(double d) {
73             return -d;
74         }
75     };
76 
77     /** The invert operator wrapped as a {@link ComposableFunction}. */
78     public static final ComposableFunction INVERT = new ComposableFunction () {
79         /** {@inheritDoc} */
80         @Override
81         public double value(double d){
82             return 1/d;
83         }
84     };
85 
86     /** The {@code FastMath.sin} method wrapped as a {@link ComposableFunction}. */
87     public static final ComposableFunction SIN = new ComposableFunction() {
88         /** {@inheritDoc} */
89         @Override
90         public double value(double d) {
91             return FastMath.sin(d);
92         }
93     };
94 
95     /** The {@code FastMath.sqrt} method wrapped as a {@link ComposableFunction}. */
96     public static final ComposableFunction SQRT = new ComposableFunction() {
97         /** {@inheritDoc} */
98         @Override
99         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      */
of(final UnivariateRealFunction f)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 }
507