Exemple #1
0
    def trotter_step(self,
                     qubits: Sequence[cirq.Qid],
                     time: float,
                     control_qubit: Optional[cirq.Qid] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        # Simulate the one-body terms for half of the full time
        yield (cirq.rz(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 rot11(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.rz(rads=-0.5 * self.orbital_energies[i] * time).on(
            qubits[i]) for i in range(n_qubits))
Exemple #2
0
    def trotter_step(self,
                     qubits: Sequence[cirq.Qid],
                     time: float,
                     control_qubit: Optional[cirq.Qid] = None) -> cirq.OP_TREE:

        n_qubits = len(qubits)

        if not isinstance(control_qubit, cirq.Qid):
            raise TypeError('Control qudit must be specified.')

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

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

        # Rotate 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 the full time
        yield (rot11(rads=-self.orbital_energies[i] * time).on(
            control_qubit, qubits[i]) for i in range(n_qubits))

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

        # Apply phase from constant term
        yield cirq.rz(rads=-self.hamiltonian.constant * time).on(control_qubit)
Exemple #3
0
 def finish(self,
            qubits: Sequence[cirq.Qid],
            n_steps: int,
            control_qubit: Optional[cirq.Qid] = None,
            omit_final_swaps: bool = False) -> cirq.OP_TREE:
     # If the number of Trotter steps is odd, possibly swap qubits back
     if n_steps & 1 and not omit_final_swaps:
         yield swap_network(qubits)
Exemple #4
0
 def finish(self,
            qubits: Sequence[cirq.Qid],
            n_steps: int,
            control_qubit: Optional[cirq.Qid] = None,
            omit_final_swaps: bool = False) -> cirq.OP_TREE:
     if not omit_final_swaps:
         # If the number of swap networks was odd, swap the qubits back
         if n_steps & 1 and len(self.eigenvalues) & 1:
             yield swap_network(qubits)
Exemple #5
0
 def finish(self,
            qubits: Sequence[cirq.Qid],
            n_steps: int,
            control_qubit: Optional[cirq.Qid] = None,
            omit_final_swaps: bool = False) -> cirq.OP_TREE:
     # Rotate back to the computational basis
     yield bogoliubov_transform(qubits, self.basis_change_matrix)
     # If the number of Trotter steps is odd, possibly swap qubits back
     if n_steps & 1 and not omit_final_swaps:
         yield swap_network(qubits)
Exemple #6
0
    def trotter_step(self,
                     qubits: Sequence[cirq.Qid],
                     time: float,
                     control_qubit: Optional[cirq.Qid] = None) -> cirq.OP_TREE:

        if not isinstance(control_qubit, cirq.Qid):
            raise TypeError('Control qudit must be specified.')

        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 rot11(rads=-self.one_body_energies[p] * time).on(
                control_qubit, 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: rot111(-2 * two_body_coefficients[
                    p, q] * time).on(cast(cirq.Qid, control_qubit), a, b))
            qubits = qubits[::-1]

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

            # Update prior basis change matrix.
            prior_basis_matrix = basis_change_matrix

        # Undo final basis transformation.
        yield bogoliubov_transform(qubits, prior_basis_matrix)

        # Apply phase from constant term
        yield cirq.rz(rads=-self.hamiltonian.constant * time).on(control_qubit)
Exemple #7
0
    def trotter_step(self,
                     qubits: Sequence[cirq.Qid],
                     time: float,
                     control_qubit: Optional[cirq.Qid] = 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.rz(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: rot11(
                    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.rz(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)