Commit 26957b4b authored by Paulo Medeiros's avatar Paulo Medeiros
Browse files

Lint hollow_symmetric_matrix.py docstrings.

parent ab79ab32
......@@ -34,19 +34,27 @@ def _matrix_index_to_data_index(order, i, j):
M(i, j) = M_data(i_data)
This routine requires:
order > 0
-order <= i,j < order
Return value:
* An integer in the interval [0, n*(n - 1)/2) if i != j
* -(order + 1) if i == j (to flag that i==j elements are not stored)
This function is used in the HollowSymmetricMatrix class.
The choice of returning "-(order + 1)" for i==j instead of raising an
exception is because numba only implemented support to handling exceptions
in python < 3.7, but we need this to be used with python >= 3.6.10.
Args:
order (int): Order of the hollow symmetric matrix.
i (int): Matrix row index.
j (int): Matrix column index.
Returns:
int:
* In the interval [0, n*(n - 1)/2) if i != j
* -(order + 1) if i == j (flagging thus that i==j elements are not
stored).
The choice of returning "-(order + 1)" for i==j instead of
raising an exception is because numba only implemented support
to handling exceptions in python < 3.7, but we need this to be
used with python >= 3.6.10.
Raises:
ValueError: If order < 1.
IndexError: If the condition "-order <= i,j < order" does not hold.
This function is used in the HollowSymmetricMatrix class.
"""
if order < 1:
raise ValueError("Argument 'order' must be larger than zero")
......@@ -96,6 +104,25 @@ def _data_index_to_matrix_index(n, i_data, check_bounds=True):
consistency between the arguments is enforced.
Row-major order.
Args:
n (int): Order of the hollow symmetric matrix (HSM).
i_data (int): Index of data entry in the compact array that stores the
independent elements of the HSM.
check_bounds (bool): Whether or not to assert that n and i_data
correspond to matrix indices (i, j) within bounds.
(Default value = True).
Returns:
{
int: Matrix row index,
int: Matrix column index
}
Raises:
ValueError: If check_bounds evaluates to True and n, i_data are outside
their allowed ranges.
"""
if check_bounds:
if n < 1:
......@@ -125,6 +152,16 @@ def _to_dense(data, n, dtype):
This function is used in the HollowSymmetricMatrix class, where
consistency between the arguments is enforced.
Args:
data (numpy.array): Array that stores the independent elements of the
hollow symmetric matrix (hsm), i.e., the HSM's compact form.
n (int): The order of the HSM.
dtype (numpy.dtype): dtype of the data.
Returns:
np.nparray: Dense representation of the HSM (full 2D matrix form).
"""
dense = np.zeros(shape=(n, n), dtype=dtype)
for idata in prange(len(data)):
......@@ -137,7 +174,19 @@ def _to_dense(data, n, dtype):
@njit(cache=True, parallel=True)
def _to_compact(dense, dtype):
"""Compact matrix form of a hollow symmetric matrix from its dense form."""
"""Compact matrix form of a hollow symmetric matrix from its dense form.
Args:
dense (np.nparray): Dense representation of the HSM (full matrix form).
dtype (numpy.dtype): dtype of the data.
Returns:
numpy.array: Array with the independent elements of the HSM
Raises:
ValueError: If dense is not a 2D, square matrix.
"""
if dense.ndim != 2:
raise ValueError("dense.ndim != 2")
if dense.shape[0] != dense.shape[1]:
......@@ -154,7 +203,21 @@ def _to_compact(dense, dtype):
@njit(cache=True)
def _get_hsm_subspace_from_compact(compact, indices):
"""Subspace of an HSM compact, as "irow in indices & icol=irow"."""
"""Subspace of an HSM compact, as "irow in indices & icol=irow".
Args:
compact (numpy.array): Array with the independent elements of the HSM
indices (list): Indices of the subdimentions of the HSM to include in
the subspace.
Returns:
numpy.array: Compact form of the selected subspace.
Raises:
ValueError: If the number of elements in the subspace is not
consistent with the passed indices.
"""
n_indep = len(compact)
n = int(np.rint(0.5 * (1.0 + np.sqrt(1.0 + 8.0 * n_indep))))
new_n = len(indices)
......@@ -184,6 +247,18 @@ def _get_submatrix_from_hsm_compact(hsm_compact, order, bcasted_keys):
allocation for the submatrix elemnts only.
Used in the __getitem__ method of HollowSymmetricMatrix
Args:
hsm_compact (numpy.array): Array with the compact form of the HSM.
order (int): Order of the HSM.
bcasted_keys (list): Broadcasted keys passed to the __getitem__
method that calls this function. See also the function
_getitem_keys_to_bcast_arrays.
Returns:
np.ndarray: Submatrix selected according to the indices contructed
from bcasted_keys.
"""
submatrix_shape = bcasted_keys[0].shape
n_data = bcasted_keys[0].size
......@@ -211,13 +286,13 @@ def _getitem_keys_to_bcast_arrays(keys):
@njit(cache=True)
def _slice2range(the_slice, array_length):
"""Convert a slice into a list of indices."""
"""Convert a slice into a list of indices according to the array length."""
return range(*the_slice.indices(array_length))
@njit(cache=True)
def _get_hsm_double_slice(hsm_compact, order, row_slice, col_slice):
"""Extract [row_slice, col_slice] from HollowSymmetricMatrix dense form."""
"""Extract [row_slice, col_slice] from HSM compact form."""
row_numbers = _slice2range(row_slice, order)
col_numbers = _slice2range(col_slice, order)
submatrix_shape = (len(row_numbers), len(col_numbers))
......@@ -237,17 +312,17 @@ def _get_hsm_double_slice(hsm_compact, order, row_slice, col_slice):
def _get_hsm_row_slice(hsm_compact, order, the_slice):
"""Extract row slice from a HollowSymmetricMatrix in dense form."""
"""Extract row slice from a HollowSymmetricMatrix in compact form."""
return _get_hsm_double_slice(hsm_compact, order, the_slice, slice(None))
def _get_hsm_col_slice(hsm_compact, order, the_slice):
"""Extract column slice from a HollowSymmetricMatrix in dense form."""
"""Extract column slice from a HollowSymmetricMatrix in compact form."""
return _get_hsm_double_slice(hsm_compact, order, slice(None), the_slice)
class _MemSize:
"""Just to be able to pretty-print HollowSymmetricMatrix memsize."""
"""Prepare a "pretty-print" form of the HollowSymmetricMatrix memsize."""
def __init__(self, size_in_bytes):
if size_in_bytes < 0:
......@@ -272,6 +347,7 @@ def _implements_np_function_for_hsm(np_function):
"""Register __array_function__ implementation for HollowSymmetricMatrix."""
def decorator(func):
"""Get decorator to add implementations of numpy array functions."""
_NUMPY_FUNCTIONS_HANDLED_BY_HSM[np_function] = func
return func
......@@ -308,6 +384,7 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
When used with HDBSCAN, the following relation holds for memory usage:
"memory" < "speed_mem_compromise" < "speed",
and the inverse relation holds for execution times.
"""
def __init__(self, data, dtype=None, optimize_mode="memory"):
......@@ -334,7 +411,7 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
@classmethod
def validated_data(cls, data):
"""rtn: HSM-compatible version of data. ValueError if not possible."""
"""Get HSM-compatible version of data. ValueError if not possible."""
if np.ndim(data) == 1:
n_indep = len(data)
order = 0.5 * (1.0 + np.sqrt(1.0 + 8.0 * n_indep))
......@@ -432,10 +509,13 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
def transpose(self):
"""Transpose of a HollowSymmetricMatrix object: A copy of the object.
This simply returns a copy of the object, as HollowSymmetricMatrix
objects are, well, symmetric.
This also implements np.transpose for HollowSymmetricMatrix objects
Returns:
netatmoqc.hollow_symmetric_matrix.HollowSymmetricMatrix: Just a
copy of self, as HollowSymmetricMatrix objects are, well,
symmetric.
"""
return self.copy()
......@@ -493,7 +573,7 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
return rtn
def subspace(self, indices):
"""Subspace of self formed as 'irow in indices & icol=irow'."""
"""Subspace of self constructed as "irow in indices & icol=irow"."""
logger.debug("%s: Subspace requested", type(self).__name__)
# In case we get, e.g., panda Series objects
......@@ -583,10 +663,15 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
return rtn
def copy(self):
"""Return a copy of the matrix.
"""Return a copy of the matrix, formatted depending on optimize_mode.
Returns:
{
numpy.ndarray: If optimize_mode == "speed". Dense form.
netatmoqc.hollow_symmetric_matrix.HollowSymmetricMatrix: If
optimize_mode != "speed".
}
If optimize_mode == "speed", then a numpy array with the matrix
dense-mode representation will be returned.
"""
logger.debug("%s: Calling 'copy' method", type(self).__name__)
if self.optimize_mode == "speed":
......@@ -730,12 +815,11 @@ class HollowSymmetricMatrix(np.lib.mixins.NDArrayOperatorsMixin):
return ufunc_method(*new_inputs, **kwargs)
def __array_function__(self, func, types, args, kwargs):
"""Allow class to define how numpy functions operate on its objects.
"""Allow class to define how numpy functions operate on its objects."""
# Adapted from Numpy's own suggestions found on:
# <https://numpy.org/neps/nep-0018-array-function-protocol.html>
# <https://numpy.org/doc/stable/user/basics.dispatch.html>
Adapted from Numpy's own suggestions found on:
<https://numpy.org/neps/nep-0018-array-function-protocol.html>
<https://numpy.org/doc/stable/user/basics.dispatch.html>
"""
# Allow subclasses that don't override __array_function__
# to handle HollowSymmetricMatrix objects
if not all(issubclass(t, (self.__class__, np.ndarray)) for t in types):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment