def test_derivative_wrt_pulse_zero(tls_control_system):
    """Test that μ=0 if taking derivative wrt pulse not in objective"""
    objectives, pulses, pulses_mapping = tls_control_system
    # distinction between controls and pulses doesn't matter here, we're only
    # considering linear controls and don't plug in any time_index
    i_objective = 0
    mu = krotov.mu.derivative_wrt_pulse(
        objectives,
        i_objective,
        pulses,
        pulses_mapping,
        i_pulse=1,
        time_index=0,
    )
    for state in (ket('0'), ket('1')):
        assert mu(state).norm('max') == 0
        assert (mu(state)).dims == state.dims

    i_objective = 1
    mu = krotov.mu.derivative_wrt_pulse(
        objectives,
        i_objective,
        pulses,
        pulses_mapping,
        i_pulse=0,
        time_index=0,
    )
    for state in (ket('0'), ket('1')):
        assert mu(state).norm('max') == 0
        assert (mu(state)).dims == state.dims
Exemple #2
0
def test_chi_hs_transmon(transmon_3states_objectives):
    objectives = transmon_3states_objectives
    n_qubit = objectives[0].initial_state.dims[0][0]
    ket00 = qutip.ket((0, 0), dim=(n_qubit, n_qubit))
    ket01 = qutip.ket((0, 1), dim=(n_qubit, n_qubit))
    ket10 = qutip.ket((1, 0), dim=(n_qubit, n_qubit))
    ket11 = qutip.ket((1, 1), dim=(n_qubit, n_qubit))
    ρ_mixed = 0.25 * (ket00 * ket00.dag() + ket01 * ket01.dag() +
                      ket10 * ket10.dag() + ket11 * ket11.dag())
    assert (ρ_mixed * ρ_mixed).tr() == 0.25
    assert (ρ_mixed - objectives[2].target).norm('max') < 1e-14
    fw_states_T = [ρ_mixed, ρ_mixed, ρ_mixed]
    χs = krotov.functionals.chis_hs(fw_states_T, objectives, None)
    χ1 = (1 / 6.0) * (60.0 / 22.0) * (objectives[0].target - ρ_mixed)
    χ2 = (1 / 6.0) * (3.0 / 22.0) * (objectives[1].target - ρ_mixed)
    χ3 = 0.0 * ρ_mixed
    assert (χs[0] - χ1).norm('max') < 1e-14
    assert (χs[1] - χ2).norm('max') < 1e-14
    assert (χs[2] - χ3).norm('max') < 1e-14

    # without weights
    objectives = copy.deepcopy(objectives)
    for obj in objectives:
        del obj.weight
    χs = krotov.functionals.chis_hs(fw_states_T, objectives, None)
    χ1 = (1 / 6.0) * (objectives[0].target - ρ_mixed)
    χ2 = (1 / 6.0) * (objectives[1].target - ρ_mixed)
    χ3 = 0.0 * ρ_mixed
    assert (χs[0] - χ1).norm('max') < 1e-14
    assert (χs[1] - χ2).norm('max') < 1e-14
    assert (χs[2] - χ3).norm('max') < 1e-14
Exemple #3
0
def teleport(state, mres):
    q0, q1 = map(int, twoQ_basis[mres])

    s0_name = twoQ_basis[mres] + '0'
    s1_name = twoQ_basis[mres] + '1'
    s0 = qt.bra(s0_name)
    s1 = qt.bra(s1_name)

    a = (s0 * state).tr()
    b = (s1 * state).tr()
    red_state = (a * qt.ket([0], 2) + b * qt.ket([1], 2)).unit()

    H = Gate('SNOT', targets=0)
    sqrtX = Gate('SQRTNOT', targets=0)
    qc = QubitCircuit(N=1)

    if q1 == 1:
        qc.add_gate(sqrtX)
        qc.add_gate(sqrtX)
    if q0 == 1:
        qc.add_gate(H)
        qc.add_gate(sqrtX)
        qc.add_gate(sqrtX)
        qc.add_gate(H)
    gates_sequence = qc.propagators()
    scheme = oper.gate_sequence_product(gates_sequence)

    return scheme * red_state
def test_derivative_wrt_pulse_no_timedependent_cops(tls_control_system_tdcops):
    """Test that time-dependent collapse operators are no allowed"""
    objectives, pulses, pulses_mapping = tls_control_system_tdcops
    i_objective = 0
    with pytest.raises(NotImplementedError):
        krotov.mu.derivative_wrt_pulse(
            objectives,
            i_objective,
            pulses,
            pulses_mapping,
            i_pulse=0,
            time_index=0,
        )
    # however, we do allow the c_ops to be time-dependent with controls we're
    # not taking the derivative with respect to
    mu = krotov.mu.derivative_wrt_pulse(
        objectives,
        i_objective,
        pulses,
        pulses_mapping,
        i_pulse=1,
        time_index=0,
    )
    for state in (ket('0'), ket('1')):
        assert mu(state).norm('max') == 0
        assert (mu(state)).dims == state.dims
