Source code for nnsa.utils.mathematics

"""
Functions related to math.
"""
import warnings

import numpy as np

__all__ = [
    'abs_der',
    'compute_entropy',
    'mag2db',
    'nextpow2',
    'matrix_cofactor',
]


[docs]def abs_der(x): """ Derivative of abs(x). Args: x (np.ndarray): array with values. The derivative is computed for every value in the array. Returns: (np.ndarray): array with the same shape as `x` containing the derivative of every entry. """ mask1 = (x >= 0) mask2 = ~mask1 return 1.0 * mask1 - 1.0 * mask2
def closest_multiple(x, n): """ Return a multiple of `n` that is closest to `x`. Args: x (int, float, np.ndarray): number(s) to find the closest multiple to `n` of. n (int, float): the multiplier. Returns: y (int, float): multiple of n closest to x, has same type as `n`. Examples: >>> closest_multiple(7, 2) 8 >>> closest_multiple(7, 3) 6 >>> closest_multiple(8, 3) 9 >>> closest_multiple(231, 8) 232 >>> closest_multiple(0.7, 0.3) 0.6 >>> closest_multiple(np.arange(6), 2) array([0, 2, 2, 4, 4, 6]) """ # Use numpy's divide here so that the returned value is a numpy object on # which we can call .astype() later. y = x + np.divide(n, 2) y = y - (y % n) return y.astype(type(n))
[docs]def compute_entropy(p, axis=-1): """ Compute entropy of a probability distribution `p` along an axis. Args: p (np.ndarray): probability distribution(s). axis (int): axis along which to compute the entropy. Returns: entropy (float or np.ndarray): entropy of distribution(s) in `p`. """ entropy = -1*np.sum(p * np.log2(p), axis=axis) return entropy
[docs]def mag2db(mag): """ Convert magnitude to decibels. """ return 20 * np.log10(mag)
[docs]def nextpow2(x): """ Returns the next power of 2 such that 2**nextpow2(x) >= x. Args: x (float or np.ndarray): number to compute the next power of two of. If an array is given, the next power of two is computed element-wise. Returns: (np.int32 or np.ndarray of np.int32): element-wise next power of two of x. """ return np.ceil(np.log2(x)).astype(int)
def prevpow2(x): """ Returns the previous power of 2 such that 2**prevpow2(x) <= x. Args: x (float or np.ndarray): number to compute the next power of two of. If an array is given, the next power of two is computed element-wise. Returns: (np.int32 or np.ndarray of np.int32): element-wise next power of two of x. """ return np.floor(np.log2(x)).astype(int) def sigmoid(x): """ Sigmoid function. """ x = np.asarray(x) sig = np.where(x < 0, np.exp(x)/(1 + np.exp(x)), 1/(1 + np.exp(-x))) return sig
[docs]def matrix_cofactor(matrix, raise_error=True): """ Compute the cofactors of all elements of a matrix. From: https://www.geeksforgeeks.org/how-to-find-cofactor-of-a-matrix-using-numpy/ Args: matrix (np.ndarray): input matrix to find the cofactors of. raise_error (bool): raise error if an Exception occurs (True) or do not raise an exception and return nans (False). Returns: cofactor (np.ndarray): matrix with same shape as input containing the cofactors of each element in the input matrix. """ try: determinant = np.linalg.det(matrix) if determinant != 0: cofactor = np.linalg.inv(matrix).T * determinant else: raise Exception('Matrix is singular.') except Exception as e: warnings.warn("\nCould not find cofactor matrix due to {}".format(e)) if raise_error: raise else: cofactor = np.full_like(matrix, fill_value=np.nan) return cofactor