/*
 * Copyright 1998, University Corporation for Atmospheric Research
 * All Rights Reserved.
 * See file LICENSE for copying and redistribution conditions.
 *
 * $Id: LonArithProg.java,v 1.3 2001-11-06 17:37:41 steve Exp $
 */

package visad.data.in;

import visad.VisADException;

/**
 * Provides support for determining if a sequence of values is an arithmetic
 * progression of longitude values and, if so, the progression parameters.
 *
 * @author Steven R. Emmerson
 */
public final class LonArithProg
    extends	ArithProg
{
    private double              sumDel = Double.NaN;

    /**
     * Accumulates a set of floats.  Indicates whether or not the sequence is
     * consistent with the arithmetic progression so far.
     *
     * @param values		The values to accumulate.
     * @return			False if the difference between any current
     *				and previous value normalized by the current
     *				increment differs from unity by more than the
     *				nearness threshold; otherwise, true.
     * @throws VisADException	{@link #isConsistent()} was false before this
     *				method was invoked.
     * @precondition		isConsistent() is true.
     * @postcondition		A subsequent getNumber() will return
     *				values.length more than previously
     *				if the function returns true.
     * @postcondition		A subsequent getLast() will return the
     *				value argument if the function returns true.
     */
    public synchronized boolean accumulate(float[] values)
	throws VisADException
    {
	if (!isConsistent())
	    throw new VisADException(
		getClass().getName() + ".accumulate(float[]): " +
		"Sequence isn't an arithmetic progression");
	for (int i = 0; i < values.length; i++)
	{
	    double value = values[i];
	    if (n == 0)
	    {
		first = value;
	    }
	    else if (n == 1)
	    {
		sumDel = meanDel = delta(first, value);
	    }
	    else if (isConsistent)
	    {
		accum(value, fEps);
	    }
	    last = value;
	    n++;
	}
	return isConsistent;
    }

    /**
     * Accumulates a set of doubles.  Indicates whether or not the sequence is
     * consistent with the arithmetic progression so far.
     *
     * @param values		The values to accumulate.
     * @return			False if the difference between any current
     *				and previous value normalized by the current
     *				increment differs from unity by more than the
     *				nearness threshold; otherwise, true.
     * @throws VisADException	{@link #isConsistent()} was false before this
     *				method was invoked.
     * @precondition		isConsistent() is true.
     * @postcondition		A subsequent getNumber() will return
     *				values.length more than previously
     *				if the function returns true.
     * @postcondition		A subsequent getLast() will return the
     *				value argument if the function returns true.
     */
    public synchronized boolean accumulate(double[] values)
	throws VisADException
    {
	if (!isConsistent())
	    throw new VisADException(
		getClass().getName() + ".accumulate(double[]): " +
		"Sequence isn't an arithmetic progression");
	for (int i = 0; i < values.length; i++)
	{
	    double value = values[i];
	    if (n == 0)
	    {
		first = value;
	    }
	    else if (n == 1)
	    {
		sumDel = meanDel = delta(first, value);
	    }
	    else if (isConsistent)
	    {
		accum(value, dEps);
	    }
	    last = value;
	    n++;
	}
	return isConsistent;
    }

    private void accum(double value, double eps)
    {
	double uncLast = last*eps;
	double uncValue = value*eps;
	double var = uncLast*uncLast + uncValue*uncValue;
	double err = delta(last + meanDel, value);
	if (err*err > var)
	{
	    isConsistent = false;
	}
	else
	{
	    sumDel += delta(last, value);
	    meanDel = sumDel / n;
	}
    }

    /**
     * Returns the difference between two values.
     *
     * @param value1		The first value.
     * @param value2		The second value.
     * @return			The increment from the first value to the
     *				second value.
     */
    private double delta(double value1, double value2)
    {
	double	delta = (value2 - value1) % 360.0;
	if (delta < -180.0)
	    delta += 360.0;
	else if (delta > 180.0)
	    delta -= 360.0;
	return delta;
    }

    /**
     * Tests this class.
     *
     * @param args		Runtime arguments.  Ignored.
     * @throws Exception	Something went wrong.
     */
    public static void main(String[] args)
	throws Exception
    {
	double[] lons = {
	    179.2, 179.21, 179.22, 179.23, 179.24, 179.25, 179.26, 179.27, 179.28, 179.29,
	    179.3, 179.31, 179.32, 179.33, 179.34, 179.35, 179.36, 179.37, 179.38, 179.39,
	    179.4, 179.41, 179.42, 179.43, 179.44, 179.45, 179.46, 179.47, 179.48, 179.49,
	    179.5, 179.51, 179.52, 179.53, 179.54, 179.55, 179.56, 179.57, 179.58, 179.59,
	    179.6, 179.61, 179.62, 179.63, 179.64, 179.65, 179.66, 179.67, 179.68, 179.69,
	    179.7, 179.71, 179.72, 179.73, 179.74, 179.75, 179.76, 179.77, 179.78, 179.79,
	    179.8, 179.81, 179.82, 179.83, 179.84, 179.85, 179.86, 179.87, 179.88, 179.89,
	    179.9, 179.91, 179.92, 179.93, 179.94, 179.95, 179.96, 179.97, 179.98, 179.99,
	    180,
	    -179.99, -179.98, -179.97, -179.96, -179.95, -179.94, -179.93, -179.92, -179.91, -179.9,
	    -179.89, -179.88, -179.87, -179.86, -179.85, -179.84, -179.83, -179.82, -179.81, -179.8,
	    -179.79, -179.78, -179.77, -179.76, -179.75, -179.74, -179.73, -179.72, -179.71, -179.7,
	    -179.69, -179.68, -179.67, -179.66, -179.65, -179.64, -179.63, -179.62, -179.61, -179.6,
	    -179.59, -179.58, -179.57, -179.56, -179.55, -179.54, -179.53, -179.52, -179.51, -179.5,
	    -179.49, -179.48, -179.47, -179.46, -179.45, -179.44, -179.43, -179.42, -179.41, -179.4,
	    -179.39, -179.38, -179.37, -179.36, -179.35, -179.34, -179.33, -179.32, -179.31, -179.3,
	    -179.29, -179.28, -179.27, -179.26, -179.25, -179.24, -179.23, -179.22, -179.21, -179.2};
	LonArithProg	ap = new LonArithProg();

	ap.accumulate(lons);

	System.out.println("ap.isConsistent()=" + ap.isConsistent());
	System.out.println("ap.getFirst()=" + ap.getFirst());
	System.out.println("ap.getLast()=" + ap.getLast());
	System.out.println("ap.getNumber()=" + ap.getNumber());
	System.out.println("ap.getCommonDifference()=" + 
	    ap.getCommonDifference());
    }
}

 

Ads help maintain this website.