forked from BenediktRiegel/quantum-no-free-lunch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
54 lines (44 loc) · 1.83 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import pennylane as qml
import numpy as np
import torch
def int_to_bin(num, num_bits):
"""
Convert integer to binary with padding
(e.g. (num=7, num_bits = 5) -> 00111)
"""
b = bin(num)[2:]
return [0 for _ in range(num_bits - len(b))] + [int(el) for el in b]
def one_hot_encoding(num, num_bits):
"""
Returns one-hot encoding of a number
(e.g. (num=4, num_bits=7) -> 0000100)
"""
result = [0]*num_bits
result[num] = 1
return result
def normalize(point):
return point / np.linalg.norm(point)
def tensor_product(state1: np.ndarray, state2: np.ndarray):
result = np.zeros(len(state1)*len(state2), dtype=np.complex128)
for i in range(len(state1)):
result[i*len(state2):i*len(state2)+len(state2)] = state1[i] * state2
return result
def torch_tensor_product(matrix1: torch.Tensor, matrix2: torch.Tensor, device='cpu'):
result = torch.zeros((matrix1.shape[0]*matrix2.shape[0], matrix1.shape[1]*matrix2.shape[1]), dtype=torch.complex128, device=device)
for i in range(matrix1.shape[0]):
for j in range(matrix1.shape[1]):
result[i*matrix2.shape[0]:i*matrix2.shape[0]+matrix2.shape[0], j*matrix2.shape[1]:j*matrix2.shape[1]+matrix2.shape[1]] = matrix1[i, j] * matrix2
return result
def adjoint_unitary_circuit(unitary):
"""
Generates a circuit corresponding to the adjoint of the input matrix
"""
from qiskit import QuantumCircuit, Aer, transpile
unitary = np.conj(np.array(unitary)).T
qbits = int(np.log2(len(unitary)))
sv_backend = Aer.get_backend('statevector_simulator')
qc = QuantumCircuit(qbits)
qc.unitary(unitary, range(qbits))
qc_transpiled = transpile(qc, backend=sv_backend, basis_gates=sv_backend.configuration().basis_gates,
optimization_level=3)
return qml.from_qiskit(qc_transpiled)