Exemple #5
0
def infer_classical_state(qubits, idx, subset=None):
    """
    Finds classical state of n qubits given index of basis state in H2^n.

    Input
    --------------------------------------------------
    qubits: list--qubits in numeric order
    idx: int--index of '1' in basis state of 2^n dimensional Hilbert space
    subset: optional list--only output state of qubits in subset list

    Output
    --------------------------------------------------
    state: dict--{q0: qutip ket 0 or ket 1, ...}
    """
    state = {}
    num_qubits = len(qubits)
    if subset is None:
        subset = qubits
    # find classical state of qubits with tensor product ordering assumption
    for (n, qubit) in enumerate(qubits):
        if qubit in subset:
            power = num_qubits - n
            mod = 2**power
            cut_off = mod / 2
            if idx % mod >= cut_off:
                state[qubit] = qt.ket('1')
            else:
                state[qubit] = qt.ket('0')

    return state
Exemple #6
0
def simple_state_to_state_system():
    """System from 01_example_simple_state_to_state.ipynb"""
    omega = 1.0
    ampl0 = 0.2

    H0 = -0.5 * omega * qutip.operators.sigmaz()
    H1 = qutip.operators.sigmax()
    eps0 = lambda t, args: ampl0
    H = [H0, [H1, eps0]]

    psi0 = qutip.ket('0')
    psi1 = qutip.ket('1')

    objectives = [krotov.Objective(initial_state=psi0, target=psi1, H=H)]

    def S(t):
        """Shape function for the field update"""
        return krotov.shapes.flattop(
            t, t_start=0, t_stop=5, t_rise=0.3, t_fall=0.3, func='sinsq'
        )

    pulse_options = {H[1][1]: dict(lambda_a=5, update_shape=S)}

    tlist = np.linspace(0, 5, 500)

    return objectives, pulse_options, tlist
Exemple #7
0
def test_summarize_component_direct():
    krotov.objectives.Objective.reset_symbol_counters()

    H = ['H0', ['H1', 2j]]
    res = krotov.objectives._summarize_component(H, 'op')
    expected = '[H0, [H1, 2j]]'
    assert res == expected

    with pytest.raises(ValueError):
        krotov.objectives._summarize_component(H, 'invalid')

    ket0 = qutip.ket('0')
    ket1 = qutip.ket('1')
    ket2 = copy.deepcopy(ket0)
    assert krotov.objectives._summarize_component(ket0, 'state') == '|Ψ₀(2)⟩'
    assert krotov.objectives._summarize_component(ket1, 'state') == '|Ψ₁(2)⟩'
    assert krotov.objectives._summarize_component(ket2, 'state') == '|Ψ₂(2)⟩'
    krotov.objectives.Objective.reset_symbol_counters()
    assert krotov.objectives._summarize_component(ket2, 'state') == '|Ψ₀(2)⟩'

    H = qutip.sigmaz()
    assert krotov.objectives._summarize_component(H, 'op') == 'H₀[2,2]'
    assert krotov.objectives._summarize_component(H, 'lindblad') == 'L₀[2,2]'

    krotov.objectives.Objective.reset_symbol_counters()
