Ejemplo n.º 1
0
def test_sesolve_bad_H():
    H = sigmaz(),
    psi0 = basis(2, 0)
    tlist = np.linspace(0, 20, 200)
    with pytest.raises(TypeError) as exc:
        sesolve(H, psi0, tlist=tlist, e_ops=[qeye(3)])
    assert str(exc.value).startswith("Invalid H:")
Ejemplo n.º 2
0
    def compare_evolution(self,
                          H,
                          psi0,
                          tlist,
                          normalize=False,
                          td_args={},
                          tol=5e-5):
        """
        Compare integrated evolution of unitary operator with state evo
        """
        U0 = qeye(2)
        options = Options(store_states=True, normalize_output=normalize)
        out_s = sesolve(H,
                        psi0,
                        tlist,
                        [sigmax(), sigmay(), sigmaz()],
                        options=options,
                        args=td_args)
        xs, ys, zs = out_s.expect[0], out_s.expect[1], out_s.expect[2]

        out_u = sesolve(H, U0, tlist, options=options, args=td_args)
        xu = [expect(sigmax(), U * psi0) for U in out_u.states]
        yu = [expect(sigmay(), U * psi0) for U in out_u.states]
        zu = [expect(sigmaz(), U * psi0) for U in out_u.states]

        if normalize:
            msg_ext = ". (Normalized)"
        else:
            msg_ext = ". (Not normalized)"
        assert_(max(abs(xs - xu)) < tol, msg="expect X not matching" + msg_ext)
        assert_(max(abs(ys - yu)) < tol, msg="expect Y not matching" + msg_ext)
        assert_(max(abs(zs - zu)) < tol, msg="expect Z not matching" + msg_ext)
Ejemplo n.º 3
0
    def test_07_1_dynamic_args(self):
        "sesolve: state feedback"
        tol = 1e-3

        def f(t, args):
            return np.abs(args["state_vec"][1])

        H = [qeye(2), [destroy(2) + create(2), f]]
        res = sesolve(H,
                      basis(2, 1),
                      tlist=np.linspace(0, 10, 11),
                      e_ops=[num(2)],
                      args={"state_vec": basis(2, 1)})
        assert_(max(abs(res.expect[0][5:])) < tol,
                msg="evolution with feedback not proceding as expected")

        def f(t, args):
            return np.sqrt(args["expect_op_0"])

        H = [qeye(2), [destroy(2) + create(2), f]]
        res = sesolve(H,
                      basis(2, 1),
                      tlist=np.linspace(0, 10, 11),
                      e_ops=[num(2)],
                      args={"expect_op_0": num(2)})
        assert_(max(abs(res.expect[0][5:])) < tol,
                msg="evolution with feedback not proceding as expected")
Ejemplo n.º 4
0
    def check_evolution(self, H, delta, psi0, tlist, analytic_func,
                        U0=None, td_args={}, tol=5e-3):
        """
        Compare integrated evolution with analytical result
        If U0 is not None then operator evo is checked
        Otherwise state evo
        """

        if U0 is None:
            output = sesolve(H, psi0, tlist, [sigmax(), sigmay(), sigmaz()],
                            args=td_args)
            sx, sy, sz = output.expect[0], output.expect[1], output.expect[2]
        else:
            output = sesolve(H, U0, tlist, args=td_args)
            sx = [expect(sigmax(), U*psi0) for U in output.states]
            sy = [expect(sigmay(), U*psi0) for U in output.states]
            sz = [expect(sigmaz(), U*psi0) for U in output.states]

        sx_analytic = np.zeros(np.shape(tlist))
        sy_analytic = np.array([-np.sin(delta*analytic_func(t, td_args))
                                for t in tlist])
        sz_analytic = np.array([np.cos(delta*analytic_func(t, td_args))
                                for t in tlist])

        assert_(max(abs(sx - sx_analytic)) < tol,
                msg="expect X not matching analytic")
        assert_(max(abs(sy - sy_analytic)) < tol,
                msg="expect Y not matching analytic")
        assert_(max(abs(sz - sz_analytic)) < tol,
                msg="expect Z not matching analytic")
