Quanlse/Utils/RandomizedBenchmarking.py
def RB(model: PulseModel, targetQubitNum: int, initialState: ndarray, size: int, width: int,
       sche: SchedulerSuperconduct, dt: float, targetGate: FixedGateOP = None, interleaved: bool = False,
       isOpen: bool = False) -> float:
    r"""
    Return the sequence's average fidelity for different number of Clifford.

    :param model: the QHamiltonian object of the multi-qubit system.
    :param targetQubitNum: the index of the qubit being benchmarked.
    :param initialState: the initial state of the system.
    :param size: the number of Cliffords in a "width".
    :param width: the number of random sequence(s) for each "size".
    :param sche: the initiated scheduler.
    :param dt: AWG's sampling time.
    :param targetGate: the gate being benchmarked.
    :param interleaved: whether to use the interleaved benchmarking method.
    :param isOpen: whether to solve open system.
    :return: the average sequence fidelity of different number of Cliffords.
    """
    # Test inputs correctness
    if not isinstance(targetQubitNum, int):
        raise Error.ArgumentError("We only support single-qubit RB for now.")
    else:
        job = QJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt)
        ham = model.createQHamiltonian()
        jobs = ham.createJobList()
        # Get the RB-target qubit
        ham.job = job
        hamTarget = ham.subSystem(targetQubitNum)
        sche.clearCircuit()
        finalFidelity = []
        # Generate random Clifford
        a = 0
        while a < width:
            idx = np.random.randint(0, 24, size)
            b = 0
            clifford1qInvReg = []
            # Schedule m Clifford gates
            while b < size:
                if not interleaved:
                    clifford1q[idx[size - b - 1]](sche.Q[0])
                    clifford1qInvReg.append(clifford1q[idx[b]].getMatrix())
                else:
                    targetGate(sche.Q[0])
                    clifford1q[idx[size - b - 1]](sche.Q[0])
                    clifford1qInvReg.append(clifford1q[idx[b]].getMatrix() @ targetGate.getMatrix())
                b += 1
            # Schedule inverse Clifford
            gateUnitary = np.transpose(np.conjugate(reduce(np.dot, clifford1qInvReg)))
            [_, theta, phi, lamda] = fromMatrixToAngles(gateUnitary)
            U(theta, phi, lamda)(sche.Q[0])
            # Schedule the whole RB sequence
            jobTarget = sche.schedule()
            hamTarget.job = jobTarget
            jobScheFinal = hamTarget.outputInverseJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt)
            job = model.getSimJob(jobScheFinal)
            jobs.addJob(jobs=job)
            sche.clearCircuit()
            jobTarget.clearWaves()
            jobScheFinal.clearWaves()
            job.clearWaves()
            a += 1
        ham.buildCache()
        # Solve the ODE function
        if not isOpen:
            result = runHamiltonian(ham, state0=initialState, jobList=jobs)
        else:
            result = runHamiltonian(ham, state0=initialState, jobList=jobs, isOpen=True)
        rhoi = initialState @ ((initialState.transpose()).conjugate())
        for res in result.result:
            psit = res['state']
            rhot = psit @ ((psit.transpose()).conjugate())
            # Calculate the single sequence fidelity
            fidelity = 1 - np.real(rhoInfidelity(rhot, rhoi))
            finalFidelity.append(fidelity)
        ham.job.clearWaves()
        ham.clearCache()
        hamTarget.job.clearWaves()
        hamTarget.clearCache()
    return sum(finalFidelity) / width