Exemple #8
0
    def frem_anneal(self, fsch, rsch, rinit, partition, disc=0.0001, history=False):
        """
        Performs a numeric FREM anneal on H using QuTip.

        Inputs:
        ---------
        *fsch: list--forward annealing schedule [[t0, 0], ..., [tf, 1]]
        *rsch: list--reverse annealing schedule [[t0, 1], ..., [tf, 1]]
        *rinit: dict--initial state of HR
        *partition: dict--contains F-parition (HF), R-partition (HR),
        and Rqubits {'HF': {HF part}, 'HR': {HR part}, 'Rqubits': [list]}
        *disc: float--discretization between times in numeric anneal
        *history: bool--False final prob vector; True all intermediate states

        Outputs:
        ---------
        *final_state: numpy array--if history is True, then
        contains wave function amps with tensor product ordering
        else: contains sesolve output with all intermediate states
        """
        # slim down rinit to only those states relevant for R partition
        Rstate = {q: rinit[q] for q in rinit if q in partition['Rqubits']}
        # add pause to f/r schedule if it is shorter than the other
        Tf = fsch[-1][0]
        Tr = rsch[-1][0]
        rdiff = Tr - Tf
        if rdiff != 0:
            if rdiff > 0:
                fsch.append([Tf + rdiff, 1])
            else:
                rsch.append([Tr + (-1 * rdiff), 1])
        # prepare Hamiltonian/ weight function list for QuTip se solver
        fsch = utils.make_numeric_schedule(fsch, disc)
        rsch = utils.make_numeric_schedule(rsch, disc)
        fsch_A, fsch_B = utils.time_interpolation(fsch, self.processor_data)
        rsch_A, rsch_B = utils.time_interpolation(rsch, self.processor_data)        
        # list H for schrodinger equation solver
        f_Hx, f_Hz, r_Hx, r_Hz = utils.get_frem_Hs(self.qubits, partition)
        listH = [[f_Hx, fsch_A], [f_Hz, fsch_B], [r_Hx, rsch_A], [r_Hz, rsch_B]]

        # create the initial state vector for the FREM anneal
        statelist = []
        xstate = (qt.ket('0') - qt.ket('1')).unit()
        for qubit in self.qubits:
            if qubit in Rstate:
                statelist.append(Rstate[qubit])
            else:
                statelist.append(xstate)
        init_state = qt.tensor(*statelist)

        # run the numerical simulation and extract the final state
        results = qt.sesolve(listH, init_state, fsch[0])

        # only output final result if history is set to False
        if history is False:
            state = utils.qto_to_npa(results.states[-1])
            probs = (state.conj()*state).real
            return probs
        return results
Exemple #9
0
 def test_base_2_or_e(self):
     rho = qutip.ket2dm(qutip.ket("00"))
     sigma = rho + qutip.ket2dm(qutip.ket("01"))
     sigma = sigma.unit()
     assert (qutip.entropy_relative(rho, sigma) == pytest.approx(np.log(2)))
     assert (qutip.entropy_relative(rho, sigma,
                                    base=np.e) == pytest.approx(0.69314718))
     assert qutip.entropy_relative(rho, sigma, base=2) == pytest.approx(1)
Exemple #10
0
def test_gate_objectives_single_qubit_gate():
    """Test initialization of objectives for simple single-qubit gate"""
    basis = [ket([0]), ket([1])]
    gate = sigmay()  # = -i|0⟩⟨1| + i|1⟩⟨0|
    H = [sigmaz(), [sigmax(), lambda t, args: 1.0]]
    objectives = krotov.objectives.gate_objectives(basis, gate, H)
    assert objectives == [
        krotov.Objective(initial_state=basis[0], target=(1j * basis[1]), H=H),
        krotov.Objective(initial_state=basis[1], target=(-1j * basis[0]), H=H),
    ]
Exemple #11
0
def test_gate_objectives_shape_error():
    """Test that trying to construct gate objectives with a gate whose shape
    mismatches the basis throws an exception"""
    basis = [qutip.ket([0]), qutip.ket([1])]
    gate = qutip.tensor(qutip.operators.sigmay(), qutip.identity(2))
    H = [
        qutip.operators.sigmaz(),
        [qutip.operators.sigmax(), lambda t, args: 1.0],
    ]
    with pytest.raises(ValueError) as exc_info:
        krotov.objectives.gate_objectives(basis, gate, H)
    assert "same dimension as the number of basis" in str(exc_info.value)
Exemple #12
0
    def numeric_anneal(self, sch, disc=0.0001, init_state=None, history=False):
        """
        Performs in-house (QuTiP based) numeric anneal.

        Input
        --------------------
        *usch: list -- [[t0, s0], [t1, s1], ..., [tn, sn]]
        *disc (0.01): float -- discretization used between times
        *init_state (None): dict -- maps qubits to up (1) or down (0)
        None means calculate here as gs of Hx (for forward)
        *history: bool, True means return all intermediate states
        False returns only final probability vector

        Output
        --------------------
        if history == None:
            outputs-->(energy, state)
            energy: float, energy of final state reached
            state: numpy array of wave-function amplitudes
        else:
            outputs-->QuTip result
        """
        # create numeric anneal schedule
        sch = utils.make_numeric_schedule(sch, disc)
        # interpolate A and B according to schedule
        sch_A, sch_B = utils.time_interpolation(sch, self.processor_data)
        # list H for schrodinger equation solver
        listH = [[self.num_Hx, sch_A], [self.num_Hz, sch_B]]
        # calculate ground-state at H(t=0) if init_state not specified            
        if init_state is None:
            xstate = (qt.ket('0') - qt.ket('1')).unit()
            statelist = [xstate for i in range(len(self.qubits))]
            init_state = qt.tensor(*statelist)

        else:
            statelist = []
            for qubit in self.qubits:
                if qubit in init_state:
                    statelist.append(init_state[qubit])
                else:
                    raise ValueError("init_state does not specify state of qubit {}".format(qubit))
            init_state = qt.tensor(*statelist)
            
        # peform a numerical anneal on H (sch[0] is list of discrete times)
        results = qt.sesolve(listH, init_state, sch[0])

        # only output final result if history set to False
        if history is False:
            state = utils.qto_to_npa(results.states[-1])
            probs = (state.conj()*state).real
            return probs
        return results