Ejemplo n.º 5
0
    def monitor(self,
                init_state: Qobj,
                amps: List[Callable],
                times: Sequence[float],
                observables: List[Qobj] = None) -> Union[List[Qobj], List[Sequence[complex]]]:
        """
        Monitor the system at a range of points in time.
        This method allows one to look at the system continuously during a evolution. More specifically, the
        expectation value of the specified observables are returned at the specified points in time. If no observables
        are specified, the full ket vectors of the state at the specified points of time are returned.

        Parameters
        ----------
        init_state : Qobj
            The initial state.
        amps : list of complex numbers
            The control amplitudes. Must be a list of callables (which must return complex number) whose length is
            exactly the number of control operators.
        times : array_like
            The points in time where the monitoring are done.
        observables : list of Qobj or None
            The observables for which the expectation values are calculated. If None, then the ket vectors are
            returned instead of some expectation values.

        Returns
        -------
        list of floats

        Notes
        -----
        The state is not collapsed during monitoring, only the expectation values are evaluated and the state
        is not affected (which is of course impossible in an actual experiment). That is why this method is not called
        `measure` or `observe` to avoid confusion.

        """
        H_td = []

        H_td.append([self._ctrl_ops[0], lambda t, *_: amps[0](t)])
        H_td.append([self._ctrl_ops[0].dag(), lambda t, *_: np.conj(amps[0](t))])

        H_td.append([self._ctrl_ops[1], lambda t, *_: amps[1](t)])
        H_td.append([self._ctrl_ops[1].dag(), lambda t, *_: np.conj(amps[1](t))])

        H_td.append([self._ctrl_ops[2], lambda t, *_: amps[2](t)])
        H_td.append([self._ctrl_ops[2].dag(), lambda t, *_: np.conj(amps[2](t))])

        if observables is None:
            return sesolve(H_td, init_state, times, []).states
        else:
            return sesolve(H_td, init_state, times, observables).expect
Ejemplo n.º 6
0
def pulse(initial_state, duration, rabi, error = False):
    t0 = omega_plus + omega_minus #transition frequency
    
    H0 = ((1/2) * t0 * sigma_z)  
    
    H_laser = rabi * sigma_x
    
    if error == False:  
    
        H_final = [H0, [H_laser, H_laser_coeff]]
    
    if error == True: 
        H1 = (1/2) * sigma_z
        
        H_final = [H0, [H1, pink_noise_coeff], [H_laser, H_laser_coeff]]
  
   
   
    optns = qt.Options()
    
    optns.nsteps = 1000
    
    states = qt.sesolve(H_final, initial_state, np.linspace(0,duration,100), options = optns).states

   
    final_state = states[-1]

   
    return(final_state, states)
Ejemplo n.º 7
0
def time_evolution(psi, H, t):
    """
    Schrodinger evolution of a state psi under a Hamiltonian H, during
    a time t.

    Parameters
    ----------
    psi: qutip.Qobj()
        quantum state under evolution
    H: qutip.Qobj()
        Hamiltonian
    t: scalar
        time during which H is applied to psi

    Returns
    -------
    psi2 : qutip.Qobj()
        final state
    """
    if t == 0:
        return psi
    else:
        tlist = np.linspace(0, t, 20)
        psi2 = qutip.sesolve(H, psi, tlist).states[-1]
    return psi2
Ejemplo n.º 8
0
    def nf_anneal(self, schedule):
        """
        Performs a numeric forward anneal on H using QuTip.

        inputs:
        ---------
        schedule - a numeric anneal schedule defined with anneal length

        outputs:
        ---------
        probs - probability of each output state as a list ordered in canconically w.r.t. tensor product
        """
        times, svals = schedule

        # create a numeric representation of H
        ABfuncs = time_interpolation(schedule, self.processordata)
        numericH = get_numeric_H(self)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # "Analytic" or function H(t)
        analH = lambda t: A(t) * HX + B(t) * HZ
        # Define list_H for QuTiP
        listH = [[HX, A], [HZ, B]]

        # perform a numerical forward anneal on H
        results = qt.sesolve(listH, gs_calculator(analH(0)), times)
        probs = np.array([
            abs(results.states[-1][i].flatten()[0])**2
            for i in range(self.Hsize)
        ])

        return probs
