Beispiel #1
0
 def testScatteringProbability(self):
     """
     Asserts that pi pulse in TLS has P0 ~ 0 and P0+P1+P2 ~ 1
     """
     w0 = 1.0 * 2 * np.pi
     gamma = 1.0
     sm = np.sqrt(gamma) * destroy(2)
     pulseArea = np.pi
     pulseLength = 0.2 / gamma
     RabiFreq = pulseArea / (2 * pulseLength)
     psi0 = basis(2, 0)
     tlist = np.geomspace(gamma, 10 * gamma, 40) - gamma
     # Define TLS Hamiltonian
     H0S = w0 * create(2) * destroy(2)
     H1S1 = lambda t, args: \
         RabiFreq * 1j * np.exp(-1j * w0 * t) * (t < pulseLength)
     H1S2 = lambda t, args: \
         RabiFreq * -1j * np.exp(1j * w0 * t) * (t < pulseLength)
     Htls = [H0S, [sm.dag(), H1S1], [sm, H1S2]]
     # Run the test
     P0 = scattering_probability(Htls, psi0, 0, [sm], tlist)
     P1 = scattering_probability(Htls, psi0, 1, [sm], tlist)
     P2 = scattering_probability(Htls, psi0, 2, [sm], tlist)
     assert_(P0 < 1e-3)
     assert_(np.abs(P0 + P1 + P2 - 1) < 1e-3)
Beispiel #2
0
def _opto_liouvillian(N):
    from qutip.tensor import tensor
    from qutip.operators import destroy, qeye
    from qutip.superoperator import liouvillian
    Nc = 5  # Number of cavity states
    Nm = N  # Number of mech states
    kappa = 0.3  # Cavity damping rate
    E = 0.1  # Driving Amplitude
    g0 = 2.4 * kappa  # Coupling strength
    Qm = 1e4  # Mech quality factor
    gamma = 1 / Qm  # Mech damping rate
    n_th = 1  # Mech bath temperature
    delta = -0.43  # Detuning
    a = tensor(destroy(Nc), qeye(Nm))
    b = tensor(qeye(Nc), destroy(Nm))
    num_b = b.dag() * b
    num_a = a.dag() * a
    H = -delta * (num_a) + num_b + g0 * (b.dag() + b) * num_a + E * (a.dag() +
                                                                     a)
    cc = np.sqrt(kappa) * a
    cm = np.sqrt(gamma * (1.0 + n_th)) * b
    cp = np.sqrt(gamma * n_th) * b.dag()
    c_ops = [cc, cm, cp]

    return liouvillian(H, c_ops)
Beispiel #3
0
 def testScatteringAmplitude(self):
     """
     Asserts that a 2pi pulse in TLS has ~0 amplitude after pulse
     """
     w0 = 1.0 * 2 * np.pi
     gamma = 1.0
     sm = np.sqrt(gamma) * destroy(2)
     pulseArea = 2 * np.pi
     pulseLength = 0.2 / gamma
     RabiFreq = pulseArea / (2 * pulseLength)
     psi0 = basis(2, 0)
     T = 50
     tlist = np.linspace(0, 1 / gamma, T)
     # Define TLS Hamiltonian
     H0S = w0 * create(2) * destroy(2)
     H1S1 = lambda t, args: \
         RabiFreq * 1j * np.exp(-1j * w0 * t) * (t < pulseLength)
     H1S2 = lambda t, args: \
         RabiFreq * -1j * np.exp(1j * w0 * t) * (t < pulseLength)
     Htls = [H0S, [sm.dag(), H1S1], [sm, H1S2]]
     # Run the test
     state = temporal_scattered_state(Htls, psi0, 1, [sm], tlist)
     basisVec = temporal_basis_vector([[40]], T)
     amplitude = np.abs((basisVec.dag() * state).full().item())
     assert_(amplitude < 1e-3)
Beispiel #4
0
    def set_up_ops(self, N):
        """
        Generate the Hamiltonians for the spinchain model and save them in the
        attribute `ctrls`.

        Parameters
        ----------
        N: int
            The number of qubits in the system.
        """
        # single qubit terms
        self.a = tensor([destroy(self.num_levels)] +
                        [identity(2) for n in range(N)])
        self.ctrls.append(self.a.dag() * self.a)
        self.ctrls += [
            tensor([identity(self.num_levels)] +
                   [sigmax() if m == n else identity(2) for n in range(N)])
            for m in range(N)
        ]
        self.ctrls += [
            tensor([identity(self.num_levels)] +
                   [sigmaz() if m == n else identity(2) for n in range(N)])
            for m in range(N)
        ]
        # interaction terms
        for n in range(N):
            sm = tensor(
                [identity(self.num_levels)] +
                [destroy(2) if m == n else identity(2) for m in range(N)])
            self.ctrls.append(self.a.dag() * sm + self.a * sm.dag())

        self.psi_proj = tensor([basis(self.num_levels, 0)] +
                               [identity(2) for n in range(N)])
Beispiel #5
0
def test_sp_bandwidth():
    "Sparse: Bandwidth"
    # Bandwidth test 1
    A = create(25) + destroy(25) + qeye(25)
    band = sp_bandwidth(A.data)
    assert_equal(band[0], 3)
    assert_equal(band[1] == band[2] == 1, 1)
    # Bandwidth test 2
    A = np.array([[1, 0, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1],
                  [0, 1, 1, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0],
                  [1, 0, 1, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 1, 0, 1],
                  [0, 0, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1, 0, 1]],
                 dtype=np.int32)
    A = sp.csr_matrix(A)
    out1 = sp_bandwidth(A)
    assert_equal(out1[0], 13)
    assert_equal(out1[1] == out1[2] == 6, 1)
    # Bandwidth test 3
    perm = reverse_cuthill_mckee(A)
    B = sp_permute(A, perm, perm)
    out2 = sp_bandwidth(B)
    assert_equal(out2[0], 5)
    assert_equal(out2[1] == out2[2] == 2, 1)
    # Asymmetric bandwidth test
    A = destroy(25) + qeye(25)
    out1 = sp_bandwidth(A.data)
    assert_equal(out1[0], 2)
    assert_equal(out1[1], 0)
    assert_equal(out1[2], 1)
Beispiel #6
0
    def set_up_ops(self, num_qubits):
        """
        Generate the Hamiltonians for the spinchain model and save them in the
        attribute `ctrls`.

        Parameters
        ----------
        num_qubits: int
            The number of qubits in the system.
        """
        # single qubit terms
        for m in range(num_qubits):
            self.add_control(sigmax(), [m + 1], label="sx" + str(m))
        for m in range(num_qubits):
            self.add_control(sigmaz(), [m + 1], label="sz" + str(m))
        # coupling terms
        a = tensor([destroy(self.num_levels)] +
                   [identity(2) for n in range(num_qubits)])
        for n in range(num_qubits):
            sm = tensor([identity(self.num_levels)] + [
                destroy(2) if m == n else identity(2)
                for m in range(num_qubits)
            ])
            self.add_control(a.dag() * sm + a * sm.dag(),
                             list(range(num_qubits + 1)),
                             label="g" + str(n))
Beispiel #7
0
    def set_up_ops(self, N):
        """
        Generate the Hamiltonians for the circuitqed model and save them in the
        attribute `ctrls`.

        Parameters
        ----------
        N: int
            The number of qubits in the system.
        """
        # single qubit terms
        for m in range(N):
            self.pulses.append(
                Pulse(sigmax(), [m + 1], spline_kind=self.spline_kind))
        for m in range(N):
            self.pulses.append(
                Pulse(sigmaz(), [m + 1], spline_kind=self.spline_kind))
        # coupling terms
        a = tensor([destroy(self.num_levels)] +
                   [identity(2) for n in range(N)])
        for n in range(N):
            sm = tensor(
                [identity(self.num_levels)] +
                [destroy(2) if m == n else identity(2) for m in range(N)])
            self.pulses.append(
                Pulse(a.dag() * sm + a * sm.dag(),
                      list(range(N + 1)),
                      spline_kind=self.spline_kind))
Beispiel #8
0
def _jc_liouvillian(N):
    from qutip.tensor import tensor
    from qutip.operators import destroy, qeye
    from qutip.superoperator import liouvillian
    wc = 1.0  * 2 * np.pi  # cavity frequency
    wa = 1.0  * 2 * np.pi  # atom frequency
    g  = 0.05 * 2 * np.pi  # coupling strength
    kappa = 0.005          # cavity dissipation rate
    gamma = 0.05           # atom dissipation rate
    n_th_a = 1           # temperature in frequency units
    use_rwa = 0
    # operators
    a  = tensor(destroy(N), qeye(2))
    sm = tensor(qeye(N), destroy(2))
    # Hamiltonian
    if use_rwa:
        H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() * sm + a * sm.dag())
    else:
        H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() + a) * (sm + sm.dag())
    c_op_list = []

    rate = kappa * (1 + n_th_a)
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * a)

    rate = kappa * n_th_a
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * a.dag())

    rate = gamma
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * sm)

    return liouvillian(H, c_op_list)
Beispiel #9
0
def test_sp_bandwidth():
    "Sparse: Bandwidth"
    # Bandwidth test 1
    A = create(25)+destroy(25)+qeye(25)
    band = sp_bandwidth(A.data)
    assert_equal(band[0], 3)
    assert_equal(band[1] == band[2] == 1, 1)
    # Bandwidth test 2
    A = np.array([[1, 0, 0, 0, 1, 0, 0, 0],
                  [0, 1, 1, 0, 0, 1, 0, 1],
                  [0, 1, 1, 0, 1, 0, 0, 0],
                  [0, 0, 0, 1, 0, 0, 1, 0],
                  [1, 0, 1, 0, 1, 0, 0, 0],
                  [0, 1, 0, 0, 0, 1, 0, 1],
                  [0, 0, 0, 1, 0, 0, 1, 0],
                  [0, 1, 0, 0, 0, 1, 0, 1]], dtype=np.int32)
    A = sp.csr_matrix(A)
    out1 = sp_bandwidth(A)
    assert_equal(out1[0], 13)
    assert_equal(out1[1] == out1[2] == 6, 1)
    # Bandwidth test 3
    perm = reverse_cuthill_mckee(A)
    B = sp_permute(A, perm, perm)
    out2 = sp_bandwidth(B)
    assert_equal(out2[0], 5)
    assert_equal(out2[1] == out2[2] == 2, 1)
    # Asymmetric bandwidth test
    A = destroy(25)+qeye(25)
    out1 = sp_bandwidth(A.data)
    assert_equal(out1[0], 2)
    assert_equal(out1[1], 0)
    assert_equal(out1[2], 1)
Beispiel #10
0
    def set_up_ops(self, N):
        """
        Generate the Hamiltonians for the spinchain model and save them in the
        attribute `ctrls`.

        Parameters
        ----------
        N: int
            The number of qubits in the system.
        """
        # single qubit terms
        self.a = tensor(destroy(self.num_levels))
        self.pulses.append(
            Pulse(self.a.dag() * self.a, [0], spline_kind=self.spline_kind))
        for m in range(N):
            self.pulses.append(
                Pulse(sigmax(), [m + 1], spline_kind=self.spline_kind))
        for m in range(N):
            self.pulses.append(
                Pulse(sigmaz(), [m + 1], spline_kind=self.spline_kind))
        # interaction terms
        a_full = tensor([destroy(self.num_levels)] +
                        [identity(2) for n in range(N)])
        for n in range(N):
            sm = tensor(
                [identity(self.num_levels)] +
                [destroy(2) if m == n else identity(2) for m in range(N)])
            self.pulses.append(
                Pulse(a_full.dag() * sm + a_full * sm.dag(),
                      list(range(N + 1)),
                      spline_kind=self.spline_kind))

        self.psi_proj = tensor([basis(self.num_levels, 0)] +
                               [identity(2) for n in range(N)])