Exemple #13
0
 def test_rho_and_sigma_have_different_shape_and_dims(self):
     # test different shape and dims
     rho = qutip.ket("00")
     sigma = qutip.ket("0")
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho, sigma)
     assert str(exc.value) == "Inputs must have the same shape and dims."
     # test same shape, difference dims
     rho = qutip.basis([2, 3], [0, 0])
     sigma = qutip.basis([3, 2], [0, 0])
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho, sigma)
     assert str(exc.value) == "Inputs must have the same shape and dims."
def seepage_from_superoperator(U):
    """
    Calculates seepage by summing over all in and output states outside the
    computational subspace.
        L1 = 1- 1/2^{number non-computational states} sum_i sum_j abs(|<phi_i|U|phi_j>|)**2
    """
    if U.type=='oper':
        sump = 0
        for i_list in [[0,2],[1,2],[2,0],[2,1],[2,2]]:
            for j_list in [[0,2],[1,2],[2,0],[2,1],[2,2]]:
                bra_i = qtp.tensor(qtp.ket([i_list[0]], dim=[3]),
                                   qtp.ket([i_list[1]], dim=[3])).dag()
                ket_j = qtp.tensor(qtp.ket([j_list[0]], dim=[3]),
                                   qtp.ket([j_list[1]], dim=[3]))
                p = np.abs((bra_i*U*ket_j).data[0, 0])**2  # could be sped up
                sump += p
        sump /= 5  # divide by number of non-computational states
        L1 = 1-sump
        return L1
    elif U.type=='super':
        sump = 0
        for i_list in [[0,2],[1,2],[2,0],[2,1],[2,2]]:
            for j_list in [[0,2],[1,2],[2,0],[2,1],[2,2]]:
                ket_i = qtp.tensor(qtp.ket([i_list[0]], dim=[3]),
                                   qtp.ket([i_list[1]], dim=[3]))
                rho_i=qtp.operator_to_vector(qtp.ket2dm(ket_i))
                ket_j = qtp.tensor(qtp.ket([j_list[0]], dim=[3]),
                                   qtp.ket([j_list[1]], dim=[3]))
                rho_j=qtp.operator_to_vector(qtp.ket2dm(ket_j))
                p = (rho_i.dag()*U*rho_j).data[0, 0]
                sump += p
        sump /= 5  # divide by number of non-computational states
        sump=np.real(sump)
        L1 = 1-sump
        return L1
Exemple #15
0
def calc_population_02_state(U):
    """
    Calculates the population that escapes from |11> to |02>.
    Formula for unitary propagator:  population = |<02|U|11>|^2
    and similarly for the superoperator case.
        The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
    """
    if U.type == 'oper':
        sump = 0
        for i_list in [[0, 2]]:
            for j_list in [[1, 1]]:
                bra_i = qtp.tensor(qtp.ket([i_list[0]], dim=[3]),
                                   qtp.ket([i_list[1]], dim=[3])).dag()
                ket_j = qtp.tensor(qtp.ket([j_list[0]], dim=[3]),
                                   qtp.ket([j_list[1]], dim=[3]))
                p = np.abs((bra_i * U * ket_j).data[0, 0])**2
                sump += p
        return np.real(sump)
    elif U.type == 'super':
        sump = 0
        for i_list in [[0, 2]]:
            for j_list in [[1, 1]]:
                ket_i = qtp.tensor(qtp.ket([i_list[0]], dim=[3]),
                                   qtp.ket([i_list[1]], dim=[3]))
                rho_i = qtp.operator_to_vector(qtp.ket2dm(ket_i))
                ket_j = qtp.tensor(qtp.ket([j_list[0]], dim=[3]),
                                   qtp.ket([j_list[1]], dim=[3]))
                rho_j = qtp.operator_to_vector(qtp.ket2dm(ket_j))
                p = (rho_i.dag() * U * rho_j).data[0, 0]
                sump += p
        return np.real(sump)
