2.2 Wave Function Overlap by Randomized Measurement#


Basic Usage#

a. Import the instances#

from qurry import WaveFunctionOverlap

experiment_randomized = WaveFunctionOverlap()
# It's default method. WaveFunctionOverlap(method='randomized') also works

# or another short name
# from qurry import EchoListen
# experiment_hadamard = EchoListen()

b. Preparing quantum circuit#

from qiskit import QuantumCircuit
from qurry.recipe import TrivialParamagnet, GHZ
sample01 = TrivialParamagnet(8)
print("| trivial paramagnet in 8 qubits:")
print(sample01)
| trivial paramagnet in 8 qubits:
     ┌───┐
q_0: ┤ H ├
     ├───┤
q_1: ┤ H ├
     ├───┤
q_2: ┤ H ├
     ├───┤
q_3: ┤ H ├
     ├───┤
q_4: ┤ H ├
     ├───┤
q_5: ┤ H ├
     ├───┤
q_6: ┤ H ├
     ├───┤
q_7: ┤ H ├
     └───┘
sample02 = GHZ(8)
print("| GHZ in 8 qubits:")
print(sample02)
| GHZ in 8 qubits:
     ┌───┐                                   
q_0: ┤ H ├──■────────────────────────────────
     └───┘┌─┴─┐                              
q_1: ─────┤ X ├──■───────────────────────────
          └───┘┌─┴─┐                         
q_2: ──────────┤ X ├──■──────────────────────
               └───┘┌─┴─┐                    
q_3: ───────────────┤ X ├──■─────────────────
                    └───┘┌─┴─┐               
q_4: ────────────────────┤ X ├──■────────────
                         └───┘┌─┴─┐          
q_5: ─────────────────────────┤ X ├──■───────
                              └───┘┌─┴─┐     
q_6: ──────────────────────────────┤ X ├──■──
                                   └───┘┌─┴─┐
q_7: ───────────────────────────────────┤ X ├
                                        └───┘
sample03 = QuantumCircuit(8)
sample03.x(range(0, 8, 2))
print("| Custom circuit:")
print(sample03)
| Custom circuit:
     ┌───┐
q_0: ┤ X ├
     └───┘
q_1: ─────
     ┌───┐
q_2: ┤ X ├
     └───┘
q_3: ─────
     ┌───┐
q_4: ┤ X ├
     └───┘
q_5: ─────
     ┌───┐
q_6: ┤ X ├
     └───┘
q_7: ─────
          

c. Execute the circuit#

i. Directly input the circuit#

After executing, it will return a uuid of experiment. You can use this uuid to get the result of the experiment.

exp1 = experiment_randomized.measure(sample01, sample01, times=100, shots=4096)
exp1
'b1ff9de2-0ba3-478f-98c9-cc61eb290d13'

Each experiment result will be stored in a container .exps.

experiment_randomized.exps[exp1]
<EchoListenRandomizedExperiment(exp_id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13, 
  EchoListenRandomizedArguments(exp_name='experiment.N_U_100.qurrech_randomized', times=100, qubits_measured_1=[0, 1, 2, 3, 4, 5, 6, 7], qubits_measured_2=[0, 1, 2, 3, 4, 5, 6, 7], registers_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, registers_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, actual_num_qubits_1=8, actual_num_qubits_2=8, unitary_located_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, unitary_located_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, second_backend=None, second_transpile_args=None, random_unitary_seeds=None),
  Commonparams(exp_id='b1ff9de2-0ba3-478f-98c9-cc61eb290d13', target_keys=[0, 1], shots=4096, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-06-26 11:45:46', 'run.001': '2025-06-26 11:45:46'})),
  unused_args_num=0,
  analysis_num=0))>
experiment_randomized.exps[exp1].args._asdict()
{'exp_name': 'experiment.N_U_100.qurrech_randomized',
 'times': 100,
 'qubits_measured_1': [0, 1, 2, 3, 4, 5, 6, 7],
 'qubits_measured_2': [0, 1, 2, 3, 4, 5, 6, 7],
 'registers_mapping_1': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
 'registers_mapping_2': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
 'actual_num_qubits_1': 8,
 'actual_num_qubits_2': 8,
 'unitary_located_mapping_1': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
 'unitary_located_mapping_2': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
 'second_backend': None,
 'second_transpile_args': None,
 'random_unitary_seeds': None}

And use this uuid to access the experiments to execute post-processing.

