    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.optimization.fitting;
    019
    020    import java.io.Serializable;
    021
    022    import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
    023    import org.apache.commons.math.analysis.UnivariateRealFunction;
    024    import org.apache.commons.math.exception.DimensionMismatchException;
    025    import org.apache.commons.math.exception.util.LocalizedFormats;
    026    import org.apache.commons.math.exception.ZeroException;
    027    import org.apache.commons.math.exception.NullArgumentException;
    028
    029    /**
    030     * A Gaussian function.  Specifically:
    031     * <p>
    032     * <tt>f(x) = a + b*exp(-((x - c)^2 / (2*d^2)))</tt>
    033     * <p>
    034     * Notation key:
    035     * <ul>
    036     * <li><tt>x^n</tt>: <tt>x</tt> raised to the power of <tt>n</tt>
    037     * <li><tt>exp(x)</tt>: <i>e</i><tt>^x</tt>
    038     * </ul>
    039     * References:
    040     * <ul>
    041     * <li><a href="http://en.wikipedia.org/wiki/Gaussian_function">Wikipedia:
    042     *   Gaussian function</a>
    043     * </ul>
    044     *
    045     * @see GaussianDerivativeFunction
    046     * @see ParametricGaussianFunction
    047     * @since 2.2
    048     * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
    049     */
    050    public class GaussianFunction implements DifferentiableUnivariateRealFunction, Serializable {
    051
    052        /** Serializable version identifier. */
    053        private static final long serialVersionUID = -3195385616125629512L;
    054
    055        /** Parameter a of this function. */
    056        private final double a;
    057
    058        /** Parameter b of this function. */
    059        private final double b;
    060
    061        /** Parameter c of this function. */
    062        private final double c;
    063
    064        /** Parameter d of this function. */
    065        private final double d;
    066
    067        /**
    068         * Constructs an instance with the specified parameters.
    069         *
    070         * @param a <tt>a</tt> parameter value
    071         * @param b <tt>b</tt> parameter value
    072         * @param c <tt>c</tt> parameter value
    073         * @param d <tt>d</tt> parameter value
    074         *
    075         * @throws IllegalArgumentException if <code>d</code> is 0
    076         */
    077        public GaussianFunction(double a, double b, double c, double d) {
    078            if (d == 0.0) {
    079                throw new ZeroException();
    080            }
    081            this.a = a;
    082            this.b = b;
    083            this.c = c;
    084            this.d = d;
    085        }
    086
    087        /**
    088         * Constructs an instance with the specified parameters.
    089         *
    090         * @param parameters <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and <tt>d</tt>
    091         *        parameter values
    092         *
    093         * @throws IllegalArgumentException if <code>parameters</code> is null,
    094         *         <code>parameters</code> length is not 4, or if
    095         *         <code>parameters[3]</code> is 0
    096         */
    097        public GaussianFunction(double[] parameters) {
    098            if (parameters == null) {
    099                throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
    100            }
    101            if (parameters.length != 4) {
    102                throw new DimensionMismatchException(4, parameters.length);
    103            }
    104            if (parameters[3] == 0.0) {
    105                throw new ZeroException();
    106            }
    107            this.a = parameters[0];
    108            this.b = parameters[1];
    109            this.c = parameters[2];
    110            this.d = parameters[3];
    111        }
    112
    113        /** {@inheritDoc} */
    114        public UnivariateRealFunction derivative() {
    115            return new GaussianDerivativeFunction(b, c, d);
    116        }
    117
    118        /** {@inheritDoc} */
    119        public double value(double x) {
    120            final double xMc = x - c;
    121            return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d)));
    122        }
    123
    124        /**
    125         * Gets <tt>a</tt> parameter value.
    126         *
    127         * @return <tt>a</tt> parameter value
    128         */
    129        public double getA() {
    130            return a;
    131        }
    132
    133        /**
    134         * Gets <tt>b</tt> parameter value.
    135         *
    136         * @return <tt>b</tt> parameter value
    137         */
    138        public double getB() {
    139            return b;
    140        }
    141
    142        /**
    143         * Gets <tt>c</tt> parameter value.
    144         *
    145         * @return <tt>c</tt> parameter value
    146         */
    147        public double getC() {
    148            return c;
    149        }
    150
    151        /**
    152         * Gets <tt>d</tt> parameter value.
    153         *
    154         * @return <tt>d</tt> parameter value
    155         */
    156        public double getD() {
    157            return d;
    158        }
    159    }