def numpy_control_system():
    """Optimization system for State-to-State Transfer

    This is the same as in 01_example_simple_state_to_state.ipynb, but using a
    numpy array as the control.
    """
    tlist = np.linspace(0, 5, 500)

    def hamiltonian(omega=1.0, ampl0=0.2):
        """Two-level-system Hamiltonian

        Args:
            omega (float): energy separation of the qubit levels
            ampl0 (float): constant amplitude of the driving field
        """
        H0 = -0.5 * omega * qutip.operators.sigmaz()
        H1 = qutip.operators.sigmax()

        def guess_control(t, args):
            return ampl0 * krotov.shapes.flattop(
                t, t_start=0, t_stop=5, t_rise=0.3, func="blackman")

        guess_array = np.array([guess_control(t, []) for t in tlist])
        # return [H0, [H1, guess_control]]
        return [H0, [H1, guess_array]]

    H = hamiltonian()

    objectives = [
        krotov.Objective(
            initial_state=qutip.ket("0"),
            target=qutip.ket("1"),
            H=H,
        )
    ]

    def S(t):
        """Shape function for the field update"""
        return krotov.shapes.flattop(t,
                                     t_start=0,
                                     t_stop=5,
                                     t_rise=0.3,
                                     t_fall=0.3,
                                     func='blackman')

    # pulse_options = {H[1][1]: dict(lambda_a=5, update_shape=S)}
    pulse_options = {id(H[1][1]): dict(lambda_a=5, update_shape=S)}

    return tlist, objectives, pulse_options
Exemple #17
0
 def test_density_matrices_with_non_real_eigenvalues(self):
     rho = qutip.ket2dm(qutip.ket("00"))
     sigma = qutip.ket2dm(qutip.ket("01"))
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho + 1j, sigma)
     assert str(exc.value) == "Input rho has non-real eigenvalues."
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho - 1j, sigma)
     assert str(exc.value) == "Input rho has non-real eigenvalues."
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho, sigma + 1j)
     assert str(exc.value) == "Input sigma has non-real eigenvalues."
     with pytest.raises(ValueError) as exc:
         qutip.entropy_relative(rho, sigma - 1j)
     assert str(exc.value) == "Input sigma has non-real eigenvalues."
Exemple #18
0
def objective_liouville():
    a1 = np.random.random(100) + 1j * np.random.random(100)
    a2 = np.random.random(100) + 1j * np.random.random(100)
    H = [
        tensor(sigmaz(), identity(2)) + tensor(identity(2), sigmaz()),
        [tensor(sigmax(), identity(2)), a1],
        [tensor(identity(2), sigmax()), a2],
    ]
    L = krotov.objectives.liouvillian(H, c_ops=[])
    ket00 = ket((0, 0))
    ket11 = ket((1, 1))
    obj = krotov.Objective(
        initial_state=qutip.ket2dm(ket00), target=qutip.ket2dm(ket11), H=L
    )
    return obj
Exemple #19
0
def test_transmon_3states_objectives():
    L = qutip.Qobj()  # dummy Liouvillian (won't be used)
    n_qubit = 3
    ket00 = qutip.ket((0, 0), dim=(n_qubit, n_qubit))
    ket01 = qutip.ket((0, 1), dim=(n_qubit, n_qubit))
    ket10 = qutip.ket((1, 0), dim=(n_qubit, n_qubit))
    ket11 = qutip.ket((1, 1), dim=(n_qubit, n_qubit))
    basis = [ket00, ket01, ket10, ket11]
    weights = [20, 1, 1]
    objectives = krotov.gate_objectives(
        basis,
        qutip_gates.sqrtiswap(),
        L,
        liouville_states_set='3states',
        weights=weights,
    )

    rho1_tgt = (
        0.4 * ket00 * ket00.dag()
        + (0.5 / 2) * ket01 * ket01.dag()
        - (0.1j / 2) * ket01 * ket10.dag()
        + (0.1j / 2) * ket10 * ket01.dag()
        + (0.5 / 2) * ket10 * ket10.dag()
        + 0.1 * ket11 * ket11.dag()
    )

    ket00_tgt = ket00
    ket01_tgt = (ket01 + 1j * ket10) / np.sqrt(2)
    ket10_tgt = (1j * ket01 + ket10) / np.sqrt(2)
    ket11_tgt = ket11
    target_basis = [ket00_tgt, ket01_tgt, ket10_tgt, ket11_tgt]
    rho2_tgt = 0.25 * sum(
        [psi * phi.dag() for (psi, phi) in product(target_basis, target_basis)]
    )

    rho3_tgt = 0.25 * (
        ket00 * ket00.dag()
        + ket01 * ket01.dag()
        + ket10 * ket10.dag()
        + ket11 * ket11.dag()
    )
    assert (objectives[0].target - rho1_tgt).norm('max') < 1e-14
    assert (objectives[1].target - rho2_tgt).norm('max') < 1e-14
    assert (objectives[2].target - rho3_tgt).norm('max') < 1e-14

    assert objectives[0].weight == 60.0 / 22.0
    assert objectives[1].weight == 3.0 / 22.0
    assert objectives[2].weight == 3.0 / 22.0
