public class SeparableFastHartleyTransform extends AbstractSpectralTransform implements SpectralTransform
Fast Hartley transform (FHT)
(in multidimensional case — the separable fast Hartley transform).
This class implements standard onedimensional FHT algorithm over an abstract SampleArray
.
It is generalized to multidimensional case by the simplest way, implemented in
AbstractSpectralTransform
class (applying the transform separably to each dimension);
the resulting transformation for 2 or multidimensional AlgART numeric matrices
is usually called
separable fast Hartley transform (SFHT).
The samples, processed by this class, can be both real or complex (areComplexSamplesRequired()
method
returns false). This class is especially useful in a case of real samples. In this case
it is performed faster than the classic FFT, FastFourierTransform
class, because
there are no needs to allocate and process arrays of imaginary parts.
The simple relation between Hartley and Fourier transform (see below) allows to use this transform
almost in all areas where Fourier transform is applicable.
More precisely, this class implements the classic fast "butterfly" algorithm (FHT) for calculating
discrete Hartley transform (DHT), described at
Namely, let x_{0},x_{1},...,x_{N−1} are some
real or complex samples (represented by abstract SampleArray
), and
H_{0},H_{1},...,H_{N−1} are their Hartley spectrum:
the result of DHT. Let's designate
The only difference is when to normalize the result: while inverse transform (case 1) or direct transform (case 2). The Wikipedia offers formulas of the 1st case. This class allows to calculate both variants: the 1st case is chosen if the normalizeDirectTransform argument of the constructors is false or if this class is created by a constructor without this argument (it is the default behaviour), the 2nd case is chosen if the normalizeDirectTransform argument of the constructors is true.
The very useful feature of DHT is that for real samples x_{k} the Hartley spectrum
H_{k} is also real — unlike DFT, when even real samples lead to complex spectrum.
As a result, the transformation algorithms in this class can process real arrays and matrices,
without imaginary parts. In this case, they work in two and even more times faster than FFT algorithms,
implemented in FastFourierTransform
, and do not require allocating additional memory
for storing imaginary parts of the complex numbers.
The formulas above correspond to onedimensional transforms and specify the results of
directTransform
/ inverseTransform
methods.
They are generalized to multidimensional case by default algorithms, implemented in
AbstractSpectralTransform
class, i.e. by applying the transform separably to each dimension.
It leads to socalled multidimensional separable discrete Hartley transformations (SDHT). Below are
the formulas for 2dimensional separable discrete Hartley transformation of the matrix x_{ij}
(0≤i<M, 0≤j<N) for the case 1 (normalizing the inverse transform):
direct: H_{ij} = ∑_{(0≤m<M)} ∑_{(0≤n<N)} x_{mn} cas(2imπ/M) cas(2jnπ/N),
inverse: x_{mn} = (MN)^{ −1} ∑_{(0≤i<M)} ∑_{(0≤j<N)} x_{ij} cas(2imπ/M) cas(2jnπ/N).
There is the simple relation between classic DFT (discrete Fourier transform) and SDHT (separable discrete Hartley transform).
Let's consider onedimensional case (usual DHT). Let x_{0},x_{1},...,x_{N−1} are some real or complex samples, F_{0},F_{1},...,F_{N−1} are their Fourier spectrum and H_{0},H_{1},...,H_{N−1} are their Hartley spectrum. Let i is the usual imaginary unit. For simplicity, let's consider that F_{−k}=F_{N−k}, H_{−k}=H_{N−k}, k=1,2,... Then:
F_{k} = (H_{k}+H_{−k})/2 − i (H_{k}−H_{−k})/2,
H_{k} = (F_{k}+F_{−k})/2 + i (F_{k}−F_{−k})/2,
in a case of real samples: H_{k} = Re F_{k} − Im F_{k}
(of course, we consider the same definition, 1 or 2, for both DFT
and
SDHT
spectra).
In 2dimensional case, the relation between DFT and SDHT is the following (we similarly suppose that F_{−i, j}=F_{M−i, j}, F_{i,−j}=F_{i, N−j}, H_{−i, j}=H_{M−i, j}, H_{i,−j}=H_{i, N−j}):
F_{i, j} = (H_{i,−j}+H_{−i, j})/2 − i (H_{i, j}−H_{−i,−j})/2,
H_{i, j} = (F_{i,−j}+F_{−i, j})/2 + i (F_{i, j}−F_{−i,−j})/2,
in a case of real samples: H_{i, j} = Re F_{i,−j} − Im F_{i, j}.
In the common ndimensional case, there are similar formulas, which express F_{i, j,...,k} through a linear combination of 2^{n} numbers H_{± i,± j,...,± k} and, vice versa, express H_{i, j,...,k} through a linear combination of 2^{n} numbers F_{± i,± j,...,± k}.
This class contains the ready for use methods, allowing to convert ndimensional separable Hartley spectrum to Fourier one and vice versa, n=1,2,3,...:
separableHartleyToFourier(ArrayContext context, Matrix fRe, Matrix fIm, Matrix h)
converts (real) Hartley spectrum of the real matrix to its Fourier spectrum;separableHartleyToFourier(ArrayContext context, Matrix fRe, Matrix fIm, Matrix hRe, Matrix hIm)
converts (complex) Hartley spectrum of the complex matrix to its Fourier spectrum;fourierToSeparableHartley(ArrayContext context, Matrix h, Matrix fRe, Matrix fIm)
converts Fourer spectrum of the real matrix to its (real) Hartley spectrum;fourierToSeparableHartley(ArrayContext context, Matrix hRe, Matrix hIm, Matrix fRe, Matrix fIm)
converts Fourer spectrum of the complex matrix to its (complex) Hartley spectrum.If it is necessary to get the Fourier spectrum of some real matrix, probably process it and transform the Fourier spectrum back to the real matrix, you can use a combination of SHFT, provided by this class, and the conversion methods listed above (cases of real matrices). But if all that you need is to calculate a convolution of two real matrices, there is a better way: see below.
Onedimensional Hartley transform, defined by the formulas 1 and 2 above, complies with the convolution theorem. Namely, let p_{0},p_{1},...,p_{N−1} is the first complex or real numeric function and q_{0},q_{1},...,q_{N−1} is the second complex or real function, and c_{0},c_{1},...,c_{N−1} is their (complex or real) convolution, defined as:
c_{k} = ∑_{(0≤n<N)} p_{n}q_{k−n}
(here and below we consider that Z_{−k}=Z_{N−k} for all samples and spectra). Also, let P_{0},P_{1},...,P_{N−1}, Q_{0},Q_{1},...,Q_{N−1} and C_{0},C_{1},...,C_{N−1} are Hartley spectra of these functions. Then:
There are similar formulas in the common ndimensional case, allowing to express the separable Hartley spectrum of the convolution of two ndimensional matrices via the spectra of the source matrices. In particular, in the 2dimensional case:
This class contains the ready for use methods, allowing to calculate a spectrum of convolution C on the base of the given spectra P and Q of two source numeric matrices x and y according the formulas A, C and their generalization for any number of dimensions:
spectrumOfConvolution(ArrayContext context, Matrix cRe, Matrix cIm, Matrix pRe, Matrix pRe, Matrix qRe, Matrix qRe)
calculates separable Hartley spectrum of the convolution C on the base of separable Hartley spectra
P and Q of two source complex matrices;spectrumOfConvolution(ArrayContext context, Matrix c, Matrix p, Matrix q)
calculates
separable Hartley spectrum of the convolution C on the base of separable Hartley spectra
P and Q of two source real matrices.So, if you need to calculate a convolution of some real matrices, for example, for goals of linear filtering,
you can use the SFHT transform and the
spectrumOfConvolution
method, provided by this class: it is much better idea than using FastFourierTransform
class.
Please note: in the onedimensional case, the spectral transofmation algorithms, implemented by
directTransformMatrix
/ inverseTransformMatrix
methods of this class, work with normal (i.e. high) performance only if
the passed SimpleMemoryModel
(more precisely, if they are directly accessible
).
In other case, each access to every sample leads to calling accessing methods
getDouble
and setDouble
,
which can work slowly in nonsimple memory models like LargeMemoryModel
. There is the same problem for
directTransform
/ inverseTransform
methods, if the passed
sample arrays are created via RealScalarSampleArray.asSampleArray
or ComplexScalarSampleArray.asSampleArray
methods on the base of
updatable AlgART arrays, created by memory model other than SimpleMemoryModel
.
For ndimensional matrices (n≥2), this problem usually does not occur at all, even for nonsimple
memory models, if you use standard implementations of
directTransformMatrix
/ inverseTransformMatrix
from AbstractSpectralTransform
class: these implementations automatically download necessary parts
of the matrix into SimpleMemoryModel
. This problem also does not occur while using
conversion methods separableHartleyToFourier(ArrayContext, Matrix, Matrix, Matrix)
,
separableHartleyToFourier(ArrayContext, Matrix, Matrix, Matrix, Matrix)
,
fourierToSeparableHartley(ArrayContext, Matrix, Matrix, Matrix)
,
fourierToSeparableHartley(ArrayContext, Matrix, Matrix, Matrix, Matrix)
and
methods of calculation of the spectrum of convolution
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix)
and
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix, Matrix, Matrix, Matrix)
,
if all processed matrices have the same float or double element types.
MIN_SPECTRAL_JAVA_MEMORY
Constructor and Description 

SeparableFastHartleyTransform()
Creates a new instance of this class, performing separable Hartley transform according to the formula 1 from
the
comments to this class . 
SeparableFastHartleyTransform(boolean normalizeDirectTransform)
Creates a new instance of this class, performing separable Hartley transform according either to the formula 1
from the
comments to this class ,
if normalizeDirectTransform argument is false,
or to the formula 2, if this argument is true. 
SeparableFastHartleyTransform(boolean normalizeDirectTransform,
long maxTempJavaMemory)
Creates a new instance of this class, performing separable Hartley transform according either to the formula 1
from the
comments to this class ,
if normalizeDirectTransform argument is false,
or to the formula 2, if this argument is true. 
SeparableFastHartleyTransform(long maxTempJavaMemory)
Creates a new instance of this class, performing separable Hartley transform according to the formula 1 from
the
comments to this class . 
Modifier and Type  Method and Description 

boolean 
areComplexSamplesRequired()
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. 
void 
fourierToSeparableHartley(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> h,
Matrix<? extends PNumberArray> fRe,
Matrix<? extends PNumberArray> fIm)
Converts the Fourier spectrum F of some real ndimensional matrix into
the (real) separable Hartley spectrum H of the same matrix.

void 
fourierToSeparableHartley(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> hRe,
Matrix<? extends UpdatablePNumberArray> hIm,
Matrix<? extends PNumberArray> fRe,
Matrix<? extends PNumberArray> fIm)
Converts the Fourier spectrum F of some complex ndimensional matrix into
the (complex) separable Hartley spectrum H of the same matrix.

