def get_qwc_group(H: QubitOperator): ''' Return a list of qubit-wise commuting fragments of H ''' # Preparing all terms in H into a list qubit_ops = [] for pw, val in H.terms.items(): qubit_ops.append(QubitOperator(term=pw, coefficient=val)) n = len(qubit_ops) # Making commutation matrix comm_matrix = np.zeros((n, n)) for i in range(n): for j in range(i + 1, n): comm_matrix[i, j] = qubit_wise_commuting(qubit_ops[i], qubit_ops[j]) # Compute commuting fragments comm_matrix = np.identity(n) + comm_matrix + comm_matrix.T colors = largest_first(1 - comm_matrix) # Collect commuting fragments into a list of QubitOperators qwc_list = [] qwc_list_idx = 0 for key, indices in colors.items(): qwc_list.append(QubitOperator.zero()) for idx in indices: qwc_list[qwc_list_idx] += qubit_ops[idx] qwc_list_idx += 1 return qwc_list
def get_commuting_group(H: QubitOperator): ''' Get a dictionary of mutually commuting groups with terms in Hp ''' n = get_number_qubit(H) pws = [] pws_val = [] for pw, val in H.terms.items(): pws.append(pw) pws_val.append(val) binvecs = pauli2binvec(pws, n) tnum = len(binvecs) comm_matrix = np.zeros((tnum, tnum)) for i in range(tnum): for j in range(i + 1, tnum): comm_matrix[i, j] = 1 - anticommute(binvecs[i], binvecs[j]) comm_matrix = np.identity(tnum) + comm_matrix + comm_matrix.T colors = largest_first(1 - comm_matrix) dict = {} for key, indices in colors.items(): dict[key] = QubitOperator.zero() for idx in indices: dict[key] += QubitOperator(term=pws[idx], coefficient=pws_val[idx]) return dict
def map_qubits(self, qubit_map: dict): """ E.G. X(1)Y(2) --> X(3)Y(1) with qubit_map = {1:3, 2:1} Parameters ---------- qubit_map a dictionary which maps old to new qubits Returns ------- the Hamiltonian with mapped qubits """ mapped_terms = {} for k, v in self.qubit_operator.terms.items(): mk = tuple([(qubit_map[x[0]], x[1]) for x in k]) mapped_terms[mk] = v mapped = QubitOperator.zero() mapped.terms = mapped_terms return QubitHamiltonian(qubit_operator=mapped)
def remove_complex(H: QubitOperator, tiny=1e-8): ''' Removing near-zero complex coefficient ''' real_h = QubitOperator.zero() for term, val in H.terms.items(): if np.imag(val) < tiny: val = np.real(val) real_h += QubitOperator(term=term, coefficient=val) return real_h
def benchmark_linear_qubit_operator(n_qubits, n_terms, processes=None): """Test speed with getting a linear operator from a Qubit Operator. Args: n_qubits: The number of qubits, implying the dimension of the operator is 2 ** n_qubits. n_terms: The number of terms in a qubit operator. processes: The number of processors to use. Returns: runtime_operator: The time it takes to get the linear operator. runtime_matvec: The time it takes to perform matrix multiplication. """ # Generates Qubit Operator with specified number of terms. map_int_to_operator = { 0: 'X', 1: 'Y', 2: 'Z', } qubit_operator = QubitOperator.zero() for _ in range(n_terms): tuples = [] for i in range(n_qubits): operator = numpy.random.randint(4) # 3 is 'I', so just skip. if operator > 2: continue tuples.append((i, map_int_to_operator[operator])) if tuples: qubit_operator += QubitOperator(tuples, 1.00) # Gets an instance of (Parallel)LinearQubitOperator. start = time.time() if processes is None: linear_operator = LinearQubitOperator(qubit_operator, n_qubits) else: linear_operator = ParallelLinearQubitOperator( qubit_operator, n_qubits, LinearQubitOperatorOptions(processes=processes)) end = time.time() runtime_operator = end - start vec = numpy.random.rand(2**n_qubits) # Performs matrix multiplication. start = time.time() _ = linear_operator * vec end = time.time() runtime_matvec = end - start return runtime_operator, runtime_matvec
def __init__(self, qubit_hamiltonian: typing.Union[QubitOperator, str, numbers.Number] = None): """ Initialize from string or from a preexisting OpenFermion QubitOperator instance :param qubit_hamiltonian: string or openfermion.QubitOperator if string: Same conventions as openfermion if None: The Hamiltonian is initialized as identity operator if Number: initialized as scaled unit operator """ if isinstance(qubit_hamiltonian, str): self._qubit_operator = self.from_string(string=qubit_hamiltonian)._qubit_operator elif qubit_hamiltonian is None: self._qubit_operator = QubitOperator.zero() elif isinstance(qubit_hamiltonian, numbers.Number): self._qubit_operator = qubit_hamiltonian * QubitOperator.identity() else: self._qubit_operator = qubit_hamiltonian assert (isinstance(self._qubit_operator, QubitOperator))