Package net.algart.matrices.morphology

Source Code of net.algart.matrices.morphology.AbstractRankMorphology

/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2014 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.functions.LinearFunc;
import net.algart.math.patterns.Pattern;

/**
* <p>A skeletal implementation of the {@link RankMorphology} interface to minimize
* the effort required to implement this interface.</p>
*
* <p>This class extends {@link AbstractMorphology} and inherits from it all implementations of
* {@link Morphology} methods, excepting {@link
* #dilationOrErosion(Matrix dest, Matrix src, Pattern pattern, boolean isDilation, boolean disableMemoryAllocation)
* dilationOrErosion}, which is declared here as abstract.</p>
*
* <p>Among methods of {@link RankMorphology} interface, this class implements the 2nd method
* from each triplet: 1) <i>asOperation</i>, 2) <i>operation</i>, creating new matrix and
* 3) <i>operation</i>, storing result in the 1st <tt>dest</tt> argument.
* Every 2nd method from such a triplet is implemented via the 3rd one:
* it creates the necessary resulting updatable matrix and pass it as <tt>dest</tt>
* argument to the 3rd method. See more details in comments to the methods of this class.</p>
*
* <p>In addition, this class fully implements all 3 methods
* {@link #asMean(Matrix, Pattern) asMean}, {@link #mean(Matrix, Pattern) mean} (creating new matrix) and
* {@link #mean(Matrix, Matrix, Pattern) mean} (storing result in <tt>dest</tt> argument) via
* the corresponding {@link #asFunctionOfSum(Matrix, Pattern, Func) asFunctionOfSum}
* and {@link #functionOfSum(Matrix, Matrix, Pattern, Func) functionOfSum} methods.
* Also this class fully implements the methods which get the percentile indexes in a form of <tt>double</tt>
* parameters: these methods are implemented via the analogous methods getting the percentile indexes in
* {@link Matrix} parameters.</p>
*
* <p>Besides implementing methods of {@link RankMorphology}, this class declares
* {@link #constantPercentileMatrix(Matrix, double)} method, convenient for implementing
* methods which get the percentile indexes in a form of <tt>double</tt> parameters.</p>
*
* <p>AlgART Laboratory 2007&ndash;2014</p>
*
* @author Daniel Alievsky
* @version 1.2
* @since JDK 1.5
*/
public abstract class AbstractRankMorphology extends AbstractMorphology implements RankMorphology {

    /**
     * Creates an instance of this class with the given context.
     *
     * @param context the context used by this instance for all operations.
     */
    protected AbstractRankMorphology(ArrayContext context) {
        super(context);
    }

    public RankMorphology context(ArrayContext newContext) {
        return (RankMorphology) super.context(newContext);
    }

    @Override
    protected abstract Matrix<? extends PArray> asDilationOrErosion(
        Matrix<? extends PArray> src, Pattern pattern, boolean isDilation);

    @Override
    protected abstract Matrix<? extends UpdatablePArray> dilationOrErosion(
        Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src, Pattern pattern, boolean isDilation,
        boolean disableMemoryAllocation);
    // bad idea to inherit dilationOrErosion from AbstractMorphology: it is much better to call percentile

    public abstract Matrix<? extends PArray> asPercentile(
        Matrix<? extends PArray> src, Matrix<? extends PArray> percentileIndexes, Pattern pattern);