Beispiel #11
0
    def TestNoise(self):
        """
        Test for Processor with noise
        """
        # setup and fidelity without noise
        init_state = qubit_states(2, [0, 0, 0, 0])
        tlist = np.array([0., np.pi/2.])
        a = destroy(2)
        proc = Processor(N=2)
        proc.add_control(sigmax(), targets=1)
        proc.pulses[0].tlist = tlist
        proc.pulses[0].coeff = np.array([1])
        result = proc.run_state(init_state=init_state)
        assert_allclose(
            fidelity(result.states[-1], qubit_states(2, [0, 1, 0, 0])),
            1, rtol=1.e-7)

        # decoherence noise
        dec_noise = DecoherenceNoise([0.25*a], targets=1)
        proc.add_noise(dec_noise)
        result = proc.run_state(init_state=init_state)
        assert_allclose(
            fidelity(result.states[-1], qubit_states(2, [0, 1, 0, 0])),
            0.981852, rtol=1.e-3)

        # white random noise
        proc.noise = []
        white_noise = RandomNoise(0.2, np.random.normal, loc=0.1, scale=0.1)
        proc.add_noise(white_noise)
        result = proc.run_state(init_state=init_state)
Beispiel #12
0
def test_QobjHerm():
    "Qobj Hermicity"
    N = 10
    data = np.random.random((N, N)) + 1j * np.random.random(
        (N, N)) - (0.5 + 0.5j)
    q = Qobj(data)
    assert_equal(q.isherm, False)

    data = data + data.conj().T
    q = Qobj(data)
    assert_(q.isherm)

    q_a = destroy(5)
    assert_(not q_a.isherm)

    q_ad = create(5)
    assert_(not q_ad.isherm)

    # test addition of two nonhermitian operators adding up to a hermitian one
    q_x = q_a + q_ad
    assert_(q_x.isherm)  # isherm use the _isherm cache from q_a + q_ad
    q_x._isherm = None  # reset _isherm cache
    assert_(q_x.isherm)  # recalculate _isherm

    # test addition of one hermitan and one nonhermitian operator
    q = q_x + q_a
    assert_(not q.isherm)
    q._isherm = None
    assert_(not q.isherm)

    # test addition of two hermitan operators
    q = q_x + q_x
    assert_(q.isherm)
    q._isherm = None
    assert_(q.isherm)
Beispiel #13
0
def rand_super(dim=5):
    H = rand_herm(dim)
    return propagator(
        H, np.random.rand(),
        [create(dim),
         destroy(dim),
         jmat(float(dim - 1) / 2.0, 'z')])
Beispiel #14
0
def test_QobjHerm():
    "Qobj Hermicity"
    N = 10
    data = np.random.random(
        (N, N)) + 1j * np.random.random((N, N)) - (0.5 + 0.5j)
    q = Qobj(data)
    assert_equal(q.isherm, False)

    data = data + data.conj().T
    q = Qobj(data)
    assert_(q.isherm)

    q_a = destroy(5)
    assert_(not q_a.isherm)

    q_ad = create(5)
    assert_(not q_ad.isherm)

    # test addition of two nonhermitian operators adding up to a hermitian one
    q_x = q_a + q_ad
    assert_(q_x.isherm)  # isherm use the _isherm cache from q_a + q_ad
    q_x._isherm = None   # reset _isherm cache
    assert_(q_x.isherm)  # recalculate _isherm

    # test addition of one hermitan and one nonhermitian operator
    q = q_x + q_a
    assert_(not q.isherm)
    q._isherm = None
    assert_(not q.isherm)

    # test addition of two hermitan operators
    q = q_x + q_x
    assert_(q.isherm)
    q._isherm = None
    assert_(q.isherm)
Beispiel #15
0
    def TestRelaxationNoise(self):
        """
        Test for the relaxation noise
        """
        a = destroy(2)
        relnoise = RelaxationNoise(t1=[1., 1., 1.], t2=None)
        noisy_qu, c_ops = relnoise.get_noisy_dynamics(3).get_noisy_qobjevo(
            dims=3)
        assert_(len(c_ops) == 3)
        assert_allclose(c_ops[1].cte, tensor([qeye(2), a, qeye(2)]))

        relnoise = RelaxationNoise(t1=None, t2=None)
        noisy_qu, c_ops = relnoise.get_noisy_dynamics(2).get_noisy_qobjevo(
            dims=2)
        assert_(len(c_ops) == 0)

        relnoise = RelaxationNoise(t1=None, t2=[0.2, 0.7])
        noisy_qu, c_ops = relnoise.get_noisy_dynamics(2).get_noisy_qobjevo(
            dims=2)
        assert_(len(c_ops) == 2)

        relnoise = RelaxationNoise(t1=[1., 1.], t2=[0.5, 0.5])
        noisy_qu, c_ops = relnoise.get_noisy_dynamics(2).get_noisy_qobjevo(
            dims=2)
        assert_(len(c_ops) == 4)
Beispiel #16
0
def rand_super(N=5, dims=None):
    """
    Returns a randomly drawn superoperator acting on operators acting on
    N dimensions.

    Parameters
    ----------
    N : int
        Square root of the dimension of the superoperator to be returned.
    dims : list
        Dimensions of quantum object.  Used for specifying
        tensor structure. Default is dims=[[[N],[N]], [[N],[N]]].
    """
    if dims is not None:
        # TODO: check!
        pass
    else:
        dims = [[[N], [N]], [[N], [N]]]
    H = rand_herm(N)
    S = propagator(
        H, np.random.rand(),
        [create(N), destroy(N),
         jmat(float(N - 1) / 2.0, 'z')])
    S.dims = dims
    return S
