Пример #1
0
    def trotter_step(
            self,
            qubits: Sequence[cirq.QubitId],
            time: float,
            control_qubit: Optional[cirq.QubitId] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Simulate the one-body terms for half of the full time
        yield (cirq.RotZGate(rads=-0.5 * self.orbital_energies[i] * time).on(
            qubits[i]) for i in range(n_qubits))

        # Rotate to the computational basis
        yield bogoliubov_transform(qubits, self.basis_change_matrix)

        # Simulate the two-body terms for the full time
        def two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
            yield cirq.Rot11Gate(rads=-2 * self.hamiltonian.two_body[p, q] *
                                 time).on(a, b)

        yield swap_network(qubits, two_body_interaction)
        # The qubit ordering has been reversed
        qubits = qubits[::-1]

        # Rotate back to the basis in which the one-body term is diagonal
        yield cirq.inverse(
            bogoliubov_transform(qubits, self.basis_change_matrix))

        # Simulate the one-body terms for half of the full time
        yield (cirq.RotZGate(rads=-0.5 * self.orbital_energies[i] * time).on(
            qubits[i]) for i in range(n_qubits))
Пример #2
0
def test_z_matrix():
    assert np.allclose(
        cirq.RotZGate(half_turns=1).matrix(), np.array([[1, 0], [0, -1]]))
    assert np.allclose(
        cirq.RotZGate(half_turns=0.5).matrix(), np.array([[1, 0], [0, 1j]]))
    assert np.allclose(
        cirq.RotZGate(half_turns=0).matrix(), np.array([[1, 0], [0, 1]]))
    assert np.allclose(
        cirq.RotZGate(half_turns=-0.5).matrix(), np.array([[1, 0], [0, -1j]]))
Пример #3
0
def test_single_qubit_matrix_to_gates_fuzz_half_turns_merge_z_gates(
        pre_turns, post_turns):
    intended_effect = cirq.dot(
        cirq.RotZGate(half_turns=2 * pre_turns).matrix(), cirq.X.matrix(),
        cirq.RotZGate(half_turns=2 * post_turns).matrix())

    gates = cirq.single_qubit_matrix_to_gates(intended_effect, tolerance=1e-7)

    assert len(gates) <= 2
    assert_gates_implement_unitary(gates, intended_effect, atol=1e-6)
Пример #4
0
def test_single_qubit_matrix_to_native_gates_fuzz_half_turns_always_one_gate(
        pre_turns, post_turns):
    intended_effect = cirq.dot(
        cirq.RotZGate(half_turns=2 * pre_turns).matrix(), cirq.X.matrix(),
        cirq.RotZGate(half_turns=2 * post_turns).matrix())

    gates = decompositions.single_qubit_matrix_to_native_gates(
        intended_effect, tolerance=0.0001)

    assert len(gates) == 1
    assert_gates_implement_unitary(gates, intended_effect)
Пример #5
0
    def operations(self, qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
        """Produce the operations of the ansatz circuit."""

        n_qubits = len(qubits)
        param_set = set(self.params())

        for i in range(self.iterations):

            # Change to the basis in which the one-body term is diagonal
            yield bogoliubov_transform(
                qubits, self.one_body_basis_change_matrix.T.conj())

            # Simulate the one-body terms.
            for p in range(n_qubits):
                u_symbol = LetterWithSubscripts('U', p, i)
                if u_symbol in param_set:
                    yield cirq.RotZGate(half_turns=u_symbol).on(qubits[p])

            # Simulate each singular vector of the two-body terms.
            prior_basis_matrix = self.one_body_basis_change_matrix

            for j in range(len(self.eigenvalues)):

                # Get the basis change matrix.
                basis_change_matrix = self.basis_change_matrices[j]

                # Merge previous basis change matrix with the inverse of the
                # current one
                merged_basis_change_matrix = numpy.dot(
                    prior_basis_matrix, basis_change_matrix.T.conj())
                yield bogoliubov_transform(qubits, merged_basis_change_matrix)

                # Simulate the off-diagonal two-body terms.
                def two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
                    v_symbol = LetterWithSubscripts('V', p, q, j, i)
                    if v_symbol in param_set:
                        yield cirq.Rot11Gate(half_turns=v_symbol).on(a, b)

                yield swap_network(qubits, two_body_interaction)
                qubits = qubits[::-1]

                # Simulate the diagonal two-body terms.
                for p in range(n_qubits):
                    u_symbol = LetterWithSubscripts('U', p, j, i)
                    if u_symbol in param_set:
                        yield cirq.RotZGate(half_turns=u_symbol).on(qubits[p])

                # Update prior basis change matrix.
                prior_basis_matrix = basis_change_matrix

            # Undo final basis transformation.
            yield bogoliubov_transform(qubits, prior_basis_matrix)
Пример #6
0
def test_ignores_czs_separated_by_parameterized():
    a, b = cirq.LineQubit.range(2)
    assert_optimizes(
        before=cirq.Circuit([
            cirq.Moment([cirq.CZ(a, b)]),
            cirq.Moment([cirq.RotZGate(half_turns=cirq.Symbol('boo'))(a)]),
            cirq.Moment([cirq.CZ(a, b)]),
        ]),
        expected=cirq.Circuit([
            cirq.Moment([cirq.CZ(a, b)]),
            cirq.Moment([cirq.RotZGate(half_turns=cirq.Symbol('boo'))(a)]),
            cirq.Moment([cirq.CZ(a, b)]),
        ]))
Пример #7
0
    def trotter_step(
            self,
            qubits: Sequence[cirq.QubitId],
            time: float,
            control_qubit: Optional[cirq.QubitId] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Change to the basis in which the one-body term is diagonal
        yield bogoliubov_transform(qubits,
                                   self.one_body_basis_change_matrix.T.conj())

        # Simulate the one-body terms.
        for p in range(n_qubits):
            yield cirq.RotZGate(rads=-self.one_body_energies[p] * time).on(
                qubits[p])

        # Simulate each singular vector of the two-body terms.
        prior_basis_matrix = self.one_body_basis_change_matrix

        for j in range(len(self.eigenvalues)):

            # Get the two-body coefficients and basis change matrix.
            two_body_coefficients = self.scaled_density_density_matrices[j]
            basis_change_matrix = self.basis_change_matrices[j]

            # Merge previous basis change matrix with the inverse of the
            # current one
            merged_basis_change_matrix = numpy.dot(
                prior_basis_matrix, basis_change_matrix.T.conj())
            yield bogoliubov_transform(qubits, merged_basis_change_matrix)

            # Simulate the off-diagonal two-body terms.
            yield swap_network(
                qubits, lambda p, q, a, b: cirq.Rot11Gate(
                    rads=-2 * two_body_coefficients[p, q] * time).on(a, b))
            qubits = qubits[::-1]

            # Simulate the diagonal two-body terms.
            for p in range(n_qubits):
                yield cirq.RotZGate(rads=-two_body_coefficients[p, p] *
                                    time).on(qubits[p])

            # Update prior basis change matrix
            prior_basis_matrix = basis_change_matrix

        # Undo final basis transformation
        yield bogoliubov_transform(qubits, prior_basis_matrix)
Пример #8
0
def _slater_basis_change(
        qubits: Sequence[cirq.QubitId], transformation_matrix: numpy.ndarray,
        initially_occupied_orbitals: Optional[Sequence[int]]) -> cirq.OP_TREE:
    n_qubits = len(qubits)

    if initially_occupied_orbitals is None:
        decomposition, diagonal = givens_decomposition_square(
            transformation_matrix)
        circuit_description = list(reversed(decomposition))
        # The initial state is not a computational basis state so the
        # phases left on the diagonal in the decomposition matter
        yield (cirq.RotZGate(rads=numpy.angle(diagonal[j])).on(qubits[j])
               for j in range(n_qubits))
    else:
        initially_occupied_orbitals = cast(Sequence[int],
                                           initially_occupied_orbitals)
        transformation_matrix = transformation_matrix[list(
            initially_occupied_orbitals)]
        n_occupied = len(initially_occupied_orbitals)
        # Flip bits so that the first n_occupied are 1 and the rest 0
        initially_occupied_orbitals_set = set(initially_occupied_orbitals)
        yield (cirq.X(qubits[j]) for j in range(n_qubits)
               if (j < n_occupied) != (j in initially_occupied_orbitals_set))
        circuit_description = slater_determinant_preparation_circuit(
            transformation_matrix)

    yield _ops_from_givens_rotations_circuit_description(
        qubits, circuit_description)
Пример #9
0
def rot_z_layer(h, half_turns):
    """Yields Z rotations by half_turns conditioned on the field h."""
    gate = cirq.RotZGate(half_turns=half_turns)
    for i, h_row in enumerate(h):
        for j, h_ij in enumerate(h_row):
            if h_ij == 1:
                yield gate(cirq.GridQubit(i, j))
Пример #10
0
def _gaussian_basis_change(
        qubits: Sequence[cirq.QubitId], transformation_matrix: numpy.ndarray,
        initially_occupied_orbitals: Optional[Sequence[int]]) -> cirq.OP_TREE:
    n_qubits = len(qubits)

    # Rearrange the transformation matrix because the OpenFermion routine
    # expects it to describe annihilation operators rather than creation
    # operators
    left_block = transformation_matrix[:, :n_qubits]
    right_block = transformation_matrix[:, n_qubits:]
    transformation_matrix = numpy.block(
        [numpy.conjugate(right_block),
         numpy.conjugate(left_block)])

    decomposition, left_decomposition, _, left_diagonal = (
        fermionic_gaussian_decomposition(transformation_matrix))

    if (initially_occupied_orbitals is not None
            and len(initially_occupied_orbitals) == 0):
        # Starting with the vacuum state yields additional symmetry
        circuit_description = list(reversed(decomposition))
    else:
        if initially_occupied_orbitals is None:
            # The initial state is not a computational basis state so the
            # phases left on the diagonal in the Givens decomposition matter
            yield (cirq.RotZGate(rads=numpy.angle(left_diagonal[j])).on(
                qubits[j]) for j in range(n_qubits))
        circuit_description = list(reversed(decomposition +
                                            left_decomposition))

    yield _ops_from_givens_rotations_circuit_description(
        qubits, circuit_description)
Пример #11
0
def test_arbitrary_xyz_repr():
    cirq.testing.assert_equivalent_repr(
        cirq.RotXGate(half_turns=0.1, global_shift_in_half_turns=0.2))
    cirq.testing.assert_equivalent_repr(
        cirq.RotYGate(half_turns=0.1, global_shift_in_half_turns=0.2))
    cirq.testing.assert_equivalent_repr(
        cirq.RotZGate(half_turns=0.1, global_shift_in_half_turns=0.2))
Пример #12
0
def test_text_diagrams():
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')
    circuit = Circuit.from_ops(
        cirq.SWAP(a, b),
        cirq.X(a),
        cirq.Y(a),
        cirq.Z(a),
        cirq.RotZGate(half_turns=cirq.Symbol('x')).on(a),
        cirq.CZ(a, b),
        cirq.CNOT(a, b),
        cirq.CNOT(b, a),
        cirq.H(a),
        cirq.ISWAP(a, b),
        cirq.ISWAP(a, b)**-1)

    assert circuit.to_text_diagram().strip() == """
a: ───×───X───Y───Z───Z^x───@───@───X───H───iSwap───iSwap──────
      │                     │   │   │       │       │
b: ───×─────────────────────@───X───@───────iSwap───iSwap^-1───
    """.strip()

    assert circuit.to_text_diagram(use_unicode_characters=False).strip() == """
a: ---swap---X---Y---Z---Z^x---@---@---X---H---iSwap---iSwap------
      |                        |   |   |       |       |
b: ---swap---------------------@---X---@-------iSwap---iSwap^-1---
    """.strip()
Пример #13
0
    def trotter_step(
            self,
            qubits: Sequence[cirq.QubitId],
            time: float,
            control_qubit: Optional[cirq.QubitId] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Apply one- and two-body interactions for the full time
        def one_and_two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
            yield ControlledXXYYGate(
                duration=self.hamiltonian.one_body[p, q].real * time).on(
                    control_qubit, a, b)
            yield ControlledYXXYGate(
                duration=self.hamiltonian.one_body[p, q].imag * time).on(
                    control_qubit, a, b)
            yield Rot111Gate(rads=-2 * self.hamiltonian.two_body[p, q] *
                             time).on(control_qubit, a, b)

        yield swap_network(qubits,
                           one_and_two_body_interaction,
                           fermionic=True)
        qubits = qubits[::-1]

        # Apply one-body potential for the full time
        yield (cirq.Rot11Gate(rads=-self.hamiltonian.one_body[i, i].real *
                              time).on(control_qubit, qubits[i])
               for i in range(n_qubits))

        # Apply phase from constant term
        yield cirq.RotZGate(rads=-self.hamiltonian.constant *
                            time).on(control_qubit)
Пример #14
0
def test_rot_gates_eq():
    eq = cirq.testing.EqualsTester()
    gates = [
        cirq.RotXGate, cirq.RotYGate, cirq.RotZGate, cirq.CNotGate,
        cirq.Rot11Gate
    ]
    for gate in gates:
        eq.add_equality_group(gate(half_turns=3.5), gate(half_turns=-0.5),
                              gate(rads=-np.pi / 2), gate(degs=-90))
        eq.make_equality_group(lambda: gate(half_turns=0))
        eq.make_equality_group(lambda: gate(half_turns=0.5))

    eq.add_equality_group(cirq.RotXGate(), cirq.RotXGate(half_turns=1), cirq.X)
    eq.add_equality_group(cirq.RotYGate(), cirq.RotYGate(half_turns=1), cirq.Y)
    eq.add_equality_group(cirq.RotZGate(), cirq.RotZGate(half_turns=1), cirq.Z)
    eq.add_equality_group(
        cirq.RotZGate(half_turns=1, global_shift_in_half_turns=-0.5),
        cirq.RotZGate(half_turns=5, global_shift_in_half_turns=-0.5))
    eq.add_equality_group(
        cirq.RotZGate(half_turns=3, global_shift_in_half_turns=-0.5))
    eq.add_equality_group(
        cirq.RotZGate(half_turns=1, global_shift_in_half_turns=-0.1))
    eq.add_equality_group(
        cirq.RotZGate(half_turns=5, global_shift_in_half_turns=-0.1))
    eq.add_equality_group(cirq.CNotGate(), cirq.CNotGate(half_turns=1),
                          cirq.CNOT)
    eq.add_equality_group(cirq.Rot11Gate(), cirq.Rot11Gate(half_turns=1),
                          cirq.CZ)
    def operations(self, qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
        """Produce the operations of the ansatz circuit."""
        # TODO implement asymmetric ansatzes?

        for i in range(self.iterations):

            suffix = '-{}'.format(i) if self.iterations > 1 else ''

            # Apply one- and two-body interactions with a swap network that
            # reverses the order of the modes
            def one_and_two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
                if 'T{}_{}'.format(p, q) + suffix in self.params:
                    yield XXYYGate(
                        half_turns=self.params['T{}_{}'.format(p, q) +
                                               suffix]).on(a, b)
                if 'W{}_{}'.format(p, q) + suffix in self.params:
                    yield YXXYGate(
                        half_turns=self.params['W{}_{}'.format(p, q) +
                                               suffix]).on(a, b)
                if 'V{}_{}'.format(p, q) + suffix in self.params:
                    yield cirq.Rot11Gate(
                        half_turns=self.params['V{}_{}'.format(p, q) +
                                               suffix]).on(a, b)

            yield swap_network(qubits,
                               one_and_two_body_interaction,
                               fermionic=True)
            qubits = qubits[::-1]

            # Apply one-body potential
            yield (cirq.RotZGate(half_turns=self.params['U{}'.format(p) +
                                                        suffix]).on(qubits[p])
                   for p in range(len(qubits))
                   if 'U{}'.format(p) + suffix in self.params)

            # Apply one- and two-body interactions again. This time, reorder
            # them so that the entire iteration is symmetric
            def one_and_two_body_interaction_reversed_order(p, q, a,
                                                            b) -> cirq.OP_TREE:
                if 'V{}_{}'.format(p, q) + suffix in self.params:
                    yield cirq.Rot11Gate(
                        half_turns=self.params['V{}_{}'.format(p, q) +
                                               suffix]).on(a, b)
                if 'W{}_{}'.format(p, q) + suffix in self.params:
                    yield YXXYGate(
                        half_turns=self.params['W{}_{}'.format(p, q) +
                                               suffix]).on(a, b)
                if 'T{}_{}'.format(p, q) + suffix in self.params:
                    yield XXYYGate(
                        half_turns=self.params['T{}_{}'.format(p, q) +
                                               suffix]).on(a, b)

            yield swap_network(qubits,
                               one_and_two_body_interaction_reversed_order,
                               fermionic=True,
                               offset=True)
            qubits = qubits[::-1]
Пример #16
0
def test_parameterizable_effect():
    q = cirq.NamedQubit('q')
    r = cirq.ParamResolver({'a': 0.5})

    op1 = cirq.GateOperation(cirq.RotZGate(half_turns=cirq.Symbol('a')), [q])
    assert cirq.is_parameterized(op1)
    op2 = cirq.resolve_parameters(op1, r)
    assert not cirq.is_parameterized(op2)
    assert op2 == cirq.S.on(q)
    def operations(self, qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
        """Produce the operations of the ansatz circuit."""
        # TODO implement asymmetric ansatz

        # Change to the basis in which the one-body term is diagonal
        yield cirq.inverse(
            bogoliubov_transform(qubits, self.basis_change_matrix))

        for i in range(self.iterations):

            suffix = '-{}'.format(i) if self.iterations > 1 else ''

            # Simulate one-body terms
            yield (cirq.RotZGate(half_turns=self.params['U{}'.format(p) +
                                                        suffix]).on(qubits[p])
                   for p in range(len(qubits))
                   if 'U{}'.format(p) + suffix in self.params)

            # Rotate to the computational basis
            yield bogoliubov_transform(qubits, self.basis_change_matrix)

            # Simulate the two-body terms
            def two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
                if 'V{}_{}'.format(p, q) + suffix in self.params:
                    yield cirq.Rot11Gate(
                        half_turns=self.params['V{}_{}'.format(p, q) +
                                               suffix]).on(a, b)

            yield swap_network(qubits, two_body_interaction)
            qubits = qubits[::-1]

            # Rotate back to the basis in which the one-body term is diagonal
            yield cirq.inverse(
                bogoliubov_transform(qubits, self.basis_change_matrix))

            # Simulate one-body terms again
            yield (cirq.RotZGate(half_turns=self.params['U{}'.format(p) +
                                                        suffix]).on(qubits[p])
                   for p in range(len(qubits))
                   if 'U{}'.format(p) + suffix in self.params)

        # Rotate to the computational basis
        yield bogoliubov_transform(qubits, self.basis_change_matrix)
    def operations(self, qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
        """Produce the operations of the ansatz circuit."""
        # TODO implement asymmetric ansatz

        param_set = set(self.params())

        # Change to the basis in which the one-body term is diagonal
        yield cirq.inverse(
            bogoliubov_transform(qubits, self.basis_change_matrix))

        for i in range(self.iterations):

            # Simulate one-body terms
            for p in range(len(qubits)):
                u_symbol = LetterWithSubscripts('U', p, i)
                if u_symbol in param_set:
                    yield cirq.RotZGate(half_turns=u_symbol).on(qubits[p])

            # Rotate to the computational basis
            yield bogoliubov_transform(qubits, self.basis_change_matrix)

            # Simulate the two-body terms
            def two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
                v_symbol = LetterWithSubscripts('V', p, q, i)
                if v_symbol in param_set:
                    yield cirq.Rot11Gate(half_turns=v_symbol).on(a, b)

            yield swap_network(qubits, two_body_interaction)
            qubits = qubits[::-1]

            # Rotate back to the basis in which the one-body term is diagonal
            yield cirq.inverse(
                bogoliubov_transform(qubits, self.basis_change_matrix))

            # Simulate one-body terms again
            for p in range(len(qubits)):
                u_symbol = LetterWithSubscripts('U', p, i)
                if u_symbol in param_set:
                    yield cirq.RotZGate(half_turns=u_symbol).on(qubits[p])

        # Rotate to the computational basis
        yield bogoliubov_transform(qubits, self.basis_change_matrix)
Пример #19
0
    def _rot(self, qubit, params):
        """Helper function that returns an arbitrary rotation of the form
        R = Rz(params[2]) * Ry(params[1]) * Rx(params[0])
        on the qubit, e.g. R |qubit>.

        Note that order is reversed when put into the circuit. The circuit is:
        |qubit>---Rx(params[0])---Ry(params[1])---Rz(params[2])---
        """
        rx = cirq.RotXGate(half_turns=params[0])
        ry = cirq.RotYGate(half_turns=params[1])
        rz = cirq.RotZGate(half_turns=params[2])

        yield (rx(qubit), ry(qubit), rz(qubit))
Пример #20
0
    def operations(self, qubits: Sequence[cirq.QubitId]) -> cirq.OP_TREE:
        """Produce the operations of the ansatz circuit."""
        # TODO implement asymmetric ansatz

        param_set = set(self.params())

        for i in range(self.iterations):

            # Apply one- and two-body interactions with a swap network that
            # reverses the order of the modes
            def one_and_two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
                t_symbol = LetterWithSubscripts('T', p, q, i)
                w_symbol = LetterWithSubscripts('W', p, q, i)
                v_symbol = LetterWithSubscripts('V', p, q, i)
                if t_symbol in param_set:
                    yield XXYYGate(half_turns=t_symbol).on(a, b)
                if w_symbol in param_set:
                    yield YXXYGate(half_turns=w_symbol).on(a, b)
                if v_symbol in param_set:
                    yield cirq.Rot11Gate(half_turns=v_symbol).on(a, b)

            yield swap_network(qubits,
                               one_and_two_body_interaction,
                               fermionic=True)
            qubits = qubits[::-1]

            # Apply one-body potential
            for p in range(len(qubits)):
                u_symbol = LetterWithSubscripts('U', p, i)
                if u_symbol in param_set:
                    yield cirq.RotZGate(half_turns=u_symbol).on(qubits[p])

            # Apply one- and two-body interactions again. This time, reorder
            # them so that the entire iteration is symmetric
            def one_and_two_body_interaction_reversed_order(p, q, a,
                                                            b) -> cirq.OP_TREE:
                t_symbol = LetterWithSubscripts('T', p, q, i)
                w_symbol = LetterWithSubscripts('W', p, q, i)
                v_symbol = LetterWithSubscripts('V', p, q, i)
                if v_symbol in param_set:
                    yield cirq.Rot11Gate(half_turns=v_symbol).on(a, b)
                if w_symbol in param_set:
                    yield YXXYGate(half_turns=w_symbol).on(a, b)
                if t_symbol in param_set:
                    yield XXYYGate(half_turns=t_symbol).on(a, b)

            yield swap_network(qubits,
                               one_and_two_body_interaction_reversed_order,
                               fermionic=True,
                               offset=True)
            qubits = qubits[::-1]
Пример #21
0
    def trotter_step(
            self,
            qubits: Sequence[cirq.QubitId],
            time: float,
            control_qubit: Optional[cirq.QubitId] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Apply one- and two-body interactions for half of the full time
        def one_and_two_body_interaction(p, q, a, b) -> cirq.OP_TREE:
            yield XXYYGate(duration=0.5 *
                           self.hamiltonian.one_body[p, q].real * time).on(
                               a, b)
            yield YXXYGate(duration=0.5 *
                           self.hamiltonian.one_body[p, q].imag * time).on(
                               a, b)
            yield cirq.Rot11Gate(rads=-self.hamiltonian.two_body[p, q] *
                                 time).on(a, b)

        yield swap_network(qubits,
                           one_and_two_body_interaction,
                           fermionic=True)
        qubits = qubits[::-1]

        # Apply one-body potential for the full time
        yield (cirq.RotZGate(rads=-self.hamiltonian.one_body[i, i].real *
                             time).on(qubits[i]) for i in range(n_qubits))

        # Apply one- and two-body interactions for half of the full time
        # This time, reorder the operations so that the entire Trotter step is
        # symmetric
        def one_and_two_body_interaction_reverse_order(p, q, a,
                                                       b) -> cirq.OP_TREE:
            yield cirq.Rot11Gate(rads=-self.hamiltonian.two_body[p, q] *
                                 time).on(a, b)
            yield YXXYGate(duration=0.5 *
                           self.hamiltonian.one_body[p, q].imag * time).on(
                               a, b)
            yield XXYYGate(duration=0.5 *
                           self.hamiltonian.one_body[p, q].real * time).on(
                               a, b)

        yield swap_network(qubits,
                           one_and_two_body_interaction_reverse_order,
                           fermionic=True,
                           offset=True)
Пример #22
0
def test_parameterizable_effect():
    q = cirq.NamedQubit('q')
    r = cirq.ParamResolver({'a': 0.5})

    # If the gate isn't parameterizable, you get a type error.
    op0 = cirq.GateOperation(cirq.Gate(), [q])
    assert not cirq.can_cast(cirq.ParameterizableEffect, op0)
    with pytest.raises(TypeError):
        _ = op0.is_parameterized()
    with pytest.raises(TypeError):
        _ = op0.with_parameters_resolved_by(r)

    op1 = cirq.GateOperation(cirq.RotZGate(half_turns=cirq.Symbol('a')), [q])
    assert cirq.can_cast(cirq.ParameterizableEffect, op1)
    assert op1.is_parameterized()
    op2 = op1.with_parameters_resolved_by(r)
    assert not op2.is_parameterized()
    assert op2 == cirq.S.on(q)
def rot_z_layer(h, half_turns):
    """Yields Z rotations by half_turns conditioned on the field h."""
    for (i, j), h_ij in np.ndenumerate(h):
        yield cirq.RotZGate(half_turns=(h_ij * half_turns))(cirq.GridQubit(
            i, j))
Пример #24
0
    def trotter_step(
            self,
            qubits: Sequence[cirq.QubitId],
            time: float,
            control_qubit: Optional[cirq.QubitId]=None
            ) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Simulate the off-diagonal one-body terms.
        yield swap_network(
                qubits,
                lambda p, q, a, b: ControlledXXYYGate(duration=
                    self.one_body_coefficients[p, q].real * time).on(
                        control_qubit, a, b),
                fermionic=True)
        qubits = qubits[::-1]

        # Simulate the diagonal one-body terms.
        yield (cirq.Rot11Gate(rads=
                   -self.one_body_coefficients[j, j].real * time).on(
                       control_qubit, qubits[j])
               for j in range(n_qubits))

        # Simulate each singular vector of the two-body terms.
        prior_basis_matrix = numpy.identity(n_qubits, complex)
        for j in range(len(self.eigenvalues)):

            # Get the basis change matrix and its inverse.
            two_body_coefficients = self.scaled_density_density_matrices[j]
            basis_change_matrix = self.basis_change_matrices[j]

            # If the basis change matrix is unitary, merge rotations.
            # Otherwise, you must simulate two basis rotations.
            is_unitary = cirq.is_unitary(basis_change_matrix)
            if is_unitary:
                inverse_basis_matrix = numpy.conjugate(
                    numpy.transpose(basis_change_matrix))
                merged_basis_matrix = numpy.dot(prior_basis_matrix,
                                                inverse_basis_matrix)
                yield bogoliubov_transform(qubits, merged_basis_matrix)
            else:
                # TODO add LiH test to cover this.
                # coverage: ignore
                if j:
                    yield bogoliubov_transform(qubits, prior_basis_matrix)
                yield cirq.inverse(
                    bogoliubov_transform(qubits, basis_change_matrix))

            # Simulate the off-diagonal two-body terms.
            yield swap_network(
                    qubits,
                    lambda p, q, a, b: Rot111Gate(rads=
                        -2 * two_body_coefficients[p, q] * time).on(
                            control_qubit, a, b))
            qubits = qubits[::-1]

            # Simulate the diagonal two-body terms.
            yield (cirq.Rot11Gate(rads=
                       -two_body_coefficients[k, k] * time).on(
                           control_qubit, qubits[k])
                   for k in range(n_qubits))

            # Undo basis transformation non-unitary case.
            # Else, set basis change matrix to prior matrix for merging.
            if is_unitary:
                prior_basis_matrix = basis_change_matrix
            else:
                # TODO add LiH test to cover this.
                # coverage: ignore
                yield bogoliubov_transform(qubits, basis_change_matrix)
                prior_basis_matrix = numpy.identity(n_qubits, complex)

        # Undo final basis transformation in unitary case.
        if is_unitary:
            yield bogoliubov_transform(qubits, prior_basis_matrix)

        # Apply phase from constant term
        yield cirq.RotZGate(rads=-self.constant * time).on(control_qubit)
Пример #25
0
def test_z_init():
    z = cirq.RotZGate(half_turns=5)
    assert z.half_turns == 1
Пример #26
0
def test_z_extrapolate():
    assert cirq.RotZGate(half_turns=1)**0.5 == cirq.RotZGate(half_turns=0.5)
    assert cirq.Z**-0.25 == cirq.RotZGate(half_turns=1.75)
    assert cirq.RotZGate(half_turns=0.5).phase_by(
        0.25, 0) == cirq.RotZGate(half_turns=0.5)