report01 = experiment_randomized.exps[exp1].analyze(
    selected_classical_registers=[0, 1, 2, 3],
)
report01
<ELRAnalysis(
  serial=0,
  ELRAnalysisInput(registers_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, registers_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, bitstring_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, bitstring_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, shots=4096, unitary_located_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, unitary_located_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}),
  ELRAnalysisContent(echo=1.0222416800260543, and others)),
  unused_args_num=0
  )>
main01, side_product01 = report01.export()
main01
{'echo': np.float64(1.0222416800260543),
 'echoSD': np.float64(0.9954789763938757),
 'num_classical_registers': 8,
 'classical_registers': [0, 1, 2, 3],
 'classical_registers_actually': [0, 1, 2, 3],
 'counts_num': 100,
 'taking_time': 0.002551107,
 'counts_used': None,
 'input': {'registers_mapping_1': {0: 0,
   1: 1,
   2: 2,
   3: 3,
   4: 4,
   5: 5,
   6: 6,
   7: 7},
  'registers_mapping_2': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
  'bitstring_mapping_1': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
  'bitstring_mapping_2': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7},
  'shots': 4096,
  'unitary_located_mapping_1': {0: 0,
   1: 1,
   2: 2,
   3: 3,
   4: 4,
   5: 5,
   6: 6,
   7: 7},
  'unitary_located_mapping_2': {0: 0,
   1: 1,
   2: 2,
   3: 3,
   4: 4,
   5: 5,
   6: 6,
   7: 7}},
 'header': {'serial': 0, 'datetime': '2025-06-26 11:45:47', 'log': {}}}

ii. Add the circuits to container .waves, then call them later.#

Since we have executed an experiment, the circuit we input in exp1 is stored in the container .waves with serial number 0.

experiment_randomized.waves
WaveContainer({
  0: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x775155ae4590>,
  1: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x775155ae4590>})

But we can also add the circuit to the container .waves with a custom name. The name should be unique, otherwise it will be overwritten. The method add will return the actual name of the circuit in the container.

print(experiment_randomized.add(sample02, "ghz_8"))
print(experiment_randomized.waves["ghz_8"])
ghz_8
     ┌───┐                                   
q_0: ┤ H ├──■────────────────────────────────
     └───┘┌─┴─┐                              
q_1: ─────┤ X ├──■───────────────────────────
          └───┘┌─┴─┐                         
q_2: ──────────┤ X ├──■──────────────────────
               └───┘┌─┴─┐                    
q_3: ───────────────┤ X ├──■─────────────────
                    └───┘┌─┴─┐               
q_4: ────────────────────┤ X ├──■────────────
                         └───┘┌─┴─┐          
q_5: ─────────────────────────┤ X ├──■───────
                              └───┘┌─┴─┐     
q_6: ──────────────────────────────┤ X ├──■──
                                   └───┘┌─┴─┐
q_7: ───────────────────────────────────┤ X ├
                                        └───┘

If there is a circuit with the same name, it will be replaced by the new one.

print(experiment_randomized.add(sample03, "ghz_8"))
print(experiment_randomized.waves["ghz_8"])
ghz_8
     ┌───┐
q_0: ┤ X ├
     └───┘
q_1: ─────
     ┌───┐
q_2: ┤ X ├
     └───┘
q_3: ─────
     ┌───┐
q_4: ┤ X ├
     └───┘
q_5: ─────
     ┌───┐
q_6: ┤ X ├
     └───┘
q_7: ─────
          

Otherwise, you will need to use replace="duplicate" to prevent it from being replaced.

duplicated_case01 = experiment_randomized.add(sample02, "ghz_8", replace="duplicate")
print(duplicated_case01)
print(experiment_randomized.waves[duplicated_case01])
ghz_8.3
     ┌───┐                                   
q_0: ┤ H ├──■────────────────────────────────
     └───┘┌─┴─┐                              
q_1: ─────┤ X ├──■───────────────────────────
          └───┘┌─┴─┐                         
q_2: ──────────┤ X ├──■──────────────────────
               └───┘┌─┴─┐                    
q_3: ───────────────┤ X ├──■─────────────────
                    └───┘┌─┴─┐               
q_4: ────────────────────┤ X ├──■────────────
                         └───┘┌─┴─┐          
q_5: ─────────────────────────┤ X ├──■───────
                              └───┘┌─┴─┐     
q_6: ──────────────────────────────┤ X ├──■──
                                   └───┘┌─┴─┐
q_7: ───────────────────────────────────┤ X ├
                                        └───┘

Now we have prepared the circuit and stored it in the container .waves.

experiment_randomized.waves
WaveContainer({
  0: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x775155ae4590>,
  1: <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x775155ae4590>,
  'ghz_8': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x775155ae1010>,
  'ghz_8.3': <qurry.recipe.simple.cat.GHZ object at 0x775155ae63c0>})