Beispiel #17
0
def coherent(N,alpha):
    """Generates a coherent state with eigenvalue alpha. 
    
    Constructed using displacement operator on vacuum state.
    
    Parameters
    ----------
    N : int 
        Number of Fock states in Hilbert space.
        
    alpha : float/complex 
        Eigenvalue of coherent state.
    
    Returns
    -------
    state : qobj
        Qobj quantum object for coherent state
    
    Examples
    --------        
    >>> coherent(5,0.25j)
    Quantum object: dims = [[5], [1]], shape = [5, 1], type = ket
    Qobj data = 
    [[  9.69233235e-01+0.j        ]
     [  0.00000000e+00+0.24230831j]
     [ -4.28344935e-02+0.j        ]
     [  0.00000000e+00-0.00618204j]
     [  7.80904967e-04+0.j        ]]
         
    """
    x=basis(N,0)
    a=destroy(N)
    D=(alpha*a.dag()-conj(alpha)*a).expm()
    return D*x
Beispiel #18
0
def coherent(N, alpha, method='operator'):
    """Generates a coherent state with eigenvalue alpha. 
    
    Constructed using displacement operator on vacuum state.
    
    Parameters
    ----------
    N : int 
        Number of Fock states in Hilbert space.    
    alpha : float/complex 
        Eigenvalue of coherent state.
    method : string {'operator', 'analytic'}
        Method for generating coherent state.
    
    Returns
    -------
    state : qobj
        Qobj quantum object for coherent state
    
    Examples
    --------        
    >>> coherent(5,0.25j)
    Quantum object: dims = [[5], [1]], shape = [5, 1], type = ket
    Qobj data = 
    [[  9.69233235e-01+0.j        ]
     [  0.00000000e+00+0.24230831j]
     [ -4.28344935e-02+0.j        ]
     [  0.00000000e+00-0.00618204j]
     [  7.80904967e-04+0.j        ]]
     
    Notes
    -----
    Select method 'operator' (default) or 'analytic'. With the 
    'operator' method, the coherent state is generated by displacing
    the vacuum state using the displacement operator defined in the
    truncated Hilbert space of size 'N'. This method guarantees that the 
    resulting state is normalized. With 'analytic' method the coherent state 
    is generated using the analytical formula for the coherent state 
    coefficients in the Fock basis. THIS METHOD DOES NOT GUARANTEE THAT THE 
    STATE IS NORMALIZED if truncated to a small number of Fock states, 
    but would in that case give more accurate coefficients.
         
    """
    if method == "operator":

        x=basis(N,0)
        a=destroy(N)
        D=(alpha*a.dag()-conj(alpha)*a).expm()
        return D*x

    elif method == "analytic":

        data = np.zeros([N,1],dtype=complex)
        n = arange(N)
        data[:,0] = np.exp(-(abs(alpha)**2)/2.0)*(alpha**(n))/_sqrt_factorial(n)
        return Qobj(data)

    else:
        raise TypeError("The method option can only take values 'operator' or 'analytic'")
Beispiel #19
0
    def get_noisy_dynamics(self, dims):
        """
        Return a list of Pulse object with only trivial ideal pulse (H=0) but
        non-trivial relaxation noise.

        Parameters
        ----------
        dims: list, optional
            The dimension of the components system, the default value is
            [2,2...,2] for qubits system.

        Returns
        -------
        lindblad_noise: list of :class:`qutip.qip.Pulse`
            A list of Pulse object with only trivial ideal pulse (H=0) but
            non-trivial relaxation noise.
        """
        if isinstance(dims, list):
            # for d in dims:
            #     if d != 2:
            #         raise ValueError(
            #             "Relaxation noise is defined only for qubits system")
            N = len(dims)
        else:
            N = dims

        self.t1 = self._T_to_list(self.t1, len(dims))
        self.t2 = self._T_to_list(self.t2, len(dims))
        if len(self.t1) != len(dims) or len(self.t2) != len(dims):
            raise ValueError("Length of t1 or t2 does not match N, "
                             "len(t1)={}, len(t2)={}".format(
                                 len(self.t1), len(self.t2)))
        lindblad_noise = Pulse(None, None)

        if self.targets is None:
            targets = range(N)
        else:
            targets = self.targets
        for qu_ind in targets:
            if dims[qu_ind] != 2:
                continue
            t1 = self.t1[qu_ind]
            t2 = self.t2[qu_ind]
            if t1 is not None:
                op = 1 / np.sqrt(t1) * destroy(2)
                lindblad_noise.add_lindblad_noise(op, qu_ind, coeff=True)
            if t2 is not None:
                # Keep the total dephasing ~ exp(-t/t2)
                if t1 is not None:
                    if 2 * t1 < t2:
                        raise ValueError("t1={}, t2={} does not fulfill "
                                         "2*t1>t2".format(t1, t2))
                    T2_eff = 1. / (1. / t2 - 1. / 2. / t1)
                else:
                    T2_eff = t2
                op = 1 / np.sqrt(2 * T2_eff) * sigmaz()
                lindblad_noise.add_lindblad_noise(op, qu_ind, coeff=True)
        return lindblad_noise
Beispiel #20
0
 def test_SuperChoiSuper(self):
     """
     Superoperator: Converting superoperator to Choi matrix and back.
     """
     h_5 = rand_herm(5)
     superoperator = propagator(h_5, scipy.rand(),
                                [create(5), destroy(5), jmat(2, 'z')])
     choi_matrix = super_to_choi(superoperator)
     test_supe = choi_to_super(choi_matrix)
     assert_((test_supe - superoperator).norm() < 1e-12)
Beispiel #21
0
    def test_standard(self):
        base = _random_not_singular(10)
        assert not Qobj(base).isherm
        assert Qobj(base + base.conj().T).isherm

        q_a = destroy(5)
        assert not q_a.isherm

        q_ad = create(5)
        assert not q_ad.isherm
