edu.mines.jtk.dsp
Class Sampling

java.lang.Object
  extended by edu.mines.jtk.dsp.Sampling

public class Sampling
extends java.lang.Object

Sampling of one variable.

Samplings are often used to represent independent variables for sampled functions. They describe the values at which a function is sampled. For efficiency, and to guarantee a unique mapping from sample value to function value, we restrict samplings to be strictly increasing. In other words, no two samples have equal value, and sample values increase with increasing sample index.

Samplings are either uniform or non-uniform. Uniform samplings are represented by a sample count n, a sampling interval d, and a first sample value f. Non-uniform samplings are represented by an array of sample values.

All sample values are computed and stored in double precision. This double precision can be especially important in uniform samplings, where the sampling interval d and first sample value f may be used to compute values for thousands of samples, in loops like this one:


   int n = sampling.getCount();
   double d = sampling.getDelta();
   double f = sampling.getFirst();
   double v = f;
   for (int i=0; i<n; ++i,v+=d) {
     // some calculation that uses the sample value v
   }
 
In each iteration of the loop above, the sample value v is computed by accumulating the sampling interval d. This computation is fast, but it also yields rounding error that can grow quadratically with the number of samples n. If v were computed in single (float) precision, then this rounding error could exceed the sampling interval d for as few as n=10,000 samples.

If accumulating in double precision is insufficient, a more accurate and more costly way to compute sample values is as follows:


   // ...
   double v = f;
   for (int i=0; i<n; ++i,v=f+i*d) {
     // some calculation that uses the sample value v
   }
 
With this computation of sample values, rounding errors can grow only linearly with the number of samples n.

Two samplings are considered equivalent if their sample values differ by no more than the sampling tolerance. This tolerance may be specified, as a fraction of the sampling interval, when a sampling is constructed. Alternatively, a default tolerance may be used. When comparing two samplings, the smaller of their tolerances is used.

A sampling is immutable. New samplings can be constructed by applying various transformations (e.g., shifting) to an existing sampling, but an existing sampling cannot be changed. Therefore, multiple sampled functions can safely share the same sampling.

Version:
2005.03.11
Author:
Dave Hale, Colorado School of Mines

Field Summary
static double DEFAULT_TOLERANCE
          A default fraction used to test for equivalent sample values.
 
Constructor Summary
Sampling(double[] v)
          Constructs a sampling from the specified array of values.
Sampling(double[] v, double t)
          Constructs a sampling from the specified array of values and tolerance.
Sampling(int n)
          Constructs a uniform sampling with specified count.
Sampling(int n, double d, double f)
          Constructs a uniform sampling with specified parameters.
Sampling(int n, double d, double f, double t)
          Constructs a sampling with specified parameters.
 
Method Summary
 Sampling append(int m)
          Appends samples to this sampling.
 Sampling decimate(int m)
          Decimates this sampling.
 int getCount()
          Gets the number of samples.
 double getDelta()
          Gets the sampling interval.
 double getFirst()
          Gets the first sample value.
 double getLast()
          Gets the last sample value.
 double getValue(int i)
          Gets the sample value with specified index.
 double[] getValues()
          Gets the sample values.
 int indexOf(double x)
          Returns the index of the sample with specified value.
 int indexOfNearest(double x)
          Returns the index of the sample nearest to the specified value.
 Sampling interpolate(int m)
          Interpolates this sampling.
 boolean isCompatible(Sampling s)
          Determines whether this sampling is compatible with the specified sampling.
 boolean isEquivalentTo(Sampling s)
          Determines whether this sampling is equivalent to the specified sampling.
 boolean isUniform()
          Determines whether this sampling is uniform.
 Sampling mergeWith(Sampling s)
          Returns the union of this sampling with the specified sampling.
 int[] overlapWith(Sampling s)
          Determines the overlap between this sampling and the specified sampling.
 Sampling prepend(int m)
          Prepends samples to this sampling.
 Sampling shift(double s)
          Shifts this sampling.
 double valueOfNearest(double x)
          Returns the value of the sample nearest to the specified value.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_TOLERANCE

public static final double DEFAULT_TOLERANCE
A default fraction used to test for equivalent sample values. By default, if the difference between two sample values does not exceed this fraction of the sampling interval, then those values are considered equivalent. This default is used when a tolerance is not specified explicitly when a sampling is constructed.

See Also:
Constant Field Values
Constructor Detail

Sampling

public Sampling(int n)
Constructs a uniform sampling with specified count. The sampling interval (delta) is 1.0, and the first sample value is 0.0.

Parameters:
n - the number (count) of samples; must be positive.

Sampling

public Sampling(int n,
                double d,
                double f)
Constructs a uniform sampling with specified parameters.

Parameters:
n - the number (count) of samples; must be positive.
d - the sampling interval (delta); must be positive.
f - the first sample value.

Sampling

public Sampling(int n,
                double d,
                double f,
                double t)
Constructs a sampling with specified parameters.

Parameters:
n - the number (count) of samples; must be positive.
d - the sampling interval (delta); must be positive.
f - the first sample value.
t - the sampling tolerance, expressed as fraction of delta.

Sampling

public Sampling(double[] v)
Constructs a sampling from the specified array of values. The values must be strictly increasing.

The constructed sampling may or may not be uniform, depending on the specified values and default sampling tolerance. If uniform (to within the default tolerance), then the array of values is discarded, and the sampling is represented by the count, sampling interval, and first sample value.

Parameters:
v - the array of sampling values; must have non-zero length.

Sampling

public Sampling(double[] v,
                double t)
Constructs a sampling from the specified array of values and tolerance. The values must be strictly increasing.