Ejemplo n.º 9
0
    def solve_sdeq(self,
                   tlist,
                   e_ops=None,
                   sched_prob=None,
                   sched_driver=None):
        annealing_time = tlist[-1]
        evals_driver, ekets_driver = self.H_driver.eigenstates()
        psi0 = ekets_driver[np.argmin(evals_driver)]

        if e_ops is None:
            e_ops = [ket2dm(ek) for ek in self.ekets_prob]

        Hlist = self._gen_hamil_list(sched_prob, sched_driver)

        result = sesolve(Hlist,
                         psi0,
                         tlist,
                         e_ops=e_ops,
                         args={'annealing_time': annealing_time})
        expects = np.transpose(result.expect)

        arr = np.array(list(zip(tlist, expects)),
                       dtype=[('time', float),
                              ('expect', (float, len(expects[0])))])
        return arr.view(np.recarray)
Ejemplo n.º 10
0
def f(mol_list, run_qutip=True):
    tentative_mpo = Mpo(mol_list)
    init_mps = (Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}) @ Mps.gs(
        mol_list, False)).expand_bond_dimension(hint_mpo=tentative_mpo)
    init_mpdm = MpDm.from_mps(init_mps).expand_bond_dimension(
        hint_mpo=tentative_mpo)
    e = init_mps.expectation(tentative_mpo)
    mpo = Mpo(mol_list, offset=Quantity(e))

    if run_qutip:
        # calculate result in ZT. FT result is exactly the same
        TIME_LIMIT = 10
        QUTIP_STEP = 0.01
        N_POINTS = TIME_LIMIT / QUTIP_STEP + 1
        qutip_time_series = np.linspace(0, TIME_LIMIT, N_POINTS)
        init = qutip.Qobj(init_mps.full_wfn(),
                          [qutip_h.dims[0], [1] * len(qutip_h.dims[0])])
        # the result is not exact and the error scale is approximately 1e-5
        res = qutip.sesolve(qutip_h - e,
                            init,
                            qutip_time_series,
                            e_ops=[c.dag() * c for c in qutip_clist])
        qutip_expectations = np.array(res.expect).T

        return qutip_expectations, QUTIP_STEP, init_mps, init_mpdm, mpo
    else:
        return init_mps, init_mpdm, mpo
Ejemplo n.º 11
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
Ejemplo n.º 12
0
 def solve(self):
     # noinspection PyTypeChecker
     self.solve_result = sesolve(
         self.get_hamiltonian(),
         self.psi_0,
         self.t_list,
         # e_ops=get_exp_list(self.N)[2],
         options=Options(store_states=True, nsteps=100000),
         # ntraj=2
     )
Ejemplo n.º 13
0
    def observe(self, init_state, param_vec, times, e_ops=[]):
        amps_func = self.get_amps_func(param_vec)
        H = []
        for i in range(6):
            H.append([self._ctrl_hamils[i], amps_func[i]])
        result = sesolve(H, init_state, times, e_ops)

        if e_ops == []:
            return result.states
        else:
            return result.expect
Ejemplo n.º 14
0
def imperfect_state(coeff, error=0.2, H_rand=False, with_phase=False):
    s = state(*coeff)
    if H_rand == False:
        H_rand = q.rand_dm_ginibre(len(coeff))
    H_rand = H_rand / H_rand.norm()
    H_rand = q.Qobj(
        lin.block_diag(H_rand[:], np.zeros((N - len(coeff), N - len(coeff)))))
    s_e = q.sesolve(H_rand, s, [0., error]).states[1]
    if with_phase:
        return s_e
    else:
        return list(np.ndarray.flatten(np.abs(s_e[:len(coeff)])**2))
Ejemplo n.º 15
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
Ejemplo n.º 16
0
def pattern_diff(t, args, N_, prob_no):
    m_state_t = q.sesolve(-H, m_state, [0., t]).states[1]
    P_mixed = q.expect(system, m_state_t)
    probs = np.array(args[-prob_no:])
    P_list = np.empty(int(len(args[:-prob_no]) / (N_ - 1)))

    for i in range(int(len(args[:-prob_no]) / (N_ - 1))):
        state_coeffs = [0, *args[i * (N_ - 1):(i + 1) * (N_ - 1)]]
        state_coeffs = np.roll(state_coeffs, i)
        pattern_state = q.ket2dm(state(*state_coeffs))
        P_list[i] = q.expect(pattern_state, m_state_t)

    return np.abs(P_mixed - np.sum(probs * P_list))