Beispiel #22
0
 def test_ChoiKrausChoi(self):
     """
     Superoperator: Converting superoperator to Choi matrix and back.
     """
     h_5 = rand_herm(5)
     superoperator = propagator(h_5, scipy.rand(),
                                [create(5), destroy(5), jmat(2, 'z')])
     choi_matrix = super_to_choi(superoperator)
     kraus_ops = choi_to_kraus(choi_matrix)
     test_choi = kraus_to_choi(kraus_ops)
     assert_((test_choi - choi_matrix).norm() < 1e-12)
Beispiel #23
0
 def test_SuperChoiSuper(self):
     """
     Superoperator: Converting superoperator to Choi matrix and back.
     """
     h_5 = rand_herm(5)
     superoperator = propagator(
         h_5, scipy.rand(),
         [create(5), destroy(5), jmat(2, 'z')])
     choi_matrix = super_to_choi(superoperator)
     test_supe = choi_to_super(choi_matrix)
     assert_((test_supe - superoperator).norm() < 1e-12)
Beispiel #24
0
 def test_ChoiKrausChoi(self):
     """
     Superoperator: Converting superoperator to Choi matrix and back.
     """
     h_5 = rand_herm(5)
     superoperator = propagator(
         h_5, scipy.rand(),
         [create(5), destroy(5), jmat(2, 'z')])
     choi_matrix = super_to_choi(superoperator)
     kraus_ops = choi_to_kraus(choi_matrix)
     test_choi = kraus_to_choi(kraus_ops)
     assert_((test_choi - choi_matrix).norm() < 1e-12)
Beispiel #25
0
    def get_noise(self, N, dims=None):
        """
        Return the quantum objects representing the noise.

        Parameters
        ----------
        N: int
            The number of component systems.

        dims: list, optional
            The dimension of the components system, the default value is
            [2,2...,2] for qubits system.

        Returns
        -------
        qobjevo_list: list
            A list of :class:`qutip.Qobj` or :class:`qutip.QobjEvo`
            representing the decoherence noise.
        """
        if dims is None:
            dims = [2] * N
        self.t1 = self._T_to_list(self.t1, N)
        self.t2 = self._T_to_list(self.t2, N)
        if len(self.t1) != N or len(self.t2) != N:
            raise ValueError("Length of t1 or t2 does not match N, "
                             "len(t1)={}, len(t2)={}".format(
                                 len(self.t1), len(self.t2)))
        qobjevo_list = []
        for qu_ind in range(N):
            t1 = self.t1[qu_ind]
            t2 = self.t2[qu_ind]
            if t1 is not None:
                qobjevo_list.append(
                    expand_operator(1 / np.sqrt(t1) * destroy(2),
                                    N,
                                    qu_ind,
                                    dims=dims))
            if t2 is not None:
                # Keep the total dephasing ~ exp(-t/t2)
                if t1 is not None:
                    if 2 * t1 < t2:
                        raise ValueError("t1={}, t2={} does not fulfill "
                                         "2*t1>t2".format(t1, t2))
                    T2_eff = 1. / (1. / t2 - 1. / 2. / t1)
                else:
                    T2_eff = t2
                qobjevo_list.append(
                    expand_operator(1 / np.sqrt(2 * T2_eff) * sigmaz(),
                                    N,
                                    qu_ind,
                                    dims=dims))
        return qobjevo_list
Beispiel #26
0
 def TestChooseSolver(self):
     # setup and fidelity without noise
     init_state = qubit_states(2, [0, 0, 0, 0])
     tlist = np.array([0., np.pi/2.])
     a = destroy(2)
     proc = Processor(N=2)
     proc.add_control(sigmax(), targets=1)
     proc.pulses[0].tlist = tlist
     proc.pulses[0].coeff = np.array([1])
     result = proc.run_state(init_state=init_state, solver="mcsolve")
     assert_allclose(
         fidelity(result.states[-1], qubit_states(2, [0, 1, 0, 0])),
         1, rtol=1.e-7) 
Beispiel #27
0
 def testOperatorKet(self):
     """
     expect: operator and ket
     """
     N = 10
     op_N = num(N)
     op_a = destroy(N)
     for n in range(N):
         e = expect(op_N, fock(N, n))
         assert_(e == n)
         assert_(type(e) == float)
         e = expect(op_a, fock(N, n))
         assert_(e == 0)
         assert_(type(e) == complex)
Beispiel #28
0
 def testOperatorKet(self):
     """
     expect: operator and ket
     """
     N = 10
     op_N = num(N)
     op_a = destroy(N)
     for n in range(N):
         e = expect(op_N, fock(N, n))
         assert_(e == n)
         assert_(type(e) == float)
         e = expect(op_a, fock(N, n))
         assert_(e == 0)
         assert_(type(e) == complex)
Beispiel #29
0
 def testOperatorDensityMatrix(self):
     """
     expect: operator and density matrix
     """
     N = 10
     op_N = num(N)
     op_a = destroy(N)
     for n in range(N):
         e = expect(op_N, fock_dm(N, n))
         assert_(e == n)
         assert_(type(e) == float)
         e = expect(op_a, fock_dm(N, n))
         assert_(e == 0)
         assert_(type(e) == complex)
Beispiel #30
0
 def testOperatorDensityMatrix(self):
     """
     expect: operator and density matrix
     """
     N = 10
     op_N = num(N)
     op_a = destroy(N)
     for n in range(N):
         e = expect(op_N, fock_dm(N, n))
         assert_(e == n)
         assert_(type(e) == float)
         e = expect(op_a, fock_dm(N, n))
         assert_(e == 0)
         assert_(type(e) == complex)
Beispiel #31
0
    def test_addition(self):
        q_a, q_ad = destroy(5), create(5)

        # test addition of two nonhermitian operators adding up to be hermitian
        q_x = q_a + q_ad
        assert_hermicity(q_x, True)

        # test addition of one hermitan and one nonhermitian operator
        q = q_x + q_a
        assert_hermicity(q, False)

        # test addition of two hermitan operators
        q = q_x + q_x
        assert_hermicity(q, True)