boolean 
isLengthAllowed(long length)
Returns true if the specified argument is an allowed dimension for arrays or matrices,
transformed by
directTransform , inverseTransform ,
directTransformMatrix or inverseTransformMatrix
method. 
void 
separableHartleyToFourier(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> fRe,
Matrix<? extends UpdatablePNumberArray> fIm,
Matrix<? extends PNumberArray> h)
Converts the separable Hartley spectrum H of some real ndimensional matrix into
the (complex) Fourier spectrum F of the same matrix.

void 
separableHartleyToFourier(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> fRe,
Matrix<? extends UpdatablePNumberArray> fIm,
Matrix<? extends PNumberArray> hRe,
Matrix<? extends PNumberArray> hIm)
Converts the separable Hartley spectrum H of some complex ndimensional matrix into
the (complex) Fourier spectrum F of the same matrix.

void 
spectrumOfConvolution(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> c,
Matrix<? extends PNumberArray> p,
Matrix<? extends PNumberArray> q)
Calculates C, the separable Hartley spectrum of the convolution of some two real matrices,
on the base of P and Q — the separable Hartley spectra of these two real matrices.

void 
spectrumOfConvolution(ArrayContext context,
Matrix<? extends UpdatablePNumberArray> cRe,
Matrix<? extends UpdatablePNumberArray> cIm,
Matrix<? extends PNumberArray> pRe,
Matrix<? extends PNumberArray> pIm,
Matrix<? extends PNumberArray> qRe,
Matrix<? extends PNumberArray> qIm)
Calculates C, the separable Hartley spectrum of the convolution of some two complex matrices,
on the base of P and Q — the separable Hartley spectra of these two complex matrices.

