public class Sampling
extends java.lang.Object
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.
Modifier and Type | Field and Description |
---|---|
static double |
DEFAULT_TOLERANCE
A default fraction used to test for equivalent sample values.
|
Constructor and Description |
---|
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.
|
Modifier and Type | Method and Description |
---|---|
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 |
getValueExtended(int i)
Gets the value for the specified index, assuming uniform sampling.
|
double[] |
getValues()
Gets the sample values.
|
int |
indexOf(double x)
Returns the index of the sample with specified value.
|
int |
indexOfFloorExtended(double x)
Returns the index of the floor of the specified value.
|
int |
indexOfNearest(double x)
Returns the index of the sample nearest to the specified value.
|
int |
indexOfNearestExtended(double x)
Returns the index of the sample nearest the specified value, assuming
uniform sampling.
|
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 |
isInBounds(double x)
Determines whether the specified value is in the bounds of this sampling.
|
boolean |
isInBounds(int i)
Determines whether the specified index is in the bounds of this sampling.
|
boolean |
isInBoundsExtended(double x)
Determines whether the specified value is in the bounds of this sampling,
which is assumed to be uniform.
|
boolean |
isUniform()
Determines whether this sampling is uniform.
|
Sampling |
mergeWith(Sampling s)
Returns the union of this sampling with the specified sampling.
|
double |
normalizedDifferenceExtended(double x,
int i)
Returns the normalized difference between a specified value and
the sampled value for a specified index.
|
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.
|
double |
valueOfNearestExtended(double x)
Returns the value of the sample nearest to the specified value,
assuming uniform sampling.
|
public static final double DEFAULT_TOLERANCE
public Sampling(int n)
n
- the number (count) of samples; must be positive.public Sampling(int n, double d, double f)
n
- the number (count) of samples; must be positive.d
- the sampling interval (delta); must be positive.f
- the first sample value.public Sampling(int n, double d, double f, double t)
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.public Sampling(double[] v)
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.
v
- the array of sampling values; must have non-zero length.public Sampling(double[] v, double t)
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.
v
- the array of sampling values; must have non-zero length.t
- the sampling tolerance, expressed as fraction of delta.public int getCount()
public double getDelta()
public double getFirst()
public double getLast()
public double getValue(int i)
i
- the index.public double[] getValues()
public boolean isUniform()
Note that, by this definition, samplings constructed with an array of sample values may or may not be uniform.
public boolean isEquivalentTo(Sampling s)
s
- the sampling to compare to this sampling.public boolean isCompatible(Sampling s)
s
- the sampling to compare to this sampling.public int indexOf(double x)
x
- the value.public int indexOfNearest(double x)
x
- the value.public double valueOfNearest(double x)
x
- the value.public boolean isInBounds(int i)
i
- the index.public boolean isInBounds(double x)
x
- the value.public boolean isInBoundsExtended(double x)
x
- the value.public double getValueExtended(int i)
i
- the index.public int indexOfNearestExtended(double x)
x
- the value.public double valueOfNearestExtended(double x)
x
- the value.public int indexOfFloorExtended(double x)
x
- the value.public double normalizedDifferenceExtended(double x, int i)
x
- the value.i
- the index.public int[] overlapWith(Sampling s)
s
- the sampling to compare with this sampling.public Sampling mergeWith(Sampling s)
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.
s
- the sampling to merge with this sampling.overlapWith(Sampling)
public Sampling shift(double s)
This method returns a new sampling; it does not modify this sampling.
s
- the value (shift) to add to this sampling's values.public Sampling prepend(int m)
This method returns a new sampling; it does not modify this sampling.
m
- the number of new samples prepended to this sampling.public Sampling append(int m)
This method returns a new sampling; it does not modify this sampling.
m
- the number of new samples appended to this sampling.public Sampling decimate(int m)
This method returns a new sampling; it does not modify this sampling.
m
- the factor by which to decimate; must be positive.public Sampling interpolate(int m)
This method returns a new sampling; it does not modify this sampling.
m
- the factor by which to interpolate.