Пример #1
0
    def test_pauli_word_slice(self):
        self.assertEqual(
            PauliWord("XIYXZ")[1:5:2],
            PauliWord("IX")
        )

        self.assertTrue(
            PauliWord("XIYXZ")[-1],
            PauliWord("Z")
        )
Пример #2
0
 def test_factorization(self):
     factorization = pauli_word_exp_factorization(0.1, PauliWord("XIXXYZ"))
     self.assertEqual(factorization,
                      [(-0.7853981633974483, PauliWord("IIIIXZ")),
                       (-0.7853981633974483, PauliWord("IIIZZI")),
                       (0.7853981633974483, PauliWord("IIIIXZ")),
                       (-0.7853981633974483, PauliWord("IIZYII")),
                       (0.1, PauliWord("XIYIII")),
                       (0.7853981633974483, PauliWord("IIZYII")),
                       (-0.7853981633974483, PauliWord("IIIIXZ")),
                       (0.7853981633974483, PauliWord("IIIZZI")),
                       (0.7853981633974483, PauliWord("IIIIXZ"))])
Пример #3
0
 def test_symbolic_factorization(self):
     import sympy
     factorization = pauli_word_exp_factorization(sympy.Symbol("t"),
                                                  PauliWord("XIXXYZ"))
     self.assertEqual(factorization,
                      [(-0.7853981633974483, PauliWord("IIIIXZ")),
                       (-0.7853981633974483, PauliWord("IIIZZI")),
                       (0.7853981633974483, PauliWord("IIIIXZ")),
                       (-0.7853981633974483, PauliWord("IIZYII")),
                       (sympy.Symbol("t"), PauliWord("XIYIII")),
                       (0.7853981633974483, PauliWord("IIZYII")),
                       (-0.7853981633974483, PauliWord("IIIIXZ")),
                       (0.7853981633974483, PauliWord("IIIZZI")),
                       (0.7853981633974483, PauliWord("IIIIXZ"))])
Пример #4
0
    def test_simulate(self):
        compressed_status = [True, False]

        rad = 0.75
        pauli_word = PauliWord("XZYX")

        for initial_state in range(2**len(pauli_word)):
            results = []
            for is_compressed in compressed_status:
                simulator = Simulator()
                circuit = Circuit()
                qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]
                gate = PauliWordExpGate(rad, pauli_word)
                operation = gate.on(*qubits[0:len(gate.pauli_word)])

                if is_compressed:
                    circuit.append(operation)
                else:
                    circuit.append(cirq.decompose(operation))

                result = simulator.simulate(
                    circuit, initial_state=initial_state
                )  # type: cirq.SimulationTrialResult
                # print(circuit)
                print(result.final_state)
                # print(cirq.unitary(circuit_compressed))

                results.append(result)

            self.assertTrue(
                np.allclose(results[0].final_state,
                            results[1].final_state,
                            rtol=1e-4,
                            atol=1e-5))
Пример #5
0
 def test_pauli_word(self):
     for _, input_v in self.input_labels.items():
         pauli_word = PauliWord(input_v)
         for check_k, check_v in self.check_labels.items():
             self.assertEqual(
                 check_v,
                 getattr(pauli_word, check_k)
             )
Пример #6
0
    def setUp(self) -> None:
        self.circuit_decomposed = Circuit()
        self.circuit_compressed = Circuit()
        self.qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]

        self.gate = PauliWordExpGate(0.25, PauliWord("IXXZ"))
        self.operation = self.gate.on(*self.qubits[0:4])
        self.circuit_decomposed.append(cirq.decompose(self.operation))
        self.circuit_compressed.append(self.operation)
Пример #7
0
 def test_factorization_special_case(self):
     """
     This test case reveals the bug of `pauli_word_exp_factorization` when
     choosing `k`: use `sorted` instead of `list` to create list from
     `pauli_dict_form.keys()` (which is actually unordered).
     """
     factorization = pauli_word_exp_factorization(1.2,
                                                  PauliWord("ZZIIIIIZZ"))
     print(factorization)
     self.assertEqual(len(factorization), 5)
Пример #8
0
    def test_symbolic_circuit(self):
        circuit = Circuit()
        qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]

        gate = PauliWordExpGate(sympy.Symbol("t"), PauliWord("XXZX"))
        operation = gate.on(qubits[0], qubits[1], qubits[3], qubits[2])
        circuit.append(cirq.decompose(operation))
        circuit.append(operation)

        print(circuit)