r"""
    Return the sequence's average fidelity for different number of Clifford.

    :param model: the QHamiltonian object of the multi-qubit system.
    :param targetQubitNum: the index of the qubit being benchmarked.
    :param initialState: the initial state of the system.
    :param size: the number of Cliffords in a "width".
    :param width: the number of random sequence(s) for each "size".
    :param sche: the initiated scheduler.
    :param dt: AWG's sampling time.
    :param targetGate: the gate being benchmarked.
    :param interleaved: whether to use the interleaved benchmarking method.
    :param isOpen: whether to solve open system.
    :return: the average sequence fidelity of different number of Cliffords.
    
r"""
Return the sequence's average fidelity for different number of Clifford.
r " " " Return the sequence ' s average fidelity for different number of Clifford .
def RB(model: PulseModel, targetQubitNum: int, initialState: ndarray, size: int, width: int,
       sche: SchedulerSuperconduct, dt: float, targetGate: FixedGateOP = None, interleaved: bool = False,
       isOpen: bool = False) -> float:
    if not isinstance(targetQubitNum, int):
        raise Error.ArgumentError("We only support single-qubit RB for now.")
    else:
        job = QJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt)
        ham = model.createQHamiltonian()
        jobs = ham.createJobList()
        ham.job = job
        hamTarget = ham.subSystem(targetQubitNum)
        sche.clearCircuit()
        finalFidelity = []
        a = 0
        while a < width:
            idx = np.random.randint(0, 24, size)
            b = 0
            clifford1qInvReg = []
            while b < size:
                if not interleaved:
                    clifford1q[idx[size - b - 1]](sche.Q[0])
                    clifford1qInvReg.append(clifford1q[idx[b]].getMatrix())
                else:
                    targetGate(sche.Q[0])
                    clifford1q[idx[size - b - 1]](sche.Q[0])
                    clifford1qInvReg.append(clifford1q[idx[b]].getMatrix() @ targetGate.getMatrix())
                b += 1
            gateUnitary = np.transpose(np.conjugate(reduce(np.dot, clifford1qInvReg)))
            [_, theta, phi, lamda] = fromMatrixToAngles(gateUnitary)
            U(theta, phi, lamda)(sche.Q[0])
            jobTarget = sche.schedule()
            hamTarget.job = jobTarget
            jobScheFinal = hamTarget.outputInverseJob(subSysNum=model.subSysNum, sysLevel=model.sysLevel, dt=dt)
            job = model.getSimJob(jobScheFinal)
            jobs.addJob(jobs=job)
            sche.clearCircuit()
            jobTarget.clearWaves()
            jobScheFinal.clearWaves()
            job.clearWaves()
            a += 1
        ham.buildCache()
        if not isOpen:
            result = runHamiltonian(ham, state0=initialState, jobList=jobs)
        else:
            result = runHamiltonian(ham, state0=initialState, jobList=jobs, isOpen=True)
        rhoi = initialState @ ((initialState.transpose()).conjugate())
        for res in result.result:
            psit = res['state']
            rhot = psit @ ((psit.transpose()).conjugate())
            fidelity = 1 - np.real(rhoInfidelity(rhot, rhoi))
            finalFidelity.append(fidelity)
        ham.job.clearWaves()
        ham.clearCache()
        hamTarget.job.clearWaves()
        hamTarget.clearCache()
    return sum(finalFidelity) / width
