
net.algart.matrices.morphology.RankMorphology Maven / Gradle / Ivy
Show all versions of algart Show documentation
/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.algart.matrices.morphology;
import net.algart.arrays.*;
import net.algart.math.functions.Func;
import net.algart.math.patterns.Pattern;
/**
* Rank operations over {@link Matrix n-dimensional matrices}:
* percentile, rank, mean between given percentiles or values, etc.,
* calculated on all matrix elements in an aperture with the fixed shape, represented by {@link Pattern} class.
* It is supposed that the type of matrix elements is one of primitive Java types
* (boolean
, char
, byte
, short
, int
,
* long
, float
, double
) and, so, represents an integer or a real number,
* according to comments to {@link PFixedArray#getLong(long)} and {@link PArray#getDouble(long)} methods.
* In 2-dimensional case, these operations can be used for processing grayscale digital images.
*
* The simplest rank operation is a percentile, for example, minimum, maximum or median.
* In the case of maximum, the percentile is strictly equivalent to dilation — the basic
* operation of the mathematical morphology, offered by {@link Morphology} interface.
* In the case of minimum, the percentile by some pattern P is equivalent to erosion
* by the symmetric pattern P.{@link Pattern#symmetric() symmetric()}.
* It allows to consider rank operations as an extension of the operation set of
* the traditional mathematical morphology. Really, this interface extends
* {@link Morphology} interface, and it is supposed, by definition, that
* {@link #dilation(Matrix, Pattern) dilation}(m,pattern)
method is equivalent to
* {@link #percentile(Matrix, double, Pattern) percentile}(m,c*N,pattern)
and
* {@link #erosion(Matrix, Pattern) erosion}(m,pattern)
method is equivalent to
* {@link #percentile(Matrix, double, Pattern) percentile}(m,c*N,pattern.{@link Pattern#symmetric()
* symmetric()})
, where N=pattern.{@link Pattern#pointCount() pointCount()}-1
* and c
is some constant, specified while instantiating this object
* (it is dilationLevel
argument of
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision) BasicRankMorphology.getInstance}
* method).
*
* Below is the formal definition of 5 basic rank operations with the given pattern P
* and matrix M: percentile, rank, mean between 2 percentiles,
* mean between 2 ranks and aperture sum, calculated by this class.
*
*
* - For any integer point, or position
* x = (x0, x1, ..., xn−1),
* n=M.{@link Matrix#dimCount() dimCount()}, the aperture of this point,
* or the aperture at the position x,
* is a set of points
* x−pi = (x0−pi0,
* x1−pi1, ...,
* xn−1−pi,n−1)
* for all pi∈P ({@link Pattern#roundedPoints() points}
* of the pattern P).
* We always consider that the point x lies inside M matrix
* (0≤xk<M.
{@link Matrix#dim(int) dim}(k)
* for all k), but this condition can be not true for points of the aperture
* x−pi.
*
*
* - For every point x' = x−pi of the aperture
* we consider the corresponding value vi of the source matrix M.
* The precise definition of the value can depend on implementation of this interface.
* Usually, if the point lies inside the matrix
* (0≤xk−pi,k<M.
{@link Matrix#dim(int)
* dim}(k)
for all k), it is the value of the element
* (integer: {@link PFixedArray#getLong(long)}, if the type of the matrix elements is
* boolean
, char
,
* byte
, short
, int
or long
,
* or real: {@link PArray#getDouble(long)},
* if the element type is float
or double
) of the underlying array
* M.{@link Matrix#array() array()} with an index
* M.{@link Matrix#index(long...)
* index}(x'0, x'1, ..., x'n−1),
* where x'k = xk−pi,k.
* In particular, it is true for all implementations offered by this package.
* If the point x' = x−pi lies outside the matrix
* (x'k<0 or
* x'k≥M.{@link Matrix#dim(int) dim}(k)
* for some k), then:
*
* - in the {@link BasicRankMorphology} implementation, vi is the value of the element
* ({@link PFixedArray#getLong(long)} for the fixed-point case or {@link PFloatingArray#getDouble(long)}
* for the floating-point case) of the underlying array M.{@link Matrix#array() array()}
* with an index M.{@link Matrix#pseudoCyclicIndex(long...)
* pseudoCyclicIndex}(x'0, x'1, ...,
* x'n−1);
* - in the {@link ContinuedRankMorphology} implementation, vi is the
* calculated according to the continuation mode, passed to
* {@link ContinuedRankMorphology#getInstance(RankMorphology, Matrix.ContinuationMode)}
* method;
* - other implementations may offer other ways for calculating vi.
*
*
*
*
* - So, for every point x we have an aperture, consisting of
* N=P.{@link Pattern#pointCount() pointCount()} "neighbour" points
* x−pi,
* and a corresponding set of integer or real values vi,
* i=0,1,...,N−1. Then we consider a histogram built on the base of
* vi values — the histogram, corresponding to the point x. Namely, this histogram
* is an array of non-negative integer numbers b[w], 0≤w<M,
* where every element b[w] represents the number of occurrence of the value w
* in array A, consisting of the following N integer elements
* a0, a1, ..., xN−1:
*
* - ai = min(M−1,
* ⌊max(0, vi) * σ⌋)
* (here and below ⌊y⌋ means the integer part of y or
(long)
y
* for non-negative numbers, M and σ are defined below);
* in other words, ai is an integer part of σvi,
* truncated to 0..M−1 range of allowed histogram indexes;
*
* - the histogram length M is the global parameter of this object and is equal to some power of two:
* M=2μ, μ=0,1,2... There is a guarantee that
* if the matrix is fixed-point (M.{@link Matrix#elementType()} is
*
boolean
, char
, byte
, short
,
* int
or long
),
* then μ≤β, where β is
* the number of bits per element:
* β = M.{@link Matrix#array() array()}.{@link PArray#bitsPerElement() bitsPerElement()}.
* If this object is an instance of {@link BasicRankMorphology}, then
* μ = bitLevels[bitLevels.length-1]
* for floating-point matrix elements (M.{@link Matrix#elementType()} is
* float
or double
) or
* μ = min(bitLevels[bitLevels.length-1]
, β)
* for fixed-point matrix elements, where bitLevels
is
* an array of {@link CustomRankPrecision#bitLevels() bit levels}, specified while instantiating
* this class via the last argument of
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision)} method;
*
* - the real number σ ("scale") is equal to M for a floating-point matrix
* or equal to M/2β=2μ−β,
* β = M.{@link Matrix#array() array()}.{@link PArray#bitsPerElement()
* bitsPerElement()} for a fixed-point matrix. So, in the case of a fixed-point matrix
* there is a guarantee that 1/σ is a positive integer number
* (2β−μ).
*
* In other words, the "standard" allowed range of element values
* 0..{@link Arrays#maxPossibleValue(Class, double)
* Arrays.maxPossibleValue}(M.{@link Matrix#elementType() elementType()},1.0)
* is split into M=2μ histogram bars and all aperture values
* vi are distributed between these bars; elements, which are out of the allowed range,
* are distributed between the first and last bars.
* In the simplest case of byte
elements, M is usually chosen to be 256;
* then σ=1.0 and ai = vi
* (because byte
elements, in terms of AlgART libraries, cannot be out of 0..255 range).
*
*
* - The histogram b[0], b[1], ..., b[M−1], specified above,
* is interpreted in terms of {@link Histogram} and {@link SummingHistogram} classes.
* Namely, we define the following rank characteristics:
*
* - the percentile with the given real index r is
* v(r)/σ,
* where v(r) function is defined in comments to {@link Histogram} class;
*
* - the rank of the given real value v is r(v*σ),
* where r(v) function is defined in comments to {@link Histogram} class;
*
* - the mean between 2 given percentiles with the real indexes
* r1 and r2 is
* (S(r2)−S(r1)) /
* ((r2−r1)*σ)
* if r1<r2 or some reserved value filler
* if r1≥r2,
* where S(r) function is defined in comments to {@link SummingHistogram} class;
*
* - the mean between 2 given values, the real numbers
* v1 and v2, is
* (s(v2*σ)−s(v1*σ)) /
* (r(v2*σ)−r(v1*σ))*σ)
* if v1<v2 and
* r(v1*σ)<r(v2*σ),
* where r(v) function is defined in comments to {@link Histogram} class and
* s(v) function is defined in comments to {@link SummingHistogram} class.
* If the conditions v1<v2 and
* r(v1*σ)<r(v2*σ) are not
* fulfilled, we use one of 4 following modes of calculation:
*
* - if any of these two conditions is not fulfilled, it is equal to some reserved value filler;
* - if any of these two conditions is not fulfilled, it is equal to v1;
* - if any of these two conditions is not fulfilled, it is equal to v2;
* - (most useful definition)
*
* - if v1≥v2, it is equal to
* (v1+v2)/2;
* - if v1<v2 and
* r(v2*σ)=r(v1*σ)=0,
* it is equal to v2 (see also
* {@link net.algart.arrays.SummingHistogram.CountOfValues#isLeftBound()
* CountOfValues.isLeftBound()});
* - if v1<v2 and
* r(v2*σ)=r(v1*σ)=N,
* it is equal to v1 (see also
* {@link net.algart.arrays.SummingHistogram.CountOfValues#isRightBound()
* CountOfValues.isRightBound()});
* - in other cases, it is equal to
* (v1+v2)/2.
*
*
*
* Remember that r(v) is always a non-decreasing function, so, the sentence
* "the conditions v1<v2 and
* r(v1*σ)<r(v2*σ) are not
* fulfilled" means, that either v1≥v2,
* or v1<v2 and
* r(v1*σ)=r(v2*σ).
* The last situation usually occurs "outside" the histogram, when both v1 and
* v2 values are less than (or equal to) the minimal value in the aperture
* or greater than (or equal to) the maximum value in the aperture.
* However, while using the simple histogram model, such situation is also possible on a sparse histogram
* with many zero bars;
*
* - the aperture sum is just a usual sum of all values
* v0+v1+...+vN−1 —
* the only rank characteristic which does not use the histogram b[k].
* (Of course, you can also calculate the mean of all values on the base of this sum:
* it is enough to divide the sum by N.)
*
* Note 1: it is obvious that all rank characteristics, excepting the aperture sum, depend on the
* histogram model: simple or precise (see comments to {@link Histogram} and {@link SummingHistogram} classes).
* The used model is chosen while instantiating this class, usually via
* {@link CustomRankPrecision#interpolated()} flag in the argument of {@link CustomRankPrecision} class:
* true
value ("interpolated") means the precise model, false
means the simple one.
*
* Note 2: for int
, long
,
* float
and double
element type of the source
* matrix M and for all characteristics, excepting the aperture sum, this definition supposes that
* all matrix elements lie in the "standard range": 0..Integer/Long.MAX_VALUE
* (all non-negative values) for integers or 0.0..1.0
for floating-point elements.
* If some matrix elements are negative, they are interpreted as 0; if some elements of a floating-point
* matrix are greater than 1.0
, they are interpreted as 1.0
.
* For floating-point case, the histogram length M actually specifies
* the precision of calculations: the source elements are represented with the precision
* 1/M. The aperture sum characteristic is an exception from this rule: aperture sums
* are calculated as usual sums of the source elements vi with double
precision.
*
* Note 3: for floating-point case, if the value of some element vi
* of the source matrix M inside the aperture is NaN
* (Float.NaN
for float
type, Double.NaN
for double
type),
* this situation does not lead to an exception, but the resulting values of all characteristics, listed above,
* are undocumented.
*
* Note 4: unlike this, if some arguments of the characteristics, listed above —
* the real index r for the percentile, the real value v for the rank,
* the real indexes r1 and r2 for the mean between percentiles
* or the real values v1 and v2 for the mean between values —
* are NaN, then any attempt to calculate these characteristics by methods of this interface
* can lead to IllegalArgumentException
.
*
*
*
* This interface provides method for calculating the described 5 rank characteristics for every
* integer point x lying in the matrix M. The resulting characteristics are returned
* in the result matrix with the same dimensions as M. The necessary arguments —
* the real index r for the percentile, the real value v for the rank,
* the real indexes r1 and r2 for the mean between percentiles
* or the real values v1 and v2 for the mean between values —
* are retrieved from the corresponding element (with the index
* M.{@link Matrix#index(long...)
* index}(x0, x1, ..., xn−1))
* of the {@link Matrix#array() built-in array} of some additional matrix or pair of matrices,
* passed to the methods, by {@link PArray#getDouble(long)} method. It is supposed that those matrices
* have the same dimensions as M. For the percentile and the mean between percentiles,
* there are simplified versions of the methods, which use the constant rank indexes instead of matrices of
* indexes.
*
* Most of methods of this interface allow to return not only floating-point, but also integer result matrix.
* In this case, the real rank characteristics, defined above in the section 4, are rounded by some rules,
* that are specified in comments to the concrete methods.
*
* For every rank characteristics this interface offers 3 methods for calculating it. Below are some comments
* about them.
*
* - The first version is always called "
asOperation
", for example,
* {@link #asPercentile(Matrix, Matrix, Pattern) asPercentile}.
* This method returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the necessary rank characteristic
* of the source matrix with the specified pattern (aperture shape).
* The result of such method is usually "lazy", that means that this method finishes immediately and all
* actual calculations are performed while getting elements of the returned matrix.
* It is true for all implementations provided by this package.
* However, some implementations may not support lazy execution;
* then the method may be equivalent to the second version described below.
* Note that the sequential access to the lazy result, returned by this method
* (via {@link Array#getData(long, Object, int, int) Array.getData} method, called for the
* {@link Matrix#array() built-in array} of the returned matrix), usually works much faster
* than the random access to elements of the matrix.
*
* - The second version is called "
operation
", for example,
* {@link #percentile(Matrix, Matrix, Pattern) percentile}.
* This method always returns actual (non-lazy) updatable result:
* Matrix<? extends UpdatablePArray>
.
* This method can work essentially faster than an access to
* the lazy matrix returned by the first variant of the method
* (for example, than copying it into a new matrix).
* In implementations, offered by this package, there are no difference if the source
* matrix src
(for rank operations, baseMatrix
) is direct accessible:
* src.{@link Matrix#array() array()} instanceof {@link DirectAccessible} &&
* ((DirectAccessible)src.{@link Matrix#array() array()}).{@link DirectAccessible#hasJavaArray()
* hasJavaArray()}
. If the source matrix is not direct accessible,
* the implementations, offered by this package, use {@link net.algart.matrices.StreamingApertureProcessor} technique
* to accelerate processing. Calculating aperture sums is an exception:
* {@link #functionOfSum(Matrix, Pattern, Func) functionOfSum} method uses some optimization for some kinds of
* patterns and can work much faster than accessing to {@link #asFunctionOfSum(Matrix, Pattern, Func) asFunctionOfSum}
* result.
*
* - The third version is also called "
operation
", but it is a void method:
* for example, {@link #percentile(Matrix, Matrix, Matrix, Pattern)}.
* The result matrix is passed via first argument named dest
and supposed to be allocated
* before calling the method. This way allows to save memory and time, if you need to perform several
* rank operation, because you can use the same matrices for temporary results.
* In addition, these methods allow to choose the type of element of the resulting matrix for any
* operation. The precise rules of type conversions are described in comments to concrete methods.
*
*
*
* This package provides the following basic methods for creating objects, implementing this interface:
*
*
* - {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision)};
* - {@link ContinuedRankMorphology#getInstance(RankMorphology, Matrix.ContinuationMode)}.
*
*
* Warning: all implementations of this interface, provided by this package, can process only patterns
* where {@link Pattern#pointCount() pointCount()}≤Integer.MAX_VALUE
.
* More precisely, any methods of this interface (including methods, inherited from its superinterface
* {@link Morphology}), implemented by classes of this package, which have {@link Pattern} argument,
* can throw {@link net.algart.math.patterns.TooManyPointsInPatternError TooManyPointsInPatternError}
* or OutOfMemoryError
in the same situations as {@link Pattern#points()} method.
*
* Warning: the methods of this interface, which save results into the passed dest
* matrix (like {@link #percentile(Matrix, Matrix, Matrix, Pattern)}),
* as well as any attempts to read the "lazy" results (of the methods
* like {@link #asPercentile(Matrix, Matrix, Pattern)}),
* can be non-atomic regarding the failure, if the arguments of the calculated rank characteristics —
* the real index r for the percentile, the real value v for the rank,
* the real indexes r1 and r2 for the mean between percentiles
* or the real values v1 and v2 for the mean between values —
* are floating-point NaN values for some aperture positions. In this case,
* it is possible that the result will be partially filled, and only after this the NaN value will lead to
* IllegalArgumentException
.
*
* The classes, implementing this interface, are immutable and thread-safe:
* there are no ways to modify settings of the created instance.
*
* @author Daniel Alievsky
*/
public interface RankMorphology extends Morphology {
/**
* Special value of filler
argument of methods, calculating mean between 2 values,
* which activates the mode B of calculation:
* if r(v1*σ)≥r(v2*σ),
* the mean is considered to be equal v1.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 values" term.
*
* This constant can be used with {@link #asMeanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)},
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)} and
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)} methods.
*
*
This constant contains Double.NEGATIVE_INFINITY
value,
* which is usually useless in a role of the ordinary filler for the mode A of calculations.
*/
double FILL_MIN_VALUE = Double.NEGATIVE_INFINITY;
/**
* Special value of filler
argument of methods, calculating mean between 2 values,
* which activates the mode C of calculation:
* if r(v1*σ)≥r(v2*σ),
* the mean is considered to be equal v2.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 values" term.
*
*
This constant can be used with {@link #asMeanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)},
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)} and
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)} methods.
*
*
This constant contains Double.POSITIVE_INFINITY
value,
* which is usually useless in a role of the ordinary filler for the mode A of calculations.
*/
double FILL_MAX_VALUE = Double.POSITIVE_INFINITY;
/**
* Special value of filler
argument of methods, calculating mean between 2 values,
* which activates the mode D of calculation.
* In this case:
*
* - if v1≥v2, the mean is considered to be equal to
* (v1+v2)/2;
* - if v1<v2 and
* r(v2*σ)=r(v1*σ)=0,
* the mean is considered to be equal to v2 (see also
* {@link net.algart.arrays.SummingHistogram.CountOfValues#isLeftBound()
* CountOfValues.isLeftBound()});
* - if v1<v2 and
* r(v2*σ)=r(v1*σ)=N,
* the mean is considered to be equal to v1 (see also
* {@link net.algart.arrays.SummingHistogram.CountOfValues#isRightBound()
* CountOfValues.isRightBound()});
* - in other cases,
* if r(v1*σ)=r(v2*σ),
* the mean is considered to be equal to
* (v1+v2)/2.
*
*
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 values" term.
*
*
This constant can be used with {@link #asMeanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)},
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)} and
* {@link #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)} methods.
*
*
This constant contains Double.NaN
value, which is usually useless in a role of the ordinary
* filler for the mode A of calculations.
*
*
Warning: because this constant is Double.NaN
, according to rules of Java language,
* you must not compare any numbers with this constant! A check like
*
* if (x == RankMorphology.FILL_NEAREST_VALUE
) {
* ...
* }
*
* always returns false
. You should use Double.isNaN(x)
call instead.
*/
double FILL_NEAREST_VALUE = Double.NaN;
RankMorphology context(ArrayContext newContext);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the percentile
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real index r of the percentile for every element of the result is equal
* to the corresponding element of percentileIndexes
matrix.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real percentile v(r)/σ,
* defined in the comments to this class.
* In this case, this method, instead of the real value v(r)/σ,
* returns an integer w/σ, where w is:
*
* - either the integer result of {@link Histogram#iValue(long[], long)
* Histogram.iValue} (b,
(long)Math.floor
(r)),
* if this object works in the simple histogram model
* (where b is the histogram, corresponding to every aperture position),
* - or the integer result of {@link Histogram#iPreciseValue(long[], double)
* Histogram.iPreciseValue} (b, r),
* if it works in the precise histogram model.
*
* It is necessary to remind: in a case of fixed-point elements
* there is a guarantee that 1/σ is a positive integer number, and
* w/σ=w*2β−μ,
* β = src.{@link Matrix#array() array()}.{@link PArray#bitsPerElement()
* bitsPerElement()}
,
* μ is the binary logarithm of the histogram length M —
* see the {@link RankMorphology comments to this class}, section 3.
* So, if μ is chosen less than the precision of this matrix β
* (8 for byte
, 16 for short
, etc.), then β−μ
* lowest bits in the result will be always zero.
* For {@link BasicRankMorphology} object, μ is chosen while
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision) instantiating this object}
* as min(bitLevels[bitLevels.length-1]
, β).
*
* @param src the source matrix.
* @param percentileIndexes the matrix containing r argument: the indexes of the percentile
* for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @return the "lazy" matrix containing the percentile of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asPercentile(Matrix, double, Pattern)
* @see #percentile(Matrix, Matrix, Pattern)
* @see #percentile(Matrix, Matrix, Matrix, Pattern)
*/
Matrix extends PArray> asPercentile(
Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes, Pattern pattern);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the percentile
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real index r of the percentile is equal to percentileIndex
argument for
* all aperture positions. The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* This method is equivalent to
*
*
{@link #asPercentile(Matrix, Matrix, Pattern)
* asPercentile}(src, src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex), pattern)
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real percentile v(r)/σ,
* defined in the comments to this class.
* In this case, this method, instead of the real value v(r)/σ,
* returns an integer w/σ, where w is:
*
* - either the integer result of {@link Histogram#iValue(long[], long)
* Histogram.iValue} (b,
(long)Math.floor
(r)),
* if this object works in the simple histogram model
* (where b is the histogram, corresponding to every aperture position),
* - or the integer result of {@link Histogram#iPreciseValue(long[], double)
* Histogram.iPreciseValue} (b, r),
* if it works in the precise histogram model.
*
* It is necessary to remind: in a case of fixed-point elements
* there is a guarantee that 1/σ is a positive integer number, and
* w/σ=w*2β−μ,
* β = src.{@link Matrix#array() array()}.{@link PArray#bitsPerElement()
* bitsPerElement()}
,
* μ is the binary logarithm of the histogram length M —
* see the {@link RankMorphology comments to this class}, section 3.
* So, if μ is chosen less than the precision of this matrix β
* (8 for byte
, 16 for short
, etc.), then β−μ
* lowest bits in the result will be always zero.
* For {@link BasicRankMorphology} object, μ is chosen while
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision) instantiating this object}
* as min(bitLevels[bitLevels.length-1]
, β).
*
* @param src the source matrix.
* @param percentileIndex r argument of the percentile.
* @param pattern the pattern: the shape of the aperture.
* @return the "lazy" matrix containing the percentile of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asPercentile(Matrix, Matrix, Pattern)
* @see #percentile(Matrix, double, Pattern)
* @see #percentile(Matrix, Matrix, double, Pattern)
*/
Matrix extends PArray> asPercentile(
Matrix extends PArray> src,
double percentileIndex, Pattern pattern);
/**
* Returns a new updatable matrix, containing the percentile
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real index r of the percentile for every element of the result is equal
* to the corresponding element of percentileIndexes
matrix.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real percentile v(r)/σ,
* defined in the comments to this class.
* In this case, this method, instead of the real value v(r)/σ,
* returns an integer w/σ, where w is:
*
* - either the integer result of {@link Histogram#iValue(long[], long)
* Histogram.iValue} (b,
(long)Math.floor
(r)),
* if this object works in the simple histogram model
* (where b is the histogram, corresponding to every aperture position),
* - or the integer result of {@link Histogram#iPreciseValue(long[], double)
* Histogram.iPreciseValue} (b, r),
* if it works in the precise histogram model.
*
* It is necessary to remind: in a case of fixed-point elements
* there is a guarantee that 1/σ is a positive integer number, and
* w/σ=w*2β−μ,
* β = src.{@link Matrix#array() array()}.{@link PArray#bitsPerElement()
* bitsPerElement()}
,
* μ is the binary logarithm of the histogram length M —
* see the {@link RankMorphology comments to this class}, section 3.
* So, if μ is chosen less than the precision of this matrix β
* (8 for byte
, 16 for short
, etc.), then β−μ
* lowest bits in the result will be always zero.
* For {@link BasicRankMorphology} object, μ is chosen while
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision) instantiating this object}
* as min(bitLevels[bitLevels.length-1]
, β).
*
* @param src the source matrix.
* @param percentileIndexes the matrix containing r argument: the indexes of the percentile
* for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @return the percentile of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #percentile(Matrix, double, Pattern)
* @see #asPercentile(Matrix, Matrix, Pattern)
* @see #percentile(Matrix, Matrix, Matrix, Pattern)
*/
Matrix extends UpdatablePArray> percentile(
Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes, Pattern pattern);
/**
* Returns a new updatable matrix, containing the percentile
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real index r of the percentile is equal to percentileIndex
argument for
* all aperture positions. The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* This method is equivalent to
*
*
{@link #percentile(Matrix, Matrix, Pattern)
* percentile}(src, src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex), pattern)
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real percentile v(r)/σ,
* defined in the comments to this class.
* In this case, this method, instead of the real value v(r)/σ,
* returns an integer w/σ, where w is:
*
* - either the integer result of {@link Histogram#iValue(long[], long)
* Histogram.iValue} (b,
(long)Math.floor
(r)),
* if this object works in the simple histogram model
* (where b is the histogram, corresponding to every aperture position),
* - or the integer result of {@link Histogram#iPreciseValue(long[], double)
* Histogram.iPreciseValue} (b, r),
* if it works in the precise histogram model.
*
* It is necessary to remind: in a case of fixed-point elements
* there is a guarantee that 1/σ is a positive integer number, and
* w/σ=w*2β−μ,
* β = src.{@link Matrix#array() array()}.{@link PArray#bitsPerElement()
* bitsPerElement()}
,
* μ is the binary logarithm of the histogram length M —
* see the {@link RankMorphology comments to this class}, section 3.
* So, if μ is chosen less than the precision of this matrix β
* (8 for byte
, 16 for short
, etc.), then β−μ
* lowest bits in the result will be always zero.
* For {@link BasicRankMorphology} object, μ is chosen while
* {@link BasicRankMorphology#getInstance(ArrayContext, double, CustomRankPrecision) instantiating this object}
* as min(bitLevels[bitLevels.length-1]
, β).
*
* @param src the source matrix.
* @param percentileIndex r argument of the percentile.
* @param pattern the pattern: the shape of the aperture.
* @return the percentile of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #percentile(Matrix, Matrix, Pattern)
* @see #asPercentile(Matrix, double, Pattern)
* @see #percentile(Matrix, Matrix, double, Pattern)
*/
Matrix extends UpdatablePArray> percentile(
Matrix extends PArray> src,
double percentileIndex, Pattern pattern);
/**
* Equivalent to {@link #percentile(Matrix, Matrix, Pattern)} method, but the result matrix
* will be placed in the dest
argument.
*
* If the {@link Matrix#elementType() element type} of the passed dest
matrix
* is the same as the element type of the source one, the result, saved in dest
, will be identically
* equal to the result of {@link #percentile(Matrix, Matrix, Pattern)} method with the same
* src
, percentileIndexes
and pattern
arguments. In other case,
* the result, saved in dest
, will be equal to
*
*
{@link Matrices#asFuncMatrix(boolean, Func, Class, Matrix)
* Matrices.asFuncMatrix}(true, {@link Func#IDENTITY Func.IDENTITY},
* dest.array().{@link Array#type() type()}, {@link #percentile(Matrix, Matrix, Pattern)
* percentile}(src, percentileIndexes, pattern))
*
* So, even if the precision of dest
matrix is better than the precision
* of src
—
* for example, if src.{@link Matrix#elementType() elementType()}
is byte
, but
* dest.{@link Matrix#elementType() elementType()}
is double
—
* this method does not try to calculate more precise percentile and rounds results like
* {@link #asPercentile(Matrix, Matrix, Pattern)} and
* {@link #percentile(Matrix, Matrix, Pattern)} methods.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param percentileIndexes the matrix containing r argument: the indexes of the percentile
* for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #percentile(Matrix, Matrix, double, Pattern)
* @see #asPercentile(Matrix, Matrix, Pattern)
* @see #percentile(Matrix, Matrix, Pattern)
*/
void percentile(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes, Pattern pattern);
/**
* Equivalent to {@link #percentile(Matrix, double, Pattern)} method, but the result matrix
* will be placed in the dest
argument.
*
*
This method is equivalent to
*
*
{@link #percentile(Matrix, Matrix, Matrix, Pattern)
* percentile}(dest, src, src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex), pattern)
*
* @param dest the target matrix.
* @param src the source matrix.
* @param percentileIndex r argument of the percentile.
* @param pattern the pattern: the shape of the aperture.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #percentile(Matrix, Matrix, Matrix, Pattern)
* @see #asPercentile(Matrix, double, Pattern)
* @see #percentile(Matrix, double, Pattern)
*/
void percentile(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
double percentileIndex, Pattern pattern);
/**
* Returns an immutable view of the passed baseMatrix
matrix,
* such that any reading data from it calculates and returns the ranks
* of some given values v regarding the source matrix baseMatrix
with the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "rank" term.
* The real value v for every element of the result is equal
* to the corresponding element of rankedMatrix
matrix.
*
* The matrix, returned by this method, is immutable, and the class of its built-in array
* implements one of the basic interfaces
* {@link BitArray}, {@link CharArray},
* {@link ByteArray}, {@link ShortArray},
* {@link IntArray}, {@link LongArray},
* {@link FloatArray} or {@link DoubleArray}.
* The class of desired interface (one of 8 possible classes) must be passed as requiredType
argument.
* So, it defines the element type of the returned matrix.
* The rules of casting the floating-point ranks to the desired element type are the same as in
* {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
The element types of baseMatrix
and rankedMatrix
are usually equal.
* If they are different (baseMatrix.{@link Matrix#elementType()
* elementType()}!=rankedMatrix.{@link Matrix#elementType() elementType()}
),
* this method replaces rankedMatrix
with
*
*
{@link Matrices#asFuncMatrix(boolean, Func, Class, Matrix)
* Matrices.asFuncMatrix}(true, {@link Func#IDENTITY
* Func.IDENTITY}, baseMatrix.array().{@link Array#type() type()}, rankedMatrix)
*
* before all other calculations. In other words, this method always casts the type of
* the ranked elements to the type of baseMatrix
elements.
* As a result, we can be sure, that if the source baseMatrix
matrix is fixed-point
* (boolean
, char
, byte
, short
,
* int
or long
elements),
* then the rank r(v*σ), according to the definition of the "rank" term,
* will be an integer number. In this case, you can specify requiredType=IntArray.class
and
* get the precise rank without precision loss. Moreover, if you know that the number of points in the pattern
* (pattern.{@link Pattern#pointCount() pointCount()}
) is less than
* 216=65536 or 28=256, it is enough to specify correspondingly
* requiredType=ShortArray.class
or ByteArray.class
.
*
* @param requiredType the desired type of the built-in array in the returned matrix.
* @param baseMatrix the source matrix.
* @param rankedMatrix the matrix containing v argument: the values,
* the rank of which should be calculated.
* @param pattern the pattern: the shape of the aperture.
* @return the "lazy" matrix containing the rank of the given values.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to baseMatrix.{@link Matrix#dimCount() dimCount()}
,
* or if requiredType
is not one of classes
* {@link BitArray}.class
, {@link CharArray}.class
,
* {@link ByteArray}.class
, {@link ShortArray}.class
,
* {@link IntArray}.class
, {@link LongArray}.class
,
* {@link FloatArray}.class
or {@link DoubleArray}.class
.
* @see #rank(Class, Matrix, Matrix, Pattern)
* @see #rank(Matrix, Matrix, Matrix, Pattern)
*/
Matrix asRank(
Class extends T> requiredType,
Matrix extends PArray> baseMatrix, Matrix extends PArray> rankedMatrix, Pattern pattern);
/**
* Returns a new updatable matrix, containing the rank
* of some given values v regarding the source matrix baseMatrix
with the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "rank" term.
* The real value v for every element of the result is equal
* to the corresponding element of rankedMatrix
matrix.
*
* The matrix, returned by this method, is updatable, and the class of its built-in array
* implements one of the basic interfaces
* {@link UpdatableBitArray}, {@link UpdatableCharArray},
* {@link UpdatableByteArray}, {@link UpdatableShortArray},
* {@link UpdatableIntArray}, {@link UpdatableLongArray},
* {@link UpdatableFloatArray} or {@link UpdatableDoubleArray}.
* The class of desired interface (one of 8 possible classes) must be passed as requiredType
argument.
* So, it defines the element type of the returned matrix.
* Instead of these classes, you can also pass one of corresponding immutable interfaces
* {@link BitArray}, {@link CharArray},
* {@link ByteArray}, {@link ShortArray},
* {@link IntArray}, {@link LongArray},
* {@link FloatArray} or {@link DoubleArray}:
* the result will be the same.
* The rules of casting the floating-point ranks to the desired element type are the same as in
* {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
The element types of baseMatrix
and rankedMatrix
are usually equal.
* If they are different (baseMatrix.{@link Matrix#elementType()
* elementType()}!=rankedMatrix.{@link Matrix#elementType() elementType()}
),
* this method replaces rankedMatrix
with
*
*
{@link Matrices#asFuncMatrix(boolean, Func, Class, Matrix)
* Matrices.asFuncMatrix}(true, {@link Func#IDENTITY
* Func.IDENTITY}, baseMatrix.array().{@link Array#type() type()}, rankedMatrix)
*
* before all other calculations. In other words, this method always casts the type of
* the ranked elements to the type of baseMatrix
elements.
* As a result, we can be sure, that if the source baseMatrix
matrix is fixed-point
* (boolean
, char
, byte
, short
,
* int
or long
elements),
* then the rank r(v*σ), according to the definition of the "rank" term,
* will be an integer number. In this case, you can specify requiredType=IntArray.class
and
* get the precise rank without precision loss. Moreover, if you know that the number of points in the pattern
* (pattern.{@link Pattern#pointCount() pointCount()}
) is less than
* 216=65536 or 28=256, it is enough to specify correspondingly
* requiredType=ShortArray.class
or ByteArray.class
.
* The less result precision allows you to save memory.
*
* @param requiredType the desired type of the built-in array in the returned matrix.
* @param baseMatrix the source matrix.
* @param rankedMatrix the matrix containing v argument: the values,
* the rank of which should be calculated.
* @param pattern the pattern: the shape of the aperture.
* @return the rank of the given values.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to baseMatrix.{@link Matrix#dimCount() dimCount()}
,
* or if requiredType
is not one of classes
* {@link UpdatableBitArray}.class
/
* {@link BitArray}.class
,
* {@link UpdatableCharArray}.class
/
* {@link CharArray}.class
,
* {@link UpdatableByteArray}.class
/
* {@link ByteArray}.class
,
* {@link UpdatableShortArray}.class
/
* {@link ShortArray}.class
,
* {@link UpdatableIntArray}.class
/
* {@link IntArray}.class
,
* {@link UpdatableLongArray}.class
/
* {@link LongArray}.class
,
* {@link UpdatableFloatArray}.class
/
* {@link FloatArray}.class
* or {@link UpdatableDoubleArray}.class
/
* {@link DoubleArray}.class
.
* @see #asRank(Class, Matrix, Matrix, Pattern)
* @see #rank(Matrix, Matrix, Matrix, Pattern)
*/
Matrix extends T> rank(
Class extends T> requiredType,
Matrix extends PArray> baseMatrix, Matrix extends PArray> rankedMatrix, Pattern pattern);
/**
* Equivalent to {@link #rank(Class, Matrix, Matrix, Pattern)} method, but the result matrix
* will be placed in the dest
argument and the required type will be chosen automatically
* as dest.{@link Matrix#type(Class) type}(PArray.class)
.
* More precisely, the result, saved in dest
, will be equal to
*
* {@link #rank(Class, Matrix, Matrix, Pattern)
* rank}(dest.array().{@link Array#type() type()}, baseMatrix, rankedMatrix, pattern)
*
* The element types of baseMatrix
and rankedMatrix
are usually equal.
* If they are different (baseMatrix.{@link Matrix#elementType()
* elementType()}!=rankedMatrix.{@link Matrix#elementType() elementType()}
),
* this method replaces rankedMatrix
with
*
*
{@link Matrices#asFuncMatrix(boolean, Func, Class, Matrix)
* Matrices.asFuncMatrix}(true, {@link Func#IDENTITY
* Func.IDENTITY}, baseMatrix.array().{@link Array#type() type()}, rankedMatrix)
*
* before all other calculations. In other words, this method always casts the type of
* the ranked elements to the type of baseMatrix
elements.
* As a result, we can be sure, that if the source baseMatrix
matrix is fixed-point
* (boolean
, char
, byte
, short
,
* int
or long
elements),
* then the rank r(v*σ), according to the definition of the "rank" term,
* will be an integer number. In this case, you can specify requiredType=IntArray.class
and
* get the precise rank without precision loss. Moreover, if you know that the number of points in the pattern
* (pattern.{@link Pattern#pointCount() pointCount()}
) is less than
* 216=65536 or 28=256, it is enough to specify correspondingly
* requiredType=ShortArray.class
or ByteArray.class
.
* The less result precision allows you to save memory.
*
* @param dest the target matrix.
* @param baseMatrix the source matrix.
* @param rankedMatrix the matrix containing v argument: the values,
* the rank of which should be calculated.
* @param pattern the pattern: the shape of the aperture.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to baseMatrix.{@link Matrix#dimCount() dimCount()}
.
* @see #asRank(Class, Matrix, Matrix, Pattern)
* @see #rank(Class, Matrix, Matrix, Pattern)
*/
void rank(Matrix extends UpdatablePArray> dest,
Matrix extends PArray> baseMatrix, Matrix extends PArray> rankedMatrix, Pattern pattern);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the mean between 2 percentiles
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 percentiles" term.
* The real indexes r1 and r2 of the percentiles
* for every element of the result are equal to the corresponding elements of
* fromPercentileIndexes
and toPercentileIndexes
matrices.
* The reserved value filler is specified by the last argument of this method.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param fromPercentileIndexes the matrix containing r1 argument: the indexes of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndexes the matrix containing r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @return the "lazy" matrix containing the mean between 2 given percentiles
* of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMeanBetweenPercentiles(Matrix, double, double, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double)
*/
Matrix extends PArray> asMeanBetweenPercentiles(
Matrix extends PArray> src,
Matrix extends PArray> fromPercentileIndexes,
Matrix extends PArray> toPercentileIndexes,
Pattern pattern, double filler);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the mean between 2 percentiles
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 percentiles" term.
* The real indexes r1 and r2 of the percentiles
* for every element of the result are equal to fromPercentileIndex
* and toPercentileIndex
arguments for all aperture positions.
* The reserved value filler is specified by the last argument of this method.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
This method is equivalent to
*
*
{@link #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* asMeanBetweenPercentiles}(src,
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), fromPercentileIndex),
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), toPercentileIndex),
* pattern, filler)
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param fromPercentileIndex r1 argument: the index of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndex r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @return the "lazy" matrix containing the mean between 2 given percentiles
* of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, double, double, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, double, double, Pattern, double)
*/
Matrix extends PArray> asMeanBetweenPercentiles(
Matrix extends PArray> src,
double fromPercentileIndex,
double toPercentileIndex,
Pattern pattern, double filler);
/**
* Returns a new updatable matrix, containing the mean between 2 percentiles
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 percentiles" term.
* The real indexes r1 and r2 of the percentiles
* for every element of the result are equal to the corresponding elements of
* fromPercentileIndexes
and toPercentileIndexes
matrices.
* The reserved value filler is specified by the last argument of this method.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param fromPercentileIndexes the matrix containing r1 argument: the indexes of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndexes the matrix containing r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @return the mean between 2 given percentiles of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #meanBetweenPercentiles(Matrix, double, double, Pattern, double)
* @see #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double)
*/
Matrix extends UpdatablePArray> meanBetweenPercentiles(
Matrix extends PArray> src,
Matrix extends PArray> fromPercentileIndexes,
Matrix extends PArray> toPercentileIndexes,
Pattern pattern, double filler);
/**
* Returns a new updatable matrix, containing the mean between 2 percentiles
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 percentiles" term.
* The real indexes r1 and r2 of the percentiles
* for every element of the result are equal to fromPercentileIndex
* and toPercentileIndex
arguments for all aperture positions.
* The reserved value filler is specified by the last argument of this method.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
This method is equivalent to
*
*
{@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* meanBetweenPercentiles}(src,
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), fromPercentileIndex),
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), toPercentileIndex),
* pattern, filler)
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param fromPercentileIndex r1 argument: the index of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndex r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @return the mean between 2 given percentiles of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* @see #asMeanBetweenPercentiles(Matrix, double, double, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, double, double, Pattern, double)
*/
Matrix extends UpdatablePArray> meanBetweenPercentiles(
Matrix extends PArray> src,
double fromPercentileIndex,
double toPercentileIndex,
Pattern pattern, double filler);
/**
* Equivalent to {@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)} method,
* but the result matrix will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param fromPercentileIndexes the matrix containing r1 argument: the indexes of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndexes the matrix containing r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #meanBetweenPercentiles(Matrix, Matrix, double, double, Pattern, double)
* @see #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
*/
void meanBetweenPercentiles(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
Matrix extends PArray> fromPercentileIndexes,
Matrix extends PArray> toPercentileIndexes,
Pattern pattern, double filler);
/**
* Equivalent to {@link #meanBetweenPercentiles(Matrix, double, double, Pattern, double)} method,
* but the result matrix will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param fromPercentileIndex r1 argument: the index of
* the less percentile of the averaged range for every element of the result.
* @param toPercentileIndex r2 argument: the indexes of
* the greater percentile of the averaged range for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r1≥r2.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double)
* @see #asMeanBetweenPercentiles(Matrix, double, double, Pattern, double)
* @see #meanBetweenPercentiles(Matrix, double, double, Pattern, double)
*/
void meanBetweenPercentiles(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
double fromPercentileIndex,
double toPercentileIndex,
Pattern pattern, double filler);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the mean between 2 values
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 values" term.
* The real numbers v1 and v2
* for every element of the result are equal to the corresponding elements of
* minValues
and maxValues
matrices.
* The reserved value filler and the mode of calculation (for the case
* r(v1*σ)≥r(v2*σ))
* are specified by the last filler
argument of this method:
*
* - if
filler
argument is {@link #FILL_MIN_VALUE} (Double.NEGATIVE_INFINITY
),
* the mode B is used;
* - if
filler
argument is {@link #FILL_MAX_VALUE} (Double.POSITIVE_INFINITY
),
* the mode C is used;
* - if
filler
argument is {@link #FILL_NEAREST_VALUE} (Double.NaN
),
* the mode D is used;
* - if
filler
argument contains any other value, the mode A is used and this argument specifies
* the reserved value filler.
*
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param minValues the matrix containing v1 argument: the low bound
* of the averaged range of values for every element of the result.
* @param maxValues the matrix containing v2 argument: the high bound
* of the averaged range of values for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r(v1*σ)≥r(v2*σ),
* or one of the special keys {@link #FILL_MIN_VALUE}, {@link #FILL_MAX_VALUE},
* {@link #FILL_NEAREST_VALUE}, which mean using of special calculation modes B, C, D.
* @return the "lazy" matrix containing the mean between 2 given values of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)
*/
Matrix extends PArray> asMeanBetweenValues(
Matrix extends PArray> src,
Matrix extends PArray> minValues,
Matrix extends PArray> maxValues,
Pattern pattern, double filler);
/**
* Returns a new updatable matrix, containing the mean between 2 values
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "mean between 2 values" term.
* The real numbers v1 and v2
* for every element of the result are equal to the corresponding elements of
* minValues
and maxValues
matrices.
* The reserved value filler and the mode of calculation (for the case
* r(v1*σ)≥r(v2*σ))
* are specified by the last filler
argument of this method:
*
* - if
filler
argument is {@link #FILL_MIN_VALUE} (Double.NEGATIVE_INFINITY
),
* the mode B is used;
* - if
filler
argument is {@link #FILL_MAX_VALUE} (Double.POSITIVE_INFINITY
),
* the mode C is used;
* - if
filler
argument is {@link #FILL_NEAREST_VALUE} (Double.NaN
),
* the mode D is used;
* - if
filler
argument contains any other value, the mode A is used and this argument specifies
* the reserved value filler.
*
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param src the source matrix.
* @param minValues the matrix containing v1 argument: the low bound
* of the averaged range of values for every element of the result.
* @param maxValues the matrix containing v2 argument: the high bound
* of the averaged range of values for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r(v1*σ)≥r(v2*σ),
* or one of the special keys {@link #FILL_MIN_VALUE}, {@link #FILL_MAX_VALUE},
* {@link #FILL_NEAREST_VALUE}, which mean using of special calculation modes B, C, D.
* @return the mean between 2 given values of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMeanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)
*/
Matrix extends UpdatablePArray> meanBetweenValues(
Matrix extends PArray> src,
Matrix extends PArray> minValues,
Matrix extends PArray> maxValues,
Pattern pattern, double filler);
/**
* Equivalent to {@link #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)} method, but the result matrix
* will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined in the comments to this class.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param minValues the matrix containing v1 argument: the low bound
* of the averaged range of values for every element of the result.
* @param maxValues the matrix containing v2 argument: the high bound
* of the averaged range of values for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param filler the reserved value, returned when
* r(v1*σ)≥r(v2*σ),
* or one of the special keys {@link #FILL_MIN_VALUE}, {@link #FILL_MAX_VALUE},
* {@link #FILL_NEAREST_VALUE}, which mean using of special calculation modes B, C, D.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMeanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)
* @see #meanBetweenValues(Matrix, Matrix, Matrix, Pattern, double)
*/
void meanBetweenValues(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
Matrix extends PArray> minValues,
Matrix extends PArray> maxValues,
Pattern pattern, double filler);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the mean
* of the source matrix by the specified pattern.
*
*
More precisely, this method is equivalent to
* {@link #asFunctionOfSum(Matrix, Pattern, Func) asFunctionOfSum}(src, pattern, meanFunc)
,
* where the function meanFunc
is:
*
* {@link net.algart.math.functions.LinearFunc#getInstance(double, double...)
* LinearFunc.getInstance}(0.0, 1.0/N)
3,
* N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the source matrix is floating-point (src.{@link Matrix#elementType() elementType()}
* is float
or double
) —
* in other words, this method calculates the usual mean of all elements in the aperture:
* (v0+v1+...+vN−1) /
* N;
*
* {@link net.algart.math.functions.LinearFunc#getInstance(double, double...)
* LinearFunc.getInstance}(0.5, 1.0/N)
,
* N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the source matrix is fixed-point (src.{@link Matrix#elementType() elementType()}
* is boolean
, char
, byte
, short
,
* int
or long
) —
* in other words, this method calculates the mean of all elements in the aperture plus 0.5:
* (v0+v1+...+vN−1) /
* N + 0.5.
*
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined above.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
The described rounding rule explains, why we add 0.5 to the mean in the case of a fixed-point source
* elements. Namely, in this case the combination of adding 0.5 and further truncation to the integer part
* works as rounding to the nearest integer:
* ⌊m+0.5⌋=Math.round(
m)
* (excepting some rare cases when the real mean m is a strictly half-integer:
* m=2k+½, k∈Z). In other words,
* this behaviour provides the maximal possible precision of the returned integer mean.
*
*
Note: the behaviour of this method is similar to
* {@link #asMeanBetweenPercentiles(Matrix, double, double, Pattern, double)
* asMeanBetweenPercentiles}(src, 0, N, pattern, anyFiller)
,
* where N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the histogram is processed in the simple histogram model (see
* {@link SummingHistogram comments to SummingHistogram class}).
* Really, in this case the mean between 2 percentiles is equal to
*
*
(S(r2)−S(r1)) /
* ((r2−r1)*σ) = S(N) / (N*σ) =
* (∑ 0≤j<M
* (j+0.5)*b[j])
* / (N*σ)
*
*
* In the simplest case, when the source elements are real numbers in the "standard" allowed range
* 0.0..1.0
,
* we have σ = M (the histogram length),
* ai = ⌊vi*M⌋,
* and this expression is equal to
*
*
* (∑ 0≤i<N
* (ai+0.5))
* / (NM) =
* (v'0+v'1+...+v'N−1) / N
* + 0.5 / M ≈
* (v0+v1+...+vN−1) / N
*
*
* where v'i = ai/M is an attempt
* to represent the real number vi with the given precision μ=log2M bits
* and a correction 0.5/M is very little for large M.
*
*
In another simplest case, when the source elements are integer numbers, σ=1 and
* the elements vi are non-negative integers,
* we have ai = vi, and this expression is equal to
*
*
* (∑ 0≤i<N
* (vi+0.5)) / N =
* (v0+v1+...+vN−1) / N + 0.5
*
*
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @return the "lazy" matrix containing the mean of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #mean(Matrix, Pattern)
* @see #mean(Matrix, Matrix, Pattern)
*/
Matrix extends PArray> asMean(Matrix extends PArray> src, Pattern pattern);
/**
* Returns a new updatable matrix, containing the mean
* of the source matrix by the specified pattern.
*
* More precisely, this method is equivalent to
* {@link #functionOfSum(Matrix, Pattern, Func) functionOfSum}(src, pattern, meanFunc)
,
* where the function meanFunc
is:
*
* {@link net.algart.math.functions.LinearFunc#getInstance(double, double...)
* LinearFunc.getInstance}(0.0, 1.0/N)
,
* N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the source matrix is floating-point (src.{@link Matrix#elementType() elementType()}
* is float
or double
) —
* in other words, this method calculates the usual mean of all elements in the aperture:
* (v0+v1+...+vN−1) /
* N;
*
* {@link net.algart.math.functions.LinearFunc#getInstance(double, double...)
* LinearFunc.getInstance}(0.5, 1.0/N)
,
* N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the source matrix is fixed-point (src.{@link Matrix#elementType() elementType()}
* is boolean
, char
, byte
, short
,
* int
or long
) —
* in other words, this method calculates the mean of all elements in the aperture plus 0.5:
* (v0+v1+...+vN−1) /
* N + 0.5.
*
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined above.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
The described rounding rule explains, why we add 0.5 to the mean in the case of a fixed-point source
* elements. Namely, in this case the combination of adding 0.5 and further truncation to the integer part
* works as rounding to the nearest integer:
* ⌊m+0.5⌋=Math.round(
m)
* (excepting some rare cases when the real mean m is a strictly half-integer:
* m=2k+½, k∈Z). In other words,
* this behaviour provides the maximal possible precision of the returned integer mean.
*
*
Note: the behaviour of this method is similar to
* {@link #meanBetweenPercentiles(Matrix, double, double, Pattern, double)
* meanBetweenPercentiles}(src, 0, N, pattern, anyFiller)
,
* where N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the histogram is processed in the simple histogram model (see
* {@link SummingHistogram comments to SummingHistogram class}).
* Really, in this case the mean between 2 percentiles is equal to
*
*
(S(r2)−S(r1)) /
* ((r2−r1)*σ) = S(N) / (N*σ) =
* (∑ 0≤j<M
* (j+0.5)*b[j])
* / (N*σ)
*
*
* In the simplest case, when the source elements are real numbers in the "standard" allowed range
* 0.0..1.0
,
* we have σ = M (the histogram length),
* ai = ⌊vi*M⌋,
* and this expression is equal to
*
*
* (∑ 0≤i<N
* (ai+0.5)) / (NM) =
* (v'0+v'1+...+v'N−1) / N
* + 0.5 / M ≈
* (v0+v1+...+vN−1) / N
*
*
* where v'i = ai/M is an attempt
* to represent the real number vi with the given precision μ=log2M bits
* and a correction 0.5/M is very little for large M.
*
*
In another simplest case, when the source elements are integer numbers, σ=1 and
* the elements vi are non-negative integers,
* we have ai = vi, and this expression is equal to
*
*
* (∑ 0≤i<N
* (vi+0.5)) / N =
* (v0+v1+...+vN−1) / N + 0.5
*
*
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @return the mean of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMean(Matrix, Pattern)
* @see #mean(Matrix, Matrix, Pattern)
*/
Matrix extends UpdatablePArray> mean(Matrix extends PArray> src, Pattern pattern);
/**
* Equivalent to {@link #mean(Matrix, Pattern)} method,
* but the result matrix will be placed in the dest
argument.
*
* If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real mean, defined above.
* In this case, the found mean value m is usually truncated to its integer part
* ⌊m⌋=(long)
m
* (remember that the mean value, according to our definition, is always ≥0).
* More precisely, the rules of casting the floating-point means to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
The described rounding rule explains, why we add 0.5 to the mean in the case of a fixed-point source
* elements. Namely, in this case the combination of adding 0.5 and further truncation to the integer part
* works as rounding to the nearest integer:
* ⌊m+0.5⌋=Math.round(
m)
* (excepting some rare cases when the real mean m is a strictly half-integer:
* m=2k+½, k∈Z). In other words,
* this behaviour provides the maximal possible precision of the returned integer mean.
*
*
Note: the behaviour of this method is similar to
* {@link #meanBetweenPercentiles(Matrix, Matrix, double, double, Pattern, double)
* meanBetweenPercentiles}(src, 0, N, pattern, anyFiller)
,
* where N = pattern.{@link Pattern#pointCount() pointCount()}
,
* if the histogram is processed in the simple histogram model (see
* {@link SummingHistogram comments to SummingHistogram class}).
* Really, in this case the mean between 2 percentiles is equal to
*
*
(S(r2)−S(r1)) /
* ((r2−r1)*σ) = S(N) / (N*σ) =
* (∑ 0≤j<M
* (j+0.5)*b[j])
* / (N*σ)
*
*
* In the simplest case, when the source elements are real numbers in the "standard" allowed range
* 0.0..1.0
,
* we have σ = M (the histogram length),
* ai = ⌊vi*M⌋,
* and this expression is equal to
*
*
* (∑ 0≤i<N
* (ai+0.5)) / (NM) =
* (v'0+v'1+...+v'N−1) / N
* + 0.5 / M ≈
* (v0+v1+...+vN−1) / N
*
*
* where v'i = ai/M is an attempt
* to represent the real number vi with the given precision μ=log2M bits
* and a correction 0.5/M is very little for large M.
*
*
In another simplest case, when the source elements are integer numbers, σ=1 and
* the elements vi are non-negative integers,
* we have ai = vi, and this expression is equal to
*
*
* (∑ 0≤i<N
* (vi+0.5)) / N =
* (v0+v1+...+vN−1) / N + 0.5
*
*
* @param dest the target matrix.
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asMean(Matrix, Pattern)
* @see #mean(Matrix, Pattern)
*/
void mean(Matrix extends UpdatablePArray> dest, Matrix extends PArray> src, Pattern pattern);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the result of some given function
* f(S) of the aperture sum S
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "aperture sum" term.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
* The function, applied to each calculated aperture sum S, is specified via
* processingFunc
argument. Namely, for each aperture position this method
* calculates the aperture sum S of the source matrix and returns
* processingFunc.{@link Func#get(double) get}(
S)
* in the corresponding element of the resulting matrix.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
This method can be considered as a generalization of {@link #asMean(Matrix, Pattern)}.
*
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated aperture sum.
* @return the "lazy" matrix containing the result of the given function for
* the aperture sum of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #functionOfSum(Matrix, Pattern, Func)
* @see #functionOfSum(Matrix, Matrix, Pattern, Func)
*/
Matrix extends PArray> asFunctionOfSum(
Matrix extends PArray> src,
Pattern pattern,
Func processingFunc);
/**
* Returns a new updatable matrix, containing the result of some given function
* f(S) of the aperture sum S
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the
* "aperture sum" term.
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
The function, applied to each calculated aperture sum S, is specified via
* processingFunc
argument. Namely, for each aperture position this method
* calculates the aperture sum S of the source matrix and returns
* processingFunc.{@link Func#get(double) get}(
S)
* in the corresponding element of the resulting matrix.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
This method can be considered as a generalization of {@link #mean(Matrix, Pattern)}.
*
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated aperture sum.
* @return the result of the given function for the aperture sum of the source matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asFunctionOfSum(Matrix, Pattern, Func)
* @see #functionOfSum(Matrix, Matrix, Pattern, Func)
*/
Matrix extends UpdatablePArray> functionOfSum(
Matrix extends PArray> src,
Pattern pattern, Func processingFunc);
/**
* Equivalent to {@link #functionOfSum(Matrix, Pattern, Func)} method,
* but the result matrix will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
This method can be considered as a generalization of {@link #mean(Matrix, Matrix, Pattern)}.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated aperture sum.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asFunctionOfSum(Matrix, Pattern, Func)
* @see #functionOfSum(Matrix, Pattern, Func)
*/
void functionOfSum(
Matrix extends UpdatablePArray> dest,
Matrix extends PArray> src,
Pattern pattern,
Func processingFunc);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the result of some given function
* f(v, v1,v2) of the source matrix v
* and two percentiles v1,v2
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real indexes r of two percentiles for every element of the result are equal
* to the corresponding elements of percentileIndexes1
(for v1)
* or percentileIndexes2
matrix (for v2).
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
The function, applied to each calculated three
* (v,v1,v2), is specified via
* processingFunc
argument. Namely, for each aperture position x this method takes
* the value v — the element of the source matrix src
at this aperture position x,
* calculates two percentiles v1 and v2 of the source matrix and returns
* processingFunc.{@link Func#get(double, double, double)
* get}(
v,v1,v2)
* in the corresponding element of the resulting matrix.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
You can get the same results by 2 calls of {@link #asPercentile(Matrix, Matrix, Pattern)} method
* for both matrices of percentile indexes and applying the function to them and to the source matrix via
* {@link Matrices#asFuncMatrix(Func, Class, Matrix, Matrix, Matrix)} method.
* But such a way works slower and is less convenient, than this method. A typical application of this method
* in image processing area is the contrasting image — in this case, we recommend using
* {@link net.algart.math.functions.ContrastingFunc ContrastingFunc} object as processingFunc
argument.
*
* @param src the source matrix.
* @param percentileIndexes1 the 1st matrix containing r argument: the indexes of the 1st percentile
* v1 for every element of the result.
* @param percentileIndexes2 the 2nd matrix containing r argument: the indexes of the 2nd percentile
* v2 for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @return the "lazy" matrix containing the result of the given function.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asFunctionOfPercentilePair(Matrix, double, double, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func)
*/
Matrix extends PArray> asFunctionOfPercentilePair(
Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes1,
Matrix extends PArray> percentileIndexes2,
Pattern pattern,
Func processingFunc);
/**
* Returns an immutable view of the passed source matrix,
* such that any reading data from it calculates and returns the result of some given function
* f(v, v1,v2) of the source matrix v
* and two percentiles v1,v2
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real indexes r of two percentiles for every element of the result are equal
* to percentileIndex1
(for v1)
* or percentileIndex2
argument (for v2).
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
This method is equivalent to
*
*
{@link #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func) asFunctionOfPercentilePair}(src,
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex1),
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex1),
* pattern, processingFunc)
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
You can get the same results by 2 calls of {@link #asPercentile(Matrix, double, Pattern)} method
* for both matrices of percentile indexes and applying the function to them and to the source matrix via
* {@link Matrices#asFuncMatrix(Func, Class, Matrix, Matrix, Matrix)} method.
* But such a way works slower and is less convenient, than this method. A typical application of this method
* in image processing area is the contrasting image — in this case, we recommend using
* {@link net.algart.math.functions.ContrastingFunc ContrastingFunc} object
* as processingFunc
argument.
*
* @param src the source matrix.
* @param percentileIndex1 the 1st r argument: the index of the 1st percentile v1.
* @param percentileIndex2 the 2nd r argument: the index of the 2nd percentile v2.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @return the "lazy" matrix containing the result of the given function.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, double, double, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, double, double, Pattern, Func)
*/
Matrix extends PArray> asFunctionOfPercentilePair(
Matrix extends PArray> src,
double percentileIndex1,
double percentileIndex2,
Pattern pattern,
Func processingFunc);
/**
* Returns a new updatable matrix, containing the result of some given function
* f(v, v1,v2) of the source matrix v
* and two percentiles v1,v2
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real indexes r of two percentiles for every element of the result are equal
* to the corresponding elements of percentileIndexes1
(for v1)
* or percentileIndexes2
matrix (for v2).
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
The function, applied to each calculated three
* (v,v1,v2), is specified via
* processingFunc
argument. Namely, for each aperture position x this method takes
* the value v — the element of the source matrix src
at this aperture position x,
* calculates two percentiles v1 and v2 of the source matrix and returns
* processingFunc.{@link Func#get(double, double, double)
* get}(
v,v1,v2)
* in the corresponding element of the resulting matrix.
*
*
If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
You can get the same results by 2 calls of {@link #percentile(Matrix, Matrix, Pattern)} method
* for both matrices of percentile indexes and applying the function to them and to the source matrix via
* {@link Matrices#asFuncMatrix(Func, Class, Matrix, Matrix, Matrix)} method.
* But such a way works slower and is less convenient, than this method. A typical application of this method
* in image processing area is the contrasting image — in this case, we recommend using
* {@link net.algart.math.functions.ContrastingFunc ContrastingFunc} object as processingFunc
argument.
*
* @param src the source matrix.
* @param percentileIndexes1 the 1st matrix containing r argument: the indexes of the 1st percentile
* v1 for every element of the result.
* @param percentileIndexes2 the 2nd matrix containing r argument: the indexes of the 2nd percentile
* v2 for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @return the result of the given function.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #functionOfPercentilePair(Matrix, double, double, Pattern, Func)
* @see #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func)
*/
Matrix extends UpdatablePArray> functionOfPercentilePair(
Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes1,
Matrix extends PArray> percentileIndexes2,
Pattern pattern,
Func processingFunc);
/**
* Returns a new updatable matrix, containing the result of some given function
* f(v, v1,v2) of the source matrix v
* and two percentiles v1,v2
* of the source matrix by the specified pattern.
* See the {@link RankMorphology comments to this class}, section 4 about the "percentile" term.
* The real indexes r of two percentiles for every element of the result are equal
* to percentileIndex1
(for v1)
* or percentileIndex2
argument (for v2).
* The {@link Matrix#elementType() element type}
* of the created matrix is the same as the element type of the source one.
*
*
This method is equivalent to
*
*
{@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func) functionOfPercentilePair}(src,
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex1),
* src.matrix({@link Arrays#nDoubleCopies(long, double)
* Arrays.nDoubleCopies}(src.size(), percentileIndex1),
* pattern, processingFunc)
*
* If the element type of the source matrix (and, thus, of the result) is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
*
You can get the same results by 2 calls of {@link #percentile(Matrix, double, Pattern)} method
* for both matrices of percentile indexes and applying the function to them and to the source matrix via
* {@link Matrices#asFuncMatrix(Func, Class, Matrix, Matrix, Matrix)} method.
* But such a way works slower and is less convenient, than this method. A typical application of this method
* in image processing area is the contrasting image — in this case, we recommend using
* {@link net.algart.math.functions.ContrastingFunc ContrastingFunc} object as processingFunc
argument.
*
* @param src the source matrix.
* @param percentileIndex1 the 1st r argument: the index of the 1st percentile v1.
* @param percentileIndex2 the 2nd r argument: the index of the 2nd percentile v2.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @return the result of the given function.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
* @see #asFunctionOfPercentilePair(Matrix, double, double, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, double, double, Pattern, Func)
*/
Matrix extends UpdatablePArray> functionOfPercentilePair(
Matrix extends PArray> src,
double percentileIndex1,
double percentileIndex2,
Pattern pattern,
Func processingFunc);
/**
* Equivalent to {@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)} method,
* but the result matrix will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param percentileIndexes1 the 1st matrix containing r argument: the indexes of the 1st percentile
* v1 for every element of the result.
* @param percentileIndexes2 the 2nd matrix containing r argument: the indexes of the 2nd percentile
* v2 for every element of the result.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #functionOfPercentilePair(Matrix, Matrix, double, double, Pattern, Func)
* @see #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
*/
void functionOfPercentilePair(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
Matrix extends PArray> percentileIndexes1,
Matrix extends PArray> percentileIndexes2,
Pattern pattern,
Func processingFunc);
/**
* Equivalent to {@link #functionOfPercentilePair(Matrix, double, double, Pattern, Func)} method,
* but the result matrix will be placed in the dest
argument.
*
*
If the element type of dest
matrix is fixed-point —
* boolean
, char
, byte
, short
,
* int
or long
—
* then we need to round the real function result.
* In this case, the found function result f is usually truncated to its integer part
* (long)
f.
* More precisely, the rules of casting the floating-point function results to the desired element type
* are the same as in {@link Arrays#asFuncArray(boolean, Func, Class, PArray...)}
* method with the argument truncateOverflows=true
.
*
* @param dest the target matrix.
* @param src the source matrix.
* @param percentileIndex1 the 1st r argument: the index of the 1st percentile v1.
* @param percentileIndex2 the 2nd r argument: the index of the 2nd percentile v2.
* @param pattern the pattern: the shape of the aperture.
* @param processingFunc the function, which should be applied to every calculated three
* (v,v1,v2),
* where v is the element of the source matrix,
* v1 and v2 are the corresponding percentiles.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws SizeMismatchException if the passed matrices have different dimensions.
* @throws IllegalArgumentException if the number of the pattern dimensions
* pattern.{@link Pattern#dimCount() dimCount()}
is not equal
* to src.{@link Matrix#dimCount() dimCount()}
.
* @see #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func)
* @see #asFunctionOfPercentilePair(Matrix, double, double, Pattern, Func)
* @see #functionOfPercentilePair(Matrix, double, double, Pattern, Func)
*/
void functionOfPercentilePair(
Matrix extends UpdatablePArray> dest, Matrix extends PArray> src,
double percentileIndex1,
double percentileIndex2,
Pattern pattern,
Func processingFunc);
}