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)
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.Rot11Gate(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: 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)) # 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.RotZGate(rads=-self.hamiltonian.constant * time).on(control_qubit)
def two_body_interaction(p, q, a, b) -> cirq.OP_TREE: yield Rot111Gate(rads=-2 * self.hamiltonian.two_body[p, q] * time).on(control_qubit, a, b)
def test_ccz_repr(): assert repr(Rot111Gate(half_turns=1)) == 'CCZ' assert repr(Rot111Gate(half_turns=0.5)) == 'CCZ**0.5'
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)