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 }