protected void 
transform(ArrayContext context,
SampleArray samples,
boolean inverse)
Actually performs the 1dimensional transform of the sample array, direct or inverse.

protected java.lang.String 
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 to
AbstractSpectralTransform.isLengthAllowed(long) method. 
directTransform, directTransformMatrix, inverseTransform, inverseTransformMatrix, maxTempJavaMemory, transformMatrix
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
directTransform, directTransformMatrix, inverseTransform, inverseTransformMatrix
public SeparableFastHartleyTransform()
comments to this class
.
Equivalent to SeparableFastHartleyTransform(false)
.SeparableFastHartleyTransform(long)
public SeparableFastHartleyTransform(long maxTempJavaMemory)
comments to this class
.
The maxTempJavaMemory argument specifies the amount of Java memory (heap),
that can be used by methods of this class for internal needs. It is passed to the corresponding
constructor of AbstractSpectralTransform
: see
comments to that constructor
.
maxTempJavaMemory
 desired maximal amount of Java memory, in bytes, allowed for allocation
by methods of this class for internal needs.SeparableFastHartleyTransform()
public SeparableFastHartleyTransform(boolean normalizeDirectTransform)
comments to this class
,
if normalizeDirectTransform argument is false,
or to the formula 2, if this argument is true.
The default value, used by the constructors without normalizeDirectTransform argument,
is false.
Please note: the value of normalizeDirectTransform argument affects only the transformation
methods directTransform
, inverseTransform
,
directTransformMatrix
, inverseTransformMatrix
.
This value does not matter in other methods of this class: conversions between Hartley and Fourier spectrum,
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix)
and
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix, Matrix, Matrix, Matrix)
.
normalizeDirectTransform
 true if you want to perform normalization (division by the number of
samples N) after the direct transform, false (the default value)
if you want to perform normalization after the inverse transform.SeparableFastHartleyTransform(boolean, long)
public SeparableFastHartleyTransform(boolean normalizeDirectTransform, long maxTempJavaMemory)
comments to this class
,
if normalizeDirectTransform argument is false,
or to the formula 2, if this argument is true.
The default value, used by the constructors without normalizeDirectTransform argument,
is false.
Please note: the value of normalizeDirectTransform argument affects only the transformation
methods directTransform
, inverseTransform
,
directTransformMatrix
, inverseTransformMatrix
.
This value does not matter in other methods of this class: conversions between Hartley and Fourier spectrum,
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix)
and
spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix, Matrix, Matrix, Matrix)
.
The maxTempJavaMemory argument specifies the amount of Java memory (heap),
that can be used by methods of this class for internal needs. It is passed to the corresponding
constructor of AbstractSpectralTransform
: see
comments to that constructor
.
maxTempJavaMemory
 desired maximal amount of Java memory, in bytes, allowed for allocating
by methods of this class for internal needs.normalizeDirectTransform
 true if you want to perform normalization (division by the number of
samples N) after the direct transform, false (the default value)
if you want to perform normalization after the inverse transform.SeparableFastHartleyTransform(boolean)
public void separableHartleyToFourier(ArrayContext context, Matrix<? extends UpdatablePNumberArray> fRe, Matrix<? extends UpdatablePNumberArray> fIm, Matrix<? extends PNumberArray> h)
comments to this class
about the relation formulas between
separable Hartley and Fourier spectra.
The complex matrix F is represented as a pair of AlgART matrices (fRe,fIm): the corresponding elements of these 2 matrices contain the real and imaginary parts of the corresponding elements of the complex matrix F. The real matrix H is passed as an AlgART matrix h.
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same matrix as fRe / fIm and h.
If you need to convert spectrum in a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).fRe
 the real parts of the elements of the resulting matrix (Fourier spectrum).fIm
 the imaginary parts of the elements of the resulting matrix (Fourier spectrum).h
 the source real matrix (separable Hartley spectrum).java.lang.NullPointerException
 if one of fRe, fIm, h arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.separableHartleyToFourier(ArrayContext, Matrix, Matrix, Matrix, Matrix)
