/* * 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 * <code>values.length</code> 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 * <code>values.length</code> 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()); } }