net.algart.multimatrix.NonZeroRangeCalculator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scichains-core Show documentation
Show all versions of scichains-core Show documentation
Open-source libraries, providing the base core functionality for SciChains product.
/*
* 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;
}
}