//
// Gridded1DSet.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 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.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

/**
   Gridded1DSet represents a finite set of samples of R.

*/ public class Gridded1DSet extends GriddedSet implements Gridded1DSetIface { int LengthX; float LowX, HiX; /** Whether this set is ascending or descending */ boolean Ascending; /** * 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 truly 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(); /** * Constructs a 1-D sorted sequence with no regular interval. The * coordinate system and units are the default from the set type. The error * estimate is null. * * @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. * samples[0][i] is the value of * the ith sample point. Must be sorted (either * increasing or decreasing). May be * null. * @param lengthX The number of samples. */ public Gridded1DSet(MathType type, float[][] samples, int lengthX) throws VisADException { this(type, samples, lengthX, null, null, null); } /** * Constructs a 1-D sorted sequence with no regular interval. * * @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. * samples[0][i] is the value of * the ith sample point. Must be sorted (either * increasing or decreasing). May be * null. * @param lengthX The number of samples. * @param coord_sys The coordinate system for this, particular, set. * Must be compatible with the default coordinate * system. May be null. * @param units The units for the tuple components. Only * units[0] is meaningfull. Must * be compatible with the default unit. May be * null. * @param errors The error estimates of the tuple components. * Only errors[0] is meaningful. May * be null. */ public Gridded1DSet(MathType type, float[][] samples, int lengthX, CoordinateSystem coord_sys, Unit[] units, ErrorEstimate[] errors) throws VisADException { this(type, samples, lengthX, coord_sys, units, errors, true); } /** * Constructs a 1-D sorted sequence with no regular interval. * * @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. * samples[0][i] is the value of * the ith sample point. Must be sorted (either * increasing or decreasing). May be * null. * @param lengthX The number of samples. * @param coord_sys The coordinate system for this, particular, set. * Must be compatible with the default coordinate * system. May be null. * @param units The units for the tuple components. Only * units[0] is meaningfull. Must * be compatible with the default unit. May be * null. * @param errors The error estimates of the tuple components. * Only errors[0] is meaningful. May * be null. * @param copy Whether or not to copy the values array. */ public Gridded1DSet(MathType type, float[][] samples, int lengthX, CoordinateSystem coord_sys, Unit[] units, ErrorEstimate[] errors, boolean copy) throws VisADException { super(type, samples, make_lengths(lengthX), coord_sys, units, errors, copy); LowX = Low[0]; HiX = Hi[0]; LengthX = Lengths[0]; float[][]mySamples = getMySamples(); if (mySamples != null && Lengths[0] > 1) { // samples consistency test for (int i=0; i mySamples[0][0]); if (Ascending) { for (int i=1; i mySamples[0][i-1]) { throw new SetException( "Gridded1DSet: 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. * samples[i] is the value of * the ith sample point. Must be sorted (either * increasing or decreasing). May be * null. The array is not copied, so * either don't modify it or clone it first. * @param coordSys The coordinate system for this, particular, set. * Must be compatible with the default coordinate * system. May be null. * @param unit The unit for the samples. Must be compatible * with the default unit. May be * null. * @param error The error estimate of the samples. May be * null. */ public static synchronized Gridded1DSet create( MathType type, float[] samples, CoordinateSystem coordSys, Unit unit, ErrorEstimate error) throws VisADException { Gridded1DSet newSet = new Gridded1DSet( type, new float[][] {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. */ Gridded1DSet oldSet = (Gridded1DSet)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; } static int[] make_lengths(int lengthX) { int[] lens = new int[1]; lens[0] = lengthX; return lens; } /** convert an array of 1-D indices to an array of values in R^DomainDimension */ public float[][] indexToValue(int[] index) throws VisADException { int length = index.length; float[][]mySamples = getMySamples(); if (mySamples == null) { // not used - over-ridden by Linear1DSet.indexToValue float[][] grid = new float[ManifoldDimension][length]; for (int i=0; ivalue[i][j] * contains the ith component of the * jth point. * @return Indices of nearest points. RETURN_VALUE[i] * will contain the index of the point in the set closest * to value[][i] or -1 if * value[][i] lies outside the set. */ public int[] valueToIndex(float[][] value) throws VisADException { if (value.length != DomainDimension) { throw new SetException("Gridded1DSet.valueToIndex: value dimension " + value.length + " not equal to Domain dimension " + DomainDimension); } int length = value[0].length; int[] index = new int[length]; float[][] grid = valueToGrid(value); float[] grid0 = grid[0]; float g; for (int i=0; i 1"); } */ int length = grid[0].length; float[][] value = new float[1][length]; float[][]mySamples = getMySamples(); for (int i=0; i LengthX-0.5) ) { value[0][i] = Float.NaN; } else if (Length == 1) { // just return the value if that's all we have value[0][i] = mySamples[0][0]; } else { // calculate closest integer variable int ig; if (g < 0) ig = 0; else if (g >= LengthX-1) ig = LengthX - 2; else ig = (int) g; float A = g - ig; // distance variable // do the linear interpolation value[0][i] = (1-A)*mySamples[0][ig] + A*mySamples[0][ig+1]; } } return value; } // WLH 6 Dec 2001 //private int ig = -1; /** transform an array of values in R^DomainDimension to an array of non-integer grid coordinates */ public float[][] valueToGrid(float[][] value) throws VisADException { if (value.length < DomainDimension) { throw new SetException("Gridded1DSet.valueToGrid: value dimension " + value.length + " not equal to Domain dimension " + DomainDimension); } /* remove DRM 2004-09-14 if (Lengths[0] < 2) { throw new SetException("Gridded1DSet.valueToGrid: requires all grid " + "dimensions to be > 1"); } */ float[] vals = value[0]; int length = vals.length; float[][]mySamples = getMySamples(); float[] samps = mySamples[0]; float[][] grid = new float[1][length]; int ig = (LengthX - 1)/2; /* WLH 6 Dec 2001 // use value from last call as first guess, if reasonable if (ig < 0 || ig >= LengthX) { ig = (LengthX - 1)/2; } */ for (int i=0; i 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 float 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] = Float.NaN; // next guess should be in the middle if previous value was missing ig = (LengthX - 1)/2; } } } return grid; } public int getLengthX() { return LengthX; } public float getLowX() { return LowX; } public float getHiX() { return HiX; } public boolean isAscending() { return Ascending; } public Object cloneButType(MathType type) throws VisADException { return new Gridded1DSet(type, getMySamples(), Length, DomainCoordinateSystem, SetUnits, SetErrors); } /* run 'java visad.Gridded1DSet < formatted_input_stream' to test the Gridded1DSet class */ public static void main(String[] args) throws VisADException { // Define input stream InputStreamReader inStr = new InputStreamReader(System.in); // Define temporary integer array int[] ints = new int[80]; try { ints[0] = inStr.read(); } catch(Exception e) { System.out.println("Gridded1DSet: "+e); } int l = 0; while (ints[l] != 10) { try { ints[++l] = inStr.read(); } catch (Exception e) { System.out.println("Gridded1DSet: "+e); } } // convert array of integers to array of characters char[] chars = new char[l]; for (int i=0; i " +((float) Math.round(1000000 *myValue[0][i]) /1000000)); } // Test valueToGrid function System.out.println("\nvalueToGrid test:"); float[][] gridTwo = gSet1D.valueToGrid(myValue); for (int i=0; i (" +((float) Math.round(1000000 *gridTwo[0][i]) /1000000)+")"); } System.out.println(); } /* Here's the output with sample file Gridded1D.txt: iris 25% java visad.Gridded1DSet < Gridded1D.txt num_dimensions = 1, num_coords = 20 Lengths = 20 wedge = 0 1 . . . 18 19 Samples (20): #0: -40.54849 #1: -39.462048 . . . #18: 26.026154 #19: 38.3012 gridToValue test: (-0.4) --> -40.983063 (0.5) --> -40.00527 . . . (18.5) --> 32.163677 (19.4) --> 43.211212 valueToGrid test: -40.983063 --> (-0.399998) -40.00527 --> (0.5) . . . 32.163677 --> (18.5) 43.211212 --> (19.4) iris 26% */ }

Ads help maintain this website.