add thermo calculation functions

This commit is contained in:
wyq 2025-08-16 10:40:15 +08:00
parent ba94d02890
commit ef80a76ff4
21 changed files with 1435 additions and 184 deletions

View File

@ -76,9 +76,7 @@
<dependency>
<groupId>edu.ucar</groupId>
<artifactId>cdm-zarr</artifactId>
<version>5.9.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/cdm-zarr-5.9.0-SNAPSHOT.jar</systemPath>
<version>${netcdf.version}</version>
</dependency>
<dependency>
<groupId>edu.ucar</groupId>

View File

@ -1,30 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\array">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\meteo\calc">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataset"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\web"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\others"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\test"/>
<RecentFolder Folder="D:\Working\MIScript\mywork\music"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\integrate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\special"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array\slice"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\calc"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\radar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\integrate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\calc"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_test.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_with_lcl.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\calc\mixed_layer_cape_cin_test.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_with_lcl_test.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\array\searchsorted.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_test.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_with_lcl.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\calc\mixed_layer_cape_cin_test.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\calc\parcel_profile_with_lcl_test.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\array\searchsorted.py"/>
</RecentFiles>
</File>
<Font>
@ -32,5 +34,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-6,0" MainFormSize="1322,806"/>
<Startup MainFormLocation="-6,-6" MainFormSize="1292,764"/>
</MeteoInfo>

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ Ported from MetPy.
import mipylib.numeric as np
import mipylib.numeric.ma as ma
from mipylib.geolib import Geod
from ..interpolate import interpolate_1d
from ..interpolate import interpolate_1d, log_interpolate_1d
from ..cbook import broadcast_indices
__all__ = ['resample_nn_1d', 'nearest_intersection_idx', 'first_derivative', 'find_intersections', 'gradient',
@ -198,7 +198,7 @@ def _remove_nans(*variables):
return ret
def _get_bound_pressure_height(pressure, bound, height=None, interpolate=True):
def _get_bound_pressure_height(pressure, bound, height=None, interpolate=True, is_pressure=True):
"""Calculate the bounding pressure and height in a layer.
Given pressure, optional heights and a bound, return either the closest pressure/height
@ -233,7 +233,7 @@ def _get_bound_pressure_height(pressure, bound, height=None, interpolate=True):
height = height[sort_inds]
# Bound is given in pressure
if bound.check('[length]**-1 * [mass] * [time]**-2'):
if is_pressure:
# If the bound is in the pressure data, we know the pressure bound exactly
if bound in pressure:
# By making sure this is at least a 1D array we avoid the behavior in numpy
@ -263,7 +263,7 @@ def _get_bound_pressure_height(pressure, bound, height=None, interpolate=True):
bound_height = pressure_to_height_std(bound_pressure)
# Bound is given in height
elif bound.check('[length]'):
else:
# If there is height data, see if we have the bound or need to interpolate/find nearest
if height is not None:
if bound in height: # Bound is in the height data
@ -292,16 +292,12 @@ def _get_bound_pressure_height(pressure, bound, height=None, interpolate=True):
bound_pressure = pressure[idx]
bound_height = pressure_to_height_std(bound_pressure)
# Bound has invalid units
else:
raise ValueError('Bound must be specified in units of length or pressure.')
# If the bound is out of the range of the data, we shouldn't extrapolate
if not (_greater_or_close(bound_pressure, np.nanmin(pressure))
and _less_or_close(bound_pressure, np.nanmax(pressure))):
if not (_greater_or_close(bound_pressure, np.min(pressure))
and _less_or_close(bound_pressure, np.max(pressure))):
raise ValueError('Specified bound is outside pressure range.')
if height is not None and not (_less_or_close(bound_height, np.nanmax(height))
and _greater_or_close(bound_height, np.nanmin(height))):
if height is not None and not (_less_or_close(bound_height, np.max(height))
and _greater_or_close(bound_height, np.min(height))):
raise ValueError('Specified bound is outside height range.')
return bound_pressure, bound_height
@ -439,6 +435,7 @@ def get_layer(pressure, *args, **kwargs):
bottom = kwargs.pop('bottom', None)
depth = kwargs.pop('depth', 100) #'hPa'
interpolate = kwargs.pop('interpolate', True)
is_pressure = kwargs.pop('is_pressure', True)
# Make sure pressure and datavars are the same length
for datavar in args:
@ -454,12 +451,10 @@ def get_layer(pressure, *args, **kwargs):
interpolate=interpolate)
# Calculate the top in whatever units depth is in
if depth.check('[length]**-1 * [mass] * [time]**-2'):
if is_pressure:
top = bottom_pressure - depth
elif depth.check('[length]'):
top = bottom_height + depth
else:
raise ValueError('Depth must be specified in units of length or pressure')
top = bottom_height + depth
top_pressure, _ = _get_bound_pressure_height(pressure, top, height=height,
interpolate=interpolate)
@ -479,9 +474,9 @@ def get_layer(pressure, *args, **kwargs):
if interpolate:
# If we don't have the bottom or top requested, append them
if not np.any(np.isclose(top_pressure, p_interp)):
p_interp = np.sort(np.append(p_interp.m, top_pressure.m))
p_interp = np.sort(np.append(p_interp, top_pressure))
if not np.any(np.isclose(bottom_pressure, p_interp)):
p_interp = np.sort(np.append(p_interp.m, bottom_pressure.m))
p_interp = np.sort(np.append(p_interp, bottom_pressure))
ret.append(p_interp[::-1])

View File

@ -14,6 +14,7 @@ from _io import *
from . import umath
from umath import *
from .shape_base import *
from .stride_tricks import *
__all__ = ['NDArray','DimArray','PyTableData','dtype','dimension','dim_array','nditer']
__all__ += multiarray.__all__
@ -21,4 +22,5 @@ __all__ += numeric.__all__
__all__ += fromnumeric.__all__
__all__ += umath.__all__
__all__ += _io.__all__
__all__ += shape_base.__all__
__all__ += shape_base.__all__
__all__ += stride_tricks.__all__

View File

@ -2,8 +2,10 @@
from .numeric import asarray, array, isscalar
from ._ndarray import NDArray
from .stride_tricks import broadcast_arrays
from org.meteoinfo.ndarray.math import ArrayUtil, ArrayMath
__all__ = ['cumprod', 'cumsum', 'ndim', 'nonzero', 'prod', 'ravel', 'searchsorted', 'sum',
'where']
@ -113,6 +115,7 @@ def where(condition, *args):
condition = asarray(condition)
x = asarray(x)
y = asarray(y)
x, y = broadcast_arrays(x, y)
r = ArrayUtil.where(condition._array, x._array, y._array)
return NDArray(r)

View File

@ -7,8 +7,10 @@ from org.meteoinfo.ndarray.math import ArrayMath
from ._ndarray import NDArray
from ._exceptions import AxisError
__all__ = ['normalize_axis_index','bincount']
def normalize_axis_index(axis, ndim, msg_prefix=None):
"""
Normalizes an axis index, `axis`, such that is a valid positive index into
@ -32,6 +34,7 @@ def normalize_axis_index(axis, ndim, msg_prefix=None):
else:
raise AxisError(axis, ndim, msg_prefix)
def bincount(x, weights=None, minlength=0):
"""
Count number of occurrences of each value in array of non-negative ints.

View File

@ -47,7 +47,7 @@ __all__ = [
'moveaxis','newaxis','ones','ones_like','outer','peaks','pol2cart','power','radians','reciprocal','reshape',
'repeat','roll','rolling_mean','rot90','round','sec','sign','sin','sinh','shape','smooth5','smooth9','sort',
'spacing','sphere','squeeze','split','sqrt','square','std','swapaxes','take','tan','tanh','tile',
'transpose','trapz','to_datetime','vdot','unravel_index','var','vstack','zeros','zeros_like'
'transpose','trapz','trapezoid','to_datetime','vdot','unravel_index','var','vstack','zeros','zeros_like'
]
@ -351,7 +351,7 @@ def zeros_like(a, dtype=None):
"""
shape = a.shape
if dtype is None:
dtype = _dtype.fromjava(a.dtype)
dtype = a.dtype
elif isinstance(dtype, basestring):
dtype = _dtype.DataType(dtype)
@ -2170,32 +2170,32 @@ def atleast_2d(*args):
return res[0]
else:
return res
def vstack(tup):
"""
Stack arrays in sequence vertically (row wise).
This is equivalent to concatenation along the first axis after 1-D arrays
of shape `(N,)` have been reshaped to `(1,N)`.
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
along all but the first axis. 1-D arrays must have the same length.
:returns: (*array*) The array formed by stacking the given arrays, will be
:returns: (*array*) The array formed by stacking the given arrays, will be
at least 2-D.
"""
return concatenate([atleast_2d(_m) for _m in tup], 0)
def hstack(tup):
"""
Stack arrays in sequence horizontally (column wise).
This is equivalent to concatenation along the second axis, except for 1-D
arrays where it concatenates along the first axis.
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
:param tup: (*tuple*) Sequence of array. The arrays must have the same shape
along all but the first axis. 1-D arrays must have the same length.
:returns: (*array*) The array formed by stacking the given arrays.
"""
arrs = [atleast_1d(_m) for _m in tup]
@ -2548,14 +2548,15 @@ def cylinder(r=1, n=20):
z = z[:,newaxis]
z = z.repeat(n + 1, axis=1)
return x, y, z
def broadcast_to(a, shape):
"""
Broadcast an array to a new shape.
:param a: (*array_like*) The array to broadcast.
:param shape: (*tuple*) The shape of the desired array.
:returns: (*NDArray*) A readonly view on the original array with the given shape.
"""
if isinstance(a, numbers.Number):
@ -2567,7 +2568,8 @@ def broadcast_to(a, shape):
if r is None:
raise ValueError('Can not broadcast to the shape!')
return NDArray(r)
def corrcoef(x, y):
"""
Return Pearson product-moment correlation coefficients.
@ -2690,7 +2692,7 @@ def rot90(a, k=1):
"""
return a.rot90(k)
def trapz(y, x=None, dx=1.0, axis=-1):
def trapezoid(y, x=None, dx=1.0, axis=-1):
"""
Integrate along the given axis using the composite trapezoidal rule.
@ -2727,6 +2729,10 @@ def trapz(y, x=None, dx=1.0, axis=-1):
r = ArrayMath.trapz(y.asarray(), x.asarray(), axis)
return y.array_wrap(r, axis)
trapz = trapezoid
def rolling_mean(x, window, center=False):
"""

View File

@ -3,7 +3,7 @@ Utilities that manipulate strides to achieve desirable effects.
"""
from org.meteoinfo.ndarray.math import ArrayUtil
from mipylib.numeric import core as np
from . import numeric as np
__all__ = ['broadcast_shapes','broadcast_arrays']
@ -11,15 +11,17 @@ 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..
: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.
@ -35,4 +37,4 @@ def broadcast_arrays(*args):
# Common case where nothing needs to be broadcasted.
return args
return [np.broadcast_to(array, shape) for array in args]
return [np.broadcast_to(array, shape) for array in args]

View File

@ -6,7 +6,6 @@ belong in core or in another numeric submodule with a clear purpose
from .shape_base import *
from .function_base import *
from .index_tricks import *
from .stride_tricks import *
from .type_check import *
from .arraysetops import *
from .npyio import *
@ -17,7 +16,6 @@ __all__ = []
__all__ += shape_base.__all__
__all__ += function_base.__all__
__all__ += index_tricks.__all__
__all__ += stride_tricks.__all__
__all__ += type_check.__all__
__all__ += arraysetops.__all__
__all__ += npyio.__all__

View File

@ -170,9 +170,11 @@ public class ODESolver {
integrator.integrate(equations, t0, y0v, tf, yDot);
for (int i = 0; i < tEval.getSize(); i++) {
tlist.add(tEval.getDouble(i));
denseOutputModel.setInterpolatedTime(tEval.getDouble(i));
ylist.add(denseOutputModel.getInterpolatedState());
double t = tEval.getDouble(i);
tlist.add(t);
denseOutputModel.setInterpolatedTime(t);
double[] v = denseOutputModel.getInterpolatedState();
ylist.add(v.clone());
}
}

View File

@ -4237,21 +4237,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array equal(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < r.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) == b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() == iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) == b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() == iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) == b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4369,18 +4391,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array isClose(Array a, Array b, double rTol, double aTol, boolean equalNaN) {
a = a.copyIfView();
b = b.copyIfView();
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
for (int i = 0; i < a.getSize(); i++) {
if (isClose(a.getDouble(i), b.getDouble(i), rTol, aTol, equalNaN)) {
r.setBoolean(i, true);
} else {
r.setBoolean(i, false);
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, isClose(a.getDouble(i), b.getDouble(i), rTol, aTol, equalNaN));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(isClose(iterA.getDoubleNext(), iterB.getDoubleNext(), rTol, aTol, equalNaN));
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, isClose(a.getDouble(aindex), b.getDouble(bindex), rTol, aTol, equalNaN));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4460,21 +4507,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array lessThan(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) < b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() < iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) < b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() < iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) < b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4509,21 +4578,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array lessThanOrEqual(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) <= b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() <= iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) <= b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() <= iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) <= b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4558,21 +4649,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array greaterThan(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) > b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() > iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) > b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() > iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) > b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4607,21 +4720,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array greaterThanOrEqual(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) >= b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() >= iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) >= b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() >= iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) >= b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4656,21 +4791,43 @@ public class ArrayMath {
* @return Result array
*/
public static Array notEqual(Array a, Array b) {
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) != b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() != iterB.getDoubleNext());
}
int broadcast = broadcastCheck(a, b);
switch (broadcast) {
case 0:
Array r = Array.factory(DataType.BOOLEAN, a.getShape());
if (a.getIndexPrivate().isFastIterator() && b.getIndexPrivate().isFastIterator()) {
for (int i = 0; i < a.getSize(); i++) {
r.setBoolean(i, a.getDouble(i) != b.getDouble(i));
}
} else {
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
IndexIterator iterB = b.getIndexIterator();
while (iterA.hasNext()) {
iterR.setBooleanNext(iterA.getDoubleNext() != iterB.getDoubleNext());
}
}
return r;
case 1:
int[] shape = broadcast(a, b);
r = Array.factory(DataType.BOOLEAN, 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);
r.setBoolean(i, a.getDouble(aindex) != b.getDouble(bindex));
index.incr();
}
return r;
default:
return null;
}
return r;
}
/**
@ -4885,6 +5042,13 @@ public class ArrayMath {
* @return Boolean
*/
public static boolean contains(Array a, Object v) {
if (v instanceof Array) {
Array va = (Array) v;
if (va.getSize() == 1) {
v = va.getObject(0);
}
}
if (a.getDataType().isNumeric()) {
double dv = ((Number) v).doubleValue();
if (a.getIndexPrivate().isFastIterator()) {

View File

@ -2643,7 +2643,7 @@ public class ArrayUtil {
if (idx == -1) {
idx = 0;
} else {
idx = -idx - 2;
idx = -idx - 1;
}
if (!left)