73 lines
1.5 KiB
Python
73 lines
1.5 KiB
Python
"""
|
|
_normalize_columns.py : Normalize columns.
|
|
"""
|
|
|
|
import numpy as np
|
|
|
|
|
|
def normalize_columns(columns):
|
|
"""
|
|
Normalize columns of matrix.
|
|
|
|
Parameters
|
|
----------
|
|
columns : 2d array (M x N)
|
|
Matrix with columns
|
|
|
|
Returns
|
|
-------
|
|
normalized_columns : 2d array (M x N)
|
|
columns/np.sum(columns, axis=0, keepdims=1)
|
|
"""
|
|
|
|
# broadcast sum over columns
|
|
normalized_columns = columns/np.sum(columns, axis=0, keepdims=1)
|
|
|
|
return normalized_columns
|
|
|
|
|
|
def normalize_power_columns(x, exponent):
|
|
"""
|
|
Calculate normalize_columns(x**exponent)
|
|
in a numerically safe manner.
|
|
|
|
Parameters
|
|
----------
|
|
x : 2d array (M x N)
|
|
Matrix with columns
|
|
n : float
|
|
Exponent
|
|
|
|
Returns
|
|
-------
|
|
result : 2d array (M x N)
|
|
normalize_columns(x**n) but safe
|
|
|
|
"""
|
|
|
|
assert np.all(x >= 0.0)
|
|
|
|
x = x.astype(np.float64)
|
|
|
|
# values in range [0, 1]
|
|
x = x/np.max(x, axis=0, keepdims=True)
|
|
|
|
# values in range [eps, 1]
|
|
x = np.fmax(x, np.finfo(x.dtype).eps)
|
|
|
|
if exponent < 0:
|
|
# values in range [1, 1/eps]
|
|
x /= np.min(x, axis=0, keepdims=True)
|
|
|
|
# values in range [1, (1/eps)**exponent] where exponent < 0
|
|
# this line might trigger an underflow warning
|
|
# if (1/eps)**exponent becomes zero, but that's ok
|
|
x = x**exponent
|
|
else:
|
|
# values in range [eps**exponent, 1] where exponent >= 0
|
|
x = x**exponent
|
|
|
|
result = normalize_columns(x)
|
|
|
|
return result
|