r"""Computable expression example (OverlapSquared)""" # A general way to convert familiar quantum chemistry expressions to measurement circuits. # imports from pytket import OpType from pytket.extensions.qiskit import AerBackend, AerStateBackend from inquanto.ansatzes import TrotterAnsatz from inquanto.computables import OverlapSquared from inquanto.operators import QubitOperatorString, QubitOperator, QubitOperatorList from inquanto.protocols import ComputeUncompute from inquanto.protocols import DestructiveSwapTest from inquanto.protocols import SwapTest from inquanto.protocols import SparseStatevectorProtocol from inquanto.states import QubitState # create a first simple ansatz state ansatz = TrotterAnsatz( QubitOperatorList.from_list([QubitOperator("Y0 X1 X2 X3", 1j)]), QubitState([1, 1, 0, 0]), ) # copy that state and change the symbol names so we have two similar states to test overlapping ansatz1 = ansatz.copy() ansatz1.symbol_substitution(r"{}_1") # instantiate backends backend = AerBackend() state_backend = AerStateBackend() # make two sets of Dicts to substitute into our two states # if the single symbol is set to the same value the states are identical and overlap^2=1 p = ansatz.state_symbols.construct_from_array([0.005]) p1 = ansatz1.state_symbols.construct_from_array([-0.111]) # combine the two dicts into 1 new one parameters = p.copy() parameters.update(p1) operator = QubitOperatorString.from_string("Z0") # protocol for ||^2 overlap_squared1 = OverlapSquared(ansatz, ansatz1) # protocol for ||^2 overlap_squared2 = OverlapSquared(ansatz, ansatz1, kernel=operator) # first demonstrate exact evaluation with the statevector backend sv_protocol = SparseStatevectorProtocol(state_backend) print(f"protocol: {sv_protocol.__class__.__name__}:") runner1 = sv_protocol.get_runner(overlap_squared1) runner2 = sv_protocol.get_runner(overlap_squared2) print("||^2 :", runner1(parameters)) print("||^2 :", runner2(parameters)) # make a list of protocols which can report overlap squared to iterate over for comparison protocols = [ ComputeUncompute(backend, 10000), SwapTest(backend, 10000), DestructiveSwapTest(backend, 10000), ] # evaluate the computables using the various protocols and print results for protocol in protocols: runner1 = protocol.get_runner(overlap_squared1) print(f"protocol: {protocol.__class__.__name__}:") print("||^2 :", runner1(parameters)) # runs the runner (build+run+evaluate) print("CX count: " + str(protocol.get_circuits()[0].n_gates_of_type(OpType.CX))) # print('Number of measurement circuits: ' +str(len(protocol.get_circuits()))) runner2 = protocol.get_runner(overlap_squared2) print("||^2 :", runner2(parameters)) # runs the runner (build+run+evaluate) print("CX count: " + str(protocol.get_circuits()[0].n_gates_of_type(OpType.CX)))