def RB ( model : PulseModel , targetQubitNum : int , initialState : ndarray , size : int , width : int , sche : SchedulerSuperconduct , dt : float , targetGate : FixedGateOP = None , interleaved : bool = False , isOpen : bool = False ) -> float : if not isinstance ( targetQubitNum , int ) : raise Error . ArgumentError ( "We only support single-qubit RB for now." ) else : job = QJob ( subSysNum = model . subSysNum , sysLevel = model . sysLevel , dt = dt ) ham = model . createQHamiltonian ( ) jobs = ham . createJobList ( ) ham . job = job hamTarget = ham . subSystem ( targetQubitNum ) sche . clearCircuit ( ) finalFidelity = [ ] a = 0 while a < width : idx = np . random . randint ( 0 , 24 , size ) b = 0 clifford1qInvReg = [ ] while b < size : if not interleaved : clifford1q [ idx [ size - b - 1 ] ] ( sche . Q [ 0 ] ) clifford1qInvReg . append ( clifford1q [ idx [ b ] ] . getMatrix ( ) ) else : targetGate ( sche . Q [ 0 ] ) clifford1q [ idx [ size - b - 1 ] ] ( sche . Q [ 0 ] ) clifford1qInvReg . append ( clifford1q [ idx [ b ] ] . getMatrix ( ) @ targetGate . getMatrix ( ) ) b += 1 gateUnitary = np . transpose ( np . conjugate ( reduce ( np . dot , clifford1qInvReg ) ) ) [ _ , theta , phi , lamda ] = fromMatrixToAngles ( gateUnitary ) U ( theta , phi , lamda ) ( sche . Q [ 0 ] ) jobTarget = sche . schedule ( ) hamTarget . job = jobTarget jobScheFinal = hamTarget . outputInverseJob ( subSysNum = model . subSysNum , sysLevel = model . sysLevel , dt = dt ) job = model . getSimJob ( jobScheFinal ) jobs . addJob ( jobs = job ) sche . clearCircuit ( ) jobTarget . clearWaves ( ) jobScheFinal . clearWaves ( ) job . clearWaves ( ) a += 1 ham . buildCache ( ) if not isOpen : result = runHamiltonian ( ham , state0 = initialState , jobList = jobs ) else : result = runHamiltonian ( ham , state0 = initialState , jobList = jobs , isOpen = True ) rhoi = initialState @ ( ( initialState . transpose ( ) ) . conjugate ( ) ) for res in result . result : psit = res [ 'state' ] rhot = psit @ ( ( psit . transpose ( ) ) . conjugate ( ) ) fidelity = 1 - np . real ( rhoInfidelity ( rhot , rhoi ) ) finalFidelity . append ( fidelity ) ham . job . clearWaves ( ) ham . clearCache ( ) hamTarget . job . clearWaves ( ) hamTarget . clearCache ( ) return sum ( finalFidelity ) / width
r"""
Return the sequence's average fidelity for different number of Clifford.
r " " " Return the sequence ' s average fidelity for different number of Clifford .
r"""
    Return the sequence's average fidelity for different number of Clifford.

    :param model: the QHamiltonian object of the multi-qubit system.
    :param targetQubitNum: the index of the qubit being benchmarked.
    :param initialState: the initial state of the system.
    :param size: the number of Cliffords in a "width".
    :param width: the number of random sequence(s) for each "size".
    :param sche: the initiated scheduler.
    :param dt: AWG's sampling time.
    :param targetGate: the gate being benchmarked.
    :param interleaved: whether to use the interleaved benchmarking method.
    :param isOpen: whether to solve open system.
    :return: the average sequence fidelity of different number of Cliffords.
    """ # Test inputs correctness # Get the RB-target qubit # Generate random Clifford # Schedule m Clifford gates # Schedule inverse Clifford # Schedule the whole RB sequence # Solve the ODE function # Calculate the single sequence fidelity
the average sequence fidelity of different number of Cliffords.
the average sequence fidelity of different number of Cliffords .
model
PulseModel
the QHamiltonian object of the multi-qubit system.
the QHamiltonian object of the multi - qubit system .
targetQubitNum
int
the index of the qubit being benchmarked.
the index of the qubit being benchmarked .
initialState
ndarray
the initial state of the system.
the initial state of the system .
size
int
the number of Cliffords in a "width".
the number of Cliffords in a " width " .
width
int
the number of random sequence(s) for each "size".
the number of random sequence ( s ) for each " size " .
sche
SchedulerSuperconduct
the initiated scheduler.
the initiated scheduler .
dt
float
AWG's sampling time.
AWG ' s sampling time .
targetGate
FixedGateOP
the gate being benchmarked.
the gate being benchmarked .
interleaved
bool
whether to use the interleaved benchmarking method.
whether to use the interleaved benchmarking method .
isOpen
bool
whether to solve open system.
whether to solve open system .