The constructed sampling may or may not be uniform, depending on the specified values and tolerance. If uniform (to within the specified tolerance), then the array of values is discarded, and the sampling is represented by the count, sampling interval, and first sample value.

Parameters:
v - the array of sampling values; must have non-zero length.
t - the sampling tolerance, expressed as fraction of delta.
Method Detail

getCount

public int getCount()
Gets the number of samples.

Returns:
the number of samples.

getDelta

public double getDelta()
Gets the sampling interval. If not uniformly sampled, the sampling interval is the average difference between sample values.

Returns:
the sampling interval; 1.0, if fewer than two samples.

getFirst

public double getFirst()
Gets the first sample value.

Returns:
the first sample value.

getLast

public double getLast()
Gets the last sample value.

Returns:
the last sample value.

getValue

public double getValue(int i)
Gets the sample value with specified index.

Parameters:
i - the index.
Returns:
the sample value.

getValues

public double[] getValues()
Gets the sample values. If this sampling was constructed with an array of sample values, then the returned values are equivalent (equal to within the sampling tolerance) to the values in that array.

Returns:
the sample values; returned by copy, not by reference.

isUniform

public boolean isUniform()
Determines whether this sampling is uniform. A sampling is uniform if its values can be computed, to within the sampling tolerance, by the expression v = f+i*d, for sampling indices i = 0, 1, ..., n-1. Samplings with only one sample are considered to be uniform.

Note that, by this definition, samplings constructed with an array of sample values may or may not be uniform.

Returns:
true, if uniform; false, otherwise.

isEquivalentTo

public boolean isEquivalentTo(Sampling s)
Determines whether this sampling is equivalent to the specified sampling. Two samplings are equivalent if each of their sample values differs by no more than the sampling tolerance.

Parameters:
s - the sampling to compare to this sampling.
Returns:
true, if equivalent; false, otherwise.

isCompatible

public boolean isCompatible(Sampling s)
Determines whether this sampling is compatible with the specified sampling. Two samplings are incompatible if their ranges of sample values overlap, but not all values in the overlapping parts are equivalent. Otherwise, they are compatible.

Parameters:
s - the sampling to compare to this sampling.
Returns:
true, if compatible; false, otherwise.

indexOf

public int indexOf(double x)
Returns the index of the sample with specified value. If this sampling has a sample value that equals (to within the sampling tolerance) the specified value, then this method returns the index of that sample. Otherwise, this method returns -1.

Parameters:
x - the value.
Returns:
the index of the matching sample; -1, if none.

indexOfNearest

public int indexOfNearest(double x)
Returns the index of the sample nearest to the specified value.

Parameters:
x - the value.
Returns:
the index of the nearest sample.

valueOfNearest

public double valueOfNearest(double x)
Returns the value of the sample nearest to the specified value.

Parameters:
x - the value.
Returns:
the value of the nearest sample.

overlapWith

public int[] overlapWith(Sampling s)
Determines the overlap between this sampling and the specified sampling. Both the specified sampling and this sampling represent a first-to-last range of sample values. The overlap is a contiguous set of samples that have values that are equal, to within the minimum sampling tolerance of the two samplings. This set is represented by an array of three ints, {n,it,is}, where n is the number of overlapping samples, and it and is denote the indices of the first samples in the overlapping parts of this sampling (t) and the specified sampling (s). There exist three cases.

Parameters:
s - the sampling to compare with this sampling.
Returns:
the array {n,it,is} that describes the overlap; null, if the specified sampling is incompatible with this sampling.

mergeWith

public Sampling mergeWith(Sampling s)
Returns the union of this sampling with the specified sampling. This union is possible if and only if the two samplings are compatible.

If the two samplings do not overlap, this method does not create samples within any gap that may exist between them. In other words, the number of samples in the sampling returned is exactly nt+ns-n, where nt is the number of samples in this sampling, ns is the number of samples in the specified sampling, and n is the number of samples with equivalent values in any overlapping parts of the two samplings. If the samplings do not overlap, then n = 0. One consequence of this behavior is that the union of two uniform samplings with the same sampling interval may be non-uniform.

This method returns a new sampling; it does not modify this sampling.

Parameters:
s - the sampling to merge with this sampling.
Returns:
the merged sampling; null, if no merge is possible.
See Also:
overlapWith(Sampling)

shift

public Sampling shift(double s)
Shifts this sampling.

This method returns a new sampling; it does not modify this sampling.

Parameters:
s - the value (shift) to add to this sampling's values.
Returns:
the new sampling.

prepend

public Sampling prepend(int m)
Prepends samples to this sampling. If this sampling is not uniform, prepended sample values are computed to preserve the average difference between adjacent sample values.

This method returns a new sampling; it does not modify this sampling.

Parameters:
m - the number of new samples prepended to this sampling.
Returns:
the new sampling.

append

public Sampling append(int m)
Appends samples to this sampling. If this sampling is not uniform, appended sample values are computed to preserve the average difference between adjacent sample values.

This method returns a new sampling; it does not modify this sampling.

Parameters:
m - the number of new samples appended to this sampling.
Returns:
the new sampling.

decimate

public Sampling decimate(int m)
Decimates this sampling. Beginning with the first sample, keeps only every m'th sample, while discarding the others in this sampling. If this sampling has n values, the new sampling will have 1+(n-1)/m values.

This method returns a new sampling; it does not modify this sampling.

Parameters:
m - the factor by which to decimate; must be positive.
Returns:
the new sampling.

interpolate

public Sampling interpolate(int m)
Interpolates this sampling. Inserts m-1 evenly spaced samples between each of the samples in this sampling. If this sampling has n values, the new sampling will have 1+(n-1)*m values.

This method returns a new sampling; it does not modify this sampling.

Parameters:
m - the factor by which to interpolate.
Returns:
the new sampling.