Beispiel #32
0
    def set_up_ops(self, N):
        """
        Generate the Hamiltonians for the spinchain model and save them in the
        attribute `ctrls`.

        Parameters
        ----------
        N: int
            The number of qubits in the system.
        """
        self.pulse_dict = {}
        index = 0
        # single qubit terms
        for m in range(N):
            self.pulses.append(
                Pulse(sigmax(), [m + 1], spline_kind=self.spline_kind))
            self.pulse_dict["sx" + str(m)] = index
            index += 1
        for m in range(N):
            self.pulses.append(
                Pulse(sigmaz(), [m + 1], spline_kind=self.spline_kind))
            self.pulse_dict["sz" + str(m)] = index
            index += 1
        # coupling terms
        a = tensor([destroy(self.num_levels)] +
                   [identity(2) for n in range(N)])
        for n in range(N):
            sm = tensor(
                [identity(self.num_levels)] +
                [destroy(2) if m == n else identity(2) for m in range(N)])
            self.pulses.append(
                Pulse(a.dag() * sm + a * sm.dag(),
                      list(range(N + 1)),
                      spline_kind=self.spline_kind))
            self.pulse_dict["g" + str(n)] = index
            index += 1
Beispiel #33
0
def _jc_liouvillian(N):
    from qutip.tensor import tensor
    from qutip.operators import destroy, qeye
    from qutip.superoperator import liouvillian
    wc = 1.0 * 2 * np.pi  # cavity frequency
    wa = 1.0 * 2 * np.pi  # atom frequency
    g = 0.05 * 2 * np.pi  # coupling strength
    kappa = 0.005  # cavity dissipation rate
    gamma = 0.05  # atom dissipation rate
    n_th_a = 1  # temperature in frequency units
    use_rwa = 0
    # operators
    a = tensor(destroy(N), qeye(2))
    sm = tensor(qeye(N), destroy(2))
    # Hamiltonian
    if use_rwa:
        H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() * sm +
                                                         a * sm.dag())
    else:
        H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() +
                                                         a) * (sm + sm.dag())
    c_op_list = []

    rate = kappa * (1 + n_th_a)
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * a)

    rate = kappa * n_th_a
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * a.dag())

    rate = gamma
    if rate > 0.0:
        c_op_list.append(np.sqrt(rate) * sm)

    return liouvillian(H, c_op_list)
Beispiel #34
0
def _opto_liouvillian(N):
    from qutip.tensor import tensor
    from qutip.operators import destroy, qeye
    from qutip.superoperator import liouvillian
    Nc = 5                      # Number of cavity states
    Nm = N                     # Number of mech states
    kappa = 0.3                 # Cavity damping rate
    E = 0.1                     # Driving Amplitude         
    g0 = 2.4*kappa              # Coupling strength
    Qm = 1e4                    # Mech quality factor
    gamma = 1/Qm                # Mech damping rate
    n_th = 1                    # Mech bath temperature
    delta = -0.43               # Detuning
    a = tensor(destroy(Nc), qeye(Nm))
    b = tensor(qeye(Nc), destroy(Nm))
    num_b = b.dag()*b
    num_a = a.dag()*a
    H = -delta*(num_a)+num_b+g0*(b.dag()+b)*num_a+E*(a.dag()+a)
    cc = np.sqrt(kappa)*a
    cm = np.sqrt(gamma*(1.0 + n_th))*b
    cp = np.sqrt(gamma*n_th)*b.dag()
    c_ops = [cc,cm,cp]

    return liouvillian(H, c_ops)
Beispiel #35
0
    def test_id_with_T1_T2(self):
        """
        Test for identity evolution with relaxation t1 and t2
        """
        # setup
        a = destroy(2)
        Hadamard = hadamard_transform(1)
        ex_state = basis(2, 1)
        mines_state = (basis(2, 1) - basis(2, 0)).unit()
        end_time = 2.
        tlist = np.arange(0, end_time + 0.02, 0.02)
        t1 = 1.
        t2 = 0.5

        # test t1
        test = Processor(1, t1=t1)
        # zero ham evolution
        test.add_pulse(Pulse(identity(2), 0, tlist, False))
        result = test.run_state(ex_state, e_ops=[a.dag() * a])
        assert_allclose(result.expect[0][-1],
                        np.exp(-1. / t1 * end_time),
                        rtol=1e-5,
                        err_msg="Error in t1 time simulation")

        # test t2
        test = Processor(1, t2=t2)
        test.add_pulse(Pulse(identity(2), 0, tlist, False))
        result = test.run_state(init_state=mines_state,
                                e_ops=[Hadamard * a.dag() * a * Hadamard])
        assert_allclose(result.expect[0][-1],
                        np.exp(-1. / t2 * end_time) * 0.5 + 0.5,
                        rtol=1e-5,
                        err_msg="Error in t2 time simulation")

        # test t1 and t2
        t1 = np.random.rand(1) + 0.5
        t2 = np.random.rand(1) * 0.5 + 0.5
        test = Processor(1, t1=t1, t2=t2)
        test.add_pulse(Pulse(identity(2), 0, tlist, False))
        result = test.run_state(init_state=mines_state,
                                e_ops=[Hadamard * a.dag() * a * Hadamard])
        assert_allclose(result.expect[0][-1],
                        np.exp(-1. / t2 * end_time) * 0.5 + 0.5,
                        rtol=1e-5,
                        err_msg="Error in t1 & t2 simulation, "
                        "with t1={} and t2={}".format(t1, t2))
