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