public class ComplexSpectrum extends VectorType implements Spectral, AsciiComm
ComplexSpectrum implements the Triana model for storing spectral data. The model is general enough to contain a multi-dimensional Fourier transform derived from a complex data set containing an arbitrary number of points. It is complete enough to ensure that inverse Fourier transforms can be done correctly automatically, even if the data set is a narrow-band spectrum extracted from a full spectrum that obeys the Triana model. For two-sided spectra, the Triana storage model the same as that required by the Triana FFT unit and is one of the standard FFT storage models. For one-sided data it is not quite the same as the close packing that is used by most Fast Fourier Transform (FFT) methods, so the Triana FFT unit converts from the Triana storage model to its own internal format. The Triana model is described fully here. First we deal with two-sided complete spectra, then one-sided. At the end we describe the way narrow bands are handled. The various descriptions assume a one-dimensional data set (one independent variable), but they apply to each dimension of multi-dimensional sets.
All spectral representations assume that the frequency values are uniformly spaced and are represented by an integer index k. The value of resolution is the (positive) difference between the frequencies associated with consecutive values of k. The index k is non-negative.
A two-sided ComplexSpectrum contains spectral values at both negative and positive frequencies. Values at non-negative frequencies are stored in the first part of the data vector in order of increasing frequency, and values at negative frequencies are stored in the second part, again in order of increasing frequency. The details depend on whether the total length of the spectral data set, N, is even or odd.
Two-sided, full-bandwidth spectra of even
length N (nFull = N even, narrow = false, twoSided = true):
The
frequency corresponding to the index k contained in the interval [0, N/2-1] is k *
resolution; the frequency corresponding to index k in [N/2, N-1] is (k - N)
* resolution. Thus, the highest absolute value of the frequency is associated with k = N/2. This
frequency is -(N/2) * resolution, and it is called the Nyquist frequency. It should be equal to
-highestFrequency. This is a consistency check. For even N, the spectral amplitude at this largest
negative frequency is the same as that which could be associated with the largest positive frequency, +(N/2) *
resolution. If this spectrum was or could have been derived as a Fourier transform of a real data set, then
the data values associated with k = 0 and k = N/2 are real, and the data values at indices
k and N-k are complex-conjugates of one another. Such a spectrum can be converted to a one-sided
representation without the loss of information.
Two-sided, full-bandwidth spectra of odd length N
(nFull = N odd, narrow = false, twoSided = true):
The frequency
corresponding to the index k contained in the interval [0, (N-1)/2] is k * resolution;
the frequency corresponding to index k in [(N+1)/2, N-1] is (k - N) *
resolution. Thus, the highest positive frequency is associated with k = (N-1)/2; the lowest
negative frequency with k = (N+1)/2; both these frequencies have absolute value (N-1)/2 *
resolution; and this is called the Nyquist frequency. This should equal highestFrequency (this is a
consistency check). The spectral amplitudes at the lowest and highest-frequency points are generally different when
N is odd. If this spectrum was or could have been derived as a Fourier transform of a real data set, then the
data value associated with k = 0 is real, and the data values at indices k and N-k are
complex-conjugates of one another. Such a spectrum can be converted to a one-sided representation without the loss of
information.
A one-sided ComplexSpectrum includes only non-negative frequencies. The data model contains enough information to perform an inverse Fourier transform on the spectrum on the assumption that the resulting data set will contain only real values. Thus, values at the negative frequencies that are not represented in the data set will be assumed to be the complex conjugates of the values at the corresponding positive frequencies. Details depend on whether the total number of data points in the corresponding two-sided spectrum was even or odd. For transforms of real data, one-sided representations are preferable because they require only about half the memory of two-sided representations, and they nevertheless contain the same information.
One-sided, full-bandwidth spectra of
length N derived from a two-sided spectrum with an even number of elements (nFull even, narrow =
false, twoSided = false):
In a one-sided spectrum containing N data points, the
frequency corresponding to element k contained in [0, N-1] is k * resolution. The highest
such frequency is (N-1) * resolution, and this should be equal to highestFrequency. This is a
consistency check. Since the orginal time-series is assumed to be real, the element at k = 0 should be real.
For this case, where nFull is even, the original spectrum (or time-series) must have contained 2*N-2
points. This should be the value of nFull, and this is a further consistency check. The highest-frequency
element of the current data set (index N-1) contains the value of the original spectrum at its highest
frequency (index N-1 in that set), and this should be real as well. Thus a two-sided full-bandwidth spectrum
derived from real data of length nFull = 2*N-2 can be converted to a one-sided spectrum just by
extracting the first N elements. Since the first and last of these elements are real, this extracted set
contains 2*N-2 independent numbers. This storage model differs from those used by some FFT methods, typically
because in those methods the two real elements are combined into a single complex storage location, saving one
complex storage element. The storage saving is small and it would make manipulating spectra in Triana (such as adding
or graphing them) clumsy, so it is not implemented. FFT units in Triana must perform any requisite conversions to
their internal storage model themselves.
One-sided, full-bandwidth spectra of length N derived from a
two-sided spectrum with an odd number of elements (nFull odd, narrow = false, twoSided =
false):
In a one-sided spectrum containing N data points, the frequency corresponding to element
k contained in [0, N-1] is k * resolution. The highest such frequency is (N-1) *
resolution, and this should be equal to highestFrequency. This is a consistency check. Since the
orginal time-series is assumed to be real, the element at k = 0 should be real. For this case, where
nFull is odd, the original spectrum (or time-series) must have contained 2*N - 1 points. This should be
the value of nFull, and this is a further consistency check. The highest-frequency element of the current data
set (index N-1) contains the value of the original spectrum at its highest frequency (index N-1 in that
set), and this will in general be complex. Thus a two-sided full-bandwidth spectrum derived from real data of length
nFull = 2*N-1 can be converted to a one-sided spectrum just by extracting the first N elements.
Since the first of these elements is real, this extracted set contains 2*N-1 independent numbers. The remarks
in the previous paragraph about the data storage model for FFT methods apply here as well.
The Triana spectral data model allows for the bandwidth of the data to be narrower than that of the set from which it was derived, and the parameter highestFrequency is included in this class mainly to indicate the value of the upper edge of the frequency band. The lower edge can be deduced from the other data, such as the number of points and resolution. The Triana data storage model for narrow-band spectra places certain restrictions on the way such spectra can be constructed, so as to preserve as much as possible of the information needed to invert the spectrum back to a time-series. The information enables one to convert the data back to a full-bandwidth spectrum by padding with zeros.
Two-sided, narrow-band spectra of length N derived from a two-sided spectrum with an even
number of elements (nFull even, narrow = true, twoSided = true):
Two-sided
narrow-band data must always contain data points for related positive and negative frequencies. Removing the upper
part of the spectrum requires removing the single highest-frequency value and then pairs of values for the contiguous
frequencies (each pair being a frequency and its negative), i.e. removing in total an odd number of data points.
Removing the lower part of the spectrum similarly requires removing an odd number of data points. Since the original
data set had an even number of elements, we can determine the nature of the bandwidth of the narrow-band spectrum as
follows. If N (actual number of elements) is even, then the band has been shrunk from both sides; the lower
frequency limit is highestFrequency - (N/2 - 1) * resolution and should not be zero. The whole
original frequency range can be reconstructed from these numbers and nFull. If N is odd, then either
the highest original frequency or the lowest is still present in the band; if the highest is still present then
highestFrequency = nFull/2 * resolution; if the lowest is still present then the lower frequency
limit in this case, highestFrequency - ( (N-1)/2 ) * resolution, must be zero. A consistency
test is that one of these conditions must hold if N is odd.
Two-sided, narrow-band spectra of length
N derived from a two-sided spectrum with an odd number of elements (nFull odd, narrow =
true, twoSided = true):
Two-sided narrow-band data must always contain data points for
related positive and negative frequencies. Removing the lower part of the spectrum requires removing the single
zero-frequency value and then pairs of values for the contiguous frequencies (each pair being a frequency and its
negative), i.e. removing in total an odd number of data points. This will make N (the actual number of
elements) even. Removing the upper part of the spectrum or a portion in the middle requires removing an even number
of data points in frequency pairs. This will make N odd. Therefore, if N is even, the lower part of the
spectrum has been removed, and the upper part may or may not have been removed. In this case, if
highestFrequency = (nFull-1)/2 * resolution, then the upper part of the original band is still
present. If N is odd, then the lower part of the spectrum is still present and the upper has been removed.
One-sided narrow-band spectra of length N derived from a two-sided spectrum with an even number of
elements (nFull even, narrow = true, twoSided = false):
A one-sided spectrum
is assumed derived from a two-sided spectrum that came from a Fourier transform of a real data set. This is then made
narrow-band by removing frequencies at the lower and/or upper ends of the full band. If highestFrequency =
nFull/2 * resolution, then the top of the band is still present, and (for consistency) the
highest-frequency data value should be real. The lower frequency limit is highestFrequency - (N-1) *
resolution, and this should be larger than zero. If the top of the band is missing, then one can calculate the
lower frequency limit as above; if this is zero then the bottom of the band is still present, and the
lowest-frequency data value should be real (consistency again). If the lower frequency limit is positive, then the
bottom of the band is missing. These data are sufficient to reconstruct the two-sided narrow-band spectrum associated
with this data set on the assumption that the inverse transform produces a real data set.
One-sided
narrow-band spectra of length N derived from a two-sided spectrum with an odd number of elements (nFull
odd, narrow = true, twoSided = false):
A one-sided spectrum is assumed derived from a
two-sided spectrum that came from a Fourier transform of a real data set. This is then made narrow-band by removing
frequencies at the lower and/or upper ends of the full band. If highestFrequency = (nFull-1)/2 *
resolution, then the top of the band is still present, and (for consistency) the highest-frequency data value
should be real. The lower frequency limit is highestFrequency - (N-1) * resolution, and this
should be larger than zero. If the top of the band is missing, then one can calculate the lower frequency limit as
above; if this is zero then the bottom of the band is still present, and the lowest-frequency data value should be
real (consistency again). If the lower frequency limit is positive, then the bottom of the band is missing. These
data are sufficient to reconstruct the two-sided narrow-band spectrum associated with this data set on the assumption
that the inverse transform produces a real data set.
ComplexSpectrum contains a number of methods for accessing and modifying these parameters.
Modifier and Type | Field and Description |
---|---|
double |
frequencyResolution
(Parameter that is kept for consistency with previous versions, but which is obsolete.
|
double[] |
imag
(Parameter that is kept for consistency with previous versions, but which is obsolete.
|
double[] |
real
(Parameter that is kept for consistency with previous versions, but which is obsolete.
|
double |
samplingFrequency
(Parameter that is kept for consistency with previous versions, but which is obsolete.
|
x, xlabel, y, ylabel
NOT_CONNECTED, NOT_READY, OUT_OF_RANGE
Constructor and Description |
---|
ComplexSpectrum()
Create and empty ComplexSpectrum with no parameters set.
|
ComplexSpectrum(boolean ts,
boolean nrw,
double[] real,
double[] imag,
int nOrig,
double df,
double hf)
Creates a new ComplexSpectrum with arguments giving the sidedness, whether it is narrow-band or broad-band, the
data arrays, the number of points in the original broad-band spectrum, the frequency resolution, and the highest
frequency in the current spectrum.
|
ComplexSpectrum(boolean ts,
boolean nrw,
int len,
int nOrig,
double df,
double hf)
Creates a new ComplexSpectrum with arguments giving the sidedness, whether it is narrow-band or broad-band, the
data length, the number of points in the original broad-band spectrum, the frequency resolution, and the highest
frequency in the current spectrum.
|
ComplexSpectrum(boolean ts,
double[] real,
double[] imag,
int nOrig,
double df)
Creates a new ComplexSpectrum with given sidedness, data arrays, number of points in the two-sided spectrum, and
frequency resolution.
|
ComplexSpectrum(boolean ts,
int nOrig,
double df)
Creates a new ComplexSpectrum with a given sidedness, number of points that there would be in the two-sided
spectrum, and frequency resolution.
|
ComplexSpectrum(double samplingFrequency,
double[] real)
This is an obsolete Constructor that creates a new one-sided ComplexSpectrum with a certain sampling frequency
and the actual allocated real data.
|
ComplexSpectrum(double samplingFrequency,
double[] real,
double[] imag)
This is an obsolete Constructor that creates a new one-sided ComplexSpectrum with a certain sampling frequency
and the actual allocated complex data.
|
ComplexSpectrum(double sf,
int points)
This is an obsolete Constructor that will be eliminated when possible.
|
ComplexSpectrum(Spectrum s)
Creates a ComplexSpectrum from a (real) Spectrum by setting the imaginary part of the data to zero.
|
ComplexSpectrum(Spectrum s,
boolean copy)
Creates a ComplexSpectrum from a (real) Spectrum by setting the imaginary part of the data to zero.
|
Modifier and Type | Method and Description |
---|---|
TrianaType |
copyMe()
This is one of the most important methods of Triana data.
|
protected void |
copyParameters(TrianaType source)
Copies modifiable parameters from the argument object to the current object.
|
boolean |
equals(TrianaType obj)
Determines whether the argument TrianaType is equal to the current ComplexSpectrum.
|
void |
extendWithZeros(int newLength,
boolean front)
Extends the data set to a longer set by padding with zeros, keeping the frequency resolution unchanged.
|
double |
frequencyResolution()
Obsolete method for obtaining frequency resolution.
|
double[] |
getFrequencyArray(int dim)
Returns the frequency values of the independent data points for the given dimension, in the order of lowest
frequency to highest, regardless of how the data are stored internally.
|
double |
getFrequencyResolution()
Returns the frequency resolution of the data.
|
double |
getFrequencyResolution(int dim)
Returns the frequency resolution of the data for the given dimension (independent variable).
|
java.lang.Object |
getGraphArrayImag(int dv)
Returns the imaginary part of the dependent variable ordered so that the frequency values all run monotonically
upwards.
|
java.lang.Object |
getGraphArrayReal(int dv)
Returns the real part of the dependent variable ordered so that the frequency values all run monotonically
upwards.
|
double[] |
getIndependentScaleImag(int dim)
Returns null because the data is real.
|
double[] |
getIndependentScaleReal(int dim)
Returns the independent data scaled the way they should be graphed.
|
double |
getLowerFrequencyBound()
Returns the (non-negative) value of the lowest frequency in the frequency band held in the object.
|
double |
getLowerFrequencyBound(int dim)
Returns the (non-negative) value of the lowest frequency in the frequency band held in the object, for the given
dimension dim.
|
double |
getNyquist()
Returns the Nyquist frequency, defined to be the highest frequency that this data set could contain if it were
not narrow-banded.
|
java.lang.Object |
getOrderedSpectrumImag()
Returns the imaginary parts of the values of the spectrum (data points) in a multidimensional array, ordered so
that in each dimension the values correspond to frequencies running from the lowest to the highest, regardless of
the internal data model.
|
java.lang.Object |
getOrderedSpectrumReal()
Returns the real parts of the values of the spectrum (data points) in a multidimensional array, ordered so that
in each dimension the values correspond to frequencies running from the lowest to the highest, regardless of the
internal data model.
|
int |
getOriginalN()
Returns the number of points in the data set whose transform could have led to the present data, or equivalently
the number of points in the two-sided full-bandwidth spectrum from which the present spectrum could have been
derived.
|
int |
getOriginalN(int dim)
Returns the number of points in the data set in the given dimension whose transform could have led to the present
data, or equivalently the number of points in the two-sided full-bandwidth spectrum from which the present
spectrum could have been derived.
|
double |
getSamplingRate()
Returns the sampling frequency that a time-series would have had if it had led to the present spectral data set.
|
double |
getUpperFrequencyBound()
Returns the (non-negative) value of the highest frequency in the frequency band held in the object.
|
double |
getUpperFrequencyBound(int dim)
Returns the (non-negative) value of the highest frequency in the frequency band held in the object, for the given
dimension dim.
|
void |
inputFromStream(java.io.BufferedReader dis)
Used when Triana types want to be able to receive ASCII data from the output of other programs.
|
void |
interpolateZeros(int factor,
boolean before)
Inserts zeros in between existing elements of the data set.
|
boolean |
isCompatible(TrianaType obj)
Tests the argument object to determine if it makes sense to perform arithmetic operations between it and the
current object.
|
boolean |
isNarrow()
Returns true if the data represent a narrow bandwidth derived from a full-band spectrum.
|
boolean |
isNarrow(int dim)
Returns true if the data for the given dimension represent a narrow bandwidth derived from a full-band spectrum.
|
boolean |
isTwoSided()
Returns true if the data are stored as a two-sided transform, i.e.
|
void |
outputToStream(java.io.PrintWriter dos)
Used when Triana types want to be able to send ASCII data to other programs using strings.
|
int |
points()
Obsolete method for obtaining the number of data points.
|
static ComplexSpectrum |
reduceNyquist(ComplexSpectrum inputNarrow,
boolean allocMem) |
double |
samplingFrequency()
Obsolete method for obtaining sampling frequency.
|
void |
setDefaultAxisLabelling()
Added by I.
|
void |
setFrequencyResolution(double df)
Sets the frequency resolution of the data to the given value.
|
void |
setFrequencyResolution(double df,
int dim)
Sets the frequency resolution of the data for the given dimension to the given value.
|
void |
setNarrow(boolean n)
Sets the narrow-bandedness flag to the value of the argument.
|
void |
setNarrow(boolean n,
int dim)
Sets the narrow-bandedness flag associated with the given dimension to the value of the argument.
|
void |
setOriginalN(int nOrig)
Sets to the given argument the number of points in the data set whose transform could have led to the present
data, or equivalently the number of points in the two-sided full-bandwidth spectrum from which the present
spectrum could have been derived.
|
void |
setOriginalN(int nOrig,
int dim)
Sets to the given first argument nOrig the number of points in the data set in the dimension given by the
second argument dim whose transform could have led to the present data, or equivalently the number of
points in the two-sided full-bandwidth spectrum from which the present spectrum could have been derived.
|
void |
setTwoSided(boolean s)
Sets the two-sidedness flag to the value of the argument.
|
void |
setUpperFrequencyBound(double hf)
Sets the (non-negative) value of the highest frequency in the frequency band held in the object to the given
value.
|
void |
setUpperFrequencyBound(double hf,
int dim)
Sets or resets the (non-negative) value of the highest frequency in the frequency band held in the object for the
given direction dim to the value of the given argument hf.
|
protected void |
updateObsoletePointers() |
getData, getDataImag, getDataReal, getGraph, getGraphImag, getGraphReal, getScale, getScaleImag, getScaleReal, getXArray, getXImag, getXReal, getXTriplet, initialiseData, initialiseDataComplex, initialiseDataReal, isTriplet, isUniform, length, setData, setData, setDataImag, setDataReal, setX, setX, setX, setXImag, setXReal, size, testDataModel
add, addToTitle, convertDependentDataArraysToBytes, convertDependentDataArraysToDoubles, convertDependentDataArraysToFloats, convertDependentDataArraysToInts, convertDependentDataArraysToLongs, convertDependentDataArraysToShorts, copyData, copyLabels, divide, equals, getDataArrayClass, getDataArrayImag, getDataArrayImag, getDataArrayImagAsBytes, getDataArrayImagAsDoubles, getDataArrayImagAsFloats, getDataArrayImagAsInts, getDataArrayImagAsLongs, getDataArrayImagAsShorts, getDataArrayReal, getDataArrayReal, getDataArrayRealAsBytes, getDataArrayRealAsDoubles, getDataArrayRealAsFloats, getDataArrayRealAsInts, getDataArrayRealAsLongs, getDataArrayRealAsShorts, getDataArrayTypeNames, getDependentLabels, getDependentVariableDimensions, getDependentVariables, getDimensionLengths, getDimensionLengths, getGraphArrayImagLog10, getGraphArrayRealLog10, getIndependentArrayImag, getIndependentArrayReal, getIndependentLabels, getIndependentScaleImagLog10, getIndependentScaleRealLog10, getIndependentTriplet, getIndependentVariables, getLabels, getLabelsColumn, getTitle, isArithmeticArray, isArithmeticData, isCompatible, isDependentComplex, isIndependentComplex, isPrimitiveArray, isPrimitiveData, isTriplet, isUniform, maxDependentGraphingValuesImag, maxDependentGraphingValuesReal, maxDependentVariablesImag, maxDependentVariablesReal, maxIndependentScalesImag, maxIndependentScalesReal, maxIndependentVariablesImag, maxIndependentVariablesReal, minDependentGraphingValuesImag, minDependentGraphingValuesReal, minDependentVariablesImag, minDependentVariablesReal, minIndependentScalesImag, minIndependentScalesReal, minIndependentVariablesImag, minIndependentVariablesReal, multiply, resetDependent, resetIndependent, restrictToSubdomain, restrictToSubdomain, setDataArrayImag, setDataArrayReal, setDependentLabels, setDependentVariableDimensions, setDimensionLengths, setDimensionLengths, setDimensions, setIndependentArrayImag, setIndependentArrayReal, setIndependentLabels, setIndependentTriplet, setIndependentTriplet, setLabels, setTitle, subtract
containerSize, dataExists, deleteFromContainer, getDataContainer, getFromContainer, getSequenceNumber, insertIntoContainer, inspectDataContainer, setDataContainer, setSequenceNumber
public double samplingFrequency
The sampling frequency -- this will not be supported in later versions, since it is part of the Signal interface and not the Spectral interface
public double frequencyResolution
The frequency resolution -- this is obsolete because it is public, and has been replaced by the private parameter resolution.
public double[] imag
The imaginary part of the signal
public double[] real
The real part of the signal
public ComplexSpectrum()
public ComplexSpectrum(double sf, int points)
sf
- is the sampling frequencypoints
- is the number of pointsVectorType.initialiseData()
public ComplexSpectrum(double samplingFrequency, double[] real)
samplingFrequency
- is the sampling frequencyreal
- the actual allocated datapublic ComplexSpectrum(double samplingFrequency, double[] real, double[] imag)
samplingFrequency
- is the sampling frequencyreal
- The real part of the given dataimag
- The imaginary part of the given datapublic ComplexSpectrum(boolean ts, boolean nrw, int len, int nOrig, double df, double hf)
ts
- True if the new ComplexSpectrum is to be two-sidednrw
- True if the new ComplexSpectrum is to be narrow-bandlen
- Number of points in the current data setnOrig
- Number of points in the original two-sided full spectrumdf
- Frequency resolutionhf
- Highest frequency in the current data setpublic ComplexSpectrum(boolean ts, boolean nrw, double[] real, double[] imag, int nOrig, double df, double hf)
ts
- True if the new ComplexSpectrum is to be two-sidednrw
- True if the new ComplexSpectrum is to be narrow-bandreal
- Real part of the dataimag
- Imaginary part of the datanOrig
- Number of points in the original two-sided full spectrumdf
- Frequency resolutionhf
- Highest frequency in the current data setpublic ComplexSpectrum(boolean ts, int nOrig, double df)
ts
- True if the new ComplexSpectrum is to be two-sidednOrig
- Number of points in the equivalent two-sided spectrumdf
- Frequency resolutionpublic ComplexSpectrum(boolean ts, double[] real, double[] imag, int nOrig, double df)
ts
- True if the new ComplexSpectrum is to be two-sidedreal
- The real part of the input spectrumimag
- The imaginary part of the input spectrumnOrig
- Number of points in the equivalent two-sided spectrumdf
- Frequency resolutionpublic ComplexSpectrum(Spectrum s, boolean copy)
s
- The input data setcopy
- True if the new data are to be copied from the old, false if passed by referencepublic ComplexSpectrum(Spectrum s)
s
- The input data setpublic void setDefaultAxisLabelling()
setDefaultAxisLabelling
in class GraphType
public double getFrequencyResolution(int dim)
getFrequencyResolution
in interface Spectral
dim
- The index of the independent variable being queriedpublic double getFrequencyResolution()
public void setFrequencyResolution(double df, int dim)
setFrequencyResolution
in interface Spectral
dim
- The index of the independent variable being querieddf
- The frequency resolutionpublic void setFrequencyResolution(double df)
public boolean isTwoSided()
isTwoSided
in interface Spectral
public void setTwoSided(boolean s)
setTwoSided
in interface Spectral
s
- True if the data will be two-sidedpublic int getOriginalN(int dim)
getOriginalN
in interface Spectral
dim
- The index of the independent variable being queriedpublic int getOriginalN()
public void setOriginalN(int nOrig, int dim)
setOriginalN
in interface Spectral
dim
- The index of the independent variable being queriednOrig
- The new number of points in the original data setpublic void setOriginalN(int nOrig)
nOrig
- The new number of points in the original data setpublic boolean isNarrow(int dim)
public boolean isNarrow()
public void setNarrow(boolean n, int dim)
public void setNarrow(boolean n)
n
- True if the data held are narrow-bandpublic double getLowerFrequencyBound(int dim)
getLowerFrequencyBound
in interface Spectral
dim
- The index of the independent variable being queriedpublic double getLowerFrequencyBound()
public double getUpperFrequencyBound(int dim)
getUpperFrequencyBound
in interface Spectral
dim
- The index of the independent variable being queriedpublic double getUpperFrequencyBound()
public void setUpperFrequencyBound(double hf, int dim)
setUpperFrequencyBound
in interface Spectral
dim
- The index of the independent variable being queriedhf
- The new highest frequency represented in the given directionpublic void setUpperFrequencyBound(double hf)
hf
- The new highest frequencypublic double[] getFrequencyArray(int dim)
getFrequencyArray
in interface Spectral
dim
- The dimension of the independent variablepublic java.lang.Object getOrderedSpectrumReal()
getOrderedSpectrumReal
in interface Spectral
public java.lang.Object getOrderedSpectrumImag()
getOrderedSpectrumImag
in interface Spectral
public double getNyquist()
The general formula is that if the original number of data points (given by nFull = getOriginalN()) is even, then the Nyquist frequency is nFull * resolution / 2. If the original number of data points is odd, then the Nyquist frequency is (nFull -1 ) * resolution / 2.
public double getSamplingRate()
public double samplingFrequency()
public int points()
public double frequencyResolution()
public double[] getIndependentScaleReal(int dim)
getIndependentScaleReal
in class GraphType
dim
- The independent dimension under considerationpublic double[] getIndependentScaleImag(int dim)
getIndependentScaleImag
in class GraphType
dim
- The independent dimension under considerationpublic java.lang.Object getGraphArrayReal(int dv)
getGraphArrayReal
in class GraphType
dv
- The dependent variable dimensionpublic java.lang.Object getGraphArrayImag(int dv)
getGraphArrayImag
in class GraphType
dv
- The dependent variable dimensionpublic void extendWithZeros(int newLength, boolean front)
If front is true, then nothing is done and a warning message is printed to the debug stream, because it is not possible in the Triana spectral model to extend a spectrum "below" zero-frequency. Negative frequencies are already included in the spectrum either explictly or implicitly, so there is no room for more points at the "front" of the data set. Even if the data set is narrow-band and does not include zero frequency, the data down to zero frequency are already set to zero implicitly, so that there is no way to add more of them.
If the boolean argument front is false, then the method extends the spectrum to higher frequencies, but the extra zeros are added "virtually", i.e. by extending the length nFull of the original data set and not adding the zeros explicitly. If the original data set was broad-band, it is marked as narrow-band after extension.
The details of how this works are best understood by thinking of the original (un-extended) data set as having been obtained from the final (extended one) by low-pass filtering. It is a consequence of the Triana spectral data model that applying a low-pass filter to a full-bandwidth data set of any length nFull results in a data set whose new value of nFull is odd. If the data set before extension has an odd number of elements, then the extension requires only the actions described above.
On the other hand, if the data set before extension has an even value of nFull, then it must be converted to one with an odd number before it can be extended. This is done in this method by identifying all the elements of the old set with those of the new one with the same frequency except for the highest frequency. In the new (odd-length) set there are two elements for the highest frequency, one at positive frequency and one at negative. In the old (even-length) set there is only one, at the negative frequency. The elements of the new one are determined as follows: the negative-frequency element is set equal to the old negative-frequency element divided by sqrt(2), and the positive-frequency element is set equal to the complex-conjugate of this. This choice is rather arbitrary, but it ensures that, if this data set represents a Fourier transform, then the total power is unchanged. Of course, if the original data is narrow-band and has already lost its highest frequencies, then the new element is just set to zero, and this is done "virtually", by adjusting various parameters. If the data set is one-sided, then only the positive-frequency element is added. When an element is added, then the independent variable Triplet is extended by one as well.
extendWithZeros
in class VectorType
newLength
- The new length of the data setfront
- True if padding is at the front, false for padding at the backpublic void interpolateZeros(int factor, boolean before)
If the argument factor is zero or negative, nothing is done.
In ComplexSpectrum, the interpolation is done in such a way that the frequency resolution is increased and the pre-existing data points remain at the same value of the frequency. This means that it is illegal to add zeroes before the first element, which corresponds to zero frequency. So if before is true then the method returns without doing anything, and prints a warning.
If the value of before is false, then the interpolation is done in such a way that the frequency resolution is divided by (factor + 1) and the original number of points is changed by (factor + 1). This ensures that the original data points remain at the same values of the frequency. The requisite number of zeros is added after each data point. If the spectrum is two-sided, then the way interpolation as done in VectorType is correct here too, and only the parameters are changed, as just described. If the spectrum is one-sided, then ordinary interpolation adds too many at the end, and this method removes the extra ones.
Derived types should override this if necessary to provide for the correct handling of parameters and other special features.
interpolateZeros
in class VectorType
factor
- The number of zeros per data point to be insertedbefore
- True if the zeros go before each point, false if afterpublic TrianaType copyMe()
To override, the programmer should not invoke the super.copyMe method. Instead, create an object of the current type and call methods copyData and copyParameters. If these have been written correctly, then they will do the copying. The code should createTool, for type YourType:
YourType y = null; try { y = (YourType)getClass().newInstance(); y.copyData( this ); y.copyParameters( this ); y.setLegend( this.getLegend() ); } catch (IllegalAccessException ee) { System.out.println("Illegal Access: " + ee.getMessage()); } catch (InstantiationException ee) { System.out.println("Couldn't be instantiated: " + ee.getMessage()); } return y;
The copied object's data should be identical to the original. The method here modifies only one item: a String indicating that the object was created as a copy is added to the description StringVector.
copyMe
in class VectorType
protected void copyParameters(TrianaType source)
In ComplexSpectrum, the new parameters are resolution, highestFrequency, twoSided, narrow, nFull. The obsolete parameters samplingFrequency and frequencyResolution are generated automatically when the other parameters are copied and set.
This must be overridden by any subclass that defines new parameters. The overriding method should invoke its super method. It should use the set... and get... methods for the parameters in question. This method is protected so that it cannot be called except by objects that inherit from this one. It is called by copyMe().
copyParameters
in class GraphType
source
- Data object that contains the data to be copied.public void outputToStream(java.io.PrintWriter dos) throws java.io.IOException
This method must be overridden in every subclass that defines new data or parameters. The overriding method should first call<
super.outputToStream(dos)to get output from superior classes, and then new parameters defined for the current subclass must be output. Moreover, subclasses that first dimension their data arrays must explicitly transfer these data arrays.
outputToStream
in interface AsciiComm
outputToStream
in class GraphType
dos
- The data output streamjava.io.IOException
public void inputFromStream(java.io.BufferedReader dis) throws java.io.IOException
This method must be overridden in every subclass that defines new data or parameters. The overriding method should first call
super.inputFromStream(dis)to get input from superior classes, and then new parameters defined for the current subclass must be input. Moreover, subclasses that first dimension their data arrays must explicitly transfer these data arrays.
inputFromStream
in interface AsciiComm
inputFromStream
in class GraphType
dis
- The data input streamjava.io.IOException
public boolean isCompatible(TrianaType obj)
In ComplexSpectrum, the method first tests that the input object is compatible with superior classes, and then (if it is a ComplexSpectrum( it tests if the input has the same frequency resolution, upper frequency bound, two-sidedness, and narrow-bandedness.
Classes derived from this should over-ride this method with further tests as appropriate. The over-riding method should normally have the first lines
boolean test = super.isCompatible( obj );followed by other tests. If other types not subclassed from GraphType or Const should be allowed to be compatible then other tests must be implemented.
isCompatible
in class VectorType
obj
- The data object to be compared with the current onepublic boolean equals(TrianaType obj)
This method must be over-ridden in derived types. In a derived type called xxx the method should begin
if ( !( obj instanceof xxx ) ) return false; if ( !isCompatible( obj ) ) return false;followed by tests that are specific to type xxx (testing its own parameters) and then as a last line
return super.equals( obj );This line invokes the other equals methods up the chain to GraphType. Each superior object tests its own parameters.
obj
- The object being testedprotected void updateObsoletePointers()
updateObsoletePointers
in class VectorType
public static ComplexSpectrum reduceNyquist(ComplexSpectrum inputNarrow, boolean allocMem)