Skip to content

Commit

Permalink
Trotterizable mixin (evangelistalab#253)
Browse files Browse the repository at this point in the history
* Trotterizable mixin
  • Loading branch information
JonathonMisiewicz authored May 20, 2024
1 parent 77cb673 commit ad591ab
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 129 deletions.
30 changes: 16 additions & 14 deletions src/qforte/abc/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from abc import ABC, abstractmethod
import qforte as qf
from qforte.utils.state_prep import *
from qforte.abc.mixin import Trotterizable


class Algorithm(ABC):
Expand All @@ -30,16 +31,6 @@ class Algorithm(ABC):
measurment (unphysical for quantum computer). Most algorithms only
have a fast implentation.
_trotter_order : int
The Trotter order to use for exponentiated operators.
(exact in the infinite limit).
_trotter_number : int
The number of trotter steps (m) to perform when approximating the matrix
exponentials (Um or Un). For the exponential of two non commuting terms
e^(A + B), the approximate operator C(m) = (e^(A/m) * e^(B/m))^m is
exact in the infinite m limit.
_Egs : float
The final ground state energy value.
Expand Down Expand Up @@ -69,8 +60,6 @@ def __init__(
system,
reference=None,
state_prep_type="occupation_list",
trotter_order=1,
trotter_number=1,
fast=True,
verbose=False,
print_summary_file=False,
Expand Down Expand Up @@ -119,8 +108,7 @@ def __init__(
self._hf_energy = 0.0

self._Nl = len(self._qb_ham.terms())
self._trotter_order = trotter_order
self._trotter_number = trotter_number

self._fast = fast
self._verbose = verbose
self._print_summary_file = print_summary_file
Expand Down Expand Up @@ -202,6 +190,20 @@ def verify_required_attributes(self):
"Concrete Algorithm class must define self._n_pauli_trm_measures attribute."
)

def print_generic_options(self):
"""Print options applicable to any algorithm."""
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
if isinstance(self, Trotterizable):
self.print_trotter_options()
print("Use fast version of algorithm: ", str(self._fast))
if not self._fast:
print("Measurement variance thresh: ", 0.01)


class AnsatzAlgorithm(Algorithm):
"""A class that characterizes the most basic functionality for all
Expand Down
6 changes: 5 additions & 1 deletion src/qforte/abc/ansatz.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@
from qforte.utils.state_prep import build_Uprep
from qforte.utils.trotterization import trotterize
from qforte.utils.compact_excitation_circuits import compact_excitation_circuit
from qforte.abc.mixin import Trotterizable


class UCC:
class UCC(Trotterizable):
"""A mixin class for implementing the UCC circuit ansatz, to be inherited by a
concrete class UCC+algorithm class.
"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def ansatz_circuit(self, amplitudes=None):
"""This function returns the Circuit object built
from the appropriate amplitudes.
Expand Down
32 changes: 32 additions & 0 deletions src/qforte/abc/mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
Lightweight Mixin Classes
====================================
This file contains several mixin classes.
Such classes are intended for multiple inheritance and should always
call super().__init__ in their constructors.
"""


class Trotterizable:
"""
A mixin class for methods that employ Trotter approximation.
_trotter_order : int
The Trotter order to use for exponentiated operators.
(exact in the infinite limit).
_trotter_number : int
The number of trotter steps (m) to perform when approximating the matrix
exponentials (Um or Un). For the exponential of two non commuting terms
e^(A + B), the approximate operator C(m) = (e^(A/m) * e^(B/m))^m is
exact in the infinite m limit.
"""

def __init__(self, *args, trotter_order=1, trotter_number=1, **kwargs):
super().__init__(*args, **kwargs)
self._trotter_order = trotter_order
self._trotter_number = trotter_number

def print_trotter_options(self):
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
2 changes: 1 addition & 1 deletion src/qforte/abc/uccpqeabc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import numpy as np


class UCCPQE(PQE, UCC):
class UCCPQE(UCC, PQE):
"""The abstract base class inheritied by any algorithm that seeks to find
eigenstates by minimization of the residual condition
Expand Down
5 changes: 4 additions & 1 deletion src/qforte/abc/uccvqeabc.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import numpy as np


class UCCVQE(VQE, UCC):
class UCCVQE(UCC, VQE):
"""The abstract base class inheritied by any algorithm that seeks to find
eigenstates by variational minimization of the Energy
Expand Down Expand Up @@ -70,6 +70,9 @@ class UCCVQE(VQE, UCC):
"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@abstractmethod
def get_num_ham_measurements(self):
pass
Expand Down
17 changes: 4 additions & 13 deletions src/qforte/ite/qite.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
import qforte as qf
from qforte.abc.algorithm import Algorithm
from qforte.abc.mixin import Trotterizable
from qforte.utils.transforms import get_jw_organizer, organizer_to_circuit

from qforte.utils.state_prep import *
Expand All @@ -20,7 +21,7 @@
### Throughout this file, we'll refer to DOI 10.1038/s41567-019-0704-4 as Motta.


class QITE(Algorithm):
class QITE(Trotterizable, Algorithm):
"""This class implements the quantum imaginary time evolution (QITE)
algorithm in a fashion amenable to non k-local hamiltonains, which is
the focus of the origional algorithm (see DOI 10.1038/s41567-019-0704-4).
Expand Down Expand Up @@ -185,18 +186,8 @@ def print_options_banner(self):

print("\n\n ==> QITE options <==")
print("-----------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if not self._fast:
print("Measurement variance thresh: ", 0.01)

self.print_generic_options()

# Specific QITE options.
print("Total imaginary evolution time (beta): ", self._beta)
Expand Down
18 changes: 4 additions & 14 deletions src/qforte/qkd/mrsqk.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import qforte
from qforte.abc.mixin import Trotterizable
from qforte.abc.qsdabc import QSD
from qforte.qkd.srqk import SRQK
from qforte.helper.printing import matprint
Expand All @@ -27,7 +28,7 @@
from scipy.linalg import eig


class MRSQK(QSD):
class MRSQK(Trotterizable, QSD):
"""A quantum subspace diagonalization algorithm that generates the many-body
basis from :math:`s` real time evolutions of :math:`d` differnt orthogonal
reference states :math:`| \Phi_I \\rangle`:
Expand Down Expand Up @@ -224,19 +225,8 @@ def print_options_banner(self):

print("\n\n ==> MRSQK options <==")
print("-----------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement varience thresh: ", "NA")
else:
print("Measurement varience thresh: ", 0.01)

self.print_generic_options()

# Specific QITE options.
print("Dimension of reference space (d): ", self._d)
Expand Down
9 changes: 2 additions & 7 deletions src/qforte/qkd/nt_srqk.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,8 @@ def print_options_banner(self):

print("\n\n ==> NTQK options <==")
print("-----------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)

self.print_generic_options()

# Specific SRQK options.
print("Dimension of Krylov space (N): ", self._nstates)
Expand Down
19 changes: 4 additions & 15 deletions src/qforte/qkd/srqk.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import qforte
from qforte.abc.mixin import Trotterizable
from qforte.abc.qsdabc import QSD
from qforte.helper.printing import matprint

Expand All @@ -18,7 +19,7 @@
import numpy as np


class SRQK(QSD):
class SRQK(Trotterizable, QSD):
"""A quantum subspace diagonalization algorithm that generates the many-body
basis from different durations of real time evolution:
Expand Down Expand Up @@ -73,20 +74,8 @@ def print_options_banner(self):

print("\n\n ==> QK options <==")
print("-----------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement varience thresh: ", "NA")
else:
print("Measurement varience thresh: ", 0.01)

self.print_generic_options()

# Specific SRQK options.
print("Dimension of Krylov space (N): ", self._nstates)
Expand Down
13 changes: 3 additions & 10 deletions src/qforte/qpea/qpe.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import qforte
from qforte.abc.algorithm import Algorithm
from qforte.abc.mixin import Trotterizable
from qforte.utils.transforms import (
circuit_to_organizer,
organizer_to_circuit,
Expand All @@ -15,7 +16,7 @@
from scipy import stats


class QPE(Algorithm):
class QPE(Trotterizable, Algorithm):
def run(
self, guess_energy: float, t=1.0, nruns=20, success_prob=0.5, num_precise_bits=4
):
Expand Down Expand Up @@ -147,15 +148,7 @@ def print_options_banner(self):
print("\n\n ==> QPE options <==")
print("-----------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
print("Measurement variance thresh: ", "NA" if self._fast else 0.01)
self.print_generic_options()

# Specific QPE options.
print("Target success probability: ", self._success_prob)
Expand Down
16 changes: 2 additions & 14 deletions src/qforte/ucc/adaptvqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,20 +250,8 @@ def print_options_banner(self):

print("\n\n ==> ADAPT-VQE options <==")
print("---------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement varience thresh: ", "NA")
else:
print("Measurement varience thresh: ", 0.01)

self.print_generic_options()

print("Use qubit excitations: ", self._qubit_excitations)
print("Use compact excitation circuits: ", self._compact_excitations)
Expand Down
15 changes: 2 additions & 13 deletions src/qforte/ucc/spqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,19 +325,8 @@ def print_options_banner(self):

print("\n\n ==> SPQE options <==")
print("---------------------------------------------------------")
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement varience thresh: ", "NA")
else:
print("Measurement varience thresh: ", 0.01)

self.print_generic_options()

print("Use qubit excitations: ", self._qubit_excitations)
print("Use compact excitation circuits: ", self._compact_excitations)
Expand Down
15 changes: 2 additions & 13 deletions src/qforte/ucc/uccnpqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,8 @@ def print_options_banner(self):

print("\n\n ==> UCC-PQE options <==")
print("---------------------------------------------------------")
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement varience thresh: ", "NA")
else:
print("Measurement varience thresh: ", 0.01)

self.print_generic_options()

print("Use qubit excitations: ", self._qubit_excitations)
print("Use compact excitation circuits: ", self._compact_excitations)
Expand Down
15 changes: 2 additions & 13 deletions src/qforte/ucc/uccnvqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,8 @@ def print_options_banner(self):
print("\n\n ==> UCCN-VQE options <==")
print("---------------------------------------------------------")
# General algorithm options.
print(
"Trial reference state: ",
ref_string(self._ref, self._nqb),
)
print("Number of Hamiltonian Pauli terms: ", self._Nl)
print("Trial state preparation method: ", self._state_prep_type)
print("Trotter order (rho): ", self._trotter_order)
print("Trotter number (m): ", self._trotter_number)
print("Use fast version of algorithm: ", str(self._fast))
if self._fast:
print("Measurement variance thresh: ", "NA")
else:
print("Measurement variance thresh: ", 0.01)

self.print_generic_options()

print("Use qubit excitations: ", self._qubit_excitations)
print("Use compact excitation circuits: ", self._compact_excitations)
Expand Down

0 comments on commit ad591ab

Please sign in to comment.