"""
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