Exemple #20
0
def test_gate_objectives_pe():
    """Test gate objectives for a PE optimization"""
    from qutip import ket, tensor, sigmaz, sigmax, identity
    from weylchamber import bell_basis

    basis = [ket(n) for n in [(0, 0), (0, 1), (1, 0), (1, 1)]]
    H = [
        tensor(sigmaz(), identity(2)) + tensor(identity(2), sigmaz()),
        [tensor(sigmax(), identity(2)), lambda t, args: 1.0],
        [tensor(identity(2), sigmax()), lambda t, args: 1.0],
    ]
    objectives = krotov.gate_objectives(basis, 'PE', H)
    assert len(objectives) == 4
    bell_basis_states = bell_basis(basis)
    for state in bell_basis_states:
        assert isinstance(state, qutip.Qobj)
    for i in range(4):
        expected_objective = krotov.Objective(
            initial_state=bell_basis_states[i], target='PE', H=H
        )
        assert objectives[i] == expected_objective
    assert krotov.gate_objectives(basis, 'perfect_entangler', H) == objectives
    assert krotov.gate_objectives(basis, 'perfect entangler', H) == objectives
    assert krotov.gate_objectives(basis, 'Perfect Entangler', H) == objectives
    with pytest.raises(ValueError):
        krotov.gate_objectives(basis, 'prefect(!) entanglers', H)
Exemple #21
0
def test_gate_objectives_5states(two_qubit_liouvillian):
    """Test the initialization of the "d + 1" objectives"""
    L = two_qubit_liouvillian
    basis = [qutip.ket(n) for n in [(0, 0), (0, 1), (1, 0), (1, 1)]]
    CNOT = qutip_gates.cnot()
    objectives = krotov.objectives.gate_objectives(
        basis, CNOT, L, liouville_states_set='d+1'
    )

    assert len(objectives) == 5

    rho_1 = basis[0] * basis[0].dag()
    rho_2 = basis[1] * basis[1].dag()
    rho_3 = basis[2] * basis[2].dag()
    rho_4 = basis[3] * basis[3].dag()
    rho_5 = qutip.Qobj(np.full((4, 4), 1 / 4), dims=[[2, 2], [2, 2]])

    tgt_1 = CNOT * rho_1 * CNOT.dag()
    tgt_2 = CNOT * rho_2 * CNOT.dag()
    tgt_3 = CNOT * rho_3 * CNOT.dag()
    tgt_4 = CNOT * rho_4 * CNOT.dag()
    tgt_5 = CNOT * rho_5 * CNOT.dag()

    assert (objectives[0].initial_state - rho_1).norm('max') < 1e-14
    assert (objectives[1].initial_state - rho_2).norm('max') < 1e-14
    assert (objectives[2].initial_state - rho_3).norm('max') < 1e-14
    assert (objectives[3].initial_state - rho_4).norm('max') < 1e-14
    assert (objectives[4].initial_state - rho_5).norm('max') < 1e-14

    assert (objectives[0].target - tgt_1).norm('max') < 1e-14
    assert (objectives[1].target - tgt_2).norm('max') < 1e-14
    assert (objectives[2].target - tgt_3).norm('max') < 1e-14
    assert (objectives[3].target - tgt_4).norm('max') < 1e-14
    assert (objectives[4].target - tgt_5).norm('max') < 1e-14
def test_derivative_wrt_pulse_multiple_terms(tls_control_system):
    """Test the calculation of μ if the same control appears more than once"""
    objectives, pulses, pulses_mapping = tls_control_system
    # distinction between controls and pulses doesn't matter here, we're only
    # considering linear controls and don't plug in any time_index
    i_objective = 0
    mu = krotov.mu.derivative_wrt_pulse(
        objectives,
        i_objective,
        pulses,
        pulses_mapping,
        i_pulse=0,
        time_index=0,
    )
    # 0.5 * (σ₊ + σ₋) = σₓ
    for state in (ket('0'), ket('1')):
        assert (mu(state) - (sigmax())(state)).norm('max') == 0
        assert (mu(state)).dims == state.dims
Exemple #23
0
def transmon_3states_objectives():
    # see also test_objectives:test_transmon_3states_objectives
    L = qutip.Qobj()  # dummy Liouvillian (won't be used)
    n_qubit = 3
    ket00 = qutip.ket((0, 0), dim=(n_qubit, n_qubit))
    ket01 = qutip.ket((0, 1), dim=(n_qubit, n_qubit))
    ket10 = qutip.ket((1, 0), dim=(n_qubit, n_qubit))
    ket11 = qutip.ket((1, 1), dim=(n_qubit, n_qubit))
    basis = [ket00, ket01, ket10, ket11]
    weights = [20, 1, 1]
    objectives = krotov.gate_objectives(
        basis,
        qutip_gates.sqrtiswap(),
        L,
        liouville_states_set='3states',
        weights=weights,
    )
    return objectives