Пример #9
0
    def test_simplest_case(self):
        circuit = Circuit()
        qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]
        gate = PauliWordExpGate(0.1, PauliWord("II"))
        circuit.append(gate.on(qubits[2], qubits[0]))
        # If use the following line instead, `print(circuit)` will show nothing:
        # circuit.append(cirq.decompose(gate.on(qubits[2], qubits[0])))

        print(circuit)

        self.assertTrue(np.allclose(cirq.unitary(gate), np.identity(4)))
Пример #10
0
    def test_for_random_matrix(self):
        num_qubits = 2**3

        matrix = random_complex_matrix(num_qubits, num_qubits)

        expansion = pauli_expansion_for_any_matrix(matrix)

        _matrix = 0.0
        for term, coeff in expansion.items():
            _matrix += coeff * PauliWord(term).sparray.toarray()

        self.assertTrue(np.allclose(_matrix, matrix))
Пример #11
0
 def test_array(self):
     self.assertTrue(np.allclose(
         PauliWord("XIY").sparray.toarray(),
         np.array([
             [0, 0, 0, 0, 0, -1j, 0, 0],
             [0, 0, 0, 0, 1j, 0, 0, 0],
             [0, 0, 0, 0, 0, 0, 0, -1j],
             [0, 0, 0, 0, 0, 0, 1j, 0],
             [0, -1j, 0, 0, 0, 0, 0, 0],
             [1j, 0, 0, 0, 0, 0, 0, 0],
             [0, 0, 0, -1j, 0, 0, 0, 0],
             [0, 0, 1j, 0, 0, 0, 0, 0]
         ])
     ))
Пример #12
0
    def test_diagram(self):
        qubits = [cirq.GridQubit(i, j) for i in range(2) for j in range(2)]
        circuit = cirq.circuits.Circuit()

        circuit.append(
            cirq.MatrixGate(
                splinalg.expm(1j * 0.1 * PauliWord("XX").sparray.toarray()))(
                    *qubits[0:2]))

        print(circuit)
        self.assertEqual(
            str(circuit),
            "           ┌                                           ┐\n"
            "           │0.995+0.j  0.   +0.j  0.   +0.j  0.   +0.1j│\n"
            "(0, 0): ───│0.   +0.j  0.995+0.j  0.   +0.1j 0.   +0.j │───\n"
            "           │0.   +0.j  0.   +0.1j 0.995+0.j  0.   +0.j │\n"
            "           │0.   +0.1j 0.   +0.j  0.   +0.j  0.995+0.j │\n"
            "           └                                           ┘\n"
            "           │\n"
            "(0, 1): ───#2──────────────────────────────────────────────")
Пример #13
0
 def test_effective_len(self):
     self.assertEqual(
         PauliWord("XIYXZ").effective_len,
         4
     )
Пример #14
0
 def test_identity(self):
     self.assertEqual(
         PauliWord("I" * 10).qubit_operator_str,
         ""
     )
Пример #15
0
 def test_unitary(self):
     self.assertTrue(
         np.allclose(
             cirq.unitary(self.gate),
             splinalg.expm(-1.0j * 0.25 *
                           PauliWord("IXXZ").sparray.toarray())))
