All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.algart.matrices.morphology.RankMorphology Maven / Gradle / Ivy

Go to download

Open-source Java libraries, supporting generalized smart arrays and matrices with elements of any types, including a wide set of 2D-, 3D- and multidimensional image processing and other algorithms, working with arrays and matrices.

There is a newer version: 1.4.23
Show newest version
/*
 * 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.

* *
    *
  1. 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 * xpi = (x0pi0, * x1pi1, ..., * xn−1pi,n−1) * for all piP ({@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 * xpi. *
     
  2. * *
  3. For every point x' = xpi 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≤xkpi,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 = xkpi,k. * In particular, it is true for all implementations offered by this package. * If the point x' = xpi lies outside the matrix * (x'k<0 or * x'kM.{@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. *
       
    • *
    *
  4. * *
  5. So, for every point x we have an aperture, consisting of * N=P.{@link Pattern#pointCount() pointCount()} "neighbour" points * xpi, * 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). *
     
  6. * *
  7. 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)) / * ((r2r1)*σ) * if r1<r2 or some reserved value filler * if r1r2, * 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: *
        *
      1. if any of these two conditions is not fulfilled, it is equal to some reserved value filler;
      2. *
      3. if any of these two conditions is not fulfilled, it is equal to v1;
      4. *
      5. if any of these two conditions is not fulfilled, it is equal to v2;
      6. *
      7. (most useful definition) *
          *
        1. if v1v2, it is equal to * (v1+v2)/2;
        2. *
        3. 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()});
        4. *
        5. 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()});
        6. *
        7. in other cases, it is equal to * (v1+v2)/2.
        8. *
        *
      8. *
      * 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 v1v2, * 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. *
  8. *
* *

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: *

    *
  1. if v1v2, the mean is considered to be equal to * (v1+v2)/2;
  2. *
  3. 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()});
  4. *
  5. 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()});
  6. *
  7. in other cases, * if r(v1*σ)=r(v2*σ), * the mean is considered to be equal to * (v1+v2)/2.
  8. *
*

* 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 asPercentile( Matrix src, Matrix 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 asPercentile( Matrix 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 percentile( Matrix src, Matrix 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 percentile( Matrix 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 dest, Matrix src, Matrix 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 dest, Matrix 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 requiredType, Matrix baseMatrix, Matrix 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 rank( Class requiredType, Matrix baseMatrix, Matrix 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 dest, Matrix baseMatrix, Matrix 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 * r1r2. * @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 asMeanBetweenPercentiles( Matrix src, Matrix fromPercentileIndexes, Matrix 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 * r1r2. * @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 asMeanBetweenPercentiles( Matrix 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 * r1r2. * @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 meanBetweenPercentiles( Matrix src, Matrix fromPercentileIndexes, Matrix 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 * r1r2. * @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 meanBetweenPercentiles( Matrix 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 * r1r2. * @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 dest, Matrix src, Matrix fromPercentileIndexes, Matrix 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 * r1r2. * @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 dest, Matrix 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 asMeanBetweenValues( Matrix src, Matrix minValues, Matrix 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 meanBetweenValues( Matrix src, Matrix minValues, Matrix 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 dest, Matrix src, Matrix minValues, Matrix 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+½, kZ). 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)) / * ((r2r1)*σ) = 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 asMean(Matrix 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+½, kZ). 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)) / * ((r2r1)*σ) = 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 mean(Matrix 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+½, kZ). 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)) / * ((r2r1)*σ) = 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 dest, Matrix 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 asFunctionOfSum( Matrix 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 functionOfSum( Matrix 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 dest, Matrix 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 asFunctionOfPercentilePair( Matrix src, Matrix percentileIndexes1, Matrix 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 asFunctionOfPercentilePair( Matrix 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 functionOfPercentilePair( Matrix src, Matrix percentileIndexes1, Matrix 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 functionOfPercentilePair( Matrix 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 dest, Matrix src, Matrix percentileIndexes1, Matrix 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 dest, Matrix src, double percentileIndex1, double percentileIndex2, Pattern pattern, Func processingFunc); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy