Top Description Inners Fields Constructors Methods
org.apache.commons.math3.fitting

public Class HarmonicCurveFitter

extends AbstractCurveFitter
Class Inheritance
Imports
java.util.ArrayList, .Collection, .List, org.apache.commons.math3.analysis.function.HarmonicOscillator, org.apache.commons.math3.exception.MathIllegalStateException, .NumberIsTooSmallException, .ZeroException, org.apache.commons.math3.exception.util.LocalizedFormats, org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder, .LeastSquaresProblem, org.apache.commons.math3.linear.DiagonalMatrix, org.apache.commons.math3.util.FastMath

Fits points to a harmonic oscillator function.
The initial guess values must be passed in the following order: The optimal values will be returned in the same order.
Since
3.3

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
HarmonicCurveFitter.ParameterGuesser

This class guesses harmonic coefficients from a sample.

Field Summary

Modifier and TypeField and Description
private static final HarmonicOscillator.Parametric
FUNCTION

Parametric function to be fitted.

private final double[]
initialGuess

Initial guess.

private final int
maxIter

Maximum number of iterations of the optimization algorithm.

Constructor Summary

AccessConstructor and Description
private
HarmonicCurveFitter(double[]
Initial guess. If set to null, the initial guess will be estimated using the ParameterGuesser.
initialGuess
,
int
Maximum number of iterations of the optimization algorithm.
maxIter
)

Contructor used by the factory methods.

Method Summary

Modifier and TypeMethod and Description
public static HarmonicCurveFitter

Returns:

a curve fitter.
create
()

Creates a default curve fitter.

protected LeastSquaresProblem
getProblem(Collection<WeightedObservedPoint>
Sample points.
observations
)

Implements abstract org.apache.commons.math3.fitting.AbstractCurveFitter.getProblem.

Creates a least squares problem corresponding to the appropriate curve.

public HarmonicCurveFitter

Returns:

a new instance.
withMaxIterations
(int
maximum number of iterations
newMaxIter
)

Configure the maximum number of iterations.

public HarmonicCurveFitter

Returns:

a new instance.
withStartPoint
(double[]
new start point (initial guess)
newStart
)

Configure the start point (initial guess).

Inherited from org.apache.commons.math3.fitting.AbstractCurveFitter:
fitgetOptimizer

Field Detail

FUNCTIONback to summary
private static final HarmonicOscillator.Parametric FUNCTION

Parametric function to be fitted.

initialGuessback to summary
private final double[] initialGuess

Initial guess.

maxIterback to summary
private final int maxIter

Maximum number of iterations of the optimization algorithm.

Constructor Detail

HarmonicCurveFitterback to summary
private HarmonicCurveFitter(double[] initialGuess, int maxIter)

Contructor used by the factory methods.

Parameters
initialGuess:double[]

Initial guess. If set to null, the initial guess will be estimated using the ParameterGuesser.

maxIter:int

Maximum number of iterations of the optimization algorithm.

Method Detail

createback to summary
public static HarmonicCurveFitter create()

Creates a default curve fitter. The initial guess for the parameters will be ParameterGuesser computed automatically, and the maximum number of iterations of the optimization algorithm is set to Integer#MAX_VALUE.

Returns:HarmonicCurveFitter

a curve fitter.

See Also
withStartPoint(double[]), withMaxIterations(int)
getProblemback to summary
protected LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> observations)

Implements abstract org.apache.commons.math3.fitting.AbstractCurveFitter.getProblem.

Doc from org.apache.commons.math3.fitting.AbstractCurveFitter.getProblem.

Creates a least squares problem corresponding to the appropriate curve.

Parameters
observations:Collection<WeightedObservedPoint>

Sample points.

Returns:LeastSquaresProblem

the least squares problem to use for fitting the curve to the given points.

Annotations
@Override
withMaxIterationsback to summary
public HarmonicCurveFitter withMaxIterations(int newMaxIter)

Configure the maximum number of iterations.

Parameters
newMaxIter:int

maximum number of iterations

Returns:HarmonicCurveFitter

a new instance.

withStartPointback to summary
public HarmonicCurveFitter withStartPoint(double[] newStart)

Configure the start point (initial guess).

Parameters
newStart:double[]

new start point (initial guess)

Returns:HarmonicCurveFitter

a new instance.

org.apache.commons.math3.fitting back to summary

public Class HarmonicCurveFitter.ParameterGuesser

extends Object
Class Inheritance
  • java.lang.Object
  • org.apache.commons.math3.fitting.HarmonicCurveFitter.ParameterGuesser

This class guesses harmonic coefficients from a sample.

The algorithm used to guess the coefficients is as follows:

We know \( f(t) \) at some sampling points \( t_i \) and want to find \( a \), \( \omega \) and \( \phi \) such that \( f(t) = a \cos (\omega t + \phi) \).

From the analytical expression, we can compute two primitives : \[ If2(t) = \int f^2 dt = a^2 (t + S(t)) / 2 \] \[ If'2(t) = \int f'^2 dt = a^2 \omega^2 (t - S(t)) / 2 \] where \(S(t) = \frac{\sin(2 (\omega t + \phi))}{2\omega}\)

