Class HarmonicCoefficientsGuesser

  extended by org.jscience.mathematics.analysis.fitting.HarmonicCoefficientsGuesser
All Implemented Interfaces:

public class HarmonicCoefficientsGuesser
extends java.lang.Object

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 ti 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)  = a^2 * [t + S (t)] / 2
     If'2 (t) = int (f'^2) = a^2 * omega^2 * [t - S (t)] / 2
     where S (t) = 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 t1 and ti for each ti :

   If2 (ti) - If2 (t1) = A * (ti - t1) + B * (If2 (ti) - If2 (t1))

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 (xi, yi) = A * xi + B * yi, the coefficients a and b that minimize a least square criterion Sum ((zi - z (xi, yi))^2) are given by these expressions:


Sum (yi^2) Sum (xi zi) - Sum (xi yi) Sum (yi zi) A = ------------------------------------------------ Sum (xi^2) Sum (yi^2) - Sum (xi yi) Sum (xi yi)

Sum (xi^2) Sum (yi zi) - Sum (xi yi) Sum (xi zi) B = ------------------------------------------------ Sum (xi^2) Sum (yi^2) - Sum (xi yi) Sum (xi yi)

In fact, we can assume 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 ti from t1 to t(n-1), compute: f (ti) f' (ti) = (f (t(i+1)) - f(t(i-1))) / (t(i+1) - t(i-1)) xi = ti - t1 yi = int (f^2) from t1 to ti zi = int (f'^2) from t1 to ti update the sums Sum (xi^2), Sum (yi^2), Sum (xi yi), Sum (xi zi) and Sum (yi zi) end for

|------------------------------------------------- \ | Sum (yi^2) Sum (xi zi) - Sum (xi yi) Sum (yi zi) a = \ | ------------------------------------------------ \| Sum (xi yi) Sum (xi zi) - Sum (xi^2) Sum (yi zi)

|------------------------------------------------- \ | Sum (xi yi) Sum (xi zi) - Sum (xi^2) Sum (yi zi) omega = \ | ------------------------------------------------ \| Sum (xi^2) Sum (yi^2) - Sum (xi yi) Sum (xi yi)

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.

See Also:
Serialized Form

Constructor Summary
HarmonicCoefficientsGuesser(AbstractCurveFitter.FitMeasurement[] measurements)
Method Summary
 double getA()
 double getOmega()
 double getPhi()
 void guess()
          Estimate a first guess of the coefficients.
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail


public HarmonicCoefficientsGuesser(AbstractCurveFitter.FitMeasurement[] measurements)
Method Detail


public void guess()
           throws ExhaustedSampleException,
Estimate a first guess of the coefficients.

ExhaustedSampleException - if the sample is exhausted.
MappingException - if the integrator throws one.
EstimationException - if the sample is too short or if the first guess cannot be computed (when the elements under the square roots are negative).


public double getOmega()


public double getA()


public double getPhi()