3RNN/Lib/site-packages/sklearn/utils/arrayfuncs.pyx

138 lines
3.3 KiB
Cython
Raw Normal View History

2024-05-26 19:49:15 +02:00
"""
The :mod:`sklearn.utils.arrayfuncs` module includes a small collection of auxiliary
functions that operate on arrays.
"""
from cython cimport floating
from cython.parallel cimport prange
from libc.math cimport fabs
from libc.float cimport DBL_MAX, FLT_MAX
from ._cython_blas cimport _copy, _rotg, _rot
from ._typedefs cimport float64_t
ctypedef fused real_numeric:
short
int
long
long long
float
double
def min_pos(const floating[:] X):
"""Find the minimum value of an array over positive values.
Returns the maximum representable value of the input dtype if none of the
values are positive.
Parameters
----------
X : ndarray of shape (n,)
Input array.
Returns
-------
min_val : float
The smallest positive value in the array, or the maximum representable value
of the input dtype if no positive values are found.
Examples
--------
>>> import numpy as np
>>> from sklearn.utils.arrayfuncs import min_pos
>>> X = np.array([0, -1, 2, 3, -4, 5])
>>> min_pos(X)
2.0
"""
cdef Py_ssize_t i
cdef floating min_val = FLT_MAX if floating is float else DBL_MAX
for i in range(X.size):
if 0. < X[i] < min_val:
min_val = X[i]
return min_val
def _all_with_any_reduction_axis_1(real_numeric[:, :] array, real_numeric value):
"""Check whether any row contains all values equal to `value`.
It is equivalent to `np.any(np.all(X == value, axis=1))`, but it avoids to
materialize the temporary boolean matrices in memory.
Parameters
----------
array: array-like
The array to be checked.
value: short, int, long, float, or double
The value to use for the comparison.
Returns
-------
any_all_equal: bool
Whether or not any rows contains all values equal to `value`.
"""
cdef Py_ssize_t i, j
for i in range(array.shape[0]):
for j in range(array.shape[1]):
if array[i, j] != value:
break
else: # no break
return True
return False
# General Cholesky Delete.
# Remove an element from the cholesky factorization
# m = columns
# n = rows
#
# TODO: put transpose as an option
def cholesky_delete(floating[:, :] L, int go_out):
cdef:
int n = L.shape[0]
int m = L.strides[0]
floating c, s
floating *L1
int i
if floating is float:
m /= sizeof(float)
else:
m /= sizeof(double)
# delete row go_out
L1 = &L[0, 0] + (go_out * m)
for i in range(go_out, n-1):
_copy(i + 2, L1 + m, 1, L1, 1)
L1 += m
L1 = &L[0, 0] + (go_out * m)
for i in range(go_out, n-1):
_rotg(L1 + i, L1 + i + 1, &c, &s)
if L1[i] < 0:
# Diagonals cannot be negative
L1[i] = fabs(L1[i])
c = -c
s = -s
L1[i + 1] = 0. # just for cleanup
L1 += m
_rot(n - i - 2, L1 + i, m, L1 + i + 1, m, c, s)
def sum_parallel(const floating [:] array, int n_threads):
"""Parallel sum, always using float64 internally."""
cdef:
float64_t out = 0.
int i = 0
for i in prange(
array.shape[0], schedule='static', nogil=True, num_threads=n_threads
):
out += array[i]
return out