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 asSampleArraybyRealScalarSampleArray.asSampleArrayorComplexScalarSampleArray.asSampleArraymethod. All these sample arrays are transformed bydirectTransformcall (in a case of the direct transform) or byinverseTransformcall (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 asSampleArraybyRealVectorSampleArray.asSampleArrayorComplexVectorSampleArray.asSampleArraymethod, where the vector length and step are chosen equal todim(0). All these sample arrays are transformed bydirectTransformcall (in a case of the direct transform) or byinverseTransformcall (in a case of the inverse transform). - ...
- At the last iteration, the whole n-dimensional matrix is represented as a
SampleArraybyRealVectorSampleArray.asSampleArrayorComplexVectorSampleArray.asSampleArraymethod, where the vector length and step are chosen equal todim(0)*dim(1)*...*dim(N-1). This sample array is transformed bydirectTransformcall (in a case of the direct transform) or byinverseTransformcall (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
FieldsModifier and TypeFieldDescriptionstatic final longThe minimal possible result ofmaxTempJavaMemory()method of this class: 4194304L bytes (4 MB). -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedCreates a new instance of this class.protectedAbstractSpectralTransform(long maxTempJavaMemory) Creates a new instance of this class. -
Method Summary
Modifier and TypeMethodDescriptionabstract booleanReturns 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 voiddirectTransform(ArrayContext context, SampleArray samples) This implementation checks samples array and calls .transform(context,samples,false)final voiddirectTransformMatrix(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the passed matrices and calls .transformMatrix(context,matrixRe,matrixIm,false)final voidinverseTransform(ArrayContext context, SampleArray samples) This implementation checks samples array and calls .transform(context,samples,true)final voidinverseTransformMatrix(ArrayContext context, Matrix<? extends UpdatablePNumberArray> matrixRe, Matrix<? extends UpdatablePNumberArray> matrixIm) This implementation checks the matrices and calls .transformMatrix(context,matrixRe,matrixIm,true)abstract booleanisLengthAllowed(long length) Returns true if the specified argument is an allowed dimension for arrays or matrices, transformed bydirectTransform,inverseTransform,directTransformMatrixorinverseTransformMatrixmethod.protected longSpecifies the maximal amount of usual Java memory, in bytes, that methods of this class may freely use for internal needs.protected abstract voidtransform(ArrayContext context, SampleArray samples, boolean inverse) Actually performs the 1-dimensional transform of the sample array, direct or inverse.protected voidtransformMatrix(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 StringRetrurns 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
FastFourierTransformandSeparableFastHartleyTransformclasses, 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 oftransformMatrixmethod (anddirectTransformMatrix/inverseTransformMatrixmethods), 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_MEMORYwill 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
FastFourierTransformandSeparableFastHartleyTransformclasses, 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:SpectralTransformReturns true if the specified argument is an allowed dimension for arrays or matrices, transformed bydirectTransform,inverseTransform,directTransformMatrixorinverseTransformMatrixmethod.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:
isLengthAllowedin 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:SpectralTransformReturns 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/inverseTransformchecks, whetherSampleArray.isComplex()method returns true for the samples argument, and the methodsdirectTransformMatrix/inverseTransformMatrixchecks, 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
FastFourierTransformclass and false inSeparableFastHartleyTransformclass.- Specified by:
areComplexSamplesRequiredin 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; ifisLengthAllowedreturns false, this mewthod throws IllegalArgumentException.- Specified by:
directTransformin 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 thelengthof 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; ifisLengthAllowedreturns false, this mewthod throws IllegalArgumentException.- Specified by:
inverseTransformin 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 thelengthof 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 areequalto the dimensions of matrixRe. If it is not so,SizeMismatchExceptionis 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,IllegalArgumentExceptionis thrown.- Specified by:
directTransformMatrixin 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 ofdimensionsof 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 areequalto the dimensions of matrixRe. If it is not so,SizeMismatchExceptionis 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,IllegalArgumentExceptionis thrown.- Specified by:
inverseTransformMatrixin 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 ofdimensionsof 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 inFastFourierTransformandSeparableFastHartleyTransformclasses): "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/inverseTransformmethods. 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/inverseTransformMatrixmethods. 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 constructororArrays.SystemSettings.maxTempJavaMemory(), ifthe costructor without argumenthas 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.
-