Ejemplo n.º 17
0
    def simple_check_states_e_ops(
        self,
        H,
        psi0,
        tlist,
        tol=1e-5,
        tol2=1e-4,
        krylov_dim=25,
        square_hamiltonian=True,
    ):
        """
        Compare integrated evolution with sesolve and exactsolve result.
        """

        options = Options(store_states=True)

        e_ops = [
            jmat((H.shape[0] - 1) / 2.0, "x"),
            jmat((H.shape[0] - 1) / 2.0, "y"),
            jmat((H.shape[0] - 1) / 2.0, "z"),
        ]
        if not square_hamiltonian:
            _e_ops = []
            for op in e_ops:
                op2 = op.copy()
                op2.dims = H.dims
                _e_ops.append(op2)
            e_ops = _e_ops

        output = krylovsolve(
            H, psi0, tlist, krylov_dim, e_ops=e_ops, options=options
        )
        output_ss = sesolve(H, psi0, tlist, e_ops=e_ops, options=options)
        output_exact = exactsolve(H, psi0, tlist)

        assert_err_states_less_than_tol(res_1=output,
                                        res_2=output_ss, tol=tol)

        assert_err_states_less_than_tol(res_1=output,
                                        res_2=output_exact, tol=tol)

        # for the operators, test against exactsolve for accuracy
        for i in range(len(e_ops)):

            output_exact.expect = expect_value(e_ops[i], output_exact, tlist)

            assert_err_expect_less_than_tol(exp_1=output.expect[i],
                                            exp_2=output_exact.expect,
                                            tol=tol)
Ejemplo n.º 18
0
def schroedinger_sequence(
    model,
    psi0,
    durations,
    fields,
    dt=None,
    e_ops=None,
    args=None,
    options=None,
    progress_bar=None,
    _safe_mode=True,
):
    if options is None:
        options = qt.Options(store_final_state=True)
    else:
        options.store_final_state = True

    H_int = model.hamiltonian_int()

    t0 = 0
    expect = [np.array([qt.expect(e_ops, psi0)])]
    times = [np.array([t0])]
    for duration, field in zip(durations, fields):
        t1 = t0 + duration
        if dt is None:
            time_interval = [t0, t1]
        else:
            time_interval = np.arange(t0, t1, dt)
            if time_interval[-1] != t1:
                time_interval = np.append(time_interval, t1)
        t0 = t1

        H_ext = model.hamiltonian_field(*field)
        result = qt.sesolve(
            H_int + H_ext,
            psi0,
            time_interval,
            e_ops=e_ops,
            args=args,
            options=options,
            progress_bar=progress_bar,
            _safe_mode=_safe_mode,
        )

        psi0 = result.final_state
        expect.append(np.array(result.expect)[:, 1:])
        times.append(time_interval[1:])
    return np.concatenate(times), np.concatenate(expect, axis=1)
Ejemplo n.º 19
0
    def run(self, initial_state=None, progress_bar=None, **options):
        """Simulate the sequence using QuTiP's solvers.

        Keyword Args:
            initial_state (array): The initial quantum state of the
                evolution. Will be transformed into a ``qutip.Qobj`` instance.
            progress_bar (bool): If True, the progress bar of QuTiP's
                ``qutip.sesolve()`` will be shown.
        Other Parameters:
            options: Additional simulation settings. These correspond to the
                keyword arguments of ``qutip.solver.Options`` for
                the ``qutip.sesolve()`` method.

        Returns:
            SimulationResults: Object containing the time evolution results.
        """
        if initial_state is not None:
            if isinstance(initial_state, qutip.Qobj):
                if initial_state.shape != (self.dim**self._size, 1):
                    raise ValueError("Incompatible shape of initial_state")
                self._initial_state = initial_state
            else:
                if initial_state.shape != (self.dim**self._size,):
                    raise ValueError("Incompatible shape of initial_state")
                self._initial_state = qutip.Qobj(initial_state)
        else:
            # by default, initial state is "ground" state of g-r basis.
            all_ground = [self.basis['g'] for _ in range(self._size)]
            self._initial_state = qutip.tensor(all_ground)

        result = qutip.sesolve(self._hamiltonian,
                               self._initial_state,
                               self._times,
                               progress_bar=progress_bar,
                               options=qutip.Options(max_step=5,
                                                     **options)
                               )

        if hasattr(self._seq, '_measurement'):
            meas_basis = self._seq._measurement
        else:
            meas_basis = None

        return SimulationResults(
            result.states, self.dim, self._size, self.basis_name,
            meas_basis=meas_basis
        )