public void separableHartleyToFourier(ArrayContext context, Matrix<? extends UpdatablePNumberArray> fRe, Matrix<? extends UpdatablePNumberArray> fIm, Matrix<? extends PNumberArray> hRe, Matrix<? extends PNumberArray> hIm)
comments to this class
about the relation formulas between
separable Hartley and Fourier spectra.
The complex matrix F is represented as a pair of AlgART matrices (fRe,fIm): the corresponding elements of these 2 matrices contain the real and imaginary parts of the corresponding elements of the complex matrix F. Similarly, the complex matrix H is represented as a pair of AlgART matrices (hRe,hIm).
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same complex matrix as F and H. So, you can calculate and return the result in the source matrices.
If you need to convert spectrum in a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).fRe
 the real parts of the elements of the resulting matrix (Fourier spectrum).fIm
 the imaginary parts of the elements of the resulting matrix (Fourier spectrum).hRe
 the real parts of the elements of the source matrix (separable Hartley spectrum).hIm
 the imaginary parts of the elements of the source matrix (separable Hartley spectrum).java.lang.NullPointerException
 if one of fRe, fIm, hRe, hIm
arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.separableHartleyToFourier(ArrayContext, Matrix, Matrix, Matrix)
public void fourierToSeparableHartley(ArrayContext context, Matrix<? extends UpdatablePNumberArray> h, Matrix<? extends PNumberArray> fRe, Matrix<? extends PNumberArray> fIm)
comments to this class
about the relation formulas between
separable Hartley and Fourier spectra.
If the passed Fourier spectrum is not a spectrum of a real matrix (in other words,
if the inverse Fourier transform of F matrix contains nonzero imaginary parts),
then this method still correctly calculates the real parts of the separable Hartley spectrum H.
The complex matrix F is represented as a pair of AlgART matrices (fRe,fIm): the corresponding elements of these 2 matrices contain the real and imaginary parts of the corresponding elements of the complex matrix F. The real matrix H (or the real parts of H, if the passed F matrix is not a spectrum of a real matrix) is passed as an AlgART matrix h.
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same matrix as fRe / fIm and h.
If you need to convert spectrum in a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).h
 the resulting real matrix (separable Hartley spectrum).fRe
 the real parts of the elements of the source matrix (Fourier spectrum).fIm
 the imaginary parts of the elements of the source matrix (Fourier spectrum).java.lang.NullPointerException
 if one of h, fRe, fIm arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.fourierToSeparableHartley(ArrayContext, Matrix, Matrix, Matrix, Matrix)
public void fourierToSeparableHartley(ArrayContext context, Matrix<? extends UpdatablePNumberArray> hRe, Matrix<? extends UpdatablePNumberArray> hIm, Matrix<? extends PNumberArray> fRe, Matrix<? extends PNumberArray> fIm)
comments to this class
about the relation formulas between
separable Hartley and Fourier spectra.
The complex matrix F is represented as a pair of AlgART matrices (fRe,fIm): the corresponding elements of these 2 matrices contain the real and imaginary parts of the corresponding elements of the complex matrix F. Similarly, the complex matrix H is represented as a pair of AlgART matrices (hRe,hIm).
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same complex matrix as F and H. So, you can calculate and return the result in the source matrices.
If you need to convert spectrum in a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).hRe
 the real parts of the elements of the resulting matrix (separable Hartley spectrum).hIm
 the imaginary parts of the elements of the resulting matrix (separable Hartley spectrum).fRe
 the real parts of the elements of the source matrix (Fourier spectrum).fIm
 the imaginary parts of the elements of the source matrix (Fourier spectrum).java.lang.NullPointerException
 if one of hRe, hIm, fRe, fIm
arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.fourierToSeparableHartley(ArrayContext, Matrix, Matrix, Matrix)
public void spectrumOfConvolution(ArrayContext context, Matrix<? extends UpdatablePNumberArray> c, Matrix<? extends PNumberArray> p, Matrix<? extends PNumberArray> q)
The real matrices P, Q, C are passed as AlgART matrices p, q, c.
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same complex matrix as P and Q, or as P and C, or as Q and C, or even as all three matrices. So, you can calculate and return the result in one of the source matrices.
If you need to calculate the Hartley spectrum of convolution for a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).c
 the resulting matrix (spectrum of the convolution).p
 the spectrum of the 1st matrix.q
 the spectrum of the 2nd matrix.java.lang.NullPointerException
 if one of c, p, q arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix, Matrix, Matrix, Matrix)