Beispiel #36
0
def test_QobjUnitaryOper():
    "Qobj unitarity"
    # Check some standard operators
    Sx = sigmax()
    Sy = sigmay()
    assert_unitarity(qeye(4), True)
    assert_unitarity(Sx, True)
    assert_unitarity(Sy, True)
    assert_unitarity(sigmam(), False)
    assert_unitarity(destroy(10), False)
    # Check multiplcation of unitary is unitary
    assert_unitarity(Sx * Sy, True)
    # Check some other operations clear unitarity
    assert_unitarity(Sx + Sy, False)
    assert_unitarity(4 * Sx, False)
    assert_unitarity(Sx * 4, False)
    assert_unitarity(4 + Sx, False)
    assert_unitarity(Sx + 4, False)
Beispiel #37
0
def test_QobjUnitaryOper():
    "Qobj unitarity"
    # Check some standard operators
    Sx = sigmax()
    Sy = sigmay()
    assert_unitarity(qeye(4), True, "qeye(4) should be unitary.")
    assert_unitarity(Sx, True, "sigmax() should be unitary.")
    assert_unitarity(Sy, True, "sigmax() should be unitary.")
    assert_unitarity(sigmam(), False, "sigmam() should NOT be unitary.")
    assert_unitarity(destroy(10), False, "destroy(10) should NOT be unitary.")
    # Check multiplcation of unitary is unitary
    assert_unitarity(Sx*Sy, True, "sigmax()*sigmay() should be unitary.")
    # Check some other operations clear unitarity
    assert_unitarity(Sx+Sy, False, "sigmax()+sigmay() should NOT be unitary.")
    assert_unitarity(4*Sx, False, "4*sigmax() should NOT be unitary.")
    assert_unitarity(Sx*4, False, "sigmax()*4 should NOT be unitary.")
    assert_unitarity(4+Sx, False, "4+sigmax() should NOT be unitary.")
    assert_unitarity(Sx+4, False, "sigmax()+4 should NOT be unitary.")
Beispiel #38
0
def test_QobjUnitaryOper():
    "Qobj unitarity"
    # Check some standard operators
    Sx = sigmax()
    Sy = sigmay()
    assert_unitarity(qeye(4), True, "qeye(4) should be unitary.")
    assert_unitarity(Sx, True, "sigmax() should be unitary.")
    assert_unitarity(Sy, True, "sigmax() should be unitary.")
    assert_unitarity(sigmam(), False, "sigmam() should NOT be unitary.")
    assert_unitarity(destroy(10), False, "destroy(10) should NOT be unitary.")
    # Check multiplcation of unitary is unitary
    assert_unitarity(Sx*Sy, True, "sigmax()*sigmay() should be unitary.")
    # Check some other operations clear unitarity
    assert_unitarity(Sx+Sy, False, "sigmax()+sigmay() should NOT be unitary.")
    assert_unitarity(4*Sx, False, "4*sigmax() should NOT be unitary.")
    assert_unitarity(Sx*4, False, "sigmax()*4 should NOT be unitary.")
    assert_unitarity(4+Sx, False, "4+sigmax() should NOT be unitary.")
    assert_unitarity(Sx+4, False, "sigmax()+4 should NOT be unitary.")
Beispiel #39
0
    def test_T1_T2(self):
        # setup
        a = destroy(2)
        Hadamard = hadamard_transform(1)
        ex_state = basis(2, 1)
        mines_state = (basis(2, 1)-basis(2, 0)).unit()
        end_time = 2.
        tlist = np.arange(0, end_time + 0.02, 0.02)
        H_d = 10.*sigmaz()
        t1 = 1.
        t2 = 0.5

        # test t1
        test = OptPulseProcessor(1, drift=H_d, t1=t1)
        test.tlist = tlist
        result = test.run_state(ex_state, e_ops=[a.dag()*a])

        assert_allclose(
            result.expect[0][-1], np.exp(-1./t1*end_time),
            rtol=1e-5, err_msg="Error in t1 time simulation")

        # test t2
        test = OptPulseProcessor(1, t2=t2)
        test.tlist = tlist
        result = test.run_state(
            rho0=mines_state, e_ops=[Hadamard*a.dag()*a*Hadamard])
        assert_allclose(
            result.expect[0][-1], np.exp(-1./t2*end_time)*0.5+0.5,
            rtol=1e-5, err_msg="Error in t2 time simulation")

        # test t1 and t2
        t1 = np.random.rand(1) + 0.5
        t2 = np.random.rand(1) * 0.5 + 0.5
        test = OptPulseProcessor(1, t1=t1, t2=t2)
        test.tlist = tlist
        result = test.run_state(
            rho0=mines_state, e_ops=[Hadamard*a.dag()*a*Hadamard])
        assert_allclose(
            result.expect[0][-1], np.exp(-1./t2*end_time)*0.5+0.5,
            rtol=1e-5,
            err_msg="Error in t1 & t2 simulation, "
                    "with t1={} and t2={}".format(t1, t2))
Beispiel #40
0
 def testWaveguideSplit(self):
     """
     Checks that a trivial splitting of a waveguide collapse operator like
     [sm] -> [sm/sqrt2, sm/sqrt2] doesn't affect the normalization or result
     """
     gamma = 1.0
     sm = np.sqrt(gamma) * destroy(2)
     pulseArea = np.pi
     pulseLength = 0.2 / gamma
     RabiFreq = pulseArea / (2 * pulseLength)
     psi0 = basis(2, 0)
     tlist = np.geomspace(gamma, 10 * gamma, 40) - gamma
     # Define TLS Hamiltonian with rotating frame transformation
     Htls = [[sm.dag() + sm, lambda t, args: RabiFreq * (t < pulseLength)]]
     # Run the test
     c_ops = [sm]
     c_ops_split = [sm / np.sqrt(2), sm / np.sqrt(2)]
     P1 = scattering_probability(Htls, psi0, 1, c_ops, tlist)
     P1_split = scattering_probability(Htls, psi0, 1, c_ops_split, tlist)
     tolerance = 1e-7
     assert_(1 - tolerance < P1 / P1_split < 1 + tolerance)