Ejemplo n.º 20
0
 def time_evol(self, psi0, psif, t0 = 0, T = 10, dt = 1e-2, plot=True):
     '''
     Simulate the unitary time evolution for a given Hamiltonian over a certain
     timespan. Then return output data and plot if desired.
     
     Arguments:
         
         H - The Hamiltonian to be applied in the time evolution unitary.
         psi0 - Initial state of system.
         psif - Final (desired) state of system against which to check fidelity
         t0 - Start time of simulation
         T - End time of simulation
         dt - Time increment
         
        
         display_progress - Choose whether to show progress of simulation whilst
                            it runs.
         plot - Boolean to set whether a graph is plotted.
     
     '''
     times = np.arange(t0,T,dt)
     
     
     optns = qt.Options()
     
     optns.nsteps = 10000
    
     results = qt.sesolve(self.__H, psi0, times, options = optns,progress_bar=True)
     states = results.states
     
     overlap = []
     
     for i in states:
             ov = i.overlap(psif)
             overlap.append(ov*np.conj(ov))
     
     if plot==True:
 
         plt.plot(times, overlap)
         plt.xlabel('Time/(hbar*nu)')
         plt.ylabel('|<psi(t)|D>|^2')
    #     plt.ylim([0.96,1.04])
         plt.show()
         
 
     return(overlap)
Ejemplo n.º 21
0
    def check_e_ops_callable(
        self,
        H,
        psi0,
        tlist,
        dim,
        krylov_dim=35,
        tol=1e-5,
        square_hamiltonian=True,
    ):
        "Check input possibilities when e_ops=callable"

        def e_ops(t, psi): return expect(num(dim), psi)

        if not square_hamiltonian:
            H.dims = [[H.shape[0]], [H.shape[0]]]
            psi0.dims = [[H.shape[0]], [1]]

        krylov_outputs = krylovsolve(H, psi0, tlist, krylov_dim, e_ops=e_ops)
        exact_output = exactsolve(H, psi0, tlist)
        exact_output.expect = expect_value(e_ops=e_ops,
                                           res_1=exact_output,
                                           tlist=tlist)

        try:
            sesolve_outputs = sesolve(H, psi0, tlist, e_ops=e_ops)
        except IndexError:  # if tlist=[], sesolve breaks but krylov doesn't
            pass

        if len(tlist) > 1:

            assert len(krylov_outputs.expect) == len(
                sesolve_outputs.expect
            ), "shape of outputs between krylov and sesolve differs"

            assert_err_expect_less_than_tol(exp_1=krylov_outputs.expect,
                                            exp_2=exact_output.expect,
                                            tol=tol)
        elif len(tlist) == 1:
            assert (
                np.abs(krylov_outputs.expect[0] - sesolve_outputs.expect[0])
                <= 1e-7
            ), "krylov and sesolve outputs differ for len(tlist)=1"
        else:
            assert krylov_outputs.states == []
Ejemplo n.º 22
0
def time_evol(H, psi0, psif, t0, T, dt, display_progress=True, plot=True):
    '''
    Simulate the unitary time evolution for a given Hamiltonian over a certain
    timespan. Then return output data and plot if desired.
    
    Arguments:
        
        H - The Hamiltonian to be applied in the time evolution unitary.
        psi0 - Initial state of system.
        psif - Final (desired) state of system against which to check fidelity
        t0 - Start time of simulation
        T - End time of simulation
        dt - Time increment
        
       
        display_progress - Choose whether to show progress of simulation whilst
                           it runs.
        plot - Boolean to set whether a graph is plotted.
    
    '''
    times = np.arange(t0, T, dt)

    optns = qt.Options()

    optns.nsteps = 10000

    results = qt.sesolve(H,
                         psi0,
                         times,
                         progress_bar=display_progress,
                         options=optns)
    states = results.states

    fidelities = []

    for i in states:
        fidelities.append(qt.fidelity(i, psif))

    if plot == True:

        plt.plot(times, fidelities)
        plt.show()

# print(optns)
    return (fidelities)
Ejemplo n.º 23
0
def QuantumAnnealing(Hi, Hf, psii, As, Bs, tlist):
    """
        Return the system states along the interpolation for a given parametrization and a time list    
        Parameters: 
            Hi : Initial Hamiltonian (qutip object)
            Hf : Final Hamiltonian (qutip object)
            psii : Initial State (qutip object)
            As : Parametrization function (python function)
            Bs : Parametrization function (python function)
            tlist : time list (np.array)
        Return: 
            system state in each interpolation time interval 
    """
    Ht = [[Hi, As], [Hf, Bs]]
      
    args = {'t_max': tlist[-1]} 
    result = qt.sesolve(H=Ht, psi0=psii, tlist=tlist,  args=args)
    return result.states 
