harmonic oscillator
function.
initial guess values must be passed
in the following order:
| Modifier and Type | Class and Description |
|---|---|
| public static class | HarmonicCurveFitter.
This class guesses harmonic coefficients from a sample. |
| Modifier and Type | Field and Description |
|---|---|
| private static final HarmonicOscillator. | FUNCTION
Parametric function to be fitted. |
| private final double[] | initialGuess
Initial guess. |
| private final int | maxIter
Maximum number of iterations of the optimization algorithm. |
| Access | Constructor and Description |
|---|---|
| private | HarmonicCurveFitter(double[]
Initial guess. If set to initialGuess, int null, the initial guess
will be estimated using the ParameterGuesser.Maximum number of iterations of the optimization algorithm. maxIter)Contructor used by the factory methods. |
| Modifier and Type | Method and Description |
|---|---|
| public static HarmonicCurveFitter | |
| protected LeastSquaresProblem | getProblem(Collection<WeightedObservedPoint>
Sample points. observations)Implements abstract org. Creates a least squares problem corresponding to the appropriate curve. |
| public HarmonicCurveFitter | Returns: a new instance.maximum number of iterations newMaxIter)Configure the maximum number of iterations. |
| public HarmonicCurveFitter | Returns: a new instance.new start point (initial guess) newStart)Configure the start point (initial guess). |
| FUNCTION | back to summary |
|---|---|
| private static final HarmonicOscillator. Parametric function to be fitted. | |
| initialGuess | back to summary |
|---|---|
| private final double[] initialGuess Initial guess. | |
| maxIter | back to summary |
|---|---|
| private final int maxIter Maximum number of iterations of the optimization algorithm. | |
| HarmonicCurveFitter | back to summary |
|---|---|
| private HarmonicCurveFitter(double[] initialGuess, int maxIter) Contructor used by the factory methods.
| |
| create | back to summary |
|---|---|
| public static HarmonicCurveFitter create() Creates a default curve fitter.
The initial guess for the parameters will be
| |
| getProblem | back to summary |
|---|---|
| protected LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> observations) Implements abstract org. Doc from org. Creates a least squares problem corresponding to the appropriate curve.
| |
| withMaxIterations | back to summary |
|---|---|
| public HarmonicCurveFitter withMaxIterations(int newMaxIter) Configure the maximum number of iterations.
| |
| withStartPoint | back to summary |
|---|---|
| public HarmonicCurveFitter withStartPoint(double[] newStart) Configure the start point (initial guess).
| |
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.
| Modifier and Type | Field and Description |
|---|---|
| private final double | a
Amplitude. |
| private final double | omega
Angular frequency. |
| private final double | phi
Phase. |
| Access | Constructor and Description |
|---|---|
| public | ParameterGuesser(Collection<WeightedObservedPoint>
Sampled observations. observations)Simple constructor. |
| Modifier and Type | Method and Description |
|---|---|
| public double[] | Returns: the guessed parameters, in the following order:
Gets an estimation of the parameters. |
| private double[] | Returns: the guessed amplitude (at index 0) and circular frequency (at index 1).Observations, sorted w.r.t. abscissa. observations)Estimate a first guess of the amplitude and angular frequency. |
| private double | Returns: the guessed phase.Observations, sorted w.r.t. abscissa. observations)Estimate a first guess of the phase. |
| private List | Returns: the input observations, sorted.Input observations. unsorted)Sort the observations with respect to the abscissa. |
| a | back to summary |
|---|---|
| private final double a Amplitude. | |
| omega | back to summary |
|---|---|
| private final double omega Angular frequency. | |
| phi | back to summary |
|---|---|
| private final double phi Phase. | |
| ParameterGuesser | back to summary |
|---|---|
| public ParameterGuesser(Collection<WeightedObservedPoint> observations) Simple constructor.
| |
| guess | back to summary |
|---|---|
| public double[] guess() Gets an estimation of the parameters.
| |
| guessAOmega | back to summary |
|---|---|
| private double[] guessAOmega(WeightedObservedPoint[] observations) Estimate a first guess of the amplitude and angular frequency.
| |
| guessPhi | back to summary |
|---|---|
| private double guessPhi(WeightedObservedPoint[] observations) Estimate a first guess of the phase.
| |
| sortObservations | back to summary |
|---|---|
| private List Sort the observations with respect to the abscissa.
| |