org.apache.commons.math.optimization.fitting.ParametricGaussianFunction Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.fitting;
import java.io.Serializable;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.ZeroException;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.optimization.fitting.ParametricRealFunction;
/**
* A Gaussian function. Specifically:
*
* f(x) = a + b*exp(-((x - c)^2 / (2*d^2)))
*
* The parameters have the following meaning:
*
* - a is a constant offset that shifts f(x) up or down
*
- b is the height of the peak
*
- c is the position of the center of the peak
*
- d is related to the FWHM by FWHM = 2*sqrt(2*ln(2))*d
*
* Notation key:
*
* - x^n: x raised to the power of n
*
- exp(x): e^x
*
- sqrt(x): the square root of x
*
- ln(x): the natural logarithm of x
*
* References:
*
*
* @since 2.2
* @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
*/
public class ParametricGaussianFunction implements ParametricRealFunction, Serializable {
/** Serializable version Id. */
private static final long serialVersionUID = -3875578602503903233L;
/**
* Constructs an instance.
*/
public ParametricGaussianFunction() {
}
/**
* Computes value of function f(x) for the specified x and
* parameters a, b, c, and d.
*
* @param x x value
* @param parameters values of a, b, c, and
* d
*
* @return value of f(x) evaluated at x with the specified
* parameters
*
* @throws IllegalArgumentException if parameters
is invalid as
* determined by {@link #validateParameters(double[])}
* @throws ZeroException if parameters
values are
* invalid as determined by {@link #validateParameters(double[])}
*/
public double value(double x, double[] parameters) throws ZeroException {
validateParameters(parameters);
final double a = parameters[0];
final double b = parameters[1];
final double c = parameters[2];
final double d = parameters[3];
final double xMc = x - c;
return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d)));
}
/**
* Computes the gradient vector for a four variable version of the function
* where the parameters, a, b, c, and d,
* are considered the variables, not x. That is, instead of
* computing the gradient vector for the function f(x) (which would
* just be the derivative of f(x) with respect to x since
* it's a one-dimensional function), computes the gradient vector for the
* function f(a, b, c, d) = a + b*exp(-((x - c)^2 / (2*d^2)))
* treating the specified x as a constant.
*
* The components of the computed gradient vector are the partial
* derivatives of f(a, b, c, d) with respect to each variable.
* That is, the partial derivative of f(a, b, c, d) with respect to
* a, the partial derivative of f(a, b, c, d) with respect
* to b, the partial derivative of f(a, b, c, d) with
* respect to c, and the partial derivative of f(a, b, c,
* d) with respect to d.
*
* @param x x value to be used as constant in f(a, b, c,
* d)
* @param parameters values of a, b, c, and
* d for computation of gradient vector of f(a, b, c,
* d)
*
* @return gradient vector of f(a, b, c, d)
*
* @throws IllegalArgumentException if parameters
is invalid as
* determined by {@link #validateParameters(double[])}
* @throws ZeroException if parameters
values are
* invalid as determined by {@link #validateParameters(double[])}
*/
public double[] gradient(double x, double[] parameters) throws ZeroException {
validateParameters(parameters);
final double b = parameters[1];
final double c = parameters[2];
final double d = parameters[3];
final double xMc = x - c;
final double d2 = d * d;
final double exp = Math.exp(-xMc * xMc / (2 * d2));
final double f = b * exp * xMc / d2;
return new double[] { 1.0, exp, f, f * xMc / d };
}
/**
* Validates parameters to ensure they are appropriate for the evaluation of
* the value
and gradient
methods.
*
* @param parameters values of a, b, c, and
* d
*
* @throws IllegalArgumentException if parameters
is
* null
or if parameters
does not have
* length == 4
* @throws ZeroException if parameters[3]
* (d) is 0
*/
private void validateParameters(double[] parameters) throws ZeroException {
if (parameters == null) {
throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
}
if (parameters.length != 4) {
throw new DimensionMismatchException(4, parameters.length);
}
if (parameters[3] == 0.0) {
throw new ZeroException();
}
}
}