Ejemplo n.º 24
0
def evolution_psi_microwave(system,
                            H_drive,
                            initial_state,
                            t_points=None,
                            **kwargs):
    """
    Calculates the evolution of a specific starting state for
    the gate activated by a microwave drive.

    Parameters
    ----------
    system : :class:`coupobj.CoupledObjects` or similar
        An object of a quantum system supporting system.H() method
        for the Hamiltonian.
    H_drive : :class:`qutip.Qobj`
        The time-independent part of the driving term.
        Example: f * (a + a.dag()) or f * qubit.n()
        Normalization: see `H_drive_coeff_gate` function.
    initial_state : :class:`qutip.Qobj`
        Initial state of the system.
    t_points : *array* of float (optional)
        Times at which the evolution operator is returned.
        If None, it is generated from `kwargs['T_gate']`.
    **kwargs:
        Contains gate parameters such as pulse shape and gate time.

    Returns
    -------
    *array* of :class:`qutip.Qobj`
        The evolving state at time(s) defined in `t_points`.
    """
    if t_points is None:
        T_gate = kwargs['T_gate']
        t_points = np.linspace(0, T_gate, 2 * int(T_gate) + 1)
    H_nodrive = system.H()
    H = [2 * np.pi * H_nodrive, [H_drive, H_drive_coeff_gate]]

    result = qt.sesolve(H,
                        initial_state,
                        t_points, [],
                        args=kwargs,
                        options=qt.Options(nsteps=25000))

    return result.states
Ejemplo n.º 25
0
    def schroedinger(
        self,
        model,
        psi0,
        dt=None,
        e_ops=None,
        options=None,
        progress_bar=None,
        _safe_mode=True,
        gaussian=False,
    ):
        if options is None:
            options = qt.Options(store_final_state=True)
        else:
            options.store_final_state = True

        H_int = model.hamiltonian_int()

        t0 = 0
        expect = [np.array([qt.expect(e_ops, psi0)])]
        times = [np.array([t0])]
        for duration, field in zip(self.durations, self.fields):
            time_interval = self.get_time_interval(t0, duration, dt)

            if gaussian:
                H_ext = [model.hamiltonian_field(*field), self.gaussian]
            else:
                H_ext = model.hamiltonian_field(*field)
            result = qt.sesolve(
                [H_int, H_ext],
                psi0,
                time_interval,
                e_ops=e_ops,
                options=options,
                progress_bar=progress_bar,
                _safe_mode=_safe_mode,
                args={"t0": t0, "sigma": duration / 4},
            )

            t0 = t0 + duration
            psi0 = result.final_state
            expect.append(np.array(result.expect)[:, 1:])
            times.append(time_interval[1:])
        return np.concatenate(times), np.concatenate(expect, axis=1)
Ejemplo n.º 26
0
    def check_e_ops_list_single_operator(
        self,
        e_ops,
        H,
        psi0,
        tlist,
        dim,
        krylov_dim=35,
        tol=1e-5,
        square_hamiltonian=True,
    ):
        "Check input possibilities when e_ops=[callable | qobj]"

        if not square_hamiltonian:
            H.dims = [[H.shape[0]], [H.shape[0]]]
            psi0.dims = [[H.shape[0]], [1]]

        krylov_outputs = krylovsolve(H, psi0, tlist, krylov_dim, e_ops=e_ops)
        exact_output = exactsolve(H, psi0, tlist)
        exact_output.expect = expect_value(e_ops[0], exact_output, tlist)

        try:
            sesolve_outputs = sesolve(H, psi0, tlist, e_ops=e_ops)
        except IndexError:  # if tlist=[], sesolve breaks but krylov doesn't
            pass

        if len(tlist) > 1:

            assert len(krylov_outputs.expect) == len(
                sesolve_outputs.expect
            ), "shape of outputs between krylov and sesolve differs"

            assert_err_expect_less_than_tol(exp_1=krylov_outputs.expect[0],
                                            exp_2=exact_output.expect,
                                            tol=tol)

        elif len(tlist) == 1:
            assert (
                np.abs(krylov_outputs.expect[0] - sesolve_outputs.expect[0])
                <= tol
            ), "expect outputs from krylovsolve and sesolve are not equal"
        else:
            assert krylov_outputs.states == []
