I am building up my understanding of running the GHZ circuit on qpu:ascella.
The attached code runs on a noisy simulator. I increase the noise level to observe how the probability of measuring the 000 or 111 states is affected. However, the results do not look very promising.
With the following configuration (very low noise level):
source = pcvl.Source(emission_probability=0.95, multiphoton_component=0.01)
I observe a reasonable fidelity: n0+n1/ns=0.675. Acceptable.
However, with this setup:
source = pcvl.Source(emission_probability=0.65, multiphoton_component=0.01)
The fidelity drops to n0+n1/ns=0.080
For qpu:ascella, I believe this is the appropriate configuration:
source = pcvl.Source(emission_probability=0.25, multiphoton_component=0.01)
In this case, the fidelity becomes n0+n1/ns=0.002, meaning only about 2 out of 1000 successful measurements would yield the GHZ state on qpu:ascella.
Is my circuit correct? Is my noise model too harsh? Could I make any improvements to increase the probability of measuring the 3-qubit GHZ state on the HW?
Thank you for your guidance and insights.
Jan
# cat noisy_ghz.py
import perceval as pcvl
from perceval.algorithm import Sampler
import numpy as np
print('perceval ver:',pcvl.__version__)
cnot = pcvl.catalog["heralded cnot"].build_processor()
source = pcvl.Source(emission_probability=0.25, multiphoton_component=0.01)
#source=None # activate to disable noise
num_qubit=3 # <=== change GHZ state size here
num_mode=2*num_qubit
min_photon=num_qubit + 2 * (num_qubit - 1)
# Set detected photons filter and circuit
proc = pcvl.Processor("SLOS",num_mode,source)
proc.min_detected_photons_filter(num_photon)
proc.add(0, pcvl.BS.H())
for j in range(num_qubit-1):
proc.add(2*j, cnot)
pcvl.pdisplay(proc)
# Run the simulation
shots = 10_000
sampler = Sampler(proc, max_shots_per_call=shots)
st0=pcvl.BasicState([1,0]*num_qubit) # all qubits in 0-state
st1=pcvl.BasicState([0,1]*num_qubit) # all qubits in 1-state
proc.with_input(st0 )
resD=sampler.sample_count()
photC=resD['results'] # number of photons in each mode.
n0=0
n1=0
k=0
for phSt, count in photC.items():
tag=' '
if phSt==st0:
n0=count
tag='*'
if phSt==st1:
n1=count
tag='*'
if k<15 or tag=='*':
print('%s meas phSt %s, count %d'%(tag,phSt,count))
else: print('.',end='')
k+=1
print('\ntransmission: %.2e num final states: %d'%(resD['physical_perf'], k))
print('0s prob: %.4f'% (n0/shots))
print('1s prob: %.4f'% (n1/shots))
print(' num sigma: |no-n1|/sqrt(n0+n1)=%.3f '%( abs(n0-n1)/np.sqrt(n0+n1)))
print('asymmetry: n0-n1/n0+n1 =%.4f'%( (n0-n1)/(n0+n1)))
print('fidelity: n0+n1/ns=%.3f'%((n0+n1)/shots))