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

net.algart.multimatrix.NonZeroRangeCalculator Maven / Gradle / Ivy

Go to download

Open-source libraries, providing the base core functionality for SciChains product.

There is a newer version: 4.4.7
Show newest version
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2017-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.multimatrix;

import net.algart.arrays.*;
import net.algart.math.Range;

class NonZeroRangeCalculator extends Arrays.ParallelExecutor {
    private static final int BYTE_MIN = 0;
    private static final int BYTE_MAX = 0xFF;
    private static final int CHAR_MIN = 0;
    private static final int CHAR_MAX = 0xFFFF;
    private static final int SHORT_MIN = 0;
    private static final int SHORT_MAX = 0xFFFF;
    private static final int INT_MIN = Integer.MIN_VALUE;
    private static final int INT_MAX = Integer.MAX_VALUE;
    private static final long LONG_MIN = Long.MIN_VALUE;
    private static final long LONG_MAX = Long.MAX_VALUE;
    private static final float FLOAT_MIN = Float.NEGATIVE_INFINITY;
    private static final float FLOAT_MAX = Float.POSITIVE_INFINITY;
    private static final double DOUBLE_MIN = Double.NEGATIVE_INFINITY;
    private static final double DOUBLE_MAX = Double.POSITIVE_INFINITY;

    private final DataBuffer[] buffers;
    private final double[] threadMin;
    private final double[] threadMax;
    Range resultRange;

    public NonZeroRangeCalculator(ArrayContext context, PArray src) {
        super(context, null, src, 65536, 0, 0);
        this.buffers = new DataBuffer[numberOfTasks()];
        this.threadMin = new double[numberOfTasks()];
        this.threadMax = new double[numberOfTasks()];
        JArrays.fill(threadMin, Double.POSITIVE_INFINITY);
        JArrays.fill(threadMax, Double.NEGATIVE_INFINITY);
    }

    @Override
    public void process() {
        if (src.length() == 0) {
            resultRange = null;
        } else if (src instanceof BitArray) {
            if (((BitArray) src).indexOf(0, src.length(), true) == -1) {
                resultRange = null;
            } else {
                resultRange = Range.valueOf(1.0, 1.0);
            }
        } else {
            super.process();
        }
    }

    @Override
    protected void processSubArr(long position, int count, int threadIndex) {
        DataBuffer buf = buffers[threadIndex];
        if (buf == null) {
            buf = src.buffer(DataBuffer.AccessMode.READ, blockSize);
            buffers[threadIndex] = buf;
        }
        buf.map(position, count);
        long index = position;
        if (src instanceof BitArray) {
            throw new AssertionError("Illegal usage");
            //[[Repeat() int(\s(?:v|min)) ==> char$1,,int$1,,int$1,,long$1,,float$1,,double$1;;
            //           byte ==> char,,short,,int,,long,,float,,double;;
            //           Byte ==> Char,,Short,,Int,,Long,,Float,,Double;;
            //           BYTE ==> CHAR,,SHORT,,INT,,LONG,,FLOAT,,DOUBLE;;
            //          (\s+&\s+0xFF) ==> ,,$1FF,, ,, ,, ,, ]]
        } else if (src instanceof ByteArray) {
            int min = BYTE_MAX, max = BYTE_MIN;
            byte[] ja = (byte[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                int v = ja[k] & 0xFF;
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
            //[[Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! ]]
        } else if (src instanceof CharArray) {
            char min = CHAR_MAX, max = CHAR_MIN;
            char[] ja = (char[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                char v = ja[k];
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
        } else if (src instanceof ShortArray) {
            int min = SHORT_MAX, max = SHORT_MIN;
            short[] ja = (short[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                int v = ja[k] & 0xFFFF;
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
        } else if (src instanceof IntArray) {
            int min = INT_MAX, max = INT_MIN;
            int[] ja = (int[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                int v = ja[k];
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
        } else if (src instanceof LongArray) {
            long min = LONG_MAX, max = LONG_MIN;
            long[] ja = (long[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                long v = ja[k];
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
        } else if (src instanceof FloatArray) {
            float min = FLOAT_MAX, max = FLOAT_MIN;
            float[] ja = (float[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                float v = ja[k];
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
        } else if (src instanceof DoubleArray) {
            double min = DOUBLE_MAX, max = DOUBLE_MIN;
            double[] ja = (double[])buf.data();
            for (int k = buf.from(), kMax = buf.to(); k < kMax; k++, index++) {
                double v = ja[k];
                if (v != 0) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
            if (min < threadMin[threadIndex]) {
                threadMin[threadIndex] = min;
            }
            if (max > threadMax[threadIndex]) {
                threadMax[threadIndex] = max;
            }
            //[[Repeat.AutoGeneratedEnd]]
        } else {
            throw new AssertionError("Disallowed type of passed array: " + src.getClass());
        }
    }

    @Override
    protected synchronized void finish() {
        double min = Double.POSITIVE_INFINITY;
        double max = Double.NEGATIVE_INFINITY;
        for (int k = 0; k < threadMin.length; k++) {
            if (threadMin[k] < min) {
                min = threadMin[k];
            }
            if (threadMax[k] > max) {
                max = threadMax[k];
            }
            // - note: here and above all checks will be false for NaN
        }
        this.resultRange =  min <= max ? Range.valueOf(min, max) : null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy