herutriana44's picture
First Commit
b7d9967 verified
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Arithmetic Utilities
"""
from typing import List, Tuple
import numpy as np
def normalize_vector(vector):
"""
Normalize the input state vector.
"""
return vector / np.linalg.norm(vector)
def is_power_of_2(num):
"""
Check if the input number is a power of 2.
"""
return num != 0 and ((num & (num - 1)) == 0)
def log2(num):
"""
Compute the log2 of the input number. Use bit operation if the input is a power of 2.
"""
if is_power_of_2(num):
ret = 0
while True:
if num >> ret == 1:
return ret
else:
ret += 1
else:
return np.log2(num)
def is_power(num, return_decomposition=False):
"""
Check if num is a perfect power in O(n^3) time, n=ceil(logN)
"""
b = 2
while (2**b) <= num:
a = 1
c = num
while (c - a) >= 2:
m = int((a + c) / 2)
if (m**b) < (num + 1):
p = int(m**b)
else:
p = int(num + 1)
if int(p) == int(num):
if return_decomposition:
return True, int(m), int(b)
else:
return True
if p < num:
a = int(m)
else:
c = int(m)
b = b + 1
if return_decomposition:
return False, num, 1
else:
return False
def next_power_of_2_base(n):
"""
Return the base of the smallest power of 2 no less than the input number
"""
base = 0
if n and not (n & (n - 1)): # pylint: disable=superfluous-parens
return log2(n)
while n != 0:
n >>= 1
base += 1
return base
def transpositions(permutation: List[int]) -> List[Tuple[int, int]]:
"""Return a sequence of transpositions, corresponding to the permutation.
Args:
permutation: The ``List[int]`` defining the permutation. An element at index ``j`` should be
permuted to index ``permutation[j]``.
Returns:
List of transpositions, corresponding to the permutation. For permutation = [3, 0, 2, 1],
returns [(0,1), (0,3)]
"""
unchecked = [True] * len(permutation)
cyclic_form = []
for i in range(len(permutation)):
if unchecked[i]:
cycle = [i]
unchecked[i] = False
j = i
while unchecked[permutation[j]]:
j = permutation[j]
cycle.append(j)
unchecked[j] = False
if len(cycle) > 1:
cyclic_form.append(cycle)
cyclic_form.sort()
res = []
for x in cyclic_form:
len_x = len(x)
if len_x == 2:
res.append((x[0], x[1]))
elif len_x > 2:
first = x[0]
for y in x[len_x - 1 : 0 : -1]:
res.append((first, y))
return res
def triu_to_dense(triu: np.ndarray) -> np.ndarray:
"""Converts upper triangular part of matrix to dense matrix.
Args:
triu: array in the form [[A, B, C], [D, E], [F]]
Returns:
Array [[A, B, C], [B, D, E], [C, E, F]]
"""
dim = len(triu)
matrix = np.empty((dim, dim), dtype=complex)
for i in range(dim):
for j in range(dim - i):
matrix[i, i + j] = triu[i][j]
if j != 0:
matrix[i + j, i] = triu[i][j]
return matrix