Exemple #24
0
def seepage_from_unitary(U):
    """
    Calculates leakage by summing over all in and output states in the
    computational subspace.
        L1 = 1- sum_i sum_j abs(|<phi_i|U|phi_j>|)**2
    """
    sump = 0
    for i in range(2):
        for j in range(2):
            bra_i = qtp.tensor(qtp.ket([i], dim=[2]),
                               qtp.ket([2], dim=[3])).dag()
            ket_j = qtp.tensor(qtp.ket([j], dim=[2]),
                               qtp.ket([2], dim=[3]))
            p = np.abs((bra_i*U*ket_j).data[0, 0])**2
            sump += p
    sump /= 2  # divide by dimension of comp subspace
    L1 = 1-sump
    return L1
Exemple #25
0
def objective_with_c_ops():
    u1 = lambda t, args: 1.0
    u2 = lambda t, args: 1.0
    a1 = np.random.random(100) + 1j * np.random.random(100)
    a2 = np.random.random(100) + 1j * np.random.random(100)
    H = [
        tensor(sigmaz(), identity(2)) + tensor(identity(2), sigmaz()),
        [tensor(sigmax(), identity(2)), u1],
        [tensor(identity(2), sigmax()), u2],
    ]
    C1 = [[tensor(identity(2), sigmap()), a1]]
    C2 = [[tensor(sigmap(), identity(2)), a2]]
    ket00 = ket((0, 0))
    ket11 = ket((1, 1))
    obj = krotov.Objective(
        initial_state=ket00, target=ket11, H=H, c_ops=[C1, C2]
    )
    return obj
def tls_control_system_tdcops(tls_control_system):
    """Control system with time-dependent collapse operators"""
    objectives, controls, _ = tls_control_system
    c_op = [[0.1 * sigmap(), controls[0]]]
    c_ops = [c_op]
    H1 = objectives[0].H
    H2 = objectives[1].H
    objectives = [
        krotov.Objective(
            initial_state=ket('0'), target=ket('1'), H=H1, c_ops=c_ops
        ),
        krotov.Objective(
            initial_state=ket('0'), target=ket('1'), H=H2, c_ops=c_ops
        ),
    ]
    controls_mapping = krotov.conversions.extract_controls_mapping(
        objectives, controls
    )
    return objectives, controls, controls_mapping
Exemple #27
0
def test_mapped_basis_preserves_hs_structure():
    """Test that mapped_basis preserves the hilbert space structure of the
    input basis."""
    basis = [ket(nums) for nums in [(0, 0), (0, 1), (1, 0), (1, 1)]]
    states = krotov.functionals.mapped_basis(qutip_gates.cnot(), basis)
    for state in states:
        assert isinstance(state, qutip.Qobj)
        assert state.dims == basis[0].dims
        assert state.shape == basis[0].shape
        assert state.type == basis[0].type
def tls_control_system():
    """Non-trivial control system defined on a TLS"""
    eps1 = lambda t, args: 0.5
    eps2 = lambda t, args: 1
    H1 = [0.5 * sigmaz(), [sigmap(), eps1], [sigmam(), eps1]]
    H2 = [0.5 * sigmaz(), [sigmaz(), eps2]]
    c_ops = [0.1 * sigmap()]
    objectives = [
        krotov.Objective(
            initial_state=ket('0'), target=ket('1'), H=H1, c_ops=c_ops
        ),
        krotov.Objective(
            initial_state=ket('0'), target=ket('1'), H=H2, c_ops=c_ops
        ),
    ]
    controls = [eps1, eps2]
    controls_mapping = krotov.conversions.extract_controls_mapping(
        objectives, controls
    )
    return objectives, controls, controls_mapping
Exemple #29
0
def initialise_TLS(init_sys, init_RC, states, w0, T_ph, H_RC=np.ones((2, 2))):
    # allows specific state TLS-RC states to be constructed easily
    G = qt.ket([0])
    E = qt.ket([1])
    ground_list, excited_list = ground_and_excited_states(states)
    concat_list = [ground_list, excited_list]
    N = states[1].shape[0] / 2
    if init_sys == 'coherence':
        rho_left = (states[concat_list[0][init_RC]] +
                    states[concat_list[1][init_RC]]) / np.sqrt(2)
        rho_right = rho_left.dag()
        init_rho = rho_left * rho_right
    elif type(init_sys) == tuple:
        #coherence state
        if type(init_RC) == tuple:
            # take in a 2-tuple to initialise in coherence state.
            print((init_sys, init_RC))
            rho_left = states[concat_list[init_sys[0]][init_RC[0]]]
            rho_right = states[concat_list[init_sys[1]][init_RC[1]]].dag()
            init_rho = rho_left * rho_right
        else:
            raise ValueError
    elif init_sys == 0:
        # population state
        init_rho = states[ground_list[init_RC]] * states[
            ground_list[init_RC]].dag()
    elif init_sys == 1:
        init_rho = states[excited_list[init_RC]] * states[
            excited_list[init_RC]].dag()
    elif init_sys == 2:
        Therm = qt.thermal_dm(N, Occupation(w0, T_ph))
        init_rho = qt.tensor(E * E.dag(), Therm)
        # if in neither ground or excited
        # for the minute, do nothing. This'll be fixed below.
    else:
        # finally, if not in either G or E, initialise as thermal
        num = (-H_RC * beta_f(T_ph)).expm()
        init_rho = num / num.tr()
    return init_rho