We can remove \(S\) between these expressions : \[ If'2(t) = a^2 \omega^2 t - \omega^2 If2(t) \]

The preceding expression shows that \(If'2 (t)\) is a linear combination of both \(t\) and \(If2(t)\): \[ If'2(t) = A t + B If2(t) \]

From the primitive, we can deduce the same form for definite integrals between \(t_1\) and \(t_i\) for each \(t_i\) : \[ If2(t_i) - If2(t_1) = A (t_i - t_1) + B (If2 (t_i) - If2(t_1)) \]

We can find the coefficients \(A\) and \(B\) that best fit the sample to this linear expression by computing the definite integrals for each sample points.

For a bilinear expression \(z(x_i, y_i) = A x_i + B y_i\), the coefficients \(A\) and \(B\) that minimize a least-squares criterion \(\sum (z_i - z(x_i, y_i))^2\) are given by these expressions:

\[ A = \frac{\sum y_i y_i \sum x_i z_i - \sum x_i y_i \sum y_i z_i} {\sum x_i x_i \sum y_i y_i - \sum x_i y_i \sum x_i y_i} \] \[ B = \frac{\sum x_i x_i \sum y_i z_i - \sum x_i y_i \sum x_i z_i} {\sum x_i x_i \sum y_i y_i - \sum x_i y_i \sum x_i y_i} \]

In fact, we can assume that both \(a\) and \(\omega\) are positive and compute them directly, knowing that \(A = a^2 \omega^2\) and that \(B = -\omega^2\). The complete algorithm is therefore:

For each \(t_i\) from \(t_1\) to \(t_{n-1}\), compute: \[ f(t_i) \] \[ f'(t_i) = \frac{f (t_{i+1}) - f(t_{i-1})}{t_{i+1} - t_{i-1}} \] \[ x_i = t_i - t_1 \] \[ y_i = \int_{t_1}^{t_i} f^2(t) dt \] \[ z_i = \int_{t_1}^{t_i} f'^2(t) dt \] and update the sums: \[ \sum x_i x_i, \sum y_i y_i, \sum x_i y_i, \sum x_i z_i, \sum y_i z_i \] Then: \[ a = \sqrt{\frac{\sum y_i y_i \sum x_i z_i - \sum x_i y_i \sum y_i z_i } {\sum x_i y_i \sum x_i z_i - \sum x_i x_i \sum y_i z_i }} \] \[ \omega = \sqrt{\frac{\sum x_i y_i \sum x_i z_i - \sum x_i x_i \sum y_i z_i} {\sum x_i x_i \sum y_i y_i - \sum x_i y_i \sum x_i y_i}} \]

Once we know \(\omega\) we can compute: \[ fc = \omega f(t) \cos(\omega t) - f'(t) \sin(\omega t) \] \[ fs = \omega f(t) \sin(\omega t) + f'(t) \cos(\omega t) \]

It appears that \(fc = a \omega \cos(\phi)\) and \(fs = -a \omega \sin(\phi)\), so we can use these expressions to compute \(\phi\). The best estimate over the sample is given by averaging these expressions.

Since integrals and means are involved in the preceding estimations, these operations run in \(O(n)\) time, where \(n\) is the number of measurements.

Field Summary

Modifier and TypeField and Description
private final double
a

Amplitude.

private final double
omega

Angular frequency.

private final double
phi

Phase.

Constructor Summary

AccessConstructor and Description
public
ParameterGuesser(Collection<WeightedObservedPoint>
Sampled observations.
observations
)

Simple constructor.

Method Summary

Modifier and TypeMethod and Description
public double[]

Returns:

the guessed parameters, in the following order:
  • Amplitude
  • Angular frequency
  • Phase
guess
()

Gets an estimation of the parameters.

private double[]

Returns:

the guessed amplitude (at index 0) and circular frequency (at index 1).
guessAOmega
(WeightedObservedPoint[]
Observations, sorted w.r.t. abscissa.
observations
)

Estimate a first guess of the amplitude and angular frequency.

private double

Returns:

the guessed phase.
guessPhi
(WeightedObservedPoint[]
Observations, sorted w.r.t. abscissa.
observations
)

Estimate a first guess of the phase.

private List<WeightedObservedPoint>

Returns:

the input observations, sorted.
sortObservations
(Collection<WeightedObservedPoint>
Input observations.
unsorted
)

Sort the observations with respect to the abscissa.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

aback to summary
private final double a

Amplitude.

omegaback to summary
private final double omega

Angular frequency.

phiback to summary
private final double phi

Phase.

Constructor Detail

ParameterGuesserback to summary
public ParameterGuesser(Collection<WeightedObservedPoint> observations)

Simple constructor.

Parameters
observations:Collection<WeightedObservedPoint>

Sampled observations.

Exceptions
NumberIsTooSmallException:
if the sample is too short.
ZeroException:
if the abscissa range is zero.
MathIllegalStateException:
when the guessing procedure cannot produce sensible results.

Method Detail

guessback to summary
public double[] guess()

Gets an estimation of the parameters.

Returns:double[]

the guessed parameters, in the following order:

  • Amplitude
  • Angular frequency
  • Phase
guessAOmegaback to summary
private double[] guessAOmega(WeightedObservedPoint[] observations)

Estimate a first guess of the amplitude and angular frequency.

Parameters
observations:WeightedObservedPoint[]

Observations, sorted w.r.t. abscissa.

Returns:double[]

the guessed amplitude (at index 0) and circular frequency (at index 1).

Exceptions
ZeroException:
if the abscissa range is zero.
MathIllegalStateException:
when the guessing procedure cannot produce sensible results.
guessPhiback to summary
private double guessPhi(WeightedObservedPoint[] observations)

Estimate a first guess of the phase.

Parameters
observations:WeightedObservedPoint[]

Observations, sorted w.r.t. abscissa.

Returns:double

the guessed phase.

sortObservationsback to summary
private List<WeightedObservedPoint> sortObservations(Collection<WeightedObservedPoint> unsorted)

Sort the observations with respect to the abscissa.

Parameters
unsorted:Collection<WeightedObservedPoint>

Input observations.

Returns:List<WeightedObservedPoint>

the input observations, sorted.