Skip to content

Instantly share code, notes, and snippets.

@nelimee
Last active November 19, 2019 09:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nelimee/1507460de2f61ee22ccf825111ae5c9e to your computer and use it in GitHub Desktop.
Save nelimee/1507460de2f61ee22ccf825111ae5c9e to your computer and use it in GitHub Desktop.
def normalise(vec: numpy.ndarray) -> numpy.ndarray:
norm = numpy.linalg.norm(vec)
if norm > numpy.finfo(float).eps:
return vec / norm
return vec
def reverse_normalised_kronecker(vec: numpy.ndarray, *sizes: int, under_is_zero: float = 1e-10):
"""Reverse a kronecker product of normalised vectors.
:param vec: The full vector, result of the kronecker product.
:param sizes: The sizes of the vectors that have been composed with kronecker
product to give vec.
:return:
"""
assert vec.size == numpy.product(sizes)
if len(sizes) == 1:
return [normalise(vec)]
first_size = sizes[0]
remaining_size = numpy.product(sizes[1:]).astype(int)
matrix = vec.reshape((first_size, remaining_size))
first_vec, other_vecs = None, None
for column in range(remaining_size):
if numpy.linalg.norm(matrix[:, column]) > under_is_zero:
first_vec = normalise(matrix[:, column])
break
for row in range(first_size):
if numpy.linalg.norm(matrix[row, :]) > under_is_zero:
other_vecs = reverse_normalised_kronecker(matrix[row, :], *sizes[1:])
break
if first_vec is None or other_vecs is None:
raise RuntimeError(
"Can't reverse this kronecker product because one of the "
+ "given dimension is the zero vector (and so cannot be "
+ "normalised). A norm below {}".format(under_is_zero)
+ " is considered as 0."
)
return [first_vec] + other_vecs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment