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

net.algart.matrices.morphology.AbstractRankMorphology 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.functions.LinearFunc;
import net.algart.math.patterns.Pattern;

import java.util.Objects;

/**
 * 

A skeletal implementation of the {@link RankMorphology} interface to minimize * the effort required to implement this interface.

* *

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.

* *

Among methods of {@link RankMorphology} interface, this class implements the 2nd method * from each triplet: 1) asOperation, 2) operation, creating new matrix and * 3) operation, storing result in the 1st dest 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 dest * argument to the 3rd method. See more details in comments to the methods of this class.

* *

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 dest 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 double * parameters: these methods are implemented via the analogous methods getting the percentile indexes in * {@link Matrix} parameters.

* *

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 double parameters.

* * @author Daniel Alievsky */ 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 asDilationOrErosion( Matrix src, Pattern pattern, boolean isDilation); @Override protected abstract Matrix dilationOrErosion( Matrix dest, Matrix src, Pattern pattern, boolean isDilation, boolean disableMemoryAllocation); // bad idea to inherit dilationOrErosion from AbstractMorphology: it is much better to call percentile public abstract Matrix asPercentile( Matrix src, Matrix percentileIndexes, Pattern pattern); /** * This implementation just calls * {@link #asPercentile(Matrix, Matrix, Pattern) asPercentile}(src,m,pattern), * where m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex). * * @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()}. */ public Matrix asPercentile( Matrix src, double percentileIndex, Pattern pattern) { Objects.requireNonNull(src, "Null src argument"); return asPercentile(src, constantPercentileMatrix(src, percentileIndex), pattern); } /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the percentile by the call * {@link #percentile(Matrix, Matrix, Matrix, Pattern) * percentile}(dest,src,percentileIndexes,pattern) * and returns dest 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 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()}. */ public Matrix percentile( Matrix src, Matrix percentileIndexes, Pattern pattern) { Objects.requireNonNull(pattern, "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 dest = memoryModel().newMatrix(UpdatablePArray.class, src); percentile(dest, src, percentileIndexes, pattern); return dest; } /** * This implementation just calls * {@link #percentile(Matrix, Matrix, Pattern) percentile}(src,m,pattern), * where m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex). * * @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()}. */ public Matrix percentile( Matrix src, double percentileIndex, Pattern pattern) { Objects.requireNonNull(src, "Null src argument"); return percentile(src, constantPercentileMatrix(src, percentileIndex), pattern); } public abstract void percentile( Matrix dest, Matrix src, Matrix percentileIndexes, Pattern pattern); /** * This implementation just calls * {@link #percentile(Matrix, Matrix, Matrix, Pattern) percentile}(dest,src,m,pattern), * where m={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex). * * @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()}. */ public void percentile( Matrix dest, Matrix src, double percentileIndex, Pattern pattern) { Objects.requireNonNull(src, "Null src argument"); percentile(dest, src, constantPercentileMatrix(src, percentileIndex), pattern); } public abstract Matrix asRank( Class requiredType, Matrix baseMatrix, Matrix rankedMatrix, Pattern pattern); /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Class, long...) * newMatrix}(UpdatablePArray.class,{@link Arrays#elementType(Class) * Arrays.elementType}(requiredType),baseMatrix.dimensions()), calculates the rank by the call * {@link #rank(Matrix, Matrix, Matrix, Pattern) * rank}(dest,baseMatrix,rankedMatrix,pattern) * and returns dest 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 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. */ public Matrix rank( Class requiredType, Matrix baseMatrix, Matrix rankedMatrix, Pattern pattern) { Objects.requireNonNull(pattern, "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 dest = memoryModel().newMatrix(UpdatablePArray.class, elementType, baseMatrix.dimensions()); rank(dest, baseMatrix, rankedMatrix, pattern); return dest.cast(requiredType); } public abstract void rank( Matrix dest, Matrix baseMatrix, Matrix rankedMatrix, Pattern pattern); public abstract Matrix asMeanBetweenPercentiles( Matrix src, Matrix fromPercentileIndexes, Matrix toPercentileIndexes, Pattern pattern, double filler); /** * This implementation just calls * {@link #asMeanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double) * asMeanBetweenPercentiles}(src,m1,m2,pattern,filler), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex). * * @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()}. */ public Matrix asMeanBetweenPercentiles( Matrix src, double fromPercentileIndex, double toPercentileIndex, Pattern pattern, double filler) { Objects.requireNonNull(src, "Null src argument"); return asMeanBetweenPercentiles(src, constantPercentileMatrix(src, fromPercentileIndex), constantPercentileMatrix(src, toPercentileIndex), pattern, filler); } /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the mean between 2 percentiles by the call * {@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double) * meanBetweenPercentiles}(dest,src,fromPercentileIndexes,toPercentileIndexes,pattern,filler) * and returns dest 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 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()}. */ public Matrix meanBetweenPercentiles( Matrix src, Matrix fromPercentileIndexes, Matrix toPercentileIndexes, Pattern pattern, double filler) { Objects.requireNonNull(pattern, "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 dest = memoryModel().newMatrix(UpdatablePArray.class, src); meanBetweenPercentiles(dest, src, fromPercentileIndexes, toPercentileIndexes, pattern, filler); return dest; } /** * This implementation just calls * {@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Pattern, double) * meanBetweenPercentiles}(src,m1,m2,pattern,filler), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex). * * @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()}. */ public Matrix meanBetweenPercentiles( Matrix src, double fromPercentileIndex, double toPercentileIndex, Pattern pattern, double filler) { Objects.requireNonNull(src, "Null src argument"); return meanBetweenPercentiles(src, constantPercentileMatrix(src, fromPercentileIndex), constantPercentileMatrix(src, toPercentileIndex), pattern, filler); } public abstract void meanBetweenPercentiles( Matrix dest, Matrix src, Matrix fromPercentileIndexes, Matrix toPercentileIndexes, Pattern pattern, double filler); /** * This implementation just calls * {@link #meanBetweenPercentiles(Matrix, Matrix, Matrix, Matrix, Pattern, double) * meanBetweenPercentiles}(dest,src,m1,m2,pattern,filler), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,fromPercentileIndex) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,toPercentileIndex). * * @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()}. */ public void meanBetweenPercentiles( Matrix dest, Matrix src, double fromPercentileIndex, double toPercentileIndex, Pattern pattern, double filler) { Objects.requireNonNull(src, "Null src argument"); meanBetweenPercentiles(dest, src, constantPercentileMatrix(src, fromPercentileIndex), constantPercentileMatrix(src, toPercentileIndex), pattern, filler); } public abstract Matrix asMeanBetweenValues( Matrix src, Matrix minValues, Matrix maxValues, Pattern pattern, double filler); /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the mean between 2 values by the call * {@link #meanBetweenValues(Matrix, Matrix, Matrix, Matrix, Pattern, double) * meanBetweenValues}(dest,src,minValues,maxValues,pattern,filler) * and returns dest 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 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()}. */ public Matrix meanBetweenValues( Matrix src, Matrix minValues, Matrix maxValues, Pattern pattern, double filler) { Objects.requireNonNull(pattern, "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 dest = memoryModel().newMatrix(UpdatablePArray.class, src); meanBetweenValues(dest, src, minValues, maxValues, pattern, filler); return dest; } public abstract void meanBetweenValues( Matrix dest, Matrix src, Matrix minValues, Matrix 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 {@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()}. */ public Matrix asMean(Matrix src, Pattern pattern) { Objects.requireNonNull(src, "Null src argument"); Objects.requireNonNull(pattern, "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 dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the mean by the call * {@link #mean(Matrix, Matrix, Pattern) * mean}(dest,src,pattern) * and returns dest 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 {@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()}. */ public Matrix mean(Matrix src, Pattern pattern) { Objects.requireNonNull(pattern, "Null pattern argument"); if (pattern.dimCount() != src.dimCount()) { throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch"); } Matrix 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 {@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()}. */ public void mean(Matrix dest, Matrix src, Pattern pattern) { Objects.requireNonNull(src, "Null src argument"); Objects.requireNonNull(pattern, "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 asFunctionOfSum( Matrix src, Pattern pattern, Func processingFunc); /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the function of aperture sum by the call * {@link #functionOfSum(Matrix, Matrix, Pattern, Func) * functionOfSum}(dest,src,pattern,processingFunc) * and returns dest 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 {@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()}. */ public Matrix functionOfSum( Matrix src, Pattern pattern, Func processingFunc) { Objects.requireNonNull(pattern, "Null pattern argument"); Objects.requireNonNull(processingFunc, "Null processingFunc argument"); if (pattern.dimCount() != src.dimCount()) { throw new IllegalArgumentException("Number of dimensions of the pattern and the matrix mismatch"); } Matrix dest = memoryModel().newMatrix(UpdatablePArray.class, src); functionOfSum(dest, src, pattern, processingFunc); return dest; } public abstract void functionOfSum( Matrix dest, Matrix src, Pattern pattern, Func processingFunc); public abstract Matrix asFunctionOfPercentilePair( Matrix src, Matrix percentileIndexes1, Matrix percentileIndexes2, Pattern pattern, Func processingFunc); /** * This implementation just calls * {@link #asFunctionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func) * asFunctionOfPercentilePair}(src,m1,m2,pattern,processingFunc), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2). * * @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()}. */ public Matrix asFunctionOfPercentilePair( Matrix src, double percentileIndex1, double percentileIndex2, Pattern pattern, Func processingFunc) { Objects.requireNonNull(src, "Null src argument"); return asFunctionOfPercentilePair(src, constantPercentileMatrix(src, percentileIndex1), constantPercentileMatrix(src, percentileIndex2), pattern, processingFunc); } /** * This implementation creates a new updatable matrix dest by the call * dest={@link #memoryModel() memoryModel}.{@link MemoryModel#newMatrix(Class, Matrix) * newMatrix}(UpdatablePArray.class,src), calculates the function of the source matrix * and 2 percentiles by the call * {@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func) * functionOfPercentilePair}(dest,src,percentileIndexes1,percentileIndexes2,pattern,processingFunc) * and returns dest 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 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()}. */ public Matrix functionOfPercentilePair( Matrix src, Matrix percentileIndexes1, Matrix percentileIndexes2, Pattern pattern, Func processingFunc) { Objects.requireNonNull(pattern, "Null pattern argument"); Objects.requireNonNull(processingFunc, "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 dest = memoryModel().newMatrix(UpdatablePArray.class, src); functionOfPercentilePair(dest, src, percentileIndexes1, percentileIndexes2, pattern, processingFunc); return dest; } /** * This implementation just calls * {@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Pattern, Func) * functionOfPercentilePair}(src,m1,m2,pattern,processingFunc), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2). * * @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()}. */ public Matrix functionOfPercentilePair( Matrix src, double percentileIndex1, double percentileIndex2, Pattern pattern, Func processingFunc) { Objects.requireNonNull(src, "Null src argument"); return functionOfPercentilePair(src, constantPercentileMatrix(src, percentileIndex1), constantPercentileMatrix(src, percentileIndex2), pattern, processingFunc); } public abstract void functionOfPercentilePair( Matrix dest, Matrix src, Matrix percentileIndexes1, Matrix percentileIndexes2, Pattern pattern, Func processingFunc); /** * This implementation just calls * {@link #functionOfPercentilePair(Matrix, Matrix, Matrix, Matrix, Pattern, Func) * functionOfPercentilePair}(dest,src,m1,m2,pattern,processingFunc), where * m1={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex1) * and m2={@link #constantPercentileMatrix constantPercentileMatrix}(src,percentileIndex2). * * @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()}. */ public void functionOfPercentilePair( Matrix dest, Matrix src, double percentileIndex1, double percentileIndex2, Pattern pattern, Func processingFunc) { Objects.requireNonNull(src, "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 src matrix, * backed by a constant array with the given value. * More precisely, returns src.{@link Matrix#matrix(Array) matrix}(const), * where *
    *
  • const = {@link Arrays#nLongCopies(long, long) * Arrays.nLongCopies}(src.size(), (long)percentileIndex), * if percentileIndex==(long)percentileIndex,
  • *
  • or const = {@link Arrays#nDoubleCopies(long, double) * Arrays.nDoubleCopies}(src.size(), percentileIndex) * in other case.
  • *
* * @param src some matrix. * @param percentileIndex some filler. * @return the constant matrix with the same dimensions, filled by percentileIndex. */ public static Matrix constantPercentileMatrix( Matrix src, double percentileIndex) { return src.matrix(percentileIndex == (long) percentileIndex ? Arrays.nLongCopies(src.size(), (long) percentileIndex) : Arrays.nDoubleCopies(src.size(), percentileIndex)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy