add real and imag attribute in NDArray

This commit is contained in:
wyq 2022-11-14 09:50:37 +08:00
parent 0ca8028817
commit a644572b35
10 changed files with 403 additions and 46 deletions

View File

@ -2854,7 +2854,7 @@ public class DataFrame implements Iterable {
return Sorting.sortIndex(this, dir);
}
public DataFrame sortBy(final Object... cols) {
/*public DataFrame sortBy(final Object... cols) {
final Map<Integer, SortDirection> sortCols = new LinkedHashMap<>();
for (final Object col : cols) {
final String str = col instanceof String ? String.class.cast(col) : "";
@ -2864,7 +2864,7 @@ public class DataFrame implements Iterable {
sortCols.put(c, dir);
}
return Sorting.sort(this, sortCols);
}
}*/
public DataFrame sortBy(boolean ascending, final Integer... cols) {
final Map<Integer, SortDirection> sortCols = new LinkedHashMap<>();
@ -2907,8 +2907,8 @@ public class DataFrame implements Iterable {
* @return The grouping
*/
public DataFrameGroupBy groupBy(final Object... columns) {
int[] icols = this.columns.indices(columns);
return groupBy(icols);
Integer[] iCols = Arrays.stream(this.columns.indices(columns)).boxed().toArray(Integer[]::new);
return groupBy(iCols);
}
/**
@ -2918,8 +2918,8 @@ public class DataFrame implements Iterable {
* @return The grouping
*/
public DataFrameGroupBy groupBy(final List<Object> columns) {
int[] icols = this.columns.indices(columns);
return groupBy(icols);
Integer[] iCols = Arrays.stream(this.columns.indices(columns)).boxed().toArray(Integer[]::new);
return groupBy(iCols);
}
/**

View File

@ -1,34 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\funny">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\imshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\mesh"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\optimize"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\fitting"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\linalg">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\scatter"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe\series"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\burf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\linalg"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\LaSW\airship\sounding.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\LaSW\airship\radar_bz2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\funny\rocket.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\funny\mandelbrot.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\norm_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\svd.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\LaSW\airship\sounding.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\LaSW\airship\radar_bz2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\funny\rocket.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\funny\mandelbrot.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\norm_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\svd.py"/>
</RecentFiles>
</File>
<Font>

View File

@ -617,6 +617,62 @@ class NDArray(object):
r = self
return r
@property
def real(self):
"""
Return the real part of the complex argument.
:return: (*array*) The real component of the complex argument.
"""
if self.dtype == _dtype.complex:
return NDArray(ArrayMath.getReal(self._array))
else:
return self
@real.setter
def real(self, val):
"""
Return the real part of the complex argument.
:param val: (*number or array*) Real value.
"""
if self.dtype == _dtype.complex:
if isinstance(val, (list, tuple)):
val = NDArray(val)
if isinstance(val, NDArray):
ArrayMath.setReal(self._array, val._array)
else:
ArrayMath.setReal(self._array, val)
@property
def imag(self):
"""
Return the image part of the complex argument.
:return: (*array*) The image component of the complex argument.
"""
if self.dtype == _dtype.complex:
return NDArray(ArrayMath.getImage(self._array))
else:
return self
@imag.setter
def imag(self, val):
"""
Return the image part of the complex argument.
:param val: (*number or array*) Image value.
"""
if self.dtype == _dtype.complex:
if isinstance(val, (list, tuple)):
val = NDArray(val)
if isinstance(val, NDArray):
ArrayMath.setImage(self._array, val._array)
else:
ArrayMath.setImage(self._array, val)
def min(self, axis=None):
"""
Get minimum value along an axis.
@ -626,6 +682,9 @@ class NDArray(object):
:returns: Minimum values.
"""
if isinstance(axis, (list, tuple)) and len(axis) == self.ndim:
axis = None
if axis is None:
r = ArrayMath.min(self._array)
return r
@ -684,6 +743,9 @@ class NDArray(object):
:returns: Maximum values.
"""
if isinstance(axis, (list, tuple)) and len(axis) == self.ndim:
axis = None
if axis is None:
r = ArrayMath.max(self._array)
return r
@ -695,11 +757,14 @@ class NDArray(object):
"""
Sum of array elements over a given axis.
:param axis: (*int*) Axis along which the standard deviation is computed.
The default is to compute the standard deviation of the flattened array.
:param axis: (*int*) Axis along which the sum is computed.
The default is to compute the sum of the flattened array.
returns: (*array_like*) Sum result
"""
if isinstance(axis, (list, tuple)) and len(axis) == self.ndim:
axis = None
if axis is None:
return ArrayMath.sum(self._array)
else:
@ -905,7 +970,11 @@ class NDArray(object):
:returns: Result Matrix or vector.
"""
if isinstance(other, list):
other = array(other)
other = NDArray(ArrayUtil.array(other))
if self.ndim == 1 and other.ndim == 1:
return self.__mul__(other).sum()
r = LinalgUtil.dot(self._array, other._array)
return NDArray(r)

View File

@ -45,7 +45,7 @@ __all__ = [
'fmax','fmin','full','hcurl','hdivg','hstack','identity','interp2d','interpn','isarray',
'isclose','isfinite','isinf','isnan','linspace','log','log10','logical_not','logspace',
'magnitude','max','maximum','mean','median','meshgrid','min','minimum','monthname',
'moveaxis','newaxis','ones','ones_like','outer','peaks','pol2cart','power','radians','reshape',
'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',
'sphere','squeeze','split','sqrt','square','std','swapaxes','take','tan','tanh','tile',
'transpose','trapz','vdot','unravel_index','var','vstack','zeros','zeros_like'
@ -694,6 +694,22 @@ def power(x1, x2):
return pow(x1, x2)
else:
return math.pow(x1, x2)
def reciprocal(x, dtype=None):
"""
Return the reciprocal of the argument, element-wise.
Calculates 1/x.
:param x: (*array*) Input array.
:param dtype: (*dtype*) Data type.
:return: Return array. This is a scalar if x is a scalar.
"""
if isinstance(x, (list, tuple)):
x = array(x)
return 1 / x
def degrees(x):
"""

View File

@ -1,6 +1,6 @@
from ..core.numeric import asarray
from ..core.numeric import asarray, asanyarray
__all__ = ['mintypecode']
__all__ = ['mintypecode','real','imag']
_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb?'
@ -47,4 +47,30 @@ def mintypecode(typechars, typeset='GDFgdf', default='d'):
return default
if 'F' in intersection and 'd' in intersection:
return 'D'
return min(intersection, key=_typecodes_by_elsize.index)
return min(intersection, key=_typecodes_by_elsize.index)
def real(val):
"""
Return the real part of the complex argument.
:param val: (*array*) Input array.
:return: (*array*) The real component of the complex argument.
"""
try:
return val.real
except AttributeError:
return asanyarray(val).real
def imag(val):
"""
Return the image part of the complex argument.
:param val: (*array*) Input array.
:return: (*array*) The image component of the complex argument.
"""
try:
return val.real
except AttributeError:
return asanyarray(val).imag

View File

@ -9,10 +9,11 @@
from org.meteoinfo.math.linalg import LinalgUtil
from org.meteoinfo.math.stats import StatsUtil
from ..core import NDArray
from .. import core as np
__all__ = [
'solve','cholesky','det','lu','qr', 'svd','eig','inv','lstsq','slogdet','solve_triangular'
'solve','cholesky','det','lu','qr', 'svd','eig','inv','lstsq','slogdet','solve_triangular',
'norm'
]
class LinAlgError(Exception):
@ -52,7 +53,7 @@ def solve(a, b):
"""
_assert_2d(a)
x = LinalgUtil.solve(a.asarray(), b.asarray())
r = NDArray(x)
r = np.NDArray(x)
return r
def solve_triangular(a, b, lower=False):
@ -75,7 +76,7 @@ def solve_triangular(a, b, lower=False):
Solution to the system a x = b. Returned shape is identical to ``b``.
"""
x = LinalgUtil.solve(a.asarray(), b.asarray())
return NDArray(x)
return np.NDArray(x)
def cholesky(a, lower=True):
"""
@ -102,7 +103,7 @@ def cholesky(a, lower=True):
matrix object if `a` is a matrix object.
"""
r = LinalgUtil.cholesky(a.asarray(), lower)
return NDArray(r)
return np.NDArray(r)
def lu(a):
"""
@ -138,9 +139,9 @@ def lu(a):
Upper triangular or trapezoidal matrix
"""
r = LinalgUtil.lu(a.asarray())
p = NDArray(r[0])
l = NDArray(r[1])
u = NDArray(r[2])
p = np.NDArray(r[0])
l = np.NDArray(r[1])
u = np.NDArray(r[2])
return p, l, u
def qr(a):
@ -165,15 +166,15 @@ def qr(a):
Of shape (M, N), or (K, N) for ``mode='economic'``. ``K = min(M, N)``.
"""
r = LinalgUtil.qr(a.asarray())
q = NDArray(r[0])
r = NDArray(r[1])
q = np.NDArray(r[0])
r = np.NDArray(r[1])
return q, r
def svd(a, full_matrices=True):
"""
Singular Value Decomposition.
Factorizes the matrix a into two unitary matrices U and Vh, and
Factorizes the matrix `a` into two unitary matrices U and Vh, and
a 1-D array s of singular values (real, non-negative) such that
``a == U*S*Vh``, where S is a suitably shaped matrix of zeros with
main diagonal s.
@ -200,9 +201,9 @@ def svd(a, full_matrices=True):
"""
r = LinalgUtil.svd(a.asarray())
#r = LinalgUtil.svd_EJML(a.asarray())
U = NDArray(r[0])
s = NDArray(r[1])
Vh = NDArray(r[2])
U = np.NDArray(r[0])
s = np.NDArray(r[1])
Vh = np.NDArray(r[2])
if not full_matrices:
m, n = a.shape
if m != n:
@ -239,8 +240,8 @@ def eig(a):
"""
r = LinalgUtil.eigen(a.asarray())
#r = LinalgUtil.eigen_EJML(a.asarray())
w = NDArray(r[0])
v = NDArray(r[1])
w = np.NDArray(r[0])
v = np.NDArray(r[1])
return w, v
def inv(a):
@ -252,7 +253,7 @@ def inv(a):
:returns: Inverse matrix.
"""
r = LinalgUtil.inv(a.asarray())
return NDArray(r)
return np.NDArray(r)
def lstsq(a, b):
"""
@ -275,16 +276,17 @@ def lstsq(a, b):
Sums of residues, squared 2-norm for each column in b - a x.
"""
r = StatsUtil.multipleLineRegress_OLS(b.asarray(), a.asarray(), True)
return NDArray(r[0]), NDArray(r[1])
return np.NDArray(r[0]), np.NDArray(r[1])
def det(a):
"""
Compute the determinant of an array.
arameters
parameters
----------
a : (..., M, M) array_like
Input array to compute determinants for.
Returns
-------
det : (...) array_like
@ -297,8 +299,139 @@ def det(a):
def slogdet(a):
"""
Compute the sign and (natural) logarithm of the determinant of an array.
:param a: (*array_like*) Input array, has to be a square 2-D array.
:return: Sign and logarithm of the determinant.
"""
r = LinalgUtil.sLogDet(a.asarray())
return r[0], r[1]
return r[0], r[1]
def norm(x, ord=None, axis=None, keepdims=False):
"""
Matrix or vector norm.
This function is able to return one of eight different matrix norms, or one of an infinite number
of vector norms (described below), depending on the value of the ord parameter.
Parameters
----------
x : array_like
Input array. If `axis` is None, `x` must be 1-D or 2-D, unless `ord`
is None. If both `axis` and `ord` are None, the 2-norm of
``x.ravel`` will be returned.
ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional
Order of the norm (see table under ``Notes``). inf means numpy's
`inf` object. The default is None.
axis : {None, int, 2-tuple of ints}, optional.
If `axis` is an integer, it specifies the axis of `x` along which to
compute the vector norms. If `axis` is a 2-tuple, it specifies the
axes that hold 2-D matrices, and the matrix norms of these matrices
are computed. If `axis` is None then either a vector norm (when `x`
is 1-D) or a matrix norm (when `x` is 2-D) is returned. The default
is None.
keepdims: bool, optional
If this is set to True, the axes which are normed over are left in the
result as dimensions with size one. With this option the result will
broadcast correctly against the original x.
Returns
-------
n : float or ndarray
Norm of the matrix or vector(s).
"""
x = np.asarray(x)
# Immediately handle some default, simple, fast, and common cases.
if axis is None:
ndim = x.ndim
if ((ord is None) or
(ord in ('f', 'fro') and ndim == 2) or
(ord == 2 and ndim == 1)):
x = x.ravel()
if x.dtype == np.dtype.complex:
x_real = x.real
x_imag = x.imag
sqnorm = x_real.dot(x_real) + x_imag.dot(x_imag)
else:
sqnorm = x.dot(x)
ret = np.sqrt(sqnorm)
if keepdims:
ret = ret.reshape(ndim*[1])
return ret
# Normalize the `axis` argument to a tuple.
nd = x.ndim
if axis is None:
axis = tuple(range(nd))
elif not isinstance(axis, tuple):
try:
axis = int(axis)
except Exception as e:
raise TypeError("'axis' must be None, an integer or a tuple of integers")
axis = (axis,)
if len(axis) == 1:
if ord == np.inf:
return np.abs(x).max(axis=axis)
elif ord == -np.inf:
return np.abs(x).min(axis=axis)
elif ord == 0:
# Zero norm
return (x != 0).astype(x.real.dtype).sum(axis=axis)
elif ord == 1:
return x.abs().sum(axis=axis)
elif ord is None or ord == 2:
s = (x.conj() * x).real
return np.sqrt(s.sum(axis=axis))
# None of the str-type keywords for ord ('fro', 'nuc')
# are valid for vectors
elif isinstance(ord, str):
raise ValueError("Invalid norm order '{ord}' for vectors".format(ord))
else:
absx = np.abs(x)
absx **= ord
ret = absx.sum(axis=axis)
ret **= np.reciprocal(ord)
return ret
# elif len(axis) == 2:
# row_axis, col_axis = axis
# row_axis = np.normalize_axis_index(row_axis, nd)
# col_axis = np.normalize_axis_index(col_axis, nd)
# if row_axis == col_axis:
# raise ValueError('Duplicate axes given.')
# if ord == 2:
# ret = _multi_svd_norm(x, row_axis, col_axis, amax)
# elif ord == -2:
# ret = _multi_svd_norm(x, row_axis, col_axis, amin)
# elif ord == 1:
# if col_axis > row_axis:
# col_axis -= 1
# ret = add.reduce(np.abs(x), axis=row_axis).max(axis=col_axis)
# elif ord == np.inf:
# if row_axis > col_axis:
# row_axis -= 1
# ret = add.reduce(np.abs(x), axis=col_axis).max(axis=row_axis)
# elif ord == -1:
# if col_axis > row_axis:
# col_axis -= 1
# ret = add.reduce(np.abs(x), axis=row_axis).min(axis=col_axis)
# elif ord == -np.inf:
# if row_axis > col_axis:
# row_axis -= 1
# ret = add.reduce(np.abs(x), axis=col_axis).min(axis=row_axis)
# elif ord in [None, 'fro', 'f']:
# ret = np.sqrt(add.reduce((x.conj() * x).real, axis=axis))
# elif ord == 'nuc':
# ret = _multi_svd_norm(x, row_axis, col_axis, sum)
# else:
# raise ValueError("Invalid norm order for matrices.")
# if keepdims:
# ret_shape = list(x.shape)
# ret_shape[axis[0]] = 1
# ret_shape[axis[1]] = 1
# ret = ret.reshape(ret_shape)
# return ret
# else:
# raise ValueError("Improper number of dimensions to norm.")

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="config.xml" Type="configurefile">
<Path OpenPath="D:\Temp\HYSPLIT"/>
<Path OpenPath="D:\Temp\grads"/>
<Font>
<TextFont FontName="YaHei Consolas Hybrid" FontSize="14"/>
<LegendFont FontName="宋体" FontSize="12"/>

View File

@ -8216,6 +8216,117 @@ public class ArrayMath {
return r;
}
// </editor-fold>
// <editor-fold desc="Complex">
/**
* Get real part of the array
* @param a Input array
* @return Real part array
*/
public static Array getReal(Array a) {
if (a.getDataType() == DataType.COMPLEX) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
while (iterA.hasNext()) {
iterR.setDoubleNext(iterA.getComplexNext().real());
}
return r;
} else {
return a;
}
}
/**
* Set real part of the array
* @param a Input array
* @param v Real value
*/
public static void setReal(Array a, Number v) {
if (a.getDataType() == DataType.COMPLEX) {
IndexIterator iterA = a.getIndexIterator();
Complex c;
double dv = v.doubleValue();
while (iterA.hasNext()) {
c = iterA.getComplexNext();
iterA.setComplexCurrent(new Complex(dv, c.getImaginary()));
}
}
}
/**
* Set real part of the array
* @param a Input array
* @param v Real value
*/
public static void setReal(Array a, Array v) {
if (a.getDataType() == DataType.COMPLEX) {
IndexIterator iterA = a.getIndexIterator();
Complex c;
IndexIterator iterV = v.getIndexIterator();
while (iterA.hasNext()) {
c = iterA.getComplexNext();
iterA.setComplexCurrent(new Complex(iterV.getDoubleNext(), c.getImaginary()));
}
}
}
/**
* Set image part of the array
* @param a Input array
* @param v Read value
*/
public static void setImage(Array a, Number v) {
if (a.getDataType() == DataType.COMPLEX) {
IndexIterator iterA = a.getIndexIterator();
Complex c;
double dv = v.doubleValue();
while (iterA.hasNext()) {
c = iterA.getComplexNext();
iterA.setComplexCurrent(new Complex(c.getReal(), dv));
}
}
}
/**
* Set image part of the array
* @param a Input array
* @param v Read value
*/
public static void setImage(Array a, Array v) {
if (a.getDataType() == DataType.COMPLEX) {
IndexIterator iterA = a.getIndexIterator();
Complex c;
IndexIterator iterV = v.getIndexIterator();
while (iterA.hasNext()) {
c = iterA.getComplexNext();
iterA.setComplexCurrent(new Complex(c.getReal(), iterV.getDoubleNext()));
}
}
}
/**
* Get image part of the array
* @param a Input array
* @return Image part array
*/
public static Array getImage(Array a) {
if (a.getDataType() == DataType.COMPLEX) {
Array r = Array.factory(DataType.DOUBLE, a.getShape());
IndexIterator iterA = a.getIndexIterator();
IndexIterator iterR = r.getIndexIterator();
while (iterA.hasNext()) {
iterR.setDoubleNext(iterA.getComplexNext().imag());
}
return r;
} else {
return a;
}
}
// </editor-fold>
// <editor-fold desc="Convert">