def bravyi_kitaev(operator, n_qubits=None): """Apply the Bravyi-Kitaev transform. Implementation from arXiv:quant-ph/0003137 and "A New Data Structure for Cumulative Frequency Tables" by Peter M. Fenwick. Note that this implementation is equivalent to the one described in arXiv:1208.5986, and is different from the one described in arXiv:1701.07072. The one described in arXiv:1701.07072 is implemented in OpenFermion as `bravyi_kitaev_tree`. Args: operator (openfermion.ops.FermionOperator): A FermionOperator to transform. n_qubits (int|None): Can force the number of qubits in the resulting operator above the number that appear in the input operator. Returns: transformed_operator: An instance of the QubitOperator class. Raises: ValueError: Invalid number of qubits specified. """ # Compute the number of qubits. if n_qubits is None: n_qubits = count_qubits(operator) if n_qubits < count_qubits(operator): raise ValueError('Invalid number of qubits specified.') # Compute transformed operator. transformed_terms = (_transform_operator_term( term=term, coefficient=operator.terms[term], n_qubits=n_qubits) for term in operator.terms) return inline_sum(summands=transformed_terms, seed=QubitOperator())
def _bravyi_kitaev_majorana_operator(operator, n_qubits): # Compute the number of qubits. N = count_qubits(operator) if n_qubits is None: n_qubits = N if n_qubits < N: raise ValueError('Invalid number of qubits specified.') # Compute transformed operator. transformed_terms = ( _transform_majorana_term(term=term, coefficient=coeff, n_qubits=n_qubits) for term, coeff in operator.terms.items() ) return inline_sum(summands=transformed_terms, seed=QubitOperator())
def bravyi_kitaev_tree(operator, n_qubits=None): """Apply the "tree" Bravyi-Kitaev transform. Implementation from arxiv:1701.07072 Note that this implementation is different from the one described in arXiv:quant-ph/0003137. In particular, it gives different results when the total number of modes is not a power of 2. The one described in arXiv:quant-ph/0003137 is the same as the one described in arXiv:1208.5986, and it is implemented in OpenFermion under the name `bravyi_kitaev`. Args: operator (openfermion.ops.FermionOperator): A FermionOperator to transform. n_qubits (int|None): Can force the number of qubits in the resulting operator above the number that appear in the input operator. Returns: transformed_operator: An instance of the QubitOperator class. Raises: ValueError: Invalid number of qubits specified. """ # Compute the number of qubits. from openfermion.utils import count_qubits if n_qubits is None: n_qubits = count_qubits(operator) if n_qubits < count_qubits(operator): raise ValueError('Invalid number of qubits specified.') # Build the Fenwick tree. fenwick_tree = FenwickTree(n_qubits) # Compute transformed operator. transformed_terms = (_transform_operator_term( term=term, coefficient=operator.terms[term], fenwick_tree=fenwick_tree) for term in operator.terms) return inline_sum(summands=transformed_terms, seed=QubitOperator())