Class AbstractSpectralTransform
- All Implemented Interfaces:
SpectralTransform
- Direct Known Subclasses:
FastFourierTransform
,SeparableFastHartleyTransform
A skeletal implementation of the SpectralTransform
interface to minimize
the effort required to implement this interface.
The main purpose of this class is implementing n-dimensional
directTransformMatrix
/ inverseTransformMatrix
methods via more simple (and more abstract) one-dimensional
directTransform
/ inverseTransform
methods.
The algorithm of this implementation is the following:
- At the first iteration, all 1-dimensional "lines" of the matrix, i.e. every sequential
dim(0)
numbers, are represented asSampleArray
byRealScalarSampleArray.asSampleArray
orComplexScalarSampleArray.asSampleArray
method. All these sample arrays are transformed bydirectTransform
call (in a case of the direct transform) or byinverseTransform
call (in a case of the inverse transform). - At the second iteration, all 2-dimensional "layers" of the (multidimensional) matrix, i.e. every sequential
dim(0)
*dim(1)
numbers, are represented asSampleArray
byRealVectorSampleArray.asSampleArray
orComplexVectorSampleArray.asSampleArray
method, where the vector length and step are chosen equal todim(0)
. All these sample arrays are transformed bydirectTransform
call (in a case of the direct transform) or byinverseTransform
call (in a case of the inverse transform). - ...
- At the last iteration, the whole n-dimensional matrix is represented as a
SampleArray
byRealVectorSampleArray.asSampleArray
orComplexVectorSampleArray.asSampleArray
method, where the vector length and step are chosen equal todim(0)
*dim(1)
*...*dim(N-1)
. This sample array is transformed bydirectTransform
call (in a case of the direct transform) or byinverseTransform
call (in a case of the inverse transform).
In other words, the transform is sequentially applied along the dimension 0,1,...,N−1.
The "real" case is chosen above if the second matrixIm argument of
directTransformMatrix
/ inverseTransformMatrix
methods is null; in this case, the
RealScalarSampleArray.asSampleArray
or
RealVectorSampleArray.asSampleArray
method is applied
to the corresponding subarrays
of the underlying array
of the matrixRe argument.
The "complex" case is chosen if the second matrixIm argument is not null; in this case, the
ComplexScalarSampleArray.asSampleArray
or
ComplexVectorSampleArray.asSampleArray
method is applied
to the pairs of corresponding subarrays
of the
underlying arrays
of both matrixRe and matrixIm arguments.
This algorithm is a traditional way of generalizing 1-dimensional FFT (Fourier transform) to 2-dimensional and multidimensional case. For FHT (Hartley transform), this generalization leads to so-called separable multidimensional Hartley transform.
The described algorithm is only a basic scheme of the implementation of
directTransformMatrix
and inverseTransformMatrix
methods by this class. Really, this implementation performs much more: for example, downloads parts of large
matrices into Java memory (SimpleMemoryModel
) for better performance; splits the execution into
several parallel tasks on multi-core or multiprocessor computers, according the passed ArrayContext
or via DefaultThreadPoolFactory
when this context is null; provides used interruption and
showing progress via the passed ArrayContext
(if it's not null); etc.
Please note: for very large matrices, much greater than the available Java RAM, the algorithms, implemented
in this class, are designed to tiled
matrices. For non-tiled matrices, these
algorithms can work slowly.
- Author:
- Daniel Alievsky
-
Field Summary
Modifier and TypeFieldDescriptionstatic final long
The minimal possible result ofmaxTempJavaMemory()
method of this class: 4194304L bytes (4 MB). -
Constructor Summary
ModifierConstructorDescriptionprotected
Creates a new instance of this class.protected
AbstractSpectralTransform
(long maxTempJavaMemory) Creates a new instance of this class. -
Method Summary
Modifier and TypeMethodDescriptionabstract boolean
Returns true if the transformation methods of this class (directTransform
,inverseTransform
,directTransformMatrix
,inverseTransformMatrix
) can process only complex samples, false if the real samples are also allowed.final void
directTransform
(ArrayContext context, SampleArray samples) This implementation checks samples array and calls .transform(context,samples,false)
final void
directTransformMatrix
(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the passed matrices and calls .transformMatrix(context,matrixRe,matrixIm,false)
final void
inverseTransform
(ArrayContext context, SampleArray samples) This implementation checks samples array and calls .transform(context,samples,true)
final void
inverseTransformMatrix
(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the matrices and calls .transformMatrix(context,matrixRe,matrixIm,true)
abstract boolean
isLengthAllowed
(long length) Returns true if the specified argument is an allowed dimension for arrays or matrices, transformed bydirectTransform
,inverseTransform
,directTransformMatrix
orinverseTransformMatrix
method.protected long
Specifies the maximal amount of usual Java memory, in bytes, that methods of this class may freely use for internal needs.protected abstract void
transform
(ArrayContext context, SampleArray samples, boolean inverse) Actually performs the 1-dimensional transform of the sample array, direct or inverse.protected void
transformMatrix
(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm, boolean inverse) Implements the generalization of the 1-dimensional spectral transformation, performing bytransform(ArrayContext, SampleArray, boolean)
method, to multidimensional case, as described in thecomments to this class
.protected abstract String
Retrurns a message used while throwing IllegalArgumentException by methods of this class in a case, when the length of the samples array or some of the matrix dimensions is not allowed according toisLengthAllowed(long)
method.
-
Field Details
-
MIN_SPECTRAL_JAVA_MEMORY
public static final long MIN_SPECTRAL_JAVA_MEMORYThe minimal possible result ofmaxTempJavaMemory()
method of this class: 4194304L bytes (4 MB).
-
-
Constructor Details
-
AbstractSpectralTransform
protected AbstractSpectralTransform()Creates a new instance of this class.This constructor is called by all constructors of
FastFourierTransform
andSeparableFastHartleyTransform
classes, which have no maxTempJavaMemory argument.- See Also:
-
AbstractSpectralTransform
protected AbstractSpectralTransform(long maxTempJavaMemory) Creates a new instance of this class.The maxTempJavaMemory argument specifies the amount of Java memory (heap), that can be used by methods of this class for internal needs. If this class was created by
the costructor without argument
, then the standard valueArrays.SystemSettings.maxTempJavaMemory()
will be used. This constructor allows to specify this amount manually, usually larger than that standard value. Java memory is very useful for improving performance oftransformMatrix
method (anddirectTransformMatrix
/inverseTransformMatrix
methods), especially for a case of very large matrices.If the maxTempJavaMemory argument is less then
MIN_SPECTRAL_JAVA_MEMORY
, it is ignored andMIN_SPECTRAL_JAVA_MEMORY
will be used instead.The maxTempJavaMemory value is accesed via
maxTempJavaMemory()
method only. If you override that method, you can change the described behaviour.This constructor is called by all constructors of
FastFourierTransform
andSeparableFastHartleyTransform
classes, which have maxTempJavaMemory argument.- Parameters:
maxTempJavaMemory
- desired maximal amount of Java memory, in bytes, allowed for allocating by methods of this class for internal needs.- See Also:
-
-
Method Details
-
isLengthAllowed
public abstract boolean isLengthAllowed(long length) Description copied from interface:SpectralTransform
Returns true if the specified argument is an allowed dimension for arrays or matrices, transformed bydirectTransform
,inverseTransform
,directTransformMatrix
orinverseTransformMatrix
method.More precisely, if this method returns false for the length of a sample array, passed to 1st or 2nd methods, or for some dimension of some matrix, passed to 3rd or 4th method, then those methods throw
IllegalArgumentException
. In other case, those methods will process that passed data.In both implementations of this interface, offered by this package, this method returns true if the passed length is a power of two (2k).
If the length argument is negative, the result of this method is unspecified. It is not a problem, because lengths of sample arrays and dimensions of AlgART matrices cannot be negative.
- Specified by:
isLengthAllowed
in interfaceSpectralTransform
- Parameters:
length
- the checked length or matrix dimension.- Returns:
- whether the specified argument is an allowed dimension for arrays or matrices, trasformed by this transformation.
-
areComplexSamplesRequired
public abstract boolean areComplexSamplesRequired()Description copied from interface:SpectralTransform
Returns true if the transformation methods of this class (directTransform
,inverseTransform
,directTransformMatrix
,inverseTransformMatrix
) can process only complex samples, false if the real samples are also allowed.More precisely, if this method returns true, then the methods
directTransform
/inverseTransform
checks, whetherSampleArray.isComplex()
method returns true for the samples argument, and the methodsdirectTransformMatrix
/inverseTransformMatrix
checks, whether the matrixIm argument is not null. If this condition is not fulfilled, these methods throw UnsupportedOperationException. In other case, these methods work normally.In implementations, offered by this package, this method returns true in
FastFourierTransform
class and false inSeparableFastHartleyTransform
class.- Specified by:
areComplexSamplesRequired
in interfaceSpectralTransform
- Returns:
- true if this class can transform complex samples only, false if real samples can be transformed too.
-
directTransform
This implementation checks samples array and calls .transform(context,samples,false)
Checking samples array means the following. First, if
areComplexSamplesRequired()
returns true, this method checks the result of samples.isComplex()
method, and if it is false, this method throws UnsupportedOperationException. Then this method checks samples.length()
byisLengthAllowed(long)
method; ifisLengthAllowed
returns false, this mewthod throws IllegalArgumentException.- Specified by:
directTransform
in interfaceSpectralTransform
- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).samples
- the transformed samples.- Throws:
NullPointerException
- if the samples argument is null.IllegalArgumentException
- if thelength
of the passed array is not allowed, i.e. ifisLengthAllowed(long)
method returns false for this value.UnsupportedOperationException
- ifareComplexSamplesRequired()
method returns true, but samples.isComplex()
method returns false.
-
inverseTransform
This implementation checks samples array and calls .transform(context,samples,true)
Checking samples array means the following. First, if
areComplexSamplesRequired()
returns true, this method checks the result of samples.isComplex()
method, and if it is false, this method throws UnsupportedOperationException. Then this method checks samples.length()
byisLengthAllowed(long)
method; ifisLengthAllowed
returns false, this mewthod throws IllegalArgumentException.- Specified by:
inverseTransform
in interfaceSpectralTransform
- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).samples
- the transformed samples.- Throws:
NullPointerException
- if the samples argument is null.IllegalArgumentException
- if thelength
of the passed array is not allowed, i.e. ifisLengthAllowed(long)
method returns false for this value.UnsupportedOperationException
- ifareComplexSamplesRequired()
method returns true, but samples.isComplex()
method returns false.
-
directTransformMatrix
public final void directTransformMatrix(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the passed matrices and calls .transformMatrix(context,matrixRe,matrixIm,false)
Checking matrices means the following. First, if matrixRe argument is null, this method throws NullPointerException. Second, if
areComplexSamplesRequired()
returns true and matrixIm argument is null, this method throws UnsupportedOperationException. Third, if matrixIm argument is not null, this method checks that its dimensions areequal
to the dimensions of matrixRe. If it is not so,SizeMismatchException
is thrown. Last, this method checks, whether all dimensions of the passed matrices are allowed, i.e. thatisLengthAllowed(long)
method returns true for them. If it is not so,IllegalArgumentException
is thrown.- Specified by:
directTransformMatrix
in interfaceSpectralTransform
- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).matrixRe
- the transformed matrix if we have a real matrix; the real parts of the elements of the transformed matrix if it is a complex matrix.matrixIm
- null if we have a real matrix; the imaginary parts of the elements of the transformed matrix if it is a complex matrix.- Throws:
NullPointerException
- if the matrixRe argument is null.IllegalArgumentException
- if the some ofdimensions
of the passed matrices is not allowed, i.e. ifisLengthAllowed(long)
method returns false for this value.SizeMismatchException
- if both passed matrices are not null (the case of the complex matrix) and have different dimensions.UnsupportedOperationException
- ifareComplexSamplesRequired()
method returns true and matrixIm argument is null.
-
inverseTransformMatrix
public final void inverseTransformMatrix(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the matrices and calls .transformMatrix(context,matrixRe,matrixIm,true)
Checking matrices means the following. First, if matrixRe argument is null, this method throws NullPointerException. Second, if
areComplexSamplesRequired()
returns true and matrixIm argument is null, this method throws UnsupportedOperationException. Third, if matrixIm argument is not null, this method checks that its dimensions areequal
to the dimensions of matrixRe. If it is not so,SizeMismatchException
is thrown. Last, this method checks, whether all dimensions of the passed matrices are allowed, i.e. thatisLengthAllowed(long)
method returns true for them. If it is not so,IllegalArgumentException
is thrown.- Specified by:
inverseTransformMatrix
in interfaceSpectralTransform
- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).matrixRe
- the transformed matrix if we have a real matrix; the real parts of the elements of the transformed matrix if it is a complex matrix.matrixIm
- null if we have a real matrix; the imaginary parts of the elements of the transformed matrix if it is a complex matrix.- Throws:
NullPointerException
- if the matrixRe argument is null.IllegalArgumentException
- if the some ofdimensions
of the passed matrices is not allowed, i.e. ifisLengthAllowed(long)
method returns false for this value.SizeMismatchException
- if both passed matrices are not null (the case of the complex matrix) and have different dimensions.UnsupportedOperationException
- ifareComplexSamplesRequired()
method returns true and matrixIm argument is null.
-
unallowedLengthMessage
Retrurns a message used while throwing IllegalArgumentException by methods of this class in a case, when the length of the samples array or some of the matrix dimensions is not allowed according toisLengthAllowed(long)
method. Typical examples of this message (implemented inFastFourierTransform
andSeparableFastHartleyTransform
classes): "FFT algorithm can process only 2^k elements" or "FHT algorithm can process only 2^k elements".- Returns:
- a message used while thrown exception if
isLengthAllowed(long)
method returns false.
-
transform
Actually performs the 1-dimensional transform of the sample array, direct or inverse.It is called from
directTransform
/inverseTransform
methods. In this case, there is a guarantee that: 1) samples!=null; 2) ifareComplexSamplesRequired()
, then samples.isComplex()
returns true; 3)isLengthAllowed(long)
returns true for samples.length().- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).samples
- the transformed samples.inverse
- true if this method implements the inverse transform, false if this method implements the direct transform.
-
transformMatrix
protected void transformMatrix(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm, boolean inverse) Implements the generalization of the 1-dimensional spectral transformation, performing bytransform(ArrayContext, SampleArray, boolean)
method, to multidimensional case, as described in thecomments to this class
. You can override this method, if such generalization is unsuitable, for example, if you want to implement the traditional (nonseparable) multidimensional Hartley transform.This method is called from
directTransformMatrix
/inverseTransformMatrix
methods. In this case, there is a guarantee that: 1) matrixRe!=null; 2) in a caseareComplexSamplesRequired()
, also matrixIm!=null; 3) matrixIm (if not null) has the same dimensions as matrixRe and 4)isLengthAllowed(long)
returns true for all these dimensions.- Parameters:
context
- the context that will be used by this algorithm; may be null (see comments toSpectralTransform
).matrixRe
- the transformed matrix if we have a real matrix; the real parts of the elements of the transformed matrix if it is a complex matrix.matrixIm
- null if we have a real matrix; the imaginary parts of the elements of the transformed matrix if it is a complex matrix.inverse
- true if this method implements the inverse transform, false if this method implements the direct transform.
-
maxTempJavaMemory
protected long maxTempJavaMemory()Specifies the maximal amount of usual Java memory, in bytes, that methods of this class may freely use for internal needs. Larger amounts of work memory, if necessary, are allocated by thememory model
, returned by thecontext
, passed to methods of this class.By default, this method returns max(
MIN_SPECTRAL_JAVA_MEMORY
,maxTempJavaMemory), where maxTempJavaMemory is the argument ofthe corresponding constructor
orArrays.SystemSettings.maxTempJavaMemory()
, ifthe costructor without argument
has been used.You may override this method if you want to change this behaviour. Please not return here too small values: transformation of two- or multidimensional matrices can work very slowly, if the result of this method does not allow allocate a work buffer for storing at least several matrix lines (i.e. K*
Matrix.dimX()
elements, where K is a little integer number, usually from 1-2 to 10-20).- Returns:
- maximal amount of Java memory, in bytes, allowed for allocating by methods of this class for internal needs.
-