Example #1
0
def get_quad_operator(operator, hbar=1.):
    """Convert to QuadOperator.

    Args:
        operator: BosonOperator.
        hbar (float): the value of hbar used in the definition
            of the commutator [q_i, p_j] = i hbar delta_ij.
            By default hbar=1.

    Returns:
        quad_operator: An instance of the QuadOperator class.
    """
    quad_operator = QuadOperator()

    if isinstance(operator, BosonOperator):
        for term, coefficient in operator.terms.items():
            tmp = QuadOperator('', coefficient)
            for i, d in term:
                tmp *= (1./numpy.sqrt(2.*hbar)) \
                    * (QuadOperator(((i, 'q')))
                        + QuadOperator(((i, 'p')), 1j*(-1)**d))
            quad_operator += tmp

    else:
        raise TypeError("Only BosonOperator is currently "
                        "supported for get_quad_operator.")

    return quad_operator
Example #2
0
 def test_quad_form(self, hbar):
     """Test it has the correct form using quadrature operators"""
     H, _ = beamsplitter(np.pi / 4, np.pi / 2, mode1=1, mode2=3, hbar=hbar)
     H = normal_ordered(get_quad_operator(H, hbar=hbar), hbar=hbar)
     expected = QuadOperator('q1 q3', -1)
     expected += QuadOperator('p1 p3', -1)
     assert H == expected
Example #3
0
 def test_two_mode(self):
     b = BosonOperator('0^ 2')
     q = get_quad_operator(b, hbar=self.hbar)
     expected = QuadOperator('q0') - 1j * QuadOperator('p0')
     expected *= (QuadOperator('q2') + 1j * QuadOperator('p2'))
     expected /= 2 * self.hbar
     self.assertTrue(q == expected)
Example #4
0
 def test_quad_form(self, hbar):
     """Test it has the correct form using quadrature operators"""
     H, _ = two_mode_squeezing(2, mode1=1, mode2=3, hbar=hbar)
     H = normal_ordered(get_quad_operator(H, hbar=hbar), hbar=hbar)
     expected = QuadOperator('q1 p3', 1)
     expected += QuadOperator('p1 q3', 1)
     assert H == expected
Example #5
0
 def test_quad_form(self, hbar):
     """Test it has the correct form using quadrature operators"""
     H, _ = squeezing(2, mode=1)
     H = normal_ordered(get_quad_operator(H, hbar=hbar), hbar=hbar)
     expected = QuadOperator('q1 p1', -1)
     expected += QuadOperator('', 1j)
     assert H == expected
Example #6
0
    def test_displaced_oscillator(self):
        """Test that a forced quantum oscillator produces the correct
        self.logTestName()
        trajectory in the phase space"""
        H = QuadOperator('q0 q0', 0.5)
        H += QuadOperator('p0 p0', 0.5)
        H -= QuadOperator('q0', self.F)

        res = []
        tlist = np.arange(0, self.t, self.dt)

        for t in tlist:  #pylint: disable=unused-variable
            self.eng.reset()
            q = self.eng.register
            with self.eng:
                Xgate(self.x0) | q[0]
                Zgate(self.p0) | q[0]
                GaussianPropagation(H, self.t) | q

            state = self.eng.run('gaussian')
            res.append(state.means().tolist())

        res = np.array(res)[-1]
        expected = self.displaced_oscillator_soln(self.t)
        self.assertTrue(np.allclose(res, expected))
    def test_displaced_oscillator(self):
        """Test that a forced quantum oscillator produces the correct
        self.logTestName()
        trajectory in the phase space"""
        H = QuadOperator('q0 q0', 0.5)
        H += QuadOperator('p0 p0', 0.5)
        H -= QuadOperator('q0', self.F)

        res = []
        tlist = np.arange(0, self.t, self.dt)

        eng = sf.Engine("gaussian")

        for idx, t in enumerate(tlist):  #pylint: disable=unused-variable
            prog = sf.Program(1)

            with prog.context as q:
                Xgate(self.x0) | q[0]
                Zgate(self.p0) | q[0]
                GaussianPropagation(H, self.t) | q

            state = eng.run(prog).state
            eng.reset()
            res.append(state.means().tolist())

        res = np.array(res)[-1]
        expected = self.displaced_oscillator_soln(self.t)
        assert np.allclose(res, expected)