Beispiel #41
0
def test_QobjHerm():
    "Qobj Hermicity"
    N = 10
    data = np.random.random(
        (N, N)) + 1j * np.random.random((N, N)) - (0.5 + 0.5j)
    q = Qobj(data)
    assert_equal(q.isherm, False)

    data = data + data.conj().T
    q = Qobj(data)
    assert_(q.isherm)

    q_a = destroy(5)
    assert_(not q_a.isherm)

    q_ad = create(5)
    assert_(not q_ad.isherm)

    # test addition of two nonhermitian operators adding up to a hermitian one
    q_x = q_a + q_ad
    assert_hermicity(q_x, True)

    # test addition of one hermitan and one nonhermitian operator
    q = q_x + q_a
    assert_hermicity(q, False)

    # test addition of two hermitan operators
    q = q_x + q_x
    assert_hermicity(q, True)

    # Test multiplication of two Hermitian operators.
    # This results in a skew-Hermitian operator, so
    # we're checking here that __mul__ doesn't set wrong
    # metadata.
    q = sigmax() * sigmay()
    assert_hermicity(q, False, "Expected iZ = X * Y to be skew-Hermitian.")
    # Similarly, we need to check that -Z = X * iY is correctly
    # identified as Hermitian.
    q = sigmax() * (1j * sigmay())
    assert_hermicity(q, True, "Expected -Z = X * iY to be Hermitian.")
Beispiel #42
0
def rand_super(N=5, dims=None):
    """
    Returns a randomly drawn superoperator acting on operators acting on
    N dimensions.

    Parameters
    ----------
    N : int
        Square root of the dimension of the superoperator to be returned.
    dims : list
        Dimensions of quantum object.  Used for specifying
        tensor structure. Default is dims=[[[N],[N]], [[N],[N]]].
    """
    if dims is not None:
        # TODO: check!
        pass
    else:
        dims = [[[N], [N]], [[N], [N]]]
    H = rand_herm(N)
    S = propagator(H, np.random.rand(), [create(N), destroy(N), jmat(float(N - 1) / 2.0, "z")])
    S.dims = dims
    return S
Beispiel #43
0
    def testOperatorStateList(self):
        """
        expect: operator and state list
        """
        N = 10
        op = num(N)

        res = expect(op, [fock(N, n) for n in range(N)])
        assert_(all(res == range(N)))
        assert_(isinstance(res, np.ndarray) and res.dtype == np.float64)

        res = expect(op, [fock_dm(N, n) for n in range(N)])
        assert_(all(res == range(N)))
        assert_(isinstance(res, np.ndarray) and res.dtype == np.float64)

        op = destroy(N)

        res = expect(op, [fock(N, n) for n in range(N)])
        assert_(all(res == np.zeros(N)))
        assert_(isinstance(res, np.ndarray) and res.dtype == np.complex128)

        res = expect(op, [fock_dm(N, n) for n in range(N)])
        assert_(all(res == np.zeros(N)))
        assert_(isinstance(res, np.ndarray) and res.dtype == np.complex128)
Beispiel #44
0
def rand_super(dim=5):
    H = rand_herm(dim)
    return propagator(H, np.random.rand(), [
        create(dim), destroy(dim), jmat(float(dim - 1) / 2.0, 'z')
    ])
Beispiel #45
0
def coherent(N, alpha, offset=0, method='operator'):
    """Generates a coherent state with eigenvalue alpha.

    Constructed using displacement operator on vacuum state.

    Parameters
    ----------
    N : int
        Number of Fock states in Hilbert space.

    alpha : float/complex
        Eigenvalue of coherent state.

    offset : int (default 0)
        The lowest number state that is included in the finite number state
        representation of the state. Using a non-zero offset will make the
        default method 'analytic'.

    method : string {'operator', 'analytic'}
        Method for generating coherent state.

    Returns
    -------
    state : qobj
        Qobj quantum object for coherent state

    Examples
    --------
    >>> coherent(5,0.25j)
    Quantum object: dims = [[5], [1]], shape = [5, 1], type = ket
    Qobj data =
    [[  9.69233235e-01+0.j        ]
     [  0.00000000e+00+0.24230831j]
     [ -4.28344935e-02+0.j        ]
     [  0.00000000e+00-0.00618204j]
     [  7.80904967e-04+0.j        ]]

    Notes
    -----
    Select method 'operator' (default) or 'analytic'. With the
    'operator' method, the coherent state is generated by displacing
    the vacuum state using the displacement operator defined in the
    truncated Hilbert space of size 'N'. This method guarantees that the
    resulting state is normalized. With 'analytic' method the coherent state
    is generated using the analytical formula for the coherent state
    coefficients in the Fock basis. This method does not guarantee that the
    state is normalized if truncated to a small number of Fock states,
    but would in that case give more accurate coefficients.

    """
    if method == "operator" and offset == 0:

        x = basis(N, 0)
        a = destroy(N)
        D = (alpha * a.dag() - conj(alpha) * a).expm()
        return D * x

    elif method == "analytic" or offset > 0:

        sqrtn = np.sqrt(np.arange(offset, offset+N, dtype=complex))
        sqrtn[0] = 1 # Get rid of divide by zero warning
        data = alpha/sqrtn
        if offset == 0:
            data[0] = np.exp(-abs(alpha)**2 / 2.0)
        else:
            s = np.prod(np.sqrt(np.arange(1, offset + 1))) # sqrt factorial
            data[0] = np.exp(-abs(alpha)**2 / 2.0) * alpha**(offset) / s
        np.cumprod(data, out=sqrtn) # Reuse sqrtn array
        return Qobj(sqrtn)

    else:
        raise TypeError(
            "The method option can only take values 'operator' or 'analytic'")
Beispiel #46
0
def rand_super():
    h_5 = rand_herm(5)
    return propagator(h_5, scipy.rand(), [
        create(5), destroy(5), jmat(2, 'z')
    ])