Пример #16
0
class OperationGradTest(unittest.TestCase):

    @ddt.unpack
    @ddt.data(

        # d[rx(rad)] / d[rad] = d[e^{-i X rad / 2}] / d[rad]
        #                     = -i/2 X e^{-i X rads / 2}
        #                     = -i/2 X rx(rad)
        [rx(rad).on(q0), rad,
         LCO({
             (rx(rad).on(q0), X(q0)): -0.5j
         })],

        # d[XPow(e, s)] / d[e] = i pi {s + 1/2 (I - X)} XPow(e, s)
        [XPowGate(exponent=rad, global_shift=0.3).on(q0), rad,
         LCO({
             (XPowGate(exponent=rad, global_shift=0.3).on(q0),):
                 1.0j * np.pi * (0.3 + 0.5),
             (X(q0), XPowGate(exponent=rad, global_shift=0.3).on(q0)):
                 -0.5j * np.pi
         })],

        # d[e^{-i A0 A1 rad}] / d[rad] = -i A0 A1 e^{-i A0 A1 rad}
        [TwoPauliExpGate("X", "Z", rad).on(q0, q1), rad,
         LCO({
             (TwoPauliExpGate("X", "Z", rad).on(q0, q1), X(q0), Z(q1)): -1.0j
         })],

        # d[exp(i pi rad)] / d[rad] = i pi exp(i pi rad)
        [GlobalPhaseGate(rad ** 2).on(q0), rad,
         LCO({
             (GlobalPhaseGate(rad ** 2).on(q0),): 2.0j * sympy.pi * rad
         })],

        # d[e^{−i t P}] / d[t] = -i P e^{−i t P}
        [PauliWordExpGate(rad ** 2, PauliWord("ZYX")).on(q0, q1, q2), rad,
         LCO({
             (PauliWordExpGate(rad ** 2, PauliWord("ZYX")).on(q0, q1, q2),
              Z(q0), Y(q1), X(q2)): -2.0j * rad
         })],

        # d[rx(rad) ⊗ rz(rad)] / d[rad] = -i/2 { X rx(rad) ⊗ rz(rad)
        #                                      + rx(rad) ⊗ Z rz(rad) }
        [GateBlock(
            TwoRotsGenerator()
        ).on(q0, q1), rad,
         -0.5j * LCO({
             (rz(rad).on(q1), rx(rad).on(q0), X(q0)): 1,
             (rz(rad).on(q1), rx(rad).on(q0), Z(q1)): 1
         })],

        # d[CRx(rad)] / d[rad] = |1><1| ⊗ d[Rx(rad)]/d[rad]
        #                      = -i/2 |1><1| ⊗ X Rx(rad)
        #                      = -i/4 { C[X Rx(rad)] - C[-X Rx(rad)] }
        [cirq.ControlledGate(rx(rad), num_controls=1).on(q0, q1), rad,
         -1.0j / 4 * LCO({
             (ControlledGate(X).on(q0, q1), ControlledGate(rx(rad)).on(q0, q1)): 1,
             (ControlledGate(X).on(q0, q1), ControlledGate(rx(rad)).on(q0, q1),
              ControlledGate(GlobalPhaseGate(1)).on(q0, q1)): -1
         })],

        # d[CCRz(rad)] / d[rad] = |1><1| ⊗ |1><1| ⊗ d[Rz(rad)]/d[rad]
        #                       = -i/4 { CC[Z Rz(rad)] - CC[-Z Rz(rad)] }
        [ControlledGate(
            ControlledGate(
                cirq.rz(rad)
            )
        ).on(q0, q1, q2), rad,
         -1.0j / 4 * LCO({
             (ControlledGate(ControlledGate(Z)).on(q0, q1, q2),
              ControlledGate(ControlledGate(rz(rad))).on(q0, q1, q2)): 1,
             (ControlledGate(ControlledGate(Z)).on(q0, q1, q2),
              ControlledGate(ControlledGate(rz(rad))).on(q0, q1, q2),
              ControlledGate(ControlledGate(GlobalPhaseGate(1))).on(q0, q1, q2)): -1
         })],

        # d[U(rad)] = -i/2 U(rad) X.on(q0) - i/4 { U+(rad) - U-(rad) }
        [u.on(q0, q1, q2, q3, q4), rad,
         LCO({
             (X(q0), u.on(q0, q1, q2, q3, q4),): -0.5j,  # order matters!
             (u_positive.on(q0, q1, q2, q3, q4),): -0.25j,
             (u_negative.on(q0, q1, q2, q3, q4),): +0.25j
         })]

    )
    def test_grad(self, op, param, grad_lco):
        print("[Grad of {}]".format(op))
        grad = op_grad(op, param)
        if isinstance(grad, GradNotImplemented):
            print("The grad of {} is not implemented.".format(grad.operation))
            return

        for _op_series, coeff in grad.items():
            _circuit = cirq.Circuit()
            _circuit.append(_op_series)
            print("Coefficient: {}".format(coeff))
            print(_circuit, "\n")

        random_rad = typing.cast(float, np.random.rand())
        param_resolver = {"rad": random_rad}
        # param_resolver = {"rad": 0}

        test_lco_identical_with_simulator(
            cirq.resolve_parameters(grad, param_resolver),
            cirq.resolve_parameters(grad_lco, param_resolver),
            self
        )
Пример #17
0
 def test_dict_form(self):
     self.assertEqual(
         PauliWord("XIYXZ").dict_form,
         {0: "X", 2: "Y", 3: "X", 4: "Z"}
     )
Пример #18
0
    def test_resize(self):
        word = PauliWord("XIYXZ")

        self.assertEqual(
            PauliWord(word, length=3),
            PauliWord("XIY")
        )
        self.assertEqual(
            PauliWord(word.fullstr, length=3),
            PauliWord("XIY")
        )
        self.assertEqual(
            PauliWord(word.qubit_operator_str, length=3),
            PauliWord("XIY")
        )

        self.assertEqual(
            PauliWord(word, length=8),
            PauliWord("XIYXZIII")
        )
        self.assertEqual(
            PauliWord(word.fullstr, length=8),
            PauliWord("XIYXZIII")
        )
        self.assertEqual(
            PauliWord(word.qubit_operator_str, length=8),
            PauliWord("XIYXZIII")
        )
Пример #19
0
def pauli_word_exp_factorization(
    coefficient: typing.Union[float, sympy.Basic], pauli_word: PauliWord
) -> typing.List[typing.Tuple[typing.Union[float, sympy.Basic], PauliWord]]:
    """
    Factorize the exponentiation of Pauli word P
    $$
        e^{−i t P}
    $$
    (where t is the coefficient) with formula:
    $$
        e^{−i t P} = e^{i (π/4) wk'' P2} e^{−i t P1 wk'} e^{−i (π/4) wk'' P2},
    $$
    where wk, P1 and P2 satisfy $P = P1 wk P2$. The subscript of $wk$ denotes
    that this elementary Pauli operator corresponds to the kth qubit. The word
    $P1 (P2)$ contains all qubit indices that are strictly greater (lower)
    than k. wk' and wk'' are the other two Pauli operators which satisfy
    $$
        [ w', w'' ] = 2 i w.
    $$

    :param coefficient: float
        coefficient t in the exponential.
    :param pauli_word: PauliWord
        the Pauli word P in the exponential.
    :return:
        the factorized form of $e^{−i t P}$.
        For example, if
        $$
            e^{−i t P} = e^{−i tn Pn} ... e^{−i t1 P1} e^{−i t0 P0},
        $$
        then the returned will be like:
            [
                (tn, Pn),
                ...
                (t0, P0),
            ].

        Note that 0 <= Pi.effective_len <= 2.

    """

    if pauli_word.effective_len == 0:
        return []
    elif pauli_word.effective_len < 3:
        return [(coefficient, pauli_word)]

    # choose k
    pauli_dict_form = pauli_word.dict_form
    k = sorted(pauli_dict_form.keys())[len(pauli_dict_form) // 2]

    p1, wk, p2 = [pauli_word[:k], pauli_word[k], pauli_word[k + 1:]]
    i1, i2 = map(lambda word: PauliWord("I" * len(word)), [p1, p2])
    wk1, wk2 = Pauli(wk.word).get_the_other_two_paulis()

    _factorized = pauli_word_exp_factorization(coefficient=sympy.Symbol("t"),
                                               pauli_word=PauliWord.join(
                                                   i1, wk2, p2))

    returned = [(float(c.subs({"t": -np.pi / 4})),
                 w) if isinstance(c, sympy.Basic) else (c, w)
                for c, w in _factorized]

    returned.extend(
        pauli_word_exp_factorization(coefficient=coefficient,
                                     pauli_word=PauliWord.join(p1, wk1, i2)))

    returned.extend([(float(c.subs({"t": np.pi / 4})),
                      w) if isinstance(c, sympy.Basic) else (c, w)
                     for c, w in _factorized])

    # returned = pauli_word_exp_factorization(
    #     coefficient=-np.pi / 4,
    #     pauli_word=PauliWord.join(i1, wk2, p2)
    # )
    #
    # returned.extend(pauli_word_exp_factorization(
    #     coefficient=coefficient,
    #     pauli_word=PauliWord.join(p1, wk1, i2)
    # ))
    #
    # returned.extend(pauli_word_exp_factorization(
    #     coefficient=np.pi / 4,
    #     pauli_word=PauliWord.join(i1, wk2, p2)
    # ))

    return returned