Re: Evaluating a FlatField (and VisADTimeSlider?)

Hi James,

> I'm trying to do something fairly similar to
> "Simple.java" in the Developers Guide. Simple.java
> uses an Integer1DSet as the domain, and
> "field.evaluate" works fine. However, I want to
> represent time as a Gridded1DDoubleSet in the domain.
> When I do this (see attached code) I get the exception
> below.
> 
> So should I be able to do this, or do I need to go
> about it a different way?

Thanks for finding this bug. The fix is in the attached
Gridded1DDoubleSet.java.

Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI  53706
hibbard@xxxxxxxxxxxxxxxxx  608-263-4427  fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html
//
// Gridded1DDoubleSet.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2001 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

/**
   Gridded1DDoubleSet is a Gridded1DSet with double-precision samples.<P>
*/
public class Gridded1DDoubleSet extends Gridded1DSet
       implements GriddedDoubleSet {

  double[] Low = new double[1];
  double[] Hi = new double[1];
  double LowX, HiX;
  double[][] Samples;

  /**
   * A canonicalizing cache of previously-created instances.  Because instances
   * are immutable, a cache can be used to reduce memory usage by ensuring
   * that each instance is truely unique.  By implementing the cache using a
   * {@link WeakHashMap}, this can be accomplished without the technique itself
   * adversely affecting memory usage.
   */
  private static final WeakHashMap      cache = new WeakHashMap();


  // Overridden Gridded1DSet constructors (float[][])

  /** a 1-D sequence with no regular interval with null errors,
      CoordinateSystem and Units are defaults from type */
  public Gridded1DDoubleSet(MathType type, float[][] samples, int lengthX)
         throws VisADException {
    this(type, Set.floatToDouble(samples), lengthX, null, null, null, true);
  }

  public Gridded1DDoubleSet(MathType type, float[][] samples, int lengthX,
                            CoordinateSystem coord_sys, Unit[] units,
                            ErrorEstimate[] errors) throws VisADException {
    this(type, Set.floatToDouble(samples), lengthX,
         coord_sys, units, errors, true);
  }

  /** a 1-D sorted sequence with no regular interval. samples array
      is organized float[1][number_of_samples] where lengthX
      number_of_samples. samples must be sorted (either increasing
      or decreasing). coordinate_system and units must be compatible
      with defaults for type, or may be null. errors may be null */
  public Gridded1DDoubleSet(MathType type, float[][] samples, int lengthX,
                            CoordinateSystem coord_sys, Unit[] units,
                            ErrorEstimate[] errors, boolean copy)
                            throws VisADException {
    this(type, Set.floatToDouble(samples), lengthX,
      coord_sys, units, errors, copy);
  }


  // Corresponding Gridded1DDoubleSet constructors (double[][])

  /** a 1-D sequence with no regular interval with null errors,
      CoordinateSystem and Units are defaults from type */
  public Gridded1DDoubleSet(MathType type, double[][] samples, int lengthX)
         throws VisADException {
    this(type, samples, lengthX, null, null, null, true);
  }

  public Gridded1DDoubleSet(MathType type, double[][] samples, int lengthX,
                      CoordinateSystem coord_sys, Unit[] units,
                      ErrorEstimate[] errors) throws VisADException {
    this(type, samples, lengthX, coord_sys, units, errors, true);
  }

  /** a 1-D sorted sequence with no regular interval. samples array
      is organized double[1][number_of_samples] where lengthX
      number_of_samples. samples must be sorted (either increasing
      or decreasing). coordinate_system and units must be compatible
      with defaults for type, or may be null. errors may be null */
  public Gridded1DDoubleSet(MathType type, double[][] samples, int lengthX,
                            CoordinateSystem coord_sys, Unit[] units,
                            ErrorEstimate[] errors, boolean copy)
                            throws VisADException {
    super(type, null, lengthX, coord_sys, units, errors, copy);
    if (samples == null) {
      throw new SetException("Gridded1DDoubleSet: samples are null");
    }
    init_doubles(samples, copy);
    LowX = Low[0];
    HiX = Hi[0];
    LengthX = Lengths[0];

    if (Samples != null && Lengths[0] > 1) {
      // samples consistency test
      for (int i=0; i<Length; i++) {
        if (Samples[0][i] != Samples[0][i]) {
          throw new SetException(
           "Gridded1DDoubleSet: samples values may not be missing");
        }
      }
      Ascending = (Samples[0][LengthX-1] > Samples[0][0]);
      if (Ascending) {
        for (int i=1; i<LengthX; i++) {
          if (Samples[0][i] < Samples[0][i-1]) {
            throw new SetException(
             "Gridded1DDoubleSet: samples do not form a valid grid ("+i+")");
          }
        }
      }
      else { // !Ascending
        for (int i=1; i<LengthX; i++) {
          if (Samples[0][i] > Samples[0][i-1]) {
            throw new SetException(
             "Gridded1DDoubleSet: samples do not form a valid grid ("+i+")");
          }
        }
      }
    }
  }

  /**
   * Returns an instance of this class.  This method uses a weak cache of
   * previously-created instances to reduce memory usage.
   *
   * @param type                The type of the set.  Must be a {@link 
   *                            RealType} or a single-component {@link
   *                            RealTupleType} or {@link SetType}.
   * @param samples             The values in the set.
   *                            <code>samples[i]</code> is the value of
   *                            the ith sample point.  Must be sorted (either
   *                            increasing or decreasing).  May be
   *                            <code>null</code>.  The array is not copied, so
   *                            either don't modify it or clone it first.
   * @param coord_sys           The coordinate system for this, particular, set.
   *                            Must be compatible with the default coordinate
   *                            system.  May be <code>null</code>.
   * @param unit                The unit for the samples.  Must be compatible
   *                            with the default unit.  May be 
   *                            <code>null</code>.
   * @param error               The error estimate of the samples.  May be
   *                            <code>null</code>.
   */
  public static synchronized Gridded1DDoubleSet create(
      MathType          type,
      double[]          samples,
      CoordinateSystem  coordSys,
      Unit              unit,
      ErrorEstimate     error)
    throws VisADException
  {
    Gridded1DDoubleSet  newSet
      new Gridded1DDoubleSet(
        type, new double[][] {samples}, samples.length, coordSys,
        new Unit[] {unit}, new ErrorEstimate[] {error}, false);
    WeakReference       ref = (WeakReference)cache.get(newSet);
    if (ref == null)
    {
      /*
       * The new instance is unique (any and all previously-created identical
       * instances no longer exist).
       *
       * A WeakReference is used in the following because values of a
       * WeakHashMap aren't "weak" themselves and must not strongly reference
       * their associated keys either directly or indirectly.
       */
      cache.put(newSet, new WeakReference(newSet));
    }
    else
    {
      /*
       * The new instance is a duplicate of a previously-created one.
       */
      Gridded1DDoubleSet        oldSet = (Gridded1DDoubleSet)ref.get();
      if (oldSet == null)
      {
        /* The previous instance no longer exists.  Save the new instance. */
        cache.put(newSet, new WeakReference(newSet));
      }
      else
      {
        /* The previous instance still exists.  Reuse it to save memory. */
        newSet = oldSet;
      }
    }
    return newSet;
  }


  // Overridden Gridded1DSet methods (float[][])

  public float[][] getSamples() throws VisADException {
    return getSamples(true);
  }

  public float[][] getSamples(boolean copy) throws VisADException {
    return Set.doubleToFloat(Samples);
  }

  /** convert an array of 1-D indices to an array of values in
      R^DomainDimension */
  public float[][] indexToValue(int[] index) throws VisADException {
    return Set.doubleToFloat(indexToDouble(index));
  }

  /**
   * Convert an array of values in R^DomainDimension to an array of
   * 1-D indices.  This Gridded1DDoubleSet must have at least two points in the
   * set.
   * @param value       An array of coordinates.  <code>value[i][j]
   *                    <code> contains the <code>i</code>th component of the
   *                    <code>j</code>th point.
   * @return            Indices of nearest points.  RETURN_VALUE<code>[i]</code>
   *                    will contain the index of the point in the set closest
   *                    to <code>value[][i]</code> or <code>-1</code> if
   *                    <code>value[][i]</code> lies outside the set.
   */
  public int[] valueToIndex(float[][] value) throws VisADException {
    return doubleToIndex(Set.floatToDouble(value));
  }

  public float[][] gridToValue(float[][] grid) throws VisADException {
    return Set.doubleToFloat(gridToDouble(Set.floatToDouble(grid)));
  }

  /** transform an array of values in R^DomainDimension to an array
      of non-integer grid coordinates */
  public float[][] valueToGrid(float[][] value) throws VisADException {
    return Set.doubleToFloat(doubleToGrid(Set.floatToDouble(value)));
  }

  /** for each of an array of values in R^DomainDimension, compute an array
      of 1-D indices and an array of weights, to be used for interpolation;
      indices[i] and weights[i] are null if i-th value is outside grid
      (i.e., if no interpolation is possible) */
  public void valueToInterp(float[][] value, int[][] indices,
    float[][] weights) throws VisADException
  {
    int len = weights.length;
    double[][] w = new double[len][];
    // for (int i=0; i<len; i++) w[i] = new double[weights[i].length];
    doubleToInterp(Set.floatToDouble(value), indices, w);
    for (int i=0; i<len; i++) {
      if (w[i] != null) {
        weights[i] = new float[w[i].length];
        for (int j=0; j<w[i].length; j++) {
          weights[i][j] = (float) w[i][j];
        }
      }
    }
  }

  public float getLowX() {
    return (float) LowX;
  }

  public float getHiX() {
    return (float) HiX;
  }


  // Corresponding Gridded1DDoubleSet methods (double[][])

  public double[][] getDoubles() throws VisADException {
    return getDoubles(true);
  }

  public double[][] getDoubles(boolean copy) throws VisADException {
    return copy ? Set.copyDoubles(Samples) : Samples;
  }

  /** convert an array of 1-D indices to an array of values in
      R^DomainDimension */
  public double[][] indexToDouble(int[] index) throws VisADException {
    int length = index.length;
    if (Samples == null) {
      // not used - over-ridden by Linear1DSet.indexToValue
      double[][] grid = new double[ManifoldDimension][length];
      for (int i=0; i<length; i++) {
        if (0 <= index[i] && index[i] < Length) {
          grid[0][i] = (double) index[i];
        }
        else {
          grid[0][i] = -1;
        }
      }
      return gridToDouble(grid);
    }
    else {
      double[][] values = new double[1][length];
      for (int i=0; i<length; i++) {
        if (0 <= index[i] && index[i] < Length) {
          values[0][i] = Samples[0][index[i]];
        }
        else {
          values[0][i] = Double.NaN;
        }
      }
      return values;
    }
  }

  public int[] doubleToIndex(double[][] value) throws VisADException {
    if (value.length != DomainDimension) {
      throw new SetException("Gridded1DDoubleSet.doubleToIndex: value dimension 
" +
                             value.length + " not equal to Domain dimension " +
                             DomainDimension);
    }
    int length = value[0].length;
    int[] index = new int[length];

    double[][] grid = doubleToGrid(value);
    double[] grid0 = grid[0];
    double g;
    for (int i=0; i<length; i++) {
      g = grid0[i];
      index[i] = Double.isNaN(g) ? -1 : ((int) (g + 0.5));
    }
    return index;
  }

  /** transform an array of non-integer grid coordinates to an array
      of values in R^DomainDimension */
  public double[][] gridToDouble(double[][] grid) throws VisADException {
    if (grid.length < DomainDimension) { 
      throw new SetException("Gridded1DDoubleSet.gridToDouble: grid dimension " 
+
                             grid.length + " not equal to Domain dimension " +
                             DomainDimension);
    }
    if (Lengths[0] < 2) {
      throw new SetException("Gridded1DDoubleSet.gridToDouble: " +
        "requires all grid dimensions to be > 1");
    }
    int length = grid[0].length;
    double[][] value = new double[1][length];
    for (int i=0; i<length; i++) {
      // let g be the current grid coordinate
      double g = grid[0][i];
      if ( (g < -0.5) || (g > LengthX-0.5) ) {
        value[0][i] = Double.NaN;
        continue;
      }
      // calculate closest integer variable
      int ig;
      if (g < 0) ig = 0;
      else if (g >= LengthX-1) ig = LengthX - 2;
      else ig = (int) g;
      double A = g - ig;  // distance variable
      // do the linear interpolation
      value[0][i] = (1-A)*Samples[0][ig] + A*Samples[0][ig+1];
    }
    return value;
  }

  /** transform an array of values in R^DomainDimension to an array
      of non-integer grid coordinates */
  public double[][] doubleToGrid(double[][] value) throws VisADException {
    if (value.length < DomainDimension) {
      throw new SetException("Gridded1DDoubleSet.doubleToGrid: value dimension 
" +
                             value.length + " not equal to Domain dimension " +
                             DomainDimension);
    }
    if (Lengths[0] < 2) {
      throw new SetException("Gridded1DDoubleSet.doubleToGrid: " +
        "requires all grid dimensions to be > 1");
    }
    double[] vals = value[0];
    int length = vals.length;
    double[] samps = Samples[0];
    double[][] grid = new double[1][length];
    int ig = (LengthX - 1)/2;
    for (int i=0; i<length; i++) {
      if (Double.isNaN(vals[i])) grid[0][i] = Double.NaN;
      else {
        int lower = 0;
        int upper = LengthX-1;
        while (lower < upper) {
          if ((vals[i] - samps[ig]) * (vals[i] - samps[ig+1]) <= 0) break;
          if (Ascending ? samps[ig+1] < vals[i] : samps[ig+1] > vals[i]) {
            lower = ig+1;
          }
          else if (Ascending ? samps[ig] > vals[i] : samps[ig] < vals[i]) {
            upper = ig;
          }
          if (lower < upper) ig = (lower + upper) / 2;
        }
        // Newton's method
        double solv = ig + (vals[i] - samps[ig]) / (samps[ig+1] - samps[ig]);
        if (solv >= -0.5 && solv <= LengthX - 0.5) grid[0][i] = solv;
        else {
          grid[0][i] = Double.NaN;
          // next guess should be in the middle if previous value was missing
          ig = (LengthX - 1)/2;
        }
      }
    }
    return grid;
  }

  /** for each of an array of values in R^DomainDimension, compute an array
      of 1-D indices and an array of weights, to be used for interpolation;
      indices[i] and weights[i] are null if i-th value is outside grid
      (i.e., if no interpolation is possible) */
  public void doubleToInterp(double[][] value, int[][] indices,
    double[][] weights) throws VisADException
  {
    if (value.length != DomainDimension) {
      throw new SetException("Gridded1DDoubleSet.doubleToInterp: value 
dimension " +
                             value.length + " not equal to Domain dimension " +
                             DomainDimension);
    }
    int length = value[0].length; // number of values
    if (indices.length != length) {
      throw new SetException("Gridded1DDoubleinearLatLonSet.doubleToInterp: 
indices length " +
                             indices.length +
                             " doesn't match value[0] length " +
                             value[0].length);
    }
    if (weights.length != length) {
      throw new SetException("Gridded1DDoubleSet.doubleToInterp: weights length 
" +
                             weights.length +
                             " doesn't match value[0] length " +
                             value[0].length);
    }
    // convert value array to grid coord array
    double[][] grid = doubleToGrid(value);

    int i, j, k; // loop indices
    int lis; // temporary length of is & cs
    int length_is; // final length of is & cs, varies by i
    int isoff; // offset along one grid dimension
    double a, b; // weights along one grid dimension; a + b = 1.0
    int[] is; // array of indices, becomes part of indices
    double[] cs; // array of coefficients, become part of weights

    int base; // base index, as would be returned by valueToIndex
    int[] l = new int[ManifoldDimension]; // integer 'factors' of base
    // fractions with l; -0.5 <= c <= 0.5
    double[] c = new double[ManifoldDimension];

    // array of index offsets by grid dimension
    int[] off = new int[ManifoldDimension];
    off[0] = 1;
    for (j=1; j<ManifoldDimension; j++) off[j] = off[j-1] * Lengths[j-1];

    for (i=0; i<length; i++) {
      // compute length_is, base, l & c
      length_is = 1;
      if (Double.isNaN(grid[ManifoldDimension-1][i])) {
        base = -1;
      }
      else {
        l[ManifoldDimension-1] = (int) (grid[ManifoldDimension-1][i] + 0.5);
        // WLH 23 Dec 99
        if (l[ManifoldDimension-1] == Lengths[ManifoldDimension-1]) {
          l[ManifoldDimension-1]--;
        }
        c[ManifoldDimension-1] = grid[ManifoldDimension-1][i] -
                                 ((double) l[ManifoldDimension-1]);
        if (!((l[ManifoldDimension-1] == 0 && c[ManifoldDimension-1] <= 0.0) ||
              (l[ManifoldDimension-1] == Lengths[ManifoldDimension-1] - 1 &&
               c[ManifoldDimension-1] >= 0.0))) {
          // only interp along ManifoldDimension-1
          // if between two valid grid coords
          length_is *= 2;
        }
        base = l[ManifoldDimension-1];
      }
      for (j=ManifoldDimension-2; j>=0 && base>=0; j--) {
        if (Double.isNaN(grid[j][i])) {
          base = -1;
        }
        else {
          l[j] = (int) (grid[j][i] + 0.5);
          if (l[j] == Lengths[j]) l[j]--; // WLH 23 Dec 99
          c[j] = grid[j][i] - ((double) l[j]);
          if (!((l[j] == 0 && c[j] <= 0.0) ||
                (l[j] == Lengths[j] - 1 && c[j] >= 0.0))) {
            // only interp along dimension j if between two valid grid coords
            length_is *= 2;
          }
          base = l[j] + Lengths[j] * base;
        }
      }

      if (base < 0) {
        // value is out of grid so return null
        is = null;
        cs = null;
      }
      else {
        // create is & cs of proper length, and init first element
        is = new int[length_is];
        cs = new double[length_is];
        is[0] = base;
        cs[0] = 1.0f;
        lis = 1;

        for (j=0; j<ManifoldDimension; j++) {
          if (!((l[j] == 0 && c[j] <= 0.0) ||
                (l[j] == Lengths[j] - 1 && c[j] >= 0.0))) {
            // only interp along dimension j if between two valid grid coords
            if (c[j] >= 0.0) {
              // grid coord above base
              isoff = off[j];
              a = 1.0f - c[j];
              b = c[j];
            }
            else {
              // grid coord below base
              isoff = -off[j];
              a = 1.0f + c[j];
              b = -c[j];
            }
            // double is & cs; adjust new offsets; split weights
            for (k=0; k<lis; k++) {
              is[k+lis] = is[k] + isoff;
              cs[k+lis] = cs[k] * b;
              cs[k] *= a;
            }
            lis *= 2;
          }
        }
      }
      indices[i] = is;
      weights[i] = cs;
    }
  }

  public double getDoubleLowX() {
    return LowX;
  }

  public double getDoubleHiX() {
    return HiX;
  }


  // Miscellaneous Set methods that must be overridden
  // (this code is duplicated throughout all *DoubleSet classes)

  void init_doubles(double[][] samples, boolean copy)
       throws VisADException {
    if (samples.length != DomainDimension) {
      throw new SetException("Gridded1DDoubleSet.init_doubles:" +
                             " samples dimension " + samples.length +
                             " not equal to Domain dimension " +
                             DomainDimension);
    }
    if (Length == 0) {
      // Length set in init_lengths, but not called for IrregularSet
      Length = samples[0].length;
    }
    else {
      if (Length != samples[0].length) {
        throw new SetException("Gridded1DDoubleSet.init_doubles: samples[0] 
length " +
                               samples[0].length +
                               " doesn't match expected length " + Length);
      }
    }
    // MEM
    if (copy) {
      Samples = new double[DomainDimension][Length];
    }
    else {
      Samples = samples;
    }
    for (int j=0; j<DomainDimension; j++) {
      if (samples[j].length != Length) {
        throw new SetException("Gridded1DDoubleSet.init_doubles: samples[" + j +
                               "] length " + samples[0].length +
                               " doesn't match expected length " + Length);
      }
      double[] samplesJ = samples[j];
      double[] SamplesJ = Samples[j];
      if (copy) {
        System.arraycopy(samplesJ, 0, SamplesJ, 0, Length);
      }
      Low[j] = Double.POSITIVE_INFINITY;
      Hi[j] = Double.NEGATIVE_INFINITY;
      double sum = 0.0f;
      for (int i=0; i<Length; i++) {
        if (SamplesJ[i] == SamplesJ[i] && !Double.isInfinite(SamplesJ[i])) {
          if (SamplesJ[i] < Low[j]) Low[j] = SamplesJ[i];
          if (SamplesJ[i] > Hi[j]) Hi[j] = SamplesJ[i];
        }
        else {
          SamplesJ[i] = Double.NaN;
        }
        sum += SamplesJ[i];
      }
      if (SetErrors[j] != null ) {
        SetErrors[j]
          new ErrorEstimate(SetErrors[j].getErrorValue(), sum / Length,
                            Length, SetErrors[j].getUnit());
      }
      super.Low[j] = (float) Low[j];
      super.Hi[j] = (float) Hi[j];
    }
  }

  public void cram_missing(boolean[] range_select) {
    int n = Math.min(range_select.length, Samples[0].length);
    for (int i=0; i<n; i++) {
      if (!range_select[i]) Samples[0][i] = Double.NaN;
    }
  }

  public boolean isMissing() {
    return (Samples == null);
  }

  public boolean equals(Object set) {
    if (!(set instanceof Gridded1DDoubleSet) || set == null) return false;
    if (this == set) return true;
    if (testNotEqualsCache((Set) set)) return false;
    if (testEqualsCache((Set) set)) return true;
    if (!equalUnitAndCS((Set) set)) return false;
    try {
      int i, j;
      if (DomainDimension != ((Gridded1DDoubleSet) set).getDimension() ||
          ManifoldDimension !
            ((Gridded1DDoubleSet) set).getManifoldDimension() ||
          Length != ((Gridded1DDoubleSet) set).getLength()) return false;
      for (j=0; j<ManifoldDimension; j++) {
        if (Lengths[j] != ((Gridded1DDoubleSet) set).getLength(j)) {
          return false;
        }
      }
      // Sets are immutable, so no need for 'synchronized'
      double[][] samples = ((Gridded1DDoubleSet) set).getDoubles(false);
      if (Samples != null && samples != null) {
        for (j=0; j<DomainDimension; j++) {
          for (i=0; i<Length; i++) {
            if (Samples[j][i] != samples[j][i]) {
              addNotEqualsCache((Set) set);
              return false;
            }
          }
        }
      }
      else {
        double[][] this_samples = getDoubles(false);
        if (this_samples == null) {
          if (samples != null) {
            return false;
          }
        } else if (samples == null) {
          return false;
        } else {
          for (j=0; j<DomainDimension; j++) {
            for (i=0; i<Length; i++) {
              if (this_samples[j][i] != samples[j][i]) {
                addNotEqualsCache((Set) set);
                return false;
              }
            }
          }
        }
      }
      addEqualsCache((Set) set);
      return true;
    }
    catch (VisADException e) {
      return false;
    }
  }

  /**
   * Returns the hash code of this instance. {@link Object#hashCode()} should be
   * overridden whenever {@link Object#equals(Object)} is.
   * @return                    The hash code of this instance (includes the
   *                            values).
   */
  public int hashCode()
  {
    if (!hashCodeSet)
    {
      hashCode = unitAndCSHashCode();
      hashCode ^= DomainDimension ^ ManifoldDimension ^ Length;
      for (int j=0; j<ManifoldDimension; j++)
        hashCode ^= Lengths[j];
      if (Samples != null)
        for (int j=0; j<DomainDimension; j++)
          for (int i=0; i<Length; i++)
            hashCode ^= new Double(Samples[j][i]).hashCode();
      hashCodeSet = true;
    }
    return hashCode;
  }

  public Object clone() {
    try {
      return new Gridded1DDoubleSet(Type, Samples, Length,
        DomainCoordinateSystem, SetUnits, SetErrors);
    }
    catch (VisADException e) {
      throw new VisADError("Gridded1DDoubleSet.clone: " + e.toString());
    }
  }

  public Object cloneButType(MathType type) throws VisADException {
    return new Gridded1DDoubleSet(type, Samples, Length,
      DomainCoordinateSystem, SetUnits, SetErrors);
  }

}

  • 2001 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the visad archives: