public interface SampleArray
Array of samples for transforming by some spectral algorithm like FFT.
A sample can be an element of any linear space, real or complex. Usually samples are either usual complex numbers (represented by pairs of float or double values) or vectors of such numbers. The first case is used for 1-dimensional transformations, the second case is used for multidimensional transformations, when we need parallel processing (adding, subtracting, multiplying by scalar) whole lines of a matrix.
This interface is an abstraction representing an array of samples, that should be transformed by FFT or similar algorithms. The array is updatable (elements can be overwritten), but unresizable (its length cannot be changed). This interface allows to perform the basic necessary operations over samples: copying, swapping, adding, subtracting, multiplying by a scalar. The set of supported operations is chosen according needs of fast transformation algorithms. In addition, this interface allows to allocate work memory for necessary number of temporary samples in a form of new sample array of the same type.
Different implementations of this interface can store samples of different kinds. For example, the complex numbers with double precision is one possible kind of samples, and the vectors of complex numbers with some fixed length is another kind (vectors with different lengths belong to different kinds). Moreover, usual complex numbers, stored by different technologies (by different implementations of this interface), can belong to different kinds. All operations, specified by this class between samples — copying, adding, etc. — can be performed only between samples of the same kind.
There is a guarantee that all samples in this array belong to the same kind and are fully
compatible between each other: for example, can be swapped, added or subtracted.
In particular, if the samples are vectors of complex numbers, then the lengths of all these vectors are equal.
There is also a guarantee that the samples in the array, created by newCompatibleSamplesArray(long)
method, also belong to the same kind.
All indexes, passed to methods of this class, must be in range 0..length-1,
where length is the length
of the corresponding sample array.
(In a case of multiplyRangeByRealScalar
method,
its arguments must comply the conditions 0<=fromIndex<=toIndex<=length.)
If this requirement is not satisfied, the results are unspecified.
("Unspecified" means that any elements of sample arrays can be read or changed,
or that IndexOutOfBoundsException can be thrown.)
The reason of this behaviour is that this interface is designed for maximal performance,
and its methods do not always check the passed indexes.
All calculations, performed by methods of this interface and its implementations,
are performed over floating-point numbers, corresponding to float or double Java types.
It is theoretically possible to work with sample arrays, represented by fixed-point numbers,
alike Java int, long, short and other types (for example,
if it is RealScalarSampleArray
, built on the base of
UpdatableByteArray
). In this situation,
calculations can be performed with some form of rounding, possible overflows lead to unspecified results
and algorithms can work slower.
The sample arrays are not thread-safe, but are thread-compatible and can be synchronized manually if multithread access is necessary.
Modifier and Type | Field and Description |
---|---|
static int |
GUARANTEED_COMPATIBLE_SAMPLES_ARRAY_LENGTH
The number of elements if new sample arrays, that can be allocated
by
newCompatibleSamplesArray(long) method in any case, if there is enough memory. |
Modifier and Type | Method and Description |
---|---|
void |
add(long destIndex,
long srcIndex1,
long srcIndex2)
Adds the sample #srcIndex2 of this array to the sample #srcIndex1
of this array and stores the result into position #destIndex of this array.
|
void |
add(long destIndex,
long srcIndex1,
SampleArray src2,
long srcIndex2)
Adds the sample #srcIndex2 of src2 array to the sample #srcIndex1
of this array and stores the result into position #destIndex of this array.
|
void |
add(long destIndex,
SampleArray src,
long srcIndex1,
long srcIndex2)
Adds the sample #srcIndex2 of src array to the sample #srcIndex1
of src array and stores the result into position #destIndex of this array.
|
void |
combineWithRealMultipliers(long destIndex,
long srcIndex1,
double a1,
long srcIndex2,
double a2)
Multiplies the sample #srcIndex1 of this array by the real scalar a1,
multiplies the sample #srcIndex2 of this array by the real scalar a2
and stores the sum of this two products result into position #destIndex of this array.
|
void |
copy(long destIndex,
SampleArray src,
long srcIndex)
Copies the sample #srcIndex from src array into position
#destIndex in this array.
|
boolean |
isComplex()
Returns true if the samples in this array are complex, false if they are real.
|
long |
length()
Returns the length: number of elements in this array.
|
void |
multiplyByRealScalar(long index,
double a)
Multiplies the sample #destIndex of this array by the real scalar a
and stores the result into the same position #destIndex of this array.
|
void |
multiplyByScalar(long destIndex,
SampleArray src,
long srcIndex,
double aRe,
double aIm)
Multiplies the sample #srcIndex of src array by the complex scalar
aRe+aIm*i (i is the imaginary unit)
and stores the result into position #destIndex of this array.
|
void |
multiplyRangeByRealScalar(long fromIndex,
long toIndex,
double a)
Multiplies the samples #fromIndex..toIndex-1 of this array by the real scalar a
and stores the result into the same positions of this array.
|
SampleArray |
newCompatibleSamplesArray(long length)
Creates a new array of samples of the same kind as this one.
|
void |
sub(long destIndex,
long srcIndex1,
long srcIndex2)
Subtracts the sample #srcIndex2 of this array from the sample #srcIndex1
of this array and stores the result into position #destIndex of this array.
|
void |
sub(long destIndex,
long srcIndex1,
SampleArray src2,
long srcIndex2)
Subtracts the sample #srcIndex2 of src2 array from the sample #srcIndex1
of this array and stores the result into position #destIndex of this array.
|
void |
sub(long destIndex,
SampleArray src,
long srcIndex1,
long srcIndex2)
Subtracts the sample #srcIndex2 of src array from the sample #srcIndex1
of src array and stores the result into position #destIndex of this array.
|
void |
swap(long firstIndex,
long secondIndex)
Swaps samples at positions #firstIndex and #secondIndex inside this array.
|
java.lang.String |
toString(java.lang.String format,
java.lang.String separator,
int maxStringLength)
Returns a string representation of this sample array as contatenated string representations of samples,
separating by the given separator.
|
static final int GUARANTEED_COMPATIBLE_SAMPLES_ARRAY_LENGTH
newCompatibleSamplesArray(long)
method in any case, if there is enough memory.
You may freely use that method for this or less lengths of created arrays,
as well as for creating arrays not longer than this one.
The value of this limit is 64, that is enough for most practical needs in temporary values.boolean isComplex()
multiplyByScalar(long, SampleArray, long, double, double)
works correctly
if and only if this method returns true.
Some methods of this package, for example, Fourier transformations
throw UnsupportedOperationException
if this method returns false.
long length()
SampleArray newCompatibleSamplesArray(long length)
The typical usage of this method is allocating temporary elements for storing one or several samples inside FFT algorithm.
Usually this method allocates new array in a usual Java heap (i.e.
SimpleMemoryModel
when it is based on AlgART arrays).
But some implementations can use another storages, like
LargeMemoryModel
or another custom memory models
, specified while creating
the sample array. This package provides two implementations, illustrating this:
the results of RealVectorSampleArray.asSampleArray
and ComplexVectorSampleArray.asSampleArray
method,
but only in a case, when the length of each real/complex vector (a sample) is large
(for relatively little samples, SimpleMemoryModel
is used always).
If the required length is too long and there is not enough memory, OutOfMemoryError or similar
errors will be thrown. However, for very large length values, it is also possible
that there is enough memory, but this method throws an exception — because the technology
of storing elements does not support such large lengths. For example, if it is an array of real
vectors with length 1000000, and all vectors are stored inside a single Java array float[],
then length=10000 will lead to an exception, even if there is necessary amount of Java memory
(~40 GB) — because Java cannot allocate an array longer than
length <= max(thisArray.length()
,GUARANTEED_COMPATIBLE_SAMPLES_ARRAY_LENGTH
).
So, your can freely use this method for allocating new sample arrays, not greater
than this instance, or for allocating a short arrays for temporary values, if their lengths
does not exceed GUARANTEED_COMPATIBLE_SAMPLES_ARRAY_LENGTH
limit.
length
- the length of new sample array.java.lang.IllegalArgumentException
- if the argument is negative.void copy(long destIndex, SampleArray src, long srcIndex)
destIndex
- index of sample in this array to replace.src
- the source sample array (maybe, a reference to this array).srcIndex
- index of sample in src array to be copied.java.lang.IllegalArgumentException
- if elements of src array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.void swap(long firstIndex, long secondIndex)
firstIndex
- first index of sample to exchange.secondIndex
- second index of sample to exchange.void add(long destIndex, SampleArray src, long srcIndex1, long srcIndex2)
destIndex
- index of sample in this array to store the result.src
- some other array (or, maybe, a reference to this array).srcIndex1
- the index of the first summand in src array.srcIndex2
- the index of the second summand in src array.java.lang.IllegalArgumentException
- if elements of src array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.void sub(long destIndex, SampleArray src, long srcIndex1, long srcIndex2)
destIndex
- index of sample in this array to store the result.src
- some other array (or, maybe, a reference to this array).srcIndex1
- the index of the minuend in src array.srcIndex2
- the index of the subtrahend in src array.java.lang.IllegalArgumentException
- if elements of src array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.void add(long destIndex, long srcIndex1, SampleArray src2, long srcIndex2)
destIndex
- index of sample in this array to store the result.srcIndex1
- the index of the first summand in this array.src2
- some other array (or, maybe, a reference to this array).srcIndex2
- the index of the second summand in src2 array.java.lang.IllegalArgumentException
- if elements of src2 array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.void sub(long destIndex, long srcIndex1, SampleArray src2, long srcIndex2)
destIndex
- index of sample in this array to store the result.srcIndex1
- the index of the minuend in this array.src2
- some other array (or, maybe, a reference to this array).srcIndex2
- the index of the subtrahend in src2 array.java.lang.IllegalArgumentException
- if elements of src2 array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.void add(long destIndex, long srcIndex1, long srcIndex2)
destIndex
- index of sample in this array to store the result.srcIndex1
- the index of the first summand in this array.srcIndex2
- the index of the second summand in this array.void sub(long destIndex, long srcIndex1, long srcIndex2)
destIndex
- index of sample in this array to store the result.srcIndex1
- the index of the minuend in this array.srcIndex2
- the index of the subtrahend in this array.void multiplyByScalar(long destIndex, SampleArray src, long srcIndex, double aRe, double aIm)
If this sample array consists of real samples (for example, real numbers or vectors of real numbers), then the imaginary part aIm is ignored.
destIndex
- index of sample in this array to store the result.src
- some other array (or, maybe, a reference to this array).srcIndex
- the index of the sample in src array.aRe
- the real part of the complex scalar.aIm
- the imaginary part of the complex scalar.java.lang.IllegalArgumentException
- if elements of src array do not belong to the same kind
as elements of this array, for example, they are vectors of
complex numbers with another length. Instead of this exteption,
some other exceptions are also possible in this case, for example,
ClassCastException or
SizeMismatchException
.isComplex()
void multiplyByRealScalar(long index, double a)
multiplyByScalar
(destIndex,thisInstance,destIndex,a,0.0)index
- index of sample in this array.a
- the real scalar.void combineWithRealMultipliers(long destIndex, long srcIndex1, double a1, long srcIndex2, double a2)
destIndex
- index of sample in this array to store the result.srcIndex1
- the index of the first sample in this array.a1
- the multiplier for the first sample.srcIndex2
- the index of the second sample in this array.a2
- the multiplier for the second sample.void multiplyRangeByRealScalar(long fromIndex, long toIndex, double a)
multiplyByRealScalar(index, a)
for index=fromIndex,fromIndex+1,...,toIndex-1.fromIndex
- low index (inclusive) of elements to be multiplied.toIndex
- high index (exclusive) of elements to be multiplied.a
- the real scalar.java.lang.String toString(java.lang.String format, java.lang.String separator, int maxStringLength)
If the samples are numbers (real or complex) or vectors of numbers, this method may use the format argument to clarify the format of numbers according the rules of String.format method. In other cases, this argument may be ignored.
If the necessary string length exceeds maxStringLength characters, this method break concatenation after the element, which leads to exceeding this limit, and adds "..." instead of all further elements. So, the length of returning string will never be essentially larger than maxStringLength characters.
If the passed array is empty, returns the empty string ("").
format
- format string for numeric samples.separator
- the string used for separating elements.maxStringLength
- the maximal allowed length of returned string (longer results are trunctated
with adding "..." at the end).java.lang.NullPointerException
- if format or separator argument is nulljava.lang.IllegalArgumentException
- if maxStringLength <= 0.