Beispiel #1
0
    def __init__(self,
                 hamiltonian: openfermion.InteractionOperator,
                 truncation_threshold: Optional[float]=1e-8,
                 final_rank: Optional[int]=None,
                 spin_basis=True) -> None:

        self.truncation_threshold = truncation_threshold
        self.final_rank = final_rank

        # Perform the low rank decomposition of two-body operator.
        self.eigenvalues, self.one_body_squares, one_body_correction, _ = (
            openfermion.low_rank_two_body_decomposition(
                hamiltonian.two_body_tensor,
                truncation_threshold=self.truncation_threshold,
                final_rank=self.final_rank,
                spin_basis=spin_basis))

        # Get scaled density-density terms and basis transformation matrices.
        self.scaled_density_density_matrices = []  # type: List[numpy.ndarray]
        self.basis_change_matrices = []            # type: List[numpy.ndarray]
        for j in range(len(self.eigenvalues)):
            density_density_matrix, basis_change_matrix = (
                openfermion.prepare_one_body_squared_evolution(
                    self.one_body_squares[j]))
            self.scaled_density_density_matrices.append(
                    numpy.real(self.eigenvalues[j] * density_density_matrix))
            self.basis_change_matrices.append(basis_change_matrix)

        # Get transformation matrix and orbital energies for one-body terms
        one_body_coefficients = (
                hamiltonian.one_body_tensor + one_body_correction)
        quad_ham = openfermion.QuadraticHamiltonian(one_body_coefficients)
        self.one_body_energies, self.one_body_basis_change_matrix, _ = (
                quad_ham.diagonalizing_bogoliubov_transform()
        )

        super().__init__(hamiltonian)
Beispiel #2
0
    def __init__(self,
                 hamiltonian: openfermion.InteractionOperator,
                 iterations: int=1,
                 final_rank: Optional[int]=None,
                 include_all_cz: bool=False,
                 include_all_z: bool=False,
                 adiabatic_evolution_time: Optional[float]=None,
                 spin_basis: bool=True,
                 qubits: Optional[Sequence[cirq.Qid]]=None
                 ) -> None:
        """
        Args:
            hamiltonian: The Hamiltonian used to generate the ansatz
                circuit and default initial parameters.
            iterations: The number of iterations of the basic template to
                include in the circuit. The number of parameters grows linearly
                with this value.
            final_rank: The rank at which to truncate the decomposition.
            include_all_cz: Whether to include all possible CZ-type
                parameterized gates in the ansatz (irrespective of the ansatz
                Hamiltonian)
            include_all_z: Whether to include all possible Z-type
                parameterized gates in the ansatz (irrespective of the ansatz
                Hamiltonian)
            adiabatic_evolution_time: The time scale for Hamiltonian evolution
                used to determine the default initial parameters of the ansatz.
                This is the value A from the docstring of this class.
                If not specified, defaults to the sum of the absolute values
                of the entries of the two-body tensor of the Hamiltonian.
            spin_basis: Whether the Hamiltonian is given in the spin orbital
                (rather than spatial orbital) basis.
            qubits: Qubits to be used by the ansatz circuit. If not specified,
                then qubits will automatically be generated by the
                `_generate_qubits` method.
        """
        self.hamiltonian = hamiltonian
        self.iterations = iterations
        self.final_rank = final_rank
        self.include_all_cz = include_all_cz
        self.include_all_z = include_all_z

        if adiabatic_evolution_time is None:
            adiabatic_evolution_time = (
                    numpy.sum(numpy.abs(hamiltonian.two_body_tensor)))
        self.adiabatic_evolution_time = cast(float, adiabatic_evolution_time)

        # Perform the low rank decomposition of two-body operator.
        self.eigenvalues, one_body_squares, self.one_body_correction, _ = (
            openfermion.low_rank_two_body_decomposition(
                hamiltonian.two_body_tensor,
                final_rank=self.final_rank,
                spin_basis=spin_basis))

        # Get scaled density-density terms and basis transformation matrices.
        self.scaled_density_density_matrices = []  # type: List[numpy.ndarray]
        self.basis_change_matrices = []            # type: List[numpy.ndarray]
        for j in range(len(self.eigenvalues)):
            density_density_matrix, basis_change_matrix = (
                openfermion.prepare_one_body_squared_evolution(
                    one_body_squares[j]))
            self.scaled_density_density_matrices.append(
                    numpy.real(self.eigenvalues[j] * density_density_matrix))
            self.basis_change_matrices.append(basis_change_matrix)

        # Get transformation matrix and orbital energies for one-body terms
        one_body_coefficients = (
                hamiltonian.one_body_tensor + self.one_body_correction)
        quad_ham = openfermion.QuadraticHamiltonian(one_body_coefficients)
        self.one_body_energies, self.one_body_basis_change_matrix, _ = (
                quad_ham.diagonalizing_bogoliubov_transform()
        )

        super().__init__(qubits)