Finally, we can execute the circuit and get the result.

exp2 = experiment_randomized.measure("ghz_8.3", sample01, times=100, shots=4096)
exp2
'1efa40ac-a65f-458d-9cbf-d0adc330d4d5'
experiment_randomized.exps[exp2]
<EchoListenRandomizedExperiment(exp_id=1efa40ac-a65f-458d-9cbf-d0adc330d4d5, 
  EchoListenRandomizedArguments(exp_name='experiment.N_U_100.qurrech_randomized', times=100, qubits_measured_1=[0, 1, 2, 3, 4, 5, 6, 7], qubits_measured_2=[0, 1, 2, 3, 4, 5, 6, 7], registers_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, registers_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, actual_num_qubits_1=8, actual_num_qubits_2=8, unitary_located_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, unitary_located_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, second_backend=None, second_transpile_args=None, random_unitary_seeds=None),
  Commonparams(exp_id='1efa40ac-a65f-458d-9cbf-d0adc330d4d5', target_keys=['ghz_8.3', 4], shots=4096, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-06-26 11:46:01', 'run.001': '2025-06-26 11:46:01'})),
  unused_args_num=0,
  analysis_num=0))>
report02 = experiment_randomized.exps[exp2].analyze(
    selected_classical_registers=[0, 1, 2, 3],
)
report02
<ELRAnalysis(
  serial=0,
  ELRAnalysisInput(registers_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, registers_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, bitstring_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, bitstring_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, shots=4096, unitary_located_mapping_1={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, unitary_located_mapping_2={0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}),
  ELRAnalysisContent(echo=0.06789519727230071, and others)),
  unused_args_num=0
  )>

d. Export them after all#

exp1_id, exp1_files_info = experiment_randomized.exps[exp1].write(
    save_location=".",  # where to save files
)
exp1_files_info
{'folder': 'experiment.N_U_100.qurrech_randomized.001',
 'qurryinfo': 'experiment.N_U_100.qurrech_randomized.001/qurryinfo.json',
 'args': 'experiment.N_U_100.qurrech_randomized.001/args/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.args.json',
 'advent': 'experiment.N_U_100.qurrech_randomized.001/advent/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.advent.json',
 'legacy': 'experiment.N_U_100.qurrech_randomized.001/legacy/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.legacy.json',
 'tales.unitaryOP': 'experiment.N_U_100.qurrech_randomized.001/tales/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.unitaryOP.json',
 'tales.randomized': 'experiment.N_U_100.qurrech_randomized.001/tales/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.randomized.json',
 'reports': 'experiment.N_U_100.qurrech_randomized.001/reports/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.reports.json',
 'reports.tales.echoCells': 'experiment.N_U_100.qurrech_randomized.001/tales/experiment.N_U_100.qurrech_randomized.001.id=b1ff9de2-0ba3-478f-98c9-cc61eb290d13.echoCells.reports.json'}

Post-Process Availablities and Version Info#

from qurry.process import AVAIBILITY_STATESHEET

AVAIBILITY_STATESHEET
 | Qurrium version: 0.13.0
---------------------------------------------------------------------------
 ### Qurrium Post-Processing
   - Backend Availability ................... Python Cython Rust   JAX   
 - randomized_measure
   - entangled_entropy.entropy_core_2 ....... Yes    Depr.  Yes    No    
   - entangle_entropy.purity_cell_2 ......... Yes    Depr.  Yes    No    
   - entangled_entropy_v1.entropy_core ...... Yes    Depr.  Yes    No    
   - entangle_entropy_v1.purity_cell ........ Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_core_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_cell_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_core ...... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_cell ...... Yes    Depr.  Yes    No    
 - hadamard_test
   - purity_echo_core ....................... Yes    No     Yes    No    
 - magnet_square
   - magnsq_core ............................ Yes    No     Yes    No    
 - string_operator
   - strop_core ............................. Yes    No     Yes    No    
 - classical_shadow
   - rho_m_core ............................. Yes    No     No     Yes   
 - utils
   - randomized ............................. Yes    Depr.  Yes    No    
   - counts_process ......................... Yes    No     Yes    No    
   - bit_slice .............................. Yes    No     Yes    No    
   - dummy .................................. Yes    No     Yes    No    
   - test ................................... Yes    No     Yes    No    
---------------------------------------------------------------------------
   + Yes ...... Working normally.
   + Error .... Exception occurred.
   + No ....... Not supported.
   + Depr. .... Deprecated.
---------------------------------------------------------------------------
by <Hoshi>