Hadamard Gate Synthesis Example

Hadamard Gate Synthesis Example#

import qutip as qt
import qutip_qip.operations.gates as qip
import qutip_qtrl.pulseoptim as qtrl
from feedback_grape.utils.fidelity import fidelity
from feedback_grape.grape import optimize_pulse
from feedback_grape.utils.gates import hadamard
from feedback_grape.utils.operators import (
    identity,
    sigmax,
    sigmaz,
)
def get_targets_for_hadamard_problem():
    C_target_fg = hadamard()
    C_target_qt = qip.hadamard_transform(1)
    return C_target_fg, C_target_qt
def get_results_for_hadamard_problen(optimizer, propcomp):
    ###### General
    # Number of time slots
    n_ts = 10
    # Time allowed for the evolution
    evo_time = 10

    # Fidelity error target
    fid_err_targ = 1e-10
    # Maximum iterations for the optisation algorithm
    max_iter = 200
    # Maximum (elapsed) time allowed in seconds
    max_wall_time = 120
    # Minimum gradient (sum of gradients squared)
    # as this tends to 0 -> local minima has been found
    min_grad = 1e-20

    ###### Qutip QTRL
    # Drift Hamiltonian
    H_d = qt.sigmaz()
    # The (single) control Hamiltonian
    H_c = [qt.sigmax()]
    # start point for the gate evolution
    U_0 = qt.operators.identity(2)
    # Target for the gate evolution Hadamard gate
    U_targ = qip.hadamard_transform(1)

    p_type = 'SINE'
    result_qt = qtrl.optimize_pulse_unitary(
        H_d,
        H_c,
        U_0,
        U_targ,
        n_ts,
        evo_time,
        fid_err_targ=fid_err_targ,
        min_grad=min_grad,
        max_iter=max_iter,
        max_wall_time=max_wall_time,
        init_pulse_type=p_type,
        gen_stats=True,
    )

    ###### fg
    # Drift Hamiltonian
    H_d = sigmaz()
    # The (single) control Hamiltonian
    H_c = [sigmax()]
    # start point for the gate evolution
    U_0 = identity(2)
    # Target for the gate evolution Hadamard gate
    U_targ = hadamard()

    result_fg = optimize_pulse(
        H_d,
        H_c,
        U_0,
        U_targ,
        n_ts,
        evo_time,
        max_iter=max_iter,
        learning_rate=1e-2,
        optimizer=optimizer,
        evo_type="unitary",
        propcomp=propcomp,
    )

    return (result_fg, result_qt)
def get_finals(result_fg, result_qt):
    """
    Get the final operators for the given results.
    """
    # Final operator for fg
    final_operator_fg = result_fg.final_operator
    # Final operator for qt
    final_operator_qt = result_qt.evo_full_final

    return final_operator_fg, final_operator_qt
def test_hadamard(optimizer, propcomp):
    result_fg, result_qt = get_results_for_hadamard_problen(
        optimizer, propcomp
    )
    target_fg, target_qt = get_targets_for_hadamard_problem()
    final_operator_fg, final_operator_qt = get_finals(result_fg, result_qt)

    fidelity_qt = (
        abs((qt.Qobj(target_qt).dag() * qt.Qobj(final_operator_qt)).tr())
        / target_qt.shape[0]
    )
    fidelity_fg = fidelity(
        U_final=final_operator_fg,
        C_target=target_fg,
    )

    print("fidelity using qutip: ", fidelity_qt)
    print("fidelity using grape: ", fidelity_fg)

    print("result_qt.fid_err: ", 1 - result_qt.fid_err)
    print("result_fg.final_fidelity: ", result_fg.final_fidelity)
test_hadamard(
    optimizer="adam",
    propcomp="time-efficient",
)
fidelity using qutip:  0.9999999999999487
fidelity using grape:  0.9998742335426334
result_qt.fid_err:  0.9999999999999489
result_fg.final_fidelity:  0.9998742335426334