Example #8
0
def load_operator(file_name=None, data_directory=None, plain_text=False):
    """Load FermionOperator or QubitOperator from file.

    Args:
        file_name: The name of the saved file.
        data_directory: Optional data directory to change from default data
                        directory specified in config file.
        plain_text: Whether the input file is plain text

    Returns:
        operator: The stored FermionOperator, BosonOperator,
            QuadOperator, or QubitOperator

    Raises:
        TypeError: Operator of invalid type.
    """
    file_path = get_file_path(file_name, data_directory)

    if plain_text:
        with open(file_path, 'r') as f:
            data = f.read()
            operator_type, operator_terms = data.split(":\n")

        if operator_type == 'FermionOperator':
            operator = FermionOperator(operator_terms)
        elif operator_type == 'BosonOperator':
            operator = BosonOperator(operator_terms)
        elif operator_type == 'QubitOperator':
            operator = QubitOperator(operator_terms)
        elif operator_type == 'QuadOperator':
            operator = QuadOperator(operator_terms)
        else:
            raise TypeError('Operator of invalid type.')
    else:
        with open(file_path, 'rb') as f:
            data = marshal.load(f)
            operator_type = data[0]
            operator_terms = data[1]

        if operator_type == 'FermionOperator':
            operator = FermionOperator()
            for term in operator_terms:
                operator += FermionOperator(term, operator_terms[term])
        elif operator_type == 'BosonOperator':
            operator = BosonOperator()
            for term in operator_terms:
                operator += BosonOperator(term, operator_terms[term])
        elif operator_type == 'QubitOperator':
            operator = QubitOperator()
            for term in operator_terms:
                operator += QubitOperator(term, operator_terms[term])
        elif operator_type == 'QuadOperator':
            operator = QuadOperator()
            for term in operator_terms:
                operator += QuadOperator(term, operator_terms[term])
        else:
            raise TypeError('Operator of invalid type.')

    return operator
Example #9
0
 def test_quad_form(self, hbar):
     """Test it has the correct form using quadrature operators"""
     H, _ = rotation(self.phi, mode=1, hbar=hbar)
     H = normal_ordered(get_quad_operator(H, hbar=hbar), hbar=hbar)
     expected = QuadOperator('q1 q1', -1 / hbar)
     expected += QuadOperator('p1 p1', -1 / hbar)
     expected += QuadOperator('', 1)
     assert H == expected
Example #10
0
 def test_symmetric_coefficient(self):
     coeff = 0.5+0.6j
     op = QuadOperator('q0 p0', coeff)
     res = symmetric_ordering(op, ignore_coeff=False)
     expected = QuadOperator('q0 p0', 0.5) \
         + QuadOperator('p0 q0', 0.5)
     self.assertTrue(res == coeff*expected)
     self.assertFalse(is_hermitian(res))
Example #11
0
 def test_quad_form(self):
     """Test it has the correct form using quadrature operators"""
     self.logTestName()
     H, _ = two_mode_squeezing(2, mode1=1, mode2=3, hbar=self.hbar)
     H = normal_ordered(get_quad_operator(H, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('q1 p3', 1)
     expected += QuadOperator('p1 q3', 1)
     self.assertEqual(H, expected)
Example #12
0
 def test_two_term(self):
     q = QuadOperator('p0 q0') + QuadOperator('q0 p0')
     b = get_boson_operator(q, hbar=self.hbar)
     expected = -1j*self.hbar/2 \
         * ((BosonOperator('0') + BosonOperator('0^'))
            * (BosonOperator('0') - BosonOperator('0^'))
            + (BosonOperator('0') - BosonOperator('0^'))
            * (BosonOperator('0') + BosonOperator('0^')))
     self.assertTrue(b == expected)
Example #13
0
 def test_quad_form(self):
     """Test it has the correct form using quadrature operators"""
     self.logTestName()
     H, _ = squeezing(2, mode=1)
     H = normal_ordered(get_quad_operator(H, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('q1 p1', -1)
     expected += QuadOperator('', 1j)
     self.assertEqual(H, expected)
Example #14
0
def normal_ordered_quad_term(term, coefficient, hbar=1.):
    """Return a normal ordered QuadOperator corresponding to single term.

    Args:
        term: A tuple of tuples. The first element of each tuple is
            an integer indicating the mode on which a boson ladder
            operator acts, starting from zero. The second element of each
            tuple is an integer, either 1 or 0, indicating whether creation
            or annihilation acts on that mode.
        coefficient: The coefficient of the term.
        hbar (float): the value of hbar used in the definition of the
            commutator [q_i, p_j] = i hbar delta_ij. By default hbar=1.

    Returns:
        ordered_term (QuadOperator): The normal ordered form of the input.
            Note that this might have more terms.

    In our convention, normal ordering implies terms are ordered
    from highest tensor factor (on left) to lowest (on right).
    Also, q operators come first.
    """
    # Iterate from left to right across operators and reorder to normal
    # form. Swap terms operators into correct position by moving from
    # left to right across ladder operators.
    term = list(term)
    ordered_term = QuadOperator()
    for i in range(1, len(term)):
        for j in range(i, 0, -1):
            right_operator = term[j]
            left_operator = term[j - 1]

            # Swap operators if q on right and p on left.
            # p q -> q p
            if right_operator[1] == 'q' and not left_operator[1] == 'q':
                term[j - 1] = right_operator
                term[j] = left_operator

                # Replace p q with i hbar + q p
                # if indices are the same.
                if right_operator[0] == left_operator[0]:
                    new_term = term[:(j - 1)] + term[(j + 1)::]

                    # Recursively add the processed new term.
                    ordered_term += normal_ordered_quad_term(
                        tuple(new_term), -coefficient * 1j * hbar)

            # Handle case when operator type is the same.
            elif right_operator[1] == left_operator[1]:

                # Swap if same type but lower index on left.
                if right_operator[0] > left_operator[0]:
                    term[j - 1] = right_operator
                    term[j] = left_operator

    # Add processed term and return.
    ordered_term += QuadOperator(tuple(term), coefficient)
    return ordered_term
Example #15
0
 def test_quad_form(self):
     """Test it has the correct form using quadrature operators"""
     self.logTestName()
     H, _ = rotation(self.phi, mode=1, hbar=self.hbar)
     H = normal_ordered(get_quad_operator(H, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('q1 q1', -0.5)
     expected += QuadOperator('p1 p1', -0.5)
     expected += QuadOperator('', 1)
     self.assertEqual(H, expected)
Example #16
0
    def test_commutes_identity(self):
        com = commutator(FermionOperator.identity(),
                         FermionOperator('2^ 3', 2.3))
        self.assertEqual(com, FermionOperator.zero())

        com = commutator(BosonOperator.identity(), BosonOperator('2^ 3', 2.3))
        self.assertTrue(com == BosonOperator.zero())

        com = commutator(QuadOperator.identity(), QuadOperator('q2 p3', 2.3))
        self.assertTrue(com == QuadOperator.zero())
Example #17
0
    def test_commutes_no_intersection(self):
        com = commutator(FermionOperator('2^ 3'), FermionOperator('4^ 5^ 3'))
        com = normal_ordered(com)
        self.assertEqual(com, FermionOperator.zero())

        com = commutator(BosonOperator('2^ 3'), BosonOperator('4^ 5^ 3'))
        com = normal_ordered(com)
        self.assertTrue(com == BosonOperator.zero())

        com = commutator(QuadOperator('q2 p3'), QuadOperator('q4 q5 p3'))
        com = normal_ordered(com)
        self.assertTrue(com == QuadOperator.zero())
Example #18
0
    def test_weyl_non_hermitian(self):
        res = weyl_polynomial_quantization('q0 p0')
        expected = QuadOperator('q0 p0', 0.5) \
            + QuadOperator('p0 q0', 0.5)
        self.assertTrue(res == expected)
        self.assertTrue(is_hermitian(res))

        res = weyl_polynomial_quantization('q0^2 p0')
        expected = QuadOperator('q0 q0 p0', 0.5) \
            + QuadOperator('p0 q0 q0', 0.5)
        self.assertTrue(res == expected)
        self.assertTrue(is_hermitian(res))
Example #19
0
 def test_quad_form(self):
     """Test it has the correct form using quadrature operators"""
     self.logTestName()
     H, _ = beamsplitter(np.pi / 4,
                         np.pi / 2,
                         mode1=1,
                         mode2=3,
                         hbar=self.hbar)
     H = normal_ordered(get_quad_operator(H, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('q1 q3', -1)
     expected += QuadOperator('p1 p3', -1)
     self.assertEqual(H, expected)
Example #20
0
    def test_singular_coefficients(self):
        """Test that H=p^2/2+q has displacement (q,t)=(-t^2,-t)"""
        self.eng.reset()
        q = self.eng.register

        H = QuadOperator('p0 p0', 0.5) + QuadOperator('q0')

        with self.eng:
            GaussianPropagation(H, self.t) | q[0]

        state = self.eng.run('gaussian')
        res = state.means()
        expected = [-self.t**2 / 2, -self.t]
        self.assertTrue(np.allclose(res, expected))
    def test_singular_coefficients(self):
        """Test that H=p^2/2+q has displacement (q,t)=(-t^2,-t)"""
        prog = sf.Program(1)
        eng = sf.Engine("gaussian")

        H = QuadOperator('p0 p0', 0.5) + QuadOperator('q0')

        with prog.context as q:
            GaussianPropagation(H, self.t) | q[0]

        state = eng.run(prog).state
        res = state.means()
        expected = [-self.t**2 / 2, -self.t]
        assert np.allclose(res, expected)
Example #22
0
    def test_symmetric_non_hermitian(self):
        op = BosonOperator('0^ 0')
        res = symmetric_ordering(op)
        expected = BosonOperator('0^ 0', 0.5) \
            + BosonOperator('0 0^', 0.5)
        self.assertTrue(res == expected)
        self.assertTrue(is_hermitian(res))

        op = QuadOperator('q0 p0')
        res = symmetric_ordering(op)
        expected = QuadOperator('q0 p0', 0.5) \
            + QuadOperator('p0 q0', 0.5)
        self.assertTrue(res == expected)
        self.assertTrue(is_hermitian(res))
Example #23
0
 def test_two_mode(self):
     q = QuadOperator('p2 q0')
     b = get_boson_operator(q, hbar=self.hbar)
     expected = -1j*self.hbar/2 \
         * (BosonOperator('0') + BosonOperator('0^')) \
         * (BosonOperator('2') - BosonOperator('2^'))
     self.assertTrue(b == expected)
Example #24
0
 def test_p_squared(self):
     b = self.hbar * (-BosonOperator('1^ 1^') - BosonOperator('1 1') +
                      BosonOperator('') + 2 * BosonOperator('1^ 1')) / 2
     q = normal_ordered(get_quad_operator(b, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('p1 p1')
     self.assertTrue(q == expected)
Example #25
0
 def test_q_squared(self):
     b = self.hbar * (BosonOperator('0^ 0^') + BosonOperator('0 0') +
                      BosonOperator('') + 2 * BosonOperator('0^ 0')) / 2
     q = normal_ordered(get_quad_operator(b, hbar=self.hbar),
                        hbar=self.hbar)
     expected = QuadOperator('q0 q0')
     self.assertTrue(q == expected)
Example #26
0
    def test_displacement_vector(self):
        """Test displacement vector extracted"""
        H = QuadOperator('q0', -0.432) + QuadOperator('p0', 3.213)
        A, d = quadratic_coefficients(H)
        expected_A = np.zeros([2, 2])
        expected_d = np.array([3.213, 0.432])
        assert np.allclose(A, expected_A)
        assert np.allclose(d, expected_d)

        _, d = quadratic_coefficients(QuadOperator('q0 q0'))
        expected = np.array([0, 0])
        assert np.allclose(d, expected)

        _, d = quadratic_coefficients(QuadOperator('p0 p1'))
        expected = np.array([0, 0, 0, 0])
        assert np.allclose(d, expected)
Example #27
0
 def test_two_term(self):
     b = BosonOperator('0^ 0') + BosonOperator('0 0^')
     q = get_quad_operator(b, hbar=self.hbar)
     expected = (QuadOperator('q0') - 1j*QuadOperator('p0')) \
         * (QuadOperator('q0') + 1j*QuadOperator('p0')) \
         + (QuadOperator('q0') + 1j*QuadOperator('p0')) \
         * (QuadOperator('q0') - 1j*QuadOperator('p0'))
     expected /= 2 * self.hbar
     self.assertTrue(q == expected)
Example #28
0
    def test_symmetric_two_term_same(self):
        op = BosonOperator('0^ 0^')
        res = symmetric_ordering(op)
        self.assertTrue(res == op)

        op = QuadOperator('q0 q0')
        res = symmetric_ordering(op)
        self.assertTrue(res == op)
Example #29
0
    def test_symmetric_one_term_multimode(self):
        op = BosonOperator('0^ 1^ 2 3')
        res = symmetric_ordering(op)
        self.assertTrue(res == op)

        op = QuadOperator('q0 q1 p2 p3')
        res = symmetric_ordering(op)
        self.assertTrue(res == op)
Example #30
0
    def test_symmetric_non_hermitian_order(self):
        op1 = QuadOperator('q0 p0 q0')
        op2 = QuadOperator('q0 q0 p0')
        op3 = QuadOperator('p0 q0 q0')

        w1 = symmetric_ordering(op1)
        w2 = symmetric_ordering(op2)
        w3 = symmetric_ordering(op3)

        self.assertTrue(is_hermitian(w1))
        self.assertTrue(is_hermitian(w2))
        self.assertTrue(is_hermitian(w3))

        expected = QuadOperator('q0 q0 p0', 0.5) \
            + QuadOperator('p0 q0 q0', 0.5)
        self.assertTrue(w1 == expected)
        self.assertTrue(w2 == expected)
        self.assertTrue(w3 == expected)