def leakage_from_superoperator(U):
    if U.type == 'oper':
        """
        Calculates leakage by summing over all in and output states in the
        computational subspace.
            L1 = 1- 1/2^{number computational qubits} sum_i sum_j abs(|<phi_i|U|phi_j>|)**2
        The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
        """
        sump = 0
        for i in range(4):
            for j in range(4):
                bra_i = qtp.tensor(qtp.ket([i // 2], dim=[3]),
                                   qtp.ket([i % 2], dim=[3])).dag()
                ket_j = qtp.tensor(qtp.ket([j // 2], dim=[3]),
                                   qtp.ket([j % 2], dim=[3]))
                p = np.abs((bra_i * U * ket_j).data[0, 0])**2
                sump += p
        sump /= 4  # divide by dimension of comp subspace
        L1 = 1 - sump
        return L1
    elif U.type == 'super':
        """
        Calculates leakage by summing over all in and output states in the
        computational subspace.
            L1 = 1- 1/2^{number computational qubits} sum_i sum_j Tr(rho_{x'y'}C_U(rho_{xy}))
            where C_U is U in the channel representation
        The function assumes that the computational subspace (:= the 4 energy levels chosen as the two qubits) is given by 
            the standard basis |0> /otimes |0>, |0> /otimes |1>, |1> /otimes |0>, |1> /otimes |1>.
            If this is not the case, one need to change the basis to that one, before calling this function.
        """
        sump = 0
        for i in range(4):
            for j in range(4):
                ket_i = qtp.tensor(qtp.ket([i // 2], dim=[3]),
                                   qtp.ket([i % 2],
                                           dim=[3]))  #notice it's a ket
                rho_i = qtp.operator_to_vector(qtp.ket2dm(ket_i))
                ket_j = qtp.tensor(qtp.ket([j // 2], dim=[3]),
                                   qtp.ket([j % 2], dim=[3]))
                rho_j = qtp.operator_to_vector(qtp.ket2dm(ket_j))
                p = (rho_i.dag() * U * rho_j).data[0, 0]
                sump += p
        sump /= 4  # divide by dimension of comp subspace
        sump = np.real(sump)
        L1 = 1 - sump
        return L1
def genstate(s):
    """helper function to obtain the correct initialization"""
    newstr = s.replace("+","0")
    newstr = newstr.replace("-","1")
    print(newstr)
    state = qt.ket(newstr)
    if s[0] == "+" or s[0]=="-":
        operator=qt.hadamard_transform()
    else:
        operator=qt.identity(2)
    for i in range(1,len(s),1):
        if s[i] == "+" or s[i]=="-":
            #apply hadamard
            operator = qt.tensor([operator,qt.hadamard_transform()])
        else:
            operator = qt.tensor([operator,qt.identity(2)])
    return operator * state
Exemple #32
0
def test_ket_type():
    "State CSR Type: ket"
    st = ket('10')
    assert_equal(isspmatrix_csr(st.data), True)
Exemple #33
0
    qc = qutip.QubitCircuit(n)
    if n == 1:
        qc.add_gate("SNOT", targets=[0])
    else:
        for i in range(n):
            qc.add_gate("SNOT", targets=[i])
            for j in range(2, n - i + 1):
                qc.add_gate(r"CPHASE", targets=[i], controls=[i + j - 1],
                            arg_label=r"{\pi/2^{%d}}" % (j - 1),
                            arg_value=numpy.pi / (2 ** (j - 1)))
        if swapping is True:
            for i in range(n // 2):
                qc.add_gate(r"SWAP", targets=[i, n - 1 - i])

    return qc


psi = qutip.ket('0' * n)

# start timing
start_time = timeit.default_timer()

qc0 = qft_gate_sequence(n, True)
for gate in qc0.propagators():
    psi = gate * psi

elapsed = timeit.default_timer() - start_time
# end timing

print("{0}, {1}, {2}".format(num_cores, n, elapsed))