add mod, fmod, floor_divide, divmod functions

This commit is contained in:
wyq 2021-07-14 11:04:15 +08:00
parent 7e51b40b2d
commit c34e46f2e9
21 changed files with 1136 additions and 61 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\bar">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\array">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\linalg"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
@ -10,23 +9,28 @@
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\grib"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\dataconvert"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\geotiff"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\bar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\cluster\dbscan_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\geotiff\geotif_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\bar\bar_hatch.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\mod.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\divide.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\toolbox\miml\cluster\dbscan_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\geotiff\geotif_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\bar\bar_hatch.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\array\mod.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\array\divide.py"/>
</RecentFiles>
</File>
<Font>
@ -34,5 +38,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,693"/>
<Startup MainFormLocation="-7,0" MainFormSize="1382,788"/>
</MeteoInfo>

View File

@ -1,6 +1,7 @@
"""Contains a collection of thermodynamic calculations."""
from .. import constants
from .tools import _remove_nans
import mipylib.numeric as np
__all__ = [

View File

@ -0,0 +1,19 @@
import mipylib.numeric as np
def _remove_nans(*variables):
"""Remove NaNs from arrays that cause issues with calculations.
Takes a variable number of arguments and returns masked arrays in the same
order as provided.
"""
mask = None
for v in variables:
if mask is None:
mask = np.isnan(v)
else:
mask |= np.isnan(v)
# Mask everyone with that joint mask
ret = []
for v in variables:
ret.append(v[~mask])
return ret

View File

@ -8,8 +8,11 @@ from . import fromnumeric
from fromnumeric import *
from . import _io
from _io import *
from . import umath
from umath import *
__all__ = ['NDArray','DimArray','PyTableData','dtype','dimension','normalize_axis_index']
__all__ += numeric.__all__
__all__ += fromnumeric.__all__
__all__ += umath.__all__
__all__ += _io.__all__

View File

@ -364,6 +364,40 @@ class NDArray(object):
raise ValueError('Dimension missmatch, can not broadcast!')
return NDArray(r)
def __floordiv__(self, other):
other = NDArray.__value_other(self, other)
r = ArrayMath.floorDiv(self._array, other)
if r is None:
raise ValueError('Dimension missmatch, can not broadcast!')
return NDArray(r)
def __rfloordiv__(self, other):
other = NDArray.__value_other(self, other)
r = ArrayMath.floorDiv(other, self._array)
if r is None:
raise ValueError('Dimension missmatch, can not broadcast!')
return NDArray(r)
def __mod__(self, other):
other = NDArray.__value_other(self, other)
r = ArrayMath.mod(self._array, other)
if r is None:
raise ValueError('Dimension missmatch, can not broadcast!')
return NDArray(r)
def __rmod__(self, other):
other = NDArray.__value_other(self, other)
r = ArrayMath.mod(other, self._array)
if r is None:
raise ValueError('Dimension missmatch, can not broadcast!')
return NDArray(r)
def __divmod__(self, other):
return self.__floordiv__(other), self.__mod__(other)
def __rdivmod__(self, other):
return self.__rfloordiv__(other), self.__rmod__(other)
def __pow__(self, other):
other = NDArray.__value_other(self, other)
r = ArrayMath.pow(self._array, other)

View File

@ -325,6 +325,30 @@ class DimArray(NDArray):
def __rdiv__(self, other):
r = super(DimArray, self).__rdiv__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __floordiv__(self, other):
r = super(DimArray, self).__floordiv__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __rfloordiv__(self, other):
r = super(DimArray, self).__rfloordiv__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __mod__(self, other):
r = super(DimArray, self).__mod__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __rmod__(self, other):
r = super(DimArray, self).__rmod__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __divmod__(self, other):
r = super(DimArray, self).__divmod__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __rdivmod__(self, other):
r = super(DimArray, self).__rdivmod__(other)
return DimArray(r, self.dims, self.fill_value, self.proj)
def __pow__(self, other):
r = super(DimArray, self).__pow__(other)

View File

@ -36,7 +36,7 @@ nan = Double.NaN
newaxis = None
__all__ = [
'pi','e','inf','nan','acos','abs','absolute','all','allclose','any','arange','arange1',
'pi','e','inf','nan','acos','abs','all','allclose','any','arange','arange1',
'argmin','argmax','array','array_split','asanyarray','asarray','asgridarray','asgriddata','asin',
'asmiarray','asstationdata','atleast_1d','atleast_2d','atan','atan2','ave_month','average','histogram',
'broadcast_to','cdiff','ceil','concatenate','corrcoef','cos','cumsum','degrees','delete','delnan','diag',
@ -115,7 +115,7 @@ def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
if a.ndim < ndmin:
shape = []
for i in range(ndmin - a.ndim):
for _ in range(ndmin - a.ndim):
shape.append(1)
shape.extend(a.shape)
a = a.reshape(shape)
@ -569,22 +569,6 @@ def rand(*args):
else:
return NDArray(ArrayUtil.rand(args))
def absolute(x):
'''
Calculate the absolute value element-wise.
:param x: (*array_like*) Input array.
:returns: An array containing the absolute value of each element in x.
For complex input, a + ib, the absolute value is \sqrt{ a^2 + b^2 }.
'''
if isinstance(x, list):
x = array(x)
if isinstance(x, NDArray):
return x.abs()
else:
return __builtin__.abs(x)
def abs(x):
"""
Calculate the absolute value element-wise.

View File

@ -0,0 +1,135 @@
"""
Universal math functions
"""
import __builtin__
from ._ndarray import NDArray
from .numeric import sign
__all__ = [
'absolute','add','divmod','floor_divide','fmod','mod','remainder'
]
def absolute(x):
'''
Calculate the absolute value element-wise.
:param x: (*array_like*) Input array.
:returns: An array containing the absolute value of each element in x.
For complex input, a + ib, the absolute value is \sqrt{ a^2 + b^2 }.
'''
if isinstance(x, list):
x = array(x)
if isinstance(x, NDArray):
return x.abs()
else:
return __builtin__.abs(x)
def add(x1, x2):
"""
Add arguments element-wise.
:param x1: (*array_like*) The array to be added.
:param x2: (*array_like*) The array to be added.
:return: (*array_like*) Added array
"""
if isinstance(x1, (list, tuple)):
x1 = NDArray(x1)
if isinstance(x2, (list, tuple)):
x2 = NDArray(x2)
if isinstance(x1, NDArray):
return x1.__add__(x2)
elif isinstance(x2, NDArray):
return x2.__radd__(x1)
else:
return x1 + x2
def floor_divide(x1, x2):
"""
Return the largest integer smaller or equal to the division of the inputs. It is equivalent to the
Python // operator and pairs with the Python % (remainder), function so that a = a % b + b * (a // b)
up to roundoff.
:param x1: (*array_like*) Numerator.
:param x2: (*array_like*) Denominator.
:return: (*array*) Result array.
"""
if isinstance(x1, (list, tuple)):
x1 = NDArray(x1)
if isinstance(x2, (list, tuple)):
x2 = NDArray(x2)
if isinstance(x1, NDArray):
return x1.__floordiv__(x2)
elif isinstance(x2, NDArray):
return x2.__rfloordiv__(x1)
else:
return x1 // x2
def mod(x1, x2):
"""
Return element-wise remainder of division.
:param x1: (*array_like*) Dividend array.
:param x2: (*array_like*) Divisor array.
:return: (*array*) remainder array
"""
if isinstance(x1, (list, tuple)):
x1 = NDArray(x1)
if isinstance(x2, (list, tuple)):
x2 = NDArray(x2)
if isinstance(x1, NDArray):
return x1.__mod__(x2)
elif isinstance(x2, NDArray):
return x2.__rmod__(x1)
else:
return x1 % x2
def remainder(x1, x2):
"""
Return element-wise remainder of division.
:param x1: (*array_like*) Dividend array.
:param x2: (*array_like*) Divisor array.
:return: (*array*) remainder array
"""
return mod(x1, x2)
def divmod(x1, x2):
"""
Return element-wise quotient and remainder simultaneously.
:param x1: (*array_like*) Dividend array.
:param x2: (*array_like*) Divisor array.
:return: Element-wise quotient and remainder array.
"""
if isinstance(x1, (list, tuple)):
x1 = NDArray(x1)
if isinstance(x2, (list, tuple)):
x2 = NDArray(x2)
if isinstance(x1, NDArray):
return x1.__divmod__(x2)
elif isinstance(x2, NDArray):
return x2.__rdivmod__(x1)
else:
return __builtin__.divmod(x1, x2)
def fmod(x1, x2):
"""
Return the element-wise remainder of division. For `fmod`, the sign of result is the sign of the
dividend, while for `remainder` the sign of the result is the sign of the divisor.
:param x1: (*array_like*) Dividend array.
:param x2: (*array_like*) Divisor array.
:return: Element-wise remainder array.
"""
s = sign(x1)
return mod(x1, x2) * s

View File

@ -5,7 +5,9 @@ belong in core or in another numeric submodule with a clear purpose
from .shape_base import *
from .index_tricks import *
from .stride_tricks import *
__all__ = []
__all__ += shape_base.__all__
__all__ += index_tricks.__all__
__all__ += index_tricks.__all__
__all__ += stride_tricks.__all__

View File

@ -0,0 +1,38 @@
"""
Utilities that manipulate strides to achieve desirable effects.
"""
from org.meteoinfo.ndarray.math import ArrayUtil
from mipylib.numeric import core as np
__all__ = ['broadcast_shapes','broadcast_arrays']
def _broadcast_shapes(*args):
args = [np.array(_m).shape for _m in args]
return ArrayUtil.broadcastShapes(args)
def broadcast_shapes(*args):
"""
Broadcast the input shapes into a single shape.
:param args: (*list of ints*) The shapes to be broadcast against each other..
:return: Broadcasted shape.
"""
args = [_m for _m in args]
return ArrayUtil.broadcastShapes(args)
def broadcast_arrays(*args):
"""
Broadcast any number of arrays against each other.
:param args: (*list of array*) The shapes to broadcast.
:return: Broadcasted arrays.
"""
args = [np.array(_m) for _m in args]
shape = _broadcast_shapes(*args)
if all(array.shape == shape for array in args):
# Common case where nothing needs to be broadcasted.
return args
return [np.broadcast_to(array, shape) for array in args]

View File

@ -0,0 +1,8 @@
class Unit(object):
def __init__(self, name):
"""
:param name:
"""

View File

@ -0,0 +1,12 @@
class UnitType(object):
def __init__(self, name, base_unit):
"""
Unit type.
:param name: (*str*) Type name.
:param base_unit: (*str*) Base unit name.
"""
self.name = name
self.base_unit = base_unit

View File

@ -242,7 +242,7 @@ public class ArrayDouble extends Array {
* not legal, throw ForbiddenConversionException
*/
public String getString(Index i) {
return String.valueOf(storageD[i.currentElement()]);
return String.format("%.8f", storageD[i.currentElement()]);
}
/**
@ -344,7 +344,7 @@ public class ArrayDouble extends Array {
}
public String getString(int index) {
return String.valueOf(storageD[index]);
return String.format("%.8f", storageD[index]);
}
public void setString(int index, String value) {

View File

@ -1690,39 +1690,37 @@ public class ArrayMath {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.INT, a.getShape());
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
int va,
vb;
double va, vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getInt(i);
vb = b.getInt(i);
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
va = a.getDouble(i);
vb = b.getDouble(i);
if (Double.isNaN(va) || Double.isNaN(vb)) {
r.setDouble(i, Double.NaN);
} else {
r.setInt(i, va / vb);
r.setDouble(i, va / vb);
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
int va,
vb;
double va, vb;
while (iterA.hasNext()) {
va = iterA.getIntNext();
vb = iterB.getIntNext();
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
va = iterA.getDoubleNext();
vb = iterB.getDoubleNext();
if (Double.isNaN(va) || Double.isNaN(vb)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setIntNext(va / vb);
iterR.setDoubleNext(va / vb);
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.INT, shape);
r = Array.factory(DataType.DOUBLE, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
@ -1733,10 +1731,10 @@ public class ArrayMath {
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
r.setDouble(i, Double.NaN);
} else {
r.setInt(i, a.getInt(aindex) / b.getInt(bindex));
r.setDouble(i, a.getDouble(aindex) / b.getDouble(bindex));
}
index.incr();
}
@ -1747,21 +1745,21 @@ public class ArrayMath {
}
private static Array divInt(Array a, int b) {
Array r = Array.factory(DataType.INT, a.getShape());
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setInt(i, a.getInt(i) / b);
r.setDouble(i, a.getDouble(i) / b);
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
int v;
double v;
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setIntNext(v / b);
iterR.setDoubleNext(v / b);
}
}
}
@ -1770,21 +1768,21 @@ public class ArrayMath {
}
private static Array divInt(int b, Array a) {
Array r = Array.factory(DataType.INT, a.getShape());
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setInt(i, b / a.getInt(i));
r.setDouble(i, b / a.getDouble(i));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
int v;
double v;
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setIntNext(b / v);
iterR.setDoubleNext(b / v);
}
}
}
@ -2148,6 +2146,787 @@ public class ArrayMath {
return r;
}
/**
* Array mod
*
* @param a Array a
* @param b Array b
* @return Result array
*/
public static Array mod(Array a, Array b) {
DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.modInt(a, b);
case FLOAT:
return ArrayMath.modFloat(a, b);
case DOUBLE:
return ArrayMath.modDouble(a, b);
}
return null;
}
/**
* Array mod
*
* @param a Array a
* @param b Number b
* @return Result array
*/
public static Array mod(Array a, Number b) {
DataType bType = ArrayMath.getDataType(b);
DataType type = ArrayMath.commonType(a.getDataType(), bType);
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.modInt(a, b.intValue());
case FLOAT:
return ArrayMath.modFloat(a, b.floatValue());
case DOUBLE:
return ArrayMath.modDouble(a, b.doubleValue());
}
return null;
}
/**
* Array mod
*
* @param a Array a
* @param b Number b
* @return Result array
*/
public static Array mod(Number b, Array a) {
DataType bType = ArrayMath.getDataType(b);
DataType type = ArrayMath.commonType(a.getDataType(), bType);
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.modInt(b.intValue(), a);
case FLOAT:
return ArrayMath.modFloat(b.floatValue(), a);
case DOUBLE:
return ArrayMath.modDouble(b.doubleValue(), a);
}
return null;
}
private static int mod(int a, int b) {
return a - Math.floorDiv(a, b) * b;
}
private static float mod(float a, float b) {
return a - (float)Math.floor(a / b) * b;
}
private static double mod(double a, double b) {
return a - Math.floor(a / b) * b;
}
private static Array modInt(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.INT, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
int va, vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getInt(i);
vb = b.getInt(i);
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
} else {
r.setInt(i, mod(va, vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
int va, vb;
while (iterA.hasNext()) {
va = iterA.getIntNext();
vb = iterB.getIntNext();
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(mod(va, vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.INT, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
int va, vb;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
va = a.getInt(aindex);
vb = b.getInt(bindex);
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
} else {
r.setInt(i, mod(va, vb));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array modInt(Array a, int b) {
Array r = Array.factory(DataType.INT, a.getShape());
int v;
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
v = a.getInt(i);
r.setInt(i, mod(v, b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(mod(v, b));
}
}
}
return r;
}
private static Array modInt(int b, Array a) {
Array r = Array.factory(DataType.INT, a.getShape());
int v;
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
v = a.getInt(i);
r.setInt(i, mod(b, v));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(mod(b, v));
}
}
}
return r;
}
private static Array modFloat(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.FLOAT, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
float va, vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getFloat(i);
vb = b.getFloat(i);
if (Float.isNaN(va) || Float.isNaN(vb)) {
r.setFloat(i, Float.NaN);
} else {
r.setFloat(i, mod(va, vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
float va, vb;
while (iterA.hasNext()) {
va = iterA.getFloatNext();
vb = iterB.getFloatNext();
if (Float.isNaN(va) || Float.isNaN(vb)) {
iterR.setFloatNext(Float.NaN);
} else {
iterR.setFloatNext(mod(va, vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.FLOAT, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
r.setFloat(i, Float.NaN);
} else {
r.setFloat(i, mod(a.getFloat(aindex), b.getFloat(bindex)));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array modFloat(Array a, float b) {
Array r = Array.factory(DataType.FLOAT, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setFloat(i, mod(a.getFloat(i), b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
float v;
while (iterA.hasNext()) {
v = iterA.getFloatNext();
if (Float.isNaN(v)) {
iterR.setFloatNext(v);
} else {
iterR.setFloatNext(mod(v, b));
}
}
}
return r;
}
private static Array modFloat(float b, Array a) {
Array r = Array.factory(DataType.FLOAT, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setFloat(i, mod(b, a.getFloat(i)));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
float v;
while (iterA.hasNext()) {
v = iterA.getFloatNext();
if (Float.isNaN(v)) {
iterR.setFloatNext(v);
} else {
iterR.setFloatNext(mod(b, v));
}
}
}
return r;
}
private static Array modDouble(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
double va, vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getDouble(i);
vb = b.getDouble(i);
if (Double.isNaN(va) || Double.isNaN(vb)) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, mod(va, vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
double va,
vb;
while (iterA.hasNext()) {
va = iterA.getDoubleNext();
vb = iterB.getDoubleNext();
if (Double.isNaN(va) || Double.isNaN(vb)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(mod(va, vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.DOUBLE, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, mod(a.getDouble(aindex), b.getDouble(bindex)));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array modDouble(Array a, double b) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, mod(a.getDouble(i), b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
double v;
while (iterA.hasNext()) {
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(mod(v, b));
}
}
}
return r;
}
private static Array modDouble(double b, Array a) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, mod(b, a.getDouble(i)));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
double v;
while (iterA.hasNext()) {
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(mod(b, v));
}
}
}
return r;
}
/**
* Array mod
*
* @param a Array a
* @param b Array b
* @return Result array
*/
public static Array floorDiv(Array a, Array b) {
DataType type = ArrayMath.commonType(a.getDataType(), b.getDataType());
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.floorDivInt(a, b);
case FLOAT:
return ArrayMath.floorDivFloat(a, b);
case DOUBLE:
return ArrayMath.floorDivDouble(a, b);
}
return null;
}
/**
* Array floor divide
*
* @param a Array a
* @param b Number b
* @return Result array
*/
public static Array floorDiv(Array a, Number b) {
DataType bType = ArrayMath.getDataType(b);
DataType type = ArrayMath.commonType(a.getDataType(), bType);
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.floorDivInt(a, b.intValue());
case FLOAT:
return ArrayMath.floorDivFloat(a, b.floatValue());
case DOUBLE:
return ArrayMath.floorDivDouble(a, b.doubleValue());
}
return null;
}
/**
* Array floor divide
*
* @param a Array a
* @param b Number b
* @return Result array
*/
public static Array floorDiv(Number b, Array a) {
DataType bType = ArrayMath.getDataType(b);
DataType type = ArrayMath.commonType(a.getDataType(), bType);
switch (type) {
case SHORT:
case INT:
case BOOLEAN:
return ArrayMath.floorDivInt(b.intValue(), a);
case FLOAT:
return ArrayMath.floorDivFloat(b.floatValue(), a);
case DOUBLE:
return ArrayMath.floorDivDouble(b.doubleValue(), a);
}
return null;
}
private static Array floorDivInt(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.INT, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
int va,
vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getInt(i);
vb = b.getInt(i);
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
} else {
r.setInt(i, Math.floorDiv(va, vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
int va, vb;
while (iterA.hasNext()) {
va = iterA.getIntNext();
vb = iterB.getIntNext();
if (va == Integer.MIN_VALUE || vb == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(Math.floorDiv(va, vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.INT, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (a.getInt(aindex) == Integer.MIN_VALUE || b.getInt(bindex) == Integer.MIN_VALUE) {
r.setInt(i, Integer.MIN_VALUE);
} else {
r.setInt(i, Math.floorDiv(a.getInt(aindex), b.getInt(bindex)));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array floorDivInt(Array a, int b) {
Array r = Array.factory(DataType.INT, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setInt(i, Math.floorDiv(a.getInt(i), b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
int v;
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(Math.floorDiv(v, b));
}
}
}
return r;
}
private static Array floorDivInt(int b, Array a) {
Array r = Array.factory(DataType.INT, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setInt(i, Math.floorDiv(b, a.getInt(i)));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
int v;
while (iterA.hasNext()) {
v = iterA.getIntNext();
if (v == Integer.MIN_VALUE) {
iterR.setIntNext(Integer.MIN_VALUE);
} else {
iterR.setIntNext(Math.floorDiv(b, v));
}
}
}
return r;
}
private static Array floorDivFloat(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
float va,
vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getFloat(i);
vb = b.getFloat(i);
if (Float.isNaN(va) || Float.isNaN(vb)) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, Math.floor(va / vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
float va, vb;
while (iterA.hasNext()) {
va = iterA.getFloatNext();
vb = iterB.getFloatNext();
if (Float.isNaN(va) || Float.isNaN(vb)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(Math.floor(va / vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.DOUBLE, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (Float.isNaN(a.getFloat(aindex)) || Float.isNaN(b.getFloat(bindex))) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, Math.floor(a.getFloat(aindex) / b.getFloat(bindex)));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array floorDivFloat(Array a, float b) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, Math.floor(a.getFloat(i) / b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
float v;
while (iterA.hasNext()) {
v = iterA.getFloatNext();
if (Float.isNaN(v)) {
iterR.setDoubleNext(v);
} else {
iterR.setDoubleNext(Math.floor(v / b));
}
}
}
return r;
}
private static Array floorDivFloat(float b, Array a) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, Math.floor(b / a.getFloat(i)));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
float v;
while (iterA.hasNext()) {
v = iterA.getFloatNext();
if (Float.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(Math.floor(b / v));
}
}
}
return r;
}
private static Array floorDivDouble(Array a, Array b) {
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
double va, vb;
for (int i = 0; i < r.getSize(); i++) {
va = a.getDouble(i);
vb = b.getDouble(i);
if (Double.isNaN(va) || Double.isNaN(vb)) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, Math.floor(va / vb));
}
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
double va,
vb;
while (iterA.hasNext()) {
va = iterA.getDoubleNext();
vb = iterB.getDoubleNext();
if (Double.isNaN(va) || Double.isNaN(vb)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(Math.floor(va / vb));
}
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.DOUBLE, shape);
Index index = r.getIndex();
Index aindex = a.getIndex();
Index bindex = b.getIndex();
int n = r.getRank();
int na = a.getRank();
int nb = b.getRank();
int[] current;
for (int i = 0; i < r.getSize(); i++) {
current = index.getCurrentCounter();
setIndex(aindex, bindex, current, n, na, nb);
if (Double.isNaN(a.getDouble(aindex)) || Double.isNaN(b.getDouble(bindex))) {
r.setDouble(i, Double.NaN);
} else {
r.setDouble(i, Math.floor(a.getDouble(aindex) / b.getDouble(bindex)));
}
index.incr();
}
return r;
default:
return null;
}
}
private static Array floorDivDouble(Array a, double b) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, Math.floor(a.getDouble(i) / b));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
double v;
while (iterA.hasNext()) {
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(Math.floor(v / b));
}
}
}
return r;
}
private static Array floorDivDouble(double b, Array a) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setDouble(i, Math.floor(b / a.getDouble(i)));
}
} else {
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterA = a.getIndexIterator();
double v;
while (iterA.hasNext()) {
v = iterA.getDoubleNext();
if (Double.isNaN(v)) {
iterR.setDoubleNext(Double.NaN);
} else {
iterR.setDoubleNext(Math.floor(b / v));
}
}
}
return r;
}
/**
* Array pow function
*
@ -3966,6 +4745,10 @@ public class ArrayMath {
return r;
}
private static int sign(double v) {
return (int)Math.signum(v);
}
/**
* Returns an element-wise indication of the sign of a number. The sign
* function returns -1 if x less than 0, 0 if x==0, 1 if x bigger than 0.
@ -3975,16 +4758,16 @@ public class ArrayMath {
* @return The sign of x array
*/
public static Array sign(Array x) {
Array r = Array.factory(DataType.FLOAT, x.getShape());
Array r = Array.factory(x.getDataType(), x.getShape());
if (x.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setFloat(i, Math.signum(x.getFloat(i)));
r.setObject(i, sign(x.getDouble(i)));
}
} else {
IndexIterator iterX = x.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
while (iterX.hasNext()) {
iterR.setFloatNext(Math.signum(iterX.getFloatNext()));
iterR.setObjectNext(sign(iterX.getDoubleNext()));
}
}

View File

@ -2609,6 +2609,34 @@ public class ArrayUtil {
// </editor-fold>
// <editor-fold desc="Resample/Interpolate">
/**
* Broadcast shape list to a new shape
* @param shapes The shape list
* @return Result shape
*/
public static int[] broadcastShapes(List<List<Integer>> shapes) {
int ndim = 0;
for (List<Integer> shape : shapes) {
if (ndim < shape.size())
ndim = shape.size();
}
int[] newShape = new int[ndim];
int nn;
for (List<Integer> shape : shapes) {
nn = shape.size();
for (int n : shape) {
if (newShape[ndim - nn] < n) {
newShape[ndim - nn] = n;
}
nn -= 1;
}
}
return newShape;
}
/**
* Broadcast array to a new shape
*