public void spectrumOfConvolution(ArrayContext context, Matrix<? extends UpdatablePNumberArray> cRe, Matrix<? extends UpdatablePNumberArray> cIm, Matrix<? extends PNumberArray> pRe, Matrix<? extends PNumberArray> pIm, Matrix<? extends PNumberArray> qRe, Matrix<? extends PNumberArray> qIm)
The complex matrix P is represented as a pair of AlgART matrices (pRe,pIm): the corresponding elements of these 2 matrices contain the real and imaginary parts of the corresponding elements of the complex matrix P. Similarly, the complex matrix Q is represented as a pair of AlgART matrices (qRe,qIm), and the complex matrix C is represented as a pair of AlgART matrices (cRe,cIm).
All matrices, passed to this method, must have equal dimensions
.
The element type
of the passed matrices can be different, but we recommend
using the same float or double element type for all matrices.
There are no restrictions for the dimensions of the passed matrices:
isLengthAllowed(long)
method is not used here.
This method works correctly, if you pass the same complex matrix as P and Q, or as P and C, or as Q and C, or even as all three matrices. So, you can calculate and return the result in one of the source matrices.
If you need to calculate the Hartley spectrum of convolution for a case of Matrices.matrix(Array, long...)
call, for example:
Matrices.matrix
(array, array.length()).
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).cRe
 the real parts of the elements of the resulting matrix (spectrum of the convolution).cIm
 the imaginary parts of the elements of the resulting matrix (spectrum of the convolution).pRe
 the real parts of the elements of the spectrum of the 1st matrix.pIm
 the imaginary parts of the elements of the spectrum of the 1st matrix.qRe
 the real parts of the elements of the spectrum of the 2nd matrix.qIm
 the imaginary parts of the elements of the spectrum of the 2nd matrix.java.lang.NullPointerException
 if one of cRe, cIm, pRe, pIm,
qRe, qIm arguments is null.SizeMismatchException
 if some of passed matrices have different dimensions.spectrumOfConvolution(ArrayContext, Matrix, Matrix, Matrix)
public final boolean isLengthAllowed(long length)
SpectralTransform
directTransform
, inverseTransform
,
directTransformMatrix
or inverseTransformMatrix
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 (2^{k}).
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.
isLengthAllowed
in interface SpectralTransform
isLengthAllowed
in class AbstractSpectralTransform
length
 the checked length or matrix dimension.public boolean areComplexSamplesRequired()
SpectralTransform
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, whether SampleArray.isComplex()
method returns true for the samples argument,
and the methods directTransformMatrix
/
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 in SeparableFastHartleyTransform
class.
areComplexSamplesRequired
in interface SpectralTransform
areComplexSamplesRequired
in class AbstractSpectralTransform
protected java.lang.String unallowedLengthMessage()
AbstractSpectralTransform
AbstractSpectralTransform.isLengthAllowed(long)
method.
Typical examples of this message (implemented in FastFourierTransform
and
SeparableFastHartleyTransform
classes):
"FFT algorithm can process only 2^k elements" or
"FHT algorithm can process only 2^k elements".unallowedLengthMessage
in class AbstractSpectralTransform
AbstractSpectralTransform.isLengthAllowed(long)
method returns false.protected final void transform(ArrayContext context, SampleArray samples, boolean inverse)
AbstractSpectralTransform
It is called from directTransform
/ inverseTransform
methods. In this case, there is a guarantee that:
1) samples!=null;
2) if AbstractSpectralTransform.areComplexSamplesRequired()
, then samples.isComplex()
returns true;
3) AbstractSpectralTransform.isLengthAllowed(long)
returns true for samples.length().
transform
in class AbstractSpectralTransform
context
 the context that will be used by this algorithm; may be null
(see comments to SpectralTransform
).samples
 the transformed samples.inverse
 true if this method implements the inverse transform,
false if this method implements the direct transform.