Ejemplo n.º 27
0
    def check_e_ops_none(
        self, H, psi0, tlist, dim, krylov_dim=30, tol=1e-5, tol2=1e-4
    ):
        "Check input possibilities when e_ops=None"

        krylov_outputs = krylovsolve(H, psi0, tlist, krylov_dim, e_ops=None)

        try:
            sesolve_outputs = sesolve(H, psi0, tlist, e_ops=None)
        except IndexError:  # if tlist=[], sesolve breaks but krylov doesn't
            pass

        if len(tlist) > 1:
            assert_err_states_less_than_tol(
                krylov_outputs, sesolve_outputs, tol)
        elif len(tlist) == 1:
            assert krylov_outputs.states == sesolve_outputs.states
        else:
            assert krylov_outputs.states == []
Ejemplo n.º 28
0
 def __init__(self,
              H,
              ts,
              psi0=qutip.basis(3, 1),
              options=qutip.solver.Options(),
              force_recompute=False):
     self.H = H
     if H.is_constant() or H.T is None:
         self.output = qutip.sesolve(
             H.get_qutip_descriptor(time_offset=min(ts)),
             psi0,
             ts - min(ts),
             options=options)
     else:
         #Periodic hamiltonian, use Floquet Formalism
         self.output = qutip.fsesolve(
             H.get_qutip_descriptor(time_offset=min(ts)),
             psi0,
             ts - min(ts),
             e_ops=[],
             T=H.T,
             args={})
Ejemplo n.º 29
0
    def nr_anneal(self, schedule, init_state):
        """
        Performs a numeric reverse anneal on H using QuTip.

        inputs:
        ---------
        schedule - a numeric anneal schedule
        init_state - the starting state for the reverse anneal listed as string or list
        e.g. '111' or [010]

        outputs:
        ---------
        probs - probability of each output state as a list ordered in canconically w.r.t. tensor product
        """
        times, svals = schedule

        # create a numeric representation of H
        ABfuncs = time_interpolation(schedule, self.processordata)
        numericH = get_numeric_H(self)
        A = ABfuncs['A(t)']
        B = ABfuncs['B(t)']
        HX = numericH['HX']
        HZ = numericH['HZ']
        # Define list_H for QuTiP
        listH = [[HX, A], [HZ, B]]

        # create a valid QuTip initial state
        qubit_states = [qts.ket([int(i)]) for i in init_state]
        QuTip_init_state = qt.tensor(*qubit_states)

        # perform a numerical reverse anneal on H
        results = qt.sesolve(listH, QuTip_init_state, times)
        probs = np.array([
            abs(results.states[-1][i].flatten()[0])**2
            for i in range(self.Hsize)
        ])

        return probs
Ejemplo n.º 30
0
        def _run_solver() -> CoherentResults:
            """Returns CoherentResults: Object containing evolution results."""
            # Decide if progress bar will be fed to QuTiP solver
            p_bar: Optional[bool]
            if progress_bar is True:
                p_bar = True
            elif (progress_bar is False) or (progress_bar is None):
                p_bar = None
            else:
                raise ValueError("`progress_bar` must be a bool.")

            if "dephasing" in self.config.noise:
                # temporary workaround due to a qutip bug when using mesolve
                liouvillian = qutip.liouvillian(self._hamiltonian,
                                                self._collapse_ops)
                result = qutip.mesolve(
                    liouvillian,
                    self.initial_state,
                    self._eval_times_array,
                    progress_bar=p_bar,
                    options=solv_ops,
                )
            else:
                result = qutip.sesolve(
                    self._hamiltonian,
                    self.initial_state,
                    self._eval_times_array,
                    progress_bar=p_bar,
                    options=solv_ops,
                )
            return CoherentResults(
                result.states,
                self._size,
                self.basis_name,
                self._eval_times_array,
                self._meas_basis,
                meas_errors,
            )
Ejemplo n.º 31
0
 def solve_particle(self, time_list):
     pauli_basis = [qt.sigmax(), qt.sigmay(), qt.sigmaz()]
     output = qt.sesolve(self.local_hamiltonian, self.state, time_list,
                         pauli_basis)
     return output