2 This set of classes offers an approach to calculating the Hamming distance and encoding 3 into the state phase using PYthon. Pybind11 wrapped C++ methods are used where sensible. 6 from abc
import ABC, abstractmethod
8 from PyQNLPSimulator
import DCMatrix
9 from PyQNLPSimulator
import GateOps
14 This class is used to encode the Hamming distance between two 15 qubit registers into the phase. 22 npmat = np.array([[np.exp(1j*theta), 0], [0, 1]])
23 return DCMatrix(npmat.flatten())
26 npmat = np.linalg.matrix_power([[np.exp(1j*theta), 0], [0, 1]], -2 )
27 return DCMatrix(npmat.flatten())
33 class HammingDistanceExpITheta(HammingDistance):
35 Default approach taken by Trugenberger, and others to encode 36 Hamming distance into the state phase. Results can be skewed 37 by high degeneracy in encoded patterns. 40 super().
__init__(num_bits, simulator)
42 def _step1(self, reg_mem, reg_aux, pattern):
43 self.
sim.encodeToRegister(pattern, reg_aux[0:-2], len(reg_mem))
46 for i
in range(len(reg_aux)-2):
47 self.
sim.applyGateCX(reg_aux[i], reg_mem[i])
48 self.
sim.applyGateX(reg_mem[i])
51 theta = np.pi / (2.0 * len(reg_mem))
56 for j
in range(len(reg_mem)):
57 self.
sim.applyGateU(UMat, reg_mem[j],
"U")
58 for i
in range(len(reg_mem)):
59 self.
sim.applyGateCU(CUMatPowMin2, reg_aux[-2], reg_mem[i],
"U")
62 for i
in range(len(reg_aux)-2):
63 self.
sim.applyGateX(reg_mem[i])
64 self.
sim.applyGateCX(reg_aux[i], reg_mem[i])
67 self.
sim.collapseToBasisZ(reg_aux[-2],
False)
70 self.
sim.applyGateH(reg_aux[-2])
71 self.
_step1(reg_mem, reg_aux, pattern)
72 self.
_step2(reg_mem, reg_aux)
73 self.
_step3(reg_mem, reg_aux)
74 self.
_step4(reg_mem, reg_aux)
75 self.
sim.applyGateH(reg_aux[-2])
79 for i
in range(len(reg_mem)):
80 self.
sim.applyGateX(reg_aux[i])
81 self.
sim.applyGateCCX(reg_mem[i], reg_aux[i], reg_aux[-1])
82 self.
sim.applyGateX(reg_aux[i])
83 self.
sim.applyGateCSwap(reg_mem[i], reg_aux[i], reg_aux[-1])
85 def calc(self, reg_mem, reg_aux, pattern):
90 Intermediate routine to overwrite the data in the aux register 91 with its Hamming dsiatnce to the data in the memory regsiter. 97 self.
sim.encodeToRegister(pattern, reg_aux[0:-2], len(reg_mem))
100 for idx, val
in enumerate(reg_mem):
101 self.
sim.applyGateX(reg_aux[idx])
102 self.
sim.applyGateCCX(reg_mem[idx], reg_aux[idx], reg_aux[-2])
103 self.
sim.applyGateX(reg_aux[idx])
104 self.
sim.applyGateCSwap(reg_mem[idx], reg_aux[idx], reg_aux[-2])
106 def calc(self, reg_mem, reg_aux, pattern):
112 Class attempt alternative for state amplitude weighting by 113 Hamming distance. Uses oracle-based pattern, applying the 114 appropriate rotation angle to the state determined by matching 115 the number of set bits to a pre-defined set of values. 119 super().
__init__(num_bits, simulator)
123 def calc(self, reg_mem, reg_aux, pattern):
126 self.
sim.groupQubits(reg_aux,
False)
128 for k,v
in omap.items():
129 self.
sim.addUToCache(v,
"RY_{}".format(k))
130 self.
sim.applyOracleU(k, self.
_oracle_angle_map()[k], reg_aux[0:-2], reg_aux[-2],
"RY_{}".format(k))
135 vals.append( DCMatrix( np.asarray( self.
gops.RY(np.arccos(i)) ).flatten() ) )
143 val_map.update({ 2**i - 1 : mats[i]})
147 if isinstance(vals, int):
149 elif isinstance(vals, list):
150 return [(2**val) -1
for val
in vals]
def _overwriteAux(self, reg_mem, reg_aux, pattern)
def calc(self, reg_mem, reg_aux, pattern)
def __init__(self, num_bits, simulator)
def _set_bits_to_pattern(vals)
def _step1(self, reg_mem, reg_aux, pattern)
def encode_hamming(self, reg_mem, reg_aux, pattern)
def _encodePattern(self, reg_mem, reg_aux, pattern)
def _UMatrixPowMin2(self, theta)
def __init__(self, num_bits, simulator)
def _oracle_angle_map(self)
def _step4(self, reg_mem, reg_aux)
def __init__(self, num_bits, simulator)
def _step2(self, reg_mem, reg_aux)
def _angle_matrices(self)
def _UMatrix(self, theta)
def hamming_aux_overwrite(self, reg_mem, reg_aux)
def calc(self, reg_mem, reg_aux, pattern)
def _step3(self, reg_mem, reg_aux)
def __init__(self, num_bits, simulator)
def calc(self, reg_mem, reg_aux, pattern)
def _step5(self, reg_aux)