Home | History | Annotate | Download | only in analysis
      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 fvr. 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      */
    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