    /**
     * This implementation just calls
     * <tt>{@link #asPercentile(Matrix, Matrix, Pattern) asPercentile}(src,m,pattern)</tt>,
     * where <nobr><tt>m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex)</tt></nobr>.
     *
     * @param src             the source matrix.
     * @param percentileIndex <i>r</i> 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 <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends PArray> asPercentile(Matrix<? extends PArray> src,
        double percentileIndex, Pattern pattern)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return asPercentile(src, constantPercentileMatrix(src, percentileIndex), pattern);
    }

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the percentile by the call
     * <nobr><tt>{@link #percentile(Matrix, Matrix, Matrix, Pattern)
     * percentile}(dest,src,percentileIndexes,pattern)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @param src               the source matrix.
     * @param percentileIndexes the matrix containing <i>r</i> 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 <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> percentile(
        Matrix<? extends PArray> src, Matrix<? extends PArray> percentileIndexes, Pattern pattern)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        Matrices.checkDimensionEquality(src, percentileIndexes);
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        percentile(dest, src, percentileIndexes, pattern);
        return dest;
    }

    /**
     * This implementation just calls
     * <tt>{@link #percentile(Matrix, Matrix, Pattern) percentile}(src,m,pattern)</tt>,
     * where <nobr><tt>m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex)</tt></nobr>.
     *
     * @param src             the source matrix.
     * @param percentileIndex <i>r</i> 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 <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> percentile(
        Matrix<? extends PArray> src, double percentileIndex, Pattern pattern)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return percentile(src, constantPercentileMatrix(src, percentileIndex), pattern);
    }

    public abstract void percentile(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        Matrix<? extends PArray> percentileIndexes, Pattern pattern);

    /**
     * This implementation just calls
     * <tt>{@link #percentile(Matrix, Matrix, Matrix, Pattern) percentile}(dest,src,m,pattern)</tt>,
     * where <nobr><tt>m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex)</tt></nobr>.
     *
     * @param dest            the target matrix.
     * @param src             the source matrix.
     * @param percentileIndex <i>r</i> argument of the percentile.
     * @param pattern         the pattern: the shape of the aperture.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public void percentile(Matrix<? extends UpdatablePArray> dest,
        Matrix<? extends PArray> src, double percentileIndex, Pattern pattern)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        percentile(dest, src, constantPercentileMatrix(src, percentileIndex), pattern);
    }

    public abstract  <T extends PArray> Matrix<T> asRank(Class<? extends T> requiredType,
        Matrix<? extends PArray> baseMatrix, Matrix<? extends PArray> rankedMatrix, Pattern pattern);

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Class, long...)
     * newMatrix}(UpdatablePArray.class,{@link Arrays#elementType(Class)
     * Arrays.elementType}(requiredType),baseMatrix.dimensions())</tt></nobr>, calculates the rank by the call
     * <nobr><tt>{@link #rank(Matrix, Matrix, Matrix, Pattern)
     * rank}(dest,baseMatrix,rankedMatrix,pattern)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @param requiredType the desired type of the built-in array in the returned matrix.
     * @param baseMatrix   the source matrix.
     * @param rankedMatrix the matrix containing <i>v</i> 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 <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>baseMatrix.{@link Matrix#dimCount() dimCount()}</tt>,
     *                                  or if <tt>requiredType</tt> is not one of classes
     *                                  <tt>{@link UpdatableBitArray}.class</tt> / <tt>{@link BitArray}.class</tt>,
     *                                  <tt>{@link UpdatableCharArray}.class</tt> / <tt>{@link CharArray}.class</tt>,
     *                                  <tt>{@link UpdatableByteArray}.class</tt> / <tt>{@link ByteArray}.class</tt>,
     *                                  <tt>{@link UpdatableShortArray}.class</tt> / <tt>{@link ShortArray}.class</tt>,
     *                                  <tt>{@link UpdatableIntArray}.class</tt> / <tt>{@link IntArray}.class</tt>,
     *                                  <tt>{@link UpdatableLongArray}.class</tt> / <tt>{@link LongArray}.class</tt>,
     *                                  <tt>{@link UpdatableFloatArray}.class</tt> / <tt>{@link FloatArray}.class</tt>
     *                                  or <tt>{@link UpdatableDoubleArray}.class</tt> /
     *                                  <tt>{@link DoubleArray}.class</tt>.
     */
    public <T extends PArray> Matrix<? extends T> rank(Class<? extends T> requiredType,
        Matrix<? extends PArray> baseMatrix, Matrix<? extends PArray> rankedMatrix, Pattern pattern)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        Matrices.checkDimensionEquality(baseMatrix, rankedMatrix);
        if (pattern.dimCount() != baseMatrix.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Class<?> elementType = Arrays.elementType(requiredType);
        Matrices.checkNewMatrixType(requiredType, elementType);
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class,
            elementType, baseMatrix.dimensions());
        rank(dest, baseMatrix, rankedMatrix, pattern);
        return dest.cast(requiredType);
    }

    public abstract void rank(Matrix<? extends UpdatablePArray> dest,
        Matrix<? extends PArray> baseMatrix, Matrix<? extends PArray> rankedMatrix, Pattern pattern);

    public abstract Matrix<? extends PArray> asMeanBetweenPercentiles(Matrix<? extends PArray> src,
        Matrix<? extends PArray> fromPercentileIndexes,
        Matrix<? extends PArray> toPercentileIndexes,
        Pattern pattern, double filler);

    /**
     * This implementation just calls
     * <tt>{@link #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
     * asMeanBetweenPercentiles}(src,m1,m2,pattern,filler)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex)</tt></nobr>.
     *
     * @param src                 the source matrix.
     * @param fromPercentileIndex <i>r</i><sub>1</sub> argument: the index of
     *                            the less percentile of the averaged range for every element of the result.
     * @param toPercentileIndex   <i>r</i><sub>2</sub> 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
     *                            <nobr><i>r</i><sub>1</sub>&ge;<i>r</i><sub>2</sub></nobr>.
     * @return                    the "lazy" matrix containing the mean between 2 given percentiles
     *                            of the source matrix.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends PArray> asMeanBetweenPercentiles(
        Matrix<? extends PArray> src,
        double fromPercentileIndex,
        double toPercentileIndex,
        Pattern pattern, double filler)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return asMeanBetweenPercentiles(src,
            constantPercentileMatrix(src, fromPercentileIndex),
            constantPercentileMatrix(src, toPercentileIndex),
            pattern, filler);
    }

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the mean between 2 percentiles by the call
     * <nobr><tt>{@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double)
     * meanBetweenPercentiles}(dest,src,fromPercentileIndexes,toPercentileIndexes,pattern,filler)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @param src                   the source matrix.
     * @param fromPercentileIndexes the matrix containing <i>r</i><sub>1</sub> argument: the indexes of
     *                              the less percentile of the averaged range for every element of the result.
     * @param toPercentileIndexes   the matrix containing <i>r</i><sub>2</sub> 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
     *                              <nobr><i>r</i><sub>1</sub>&ge;<i>r</i><sub>2</sub></nobr>.
     * @return                      the mean between 2 given percentiles of the source matrix.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> meanBetweenPercentiles(Matrix<? extends PArray> src,
        Matrix<? extends PArray> fromPercentileIndexes,
        Matrix<? extends PArray> toPercentileIndexes,
        Pattern pattern, double filler)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        Matrices.checkDimensionEquality(src, fromPercentileIndexes, toPercentileIndexes);
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        meanBetweenPercentiles(dest, src, fromPercentileIndexes, toPercentileIndexes, pattern, filler);
        return dest;
    }

    /**
     * This implementation just calls
     * <tt>{@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double)
     * meanBetweenPercentiles}(src,m1,m2,pattern,filler)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex)</tt></nobr>.
     *
     * @param src                 the source matrix.
     * @param fromPercentileIndex <i>r</i><sub>1</sub> argument: the index of
     *                            the less percentile of the averaged range for every element of the result.
     * @param toPercentileIndex   <i>r</i><sub>2</sub> 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
     *                            <nobr><i>r</i><sub>1</sub>&ge;<i>r</i><sub>2</sub></nobr>.
     * @return                    the mean between 2 given percentiles of the source matrix.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> meanBetweenPercentiles(Matrix<? extends PArray> src,
        double fromPercentileIndex,
        double toPercentileIndex,
        Pattern pattern, double filler)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return meanBetweenPercentiles(src,
            constantPercentileMatrix(src, fromPercentileIndex),
            constantPercentileMatrix(src, toPercentileIndex),
            pattern, filler);
    }

    public abstract void meanBetweenPercentiles(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        Matrix<? extends PArray> fromPercentileIndexes,
        Matrix<? extends PArray> toPercentileIndexes,
        Pattern pattern, double filler);

    /**
     * This implementation just calls
     * <tt>{@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double)
     * meanBetweenPercentiles}(dest,src,m1,m2,pattern,filler)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex)</tt></nobr>.
     *
     * @param dest                the target matrix.
     * @param src                 the source matrix.
     * @param fromPercentileIndex <i>r</i><sub>1</sub> argument: the index of
     *                            the less percentile of the averaged range for every element of the result.
     * @param toPercentileIndex   <i>r</i><sub>2</sub> 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
     *                            <nobr><i>r</i><sub>1</sub>&ge;<i>r</i><sub>2</sub></nobr>.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public void meanBetweenPercentiles(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        double fromPercentileIndex,
        double toPercentileIndex,
        Pattern pattern, double filler)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        meanBetweenPercentiles(dest, src,
            constantPercentileMatrix(src, fromPercentileIndex),
            constantPercentileMatrix(src, toPercentileIndex),
            pattern, filler);
    }

    public abstract Matrix<? extends PArray> asMeanBetweenValues(Matrix<? extends PArray> src,
        Matrix<? extends PArray> minValues,
        Matrix<? extends PArray> maxValues,
        Pattern pattern, double filler);

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the mean between 2 values by the call
     * <nobr><tt>{@link #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double)
     * meanBetweenValues}(dest,src,minValues,maxValues,pattern,filler)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @param src       the source matrix.
     * @param minValues the matrix containing <i>v</i><sub>1</sub> argument: the low bound
     *                  of the averaged range of values for every element of the result.
     * @param maxValues the matrix containing <i>v</i><sub>2</sub> 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
     *                  <nobr><i>r</i>(<i>v</i><sub>1</sub>*&sigma;)&ge;<i>r</i>(<i>v</i><sub>2</sub>*&sigma;)</nobr>,
     *                  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 <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> meanBetweenValues(Matrix<? extends PArray> src,
        Matrix<? extends PArray> minValues,
        Matrix<? extends PArray> maxValues,
        Pattern pattern, double filler)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        Matrices.checkDimensionEquality(src, minValues, maxValues);
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        meanBetweenValues(dest, src, minValues, maxValues, pattern, filler);
        return dest;
    }

    public abstract void meanBetweenValues(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        Matrix<? extends PArray> minValues,
        Matrix<? extends PArray> maxValues,
        Pattern pattern, double filler);

    /**
     * This method is fully implemented in this class via the equivalent call of
     * {@link #asFunctionOfSum(Matrix, Pattern, Func)} method, as described in
     * {@link RankMorphology#asMean(Matrix, Pattern) comments to this method} in {@link RankMorphology} interface.
     *
     * @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 <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends PArray> asMean(Matrix<? extends PArray> src, Pattern pattern) {
        if (src == null)
            throw new NullPointerException("Null src argument");
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Func processingFunc = LinearFunc.getInstance(
            PFloatingArray.class.isAssignableFrom(src.type()) ? 0.0 : 0.5,
            1.0 / pattern.pointCount());
        return asFunctionOfSum(src, pattern, processingFunc);
    }

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the mean by the call
     * <nobr><tt>{@link #mean(Matrix, Matrix, Pattern)
     * mean}(dest,src,pattern)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @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 <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> mean(Matrix<? extends PArray> src, Pattern pattern) {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        mean(dest, src, pattern);
        return dest;
    }

    /**
     * This method is fully implemented in this class via the equivalent call of
     * {@link #functionOfSum(Matrix, Matrix, Pattern, Func)} method, as described in
     * {@link RankMorphology#mean(Matrix, Matrix, Pattern) comments to this method}
     * in {@link RankMorphology} interface.
     *
     * @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 <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public void mean(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src, Pattern pattern) {
        if (src == null)
            throw new NullPointerException("Null src argument");
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Func processingFunc = LinearFunc.getInstance(
            PFloatingArray.class.isAssignableFrom(src.type()) ? 0.0 : 0.5,
            1.0 / pattern.pointCount());
        functionOfSum(dest, src, pattern, processingFunc);
    }


    public abstract Matrix<? extends PArray> asFunctionOfSum(Matrix<? extends PArray> src,
        Pattern pattern, Func processingFunc);

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the function of aperture sum by the call
     * <nobr><tt>{@link #functionOfSum(Matrix, Matrix, Pattern, Func)
     * functionOfSum}(dest,src,pattern,processingFunc)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new 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.
     * @return                      the result of the given function for the aperture sum of the source matrix.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> functionOfSum(Matrix<? extends PArray> src,
        Pattern pattern, Func processingFunc)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        if (processingFunc == null)
            throw new NullPointerException("Null processingFunc argument");
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        functionOfSum(dest, src, pattern, processingFunc);
        return dest;
    }

    public abstract void  functionOfSum(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        Pattern pattern, Func processingFunc);

    public abstract Matrix<? extends PArray> asFunctionOfPercentilePair(Matrix<? extends PArray> src,
        Matrix<? extends PArray> percentileIndexes1,
        Matrix<? extends PArray> percentileIndexes2,
        Pattern pattern, Func processingFunc);

    /**
     * This implementation just calls
     * <tt>{@link #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
     * asFunctionOfPercentilePair}(src,m1,m2,pattern,processingFunc)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2)</tt></nobr>.
     *
     * @param src              the source matrix.
     * @param percentileIndex1 the 1st <i>r</i> argument: the index of the 1st percentile <i>v</i><sub>1</sub>.
     * @param percentileIndex2 the 2nd <i>r</i> argument: the index of the 2nd percentile <i>v</i><sub>2</sub>.
     * @param pattern          the pattern: the shape of the aperture.
     * @param processingFunc   the function, which should be applied to every calculated three
     *                         <nobr>(<i>v</i>,<i>v</i><sub>1</sub>,<i>v</i><sub>2</sub>)</nobr>,
     *                         where <i>v</i> is the element of the source matrix,
     *                         <i>v</i><sub>1</sub> and <i>v</i><sub>2</sub> are the corresponding percentiles.
     * @return                 the "lazy" matrix containing the result of the given function.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends PArray> asFunctionOfPercentilePair(
        Matrix<? extends PArray> src,
        double percentileIndex1,
        double percentileIndex2,
        Pattern pattern, Func processingFunc)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return asFunctionOfPercentilePair(src,
            constantPercentileMatrix(src, percentileIndex1),
            constantPercentileMatrix(src, percentileIndex2),
            pattern, processingFunc);
    }

    /**
     * This implementation creates a new updatable matrix <tt>dest</tt> by the call
     * <nobr><tt>dest={@link #memoryModel memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix)
     * newMatrix}(UpdatablePArray.class,src)</tt></nobr>, calculates the function of the source matrix
     * and 2 percentiles by the call
     * <nobr><tt>{@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func)
     * functionOfPercentilePair}(dest,src,percentileIndexes1,percentileIndexes2,pattern,processingFunc)</tt></nobr>
     * and returns <tt>dest</tt> as the result.
     * All necessary checks of correctness of the arguments are performed before allocating new matrix.
     *
     * @param src                the source matrix.
     * @param percentileIndexes1 the 1st matrix containing <i>r</i> argument: the indexes of the 1st percentile
     *                           <i>v</i><sub>1</sub> for every element of the result.
     * @param percentileIndexes2 the 2nd matrix containing <i>r</i> argument: the indexes of the 2nd percentile
     *                           <i>v</i><sub>2</sub> 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
     *                           <nobr>(<i>v</i>,<i>v</i><sub>1</sub>,<i>v</i><sub>2</sub>)</nobr>,
     *                           where <i>v</i> is the element of the source matrix,
     *                           <i>v</i><sub>1</sub> and <i>v</i><sub>2</sub> are the corresponding percentiles.
     * @return                   the result of the given function.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> functionOfPercentilePair(Matrix<? extends PArray> src,
        Matrix<? extends PArray> percentileIndexes1,
        Matrix<? extends PArray> percentileIndexes2,
        Pattern pattern, Func processingFunc)
    {
        if (pattern == null)
            throw new NullPointerException("Null pattern argument");
        if (processingFunc == null)
            throw new NullPointerException("Null processingFunc argument");
        Matrices.checkDimensionEquality(src, percentileIndexes1, percentileIndexes2);
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        Matrix<? extends UpdatablePArray> dest = memoryModel().newMatrix(UpdatablePArray.class, src);
        functionOfPercentilePair(dest, src, percentileIndexes1, percentileIndexes2,
            pattern, processingFunc);
        return dest;
    }

    /**
     * This implementation just calls
     * <tt>{@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func)
     * functionOfPercentilePair}(src,m1,m2,pattern,processingFunc)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2)</tt></nobr>.
     *
     * @param src              the source matrix.
     * @param percentileIndex1 the 1st <i>r</i> argument: the index of the 1st percentile <i>v</i><sub>1</sub>.
     * @param percentileIndex2 the 2nd <i>r</i> argument: the index of the 2nd percentile <i>v</i><sub>2</sub>.
     * @param pattern          the pattern: the shape of the aperture.
     * @param processingFunc   the function, which should be applied to every calculated three
     *                         <nobr>(<i>v</i>,<i>v</i><sub>1</sub>,<i>v</i><sub>2</sub>)</nobr>,
     *                         where <i>v</i> is the element of the source matrix,
     *                         <i>v</i><sub>1</sub> and <i>v</i><sub>2</sub> are the corresponding percentiles.
     * @return                 the result of the given function.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public Matrix<? extends UpdatablePArray> functionOfPercentilePair(Matrix<? extends PArray> src,
        double percentileIndex1,
        double percentileIndex2,
        Pattern pattern, Func processingFunc)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        return functionOfPercentilePair(src,
            constantPercentileMatrix(src, percentileIndex1),
            constantPercentileMatrix(src, percentileIndex2),
            pattern, processingFunc);
    }

    public abstract void functionOfPercentilePair(
        Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        Matrix<? extends PArray> percentileIndexes1,
        Matrix<? extends PArray> percentileIndexes2,
        Pattern pattern, Func processingFunc);

    /**
     * This implementation just calls
     * <tt>{@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func)
     * functionOfPercentilePair}(dest,src,m1,m2,pattern,processingFunc)</tt>, where
     * <nobr><tt>m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1)</tt></nobr>
     * and <nobr><tt>m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2)</tt></nobr>.
     *
     * @param dest             the target matrix.
     * @param src              the source matrix.
     * @param percentileIndex1 the 1st <i>r</i> argument: the index of the 1st percentile <i>v</i><sub>1</sub>.
     * @param percentileIndex2 the 2nd <i>r</i> argument: the index of the 2nd percentile <i>v</i><sub>2</sub>.
     * @param pattern          the pattern: the shape of the aperture.
     * @param processingFunc   the function, which should be applied to every calculated three
     *                         <nobr>(<i>v</i>,<i>v</i><sub>1</sub>,<i>v</i><sub>2</sub>)</nobr>,
     *                         where <i>v</i> is the element of the source matrix,
     *                         <i>v</i><sub>1</sub> and <i>v</i><sub>2</sub> are the corresponding percentiles.
     * @throws NullPointerException     if one of the arguments is <tt>null</tt>.
     * @throws SizeMismatchException    if the passed matrices have different dimensions.
     * @throws IllegalArgumentException if the number of the pattern dimensions
     *                                  <tt>pattern.{@link Pattern#dimCount() dimCount()}</tt> is not equal
     *                                  to <tt>src.{@link Matrix#dimCount() dimCount()}</tt>.
     */
    public void functionOfPercentilePair(Matrix<? extends UpdatablePArray> dest, Matrix<? extends PArray> src,
        double percentileIndex1,
        double percentileIndex2,
        Pattern pattern, Func processingFunc)
    {
        if (src == null)
            throw new NullPointerException("Null src argument");
        if (pattern.dimCount() != src.dimCount())
            throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch");
        functionOfPercentilePair(dest, src,
            constantPercentileMatrix(src, percentileIndex1),
            constantPercentileMatrix(src, percentileIndex2),
            pattern, processingFunc);
    }

    /**
     * Returns the matrix with the same dimensions as the given <tt>src</tt> matrix,
     * backed by a constant array with the given value.
     * More precisely, returns <nobr><tt>src.{@link Matrix#matrix(Array) matrix}(const)</tt></nobr>,
     * where
     * <ul>
     * <li><nobr><tt>const = {@link Arrays#nLongCopies(long, long)
     * Arrays.nLongCopies}(src.size(), (long)percentileIndex)</tt></nobr>,
     * if <nobr><tt>percentileIndex==(long)percentileIndex</tt></nobr>,</li>
     * <li>or <nobr><tt>const = {@link Arrays#nDoubleCopies(long, double)
     * Arrays.nDoubleCopies}(src.size(), percentileIndex)</tt></nobr>
     * in other case.</li>
     * </ul>
     *
     * @param src             some matrix.
     * @param percentileIndex some filler.
     * @return                the constant matrix with the same dimensions, filled by <tt>percentileIndex</tt>.
     */
    public static Matrix<? extends PArray> constantPercentileMatrix(Matrix<? extends PArray> src,
        double percentileIndex)
    {
        return src.matrix(percentileIndex == (long) percentileIndex ?
            Arrays.nLongCopies(src.size(), (long) percentileIndex) :
            Arrays.nDoubleCopies(src.size(), percentileIndex));
    }
}
TOP

Related Classes of net.algart.matrices.morphology.AbstractRankMorphology

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.