The Hamiltonian class.
Note
Coefficients are required. And each Pauli Gate should act on different qubit.
Some examples are like this:
[[0.4, 'Y0', 'X1', 'Z2', 'I5'], [0.6]][[1, 'X0', 'I5'], [-3, 'Y3'], [0.01, 'Z5', 'Y0']]
Parameters:
-
pauli_terms
(list)
–
A list of pauli terms in the Hamiltonian.
-
coefficients
(list)
–
A list of coefficients of each pauli term in the Hamiltonian.
Examples:
>>> from QuICT.algorithm.quantum_machine_learning.utils import Hamiltonian
>>> ham = Hamiltonian([["Y0", "X1"], []], [0.4, 0.6])
>>> ham
[0.6]
[0.4, 'Y0', 'X1']
>>> ham_matrix = ham.get_hamilton_matrix(2)
>>> ham_matrix
[[0.6+0.j 0. +0.j 0. +0.j 0. -0.4j]
[0. +0.j 0.6+0.j 0. -0.4j 0. +0.j ]
[0. +0.j 0. +0.4j 0.6+0.j 0. +0.j ]
[0. +0.4j 0. +0.j 0. +0.j 0.6+0.j ]]
Instantiate the Hamiltonian class instance with pauli terms and coefficients.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __init__(self, pauli_terms: list, coefficients: list):
"""Instantiate the Hamiltonian class instance with pauli terms and coefficients."""
assert len(pauli_terms) == len(coefficients), HamiltonianError(
"The number of pauli terms and coefficients shoule be same."
)
self._operators = self._get_operator_dict(pauli_terms, coefficients)
self._del_zeros()
self._coefficients = list(self._operators.values())
self._pauli_str = self._get_pauli_str()
|
coefficients
property
The coefficient of each term in the Hamiltonian, i.e. [0.4, 0.6].
operators
property
The pauli operators of the Hamiltonian, i.e. {'X1 Y0': 0.4, '': 0.6}
pauli_str
property
The pauli string of the Hamiltonian, i.e. [[0.4, 'Y0', 'X1'], [0.6]].
__add__
Concatenate two Pauli Strings.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __add__(self, other):
"""Concatenate two Pauli Strings."""
assert isinstance(other, Hamiltonian), TypeError(
"Hamiltonian.__add__.other", "Hamiltonian", type(other)
)
return Hamiltonian.from_pauli_str(self.pauli_str + other.pauli_str)
|
__eq__
Determine whether two Hamiltonians are the same.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __eq__(self, other):
"""Determine whether two Hamiltonians are the same."""
assert isinstance(other, Hamiltonian), TypeError(
"Hamiltonian.__eq__.other", "Hamiltonian", type(other)
)
if len(self.pauli_str) != len(other.pauli_str):
return False
for op1, op2 in zip(self.pauli_str, other.pauli_str):
if abs(op1[0] - op1[0]) > 1e-8:
return False
if op1[1:] != op2[1:]:
return False
return True
|
__getitem__
Get slice according to the indexes.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __getitem__(self, indexes):
"""Get slice according to the indexes."""
pauli_str = []
if isinstance(indexes, int):
indexes = [indexes]
for idx in indexes:
pauli_str.append(self.pauli_str[idx])
return Hamiltonian(pauli_str)
|
__mul__
Number multiplication operation for coefficients or multiplication between Hamiltonians.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __mul__(self, multiplier):
"""Number multiplication operation for coefficients or multiplication between Hamiltonians."""
if isinstance(multiplier, numbers.Number):
pauli_terms = list(self.operators.keys())
coefficients = [coeff * multiplier for coeff in self.coefficients]
return Hamiltonian(pauli_terms, coefficients)
elif isinstance(multiplier, Hamiltonian):
new_operators = dict()
for left_term, left_coeff in self.operators.items():
for right_term, right_coeff in multiplier.operators.items():
new_coeff = left_coeff * right_coeff
if not left_term or not right_term:
new_term = left_term + right_term
else:
new_term = left_term + " " + right_term
new_term, new_coeff = self._simplify(new_term, new_coeff)
# Update result dict.
if new_term in new_operators:
new_operators[new_term] += new_coeff
else:
new_operators[new_term] = new_coeff
return Hamiltonian(list(new_operators.keys()), list(new_operators.values()))
else:
raise TypeError(
"Hamiltonian.__mul__.multiplier",
"[numbers.Number, Hamiltonian]",
type(multiplier),
)
|
__repr__
Return a sorted pauli string of the Hamiltonian.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __repr__(self):
"""Return a sorted pauli string of the Hamiltonian."""
ham_str = ""
pauli_str = sorted(self._pauli_str, key=lambda factor: factor[1:])
for factor in pauli_str:
ham_str += str(factor) + "\n"
return ham_str[:-1]
|
__sub__
Concatenate two Pauli strings after the coefficients of the subtrahend term become the opposite.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def __sub__(self, other):
"""Concatenate two Pauli strings after the coefficients of the subtrahend term become the opposite."""
return self.__add__(other.__mul__(-1))
|
construct_hamilton_circuit
construct_hamilton_circuit(n_qubits)
Construct a circuit form of the Hamiltonian.
Parameters:
Returns:
-
–
list: A list of circuits corresponding to the Hamiltonian.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def construct_hamilton_circuit(self, n_qubits):
"""Construct a circuit form of the Hamiltonian.
Args:
n_qubits (int): The number of qubits.
Returns:
list<Circuit>: A list of circuits corresponding to the Hamiltonian.
"""
hamilton_circuits = []
gate_dict = {"X": X, "Y": Y, "Z": Z}
for term in self._operators.keys():
circuit = Circuit(n_qubits)
if term == "":
hamilton_circuits.append(circuit)
continue
pauli_gates = [gate for gate in re.sub("[0-9]", "", term).split(" ")]
qubit_indexes = [
int(index) for index in re.sub("[a-zA-Z]", "", term).split(" ")
]
for qid, gate in zip(qubit_indexes, pauli_gates):
if gate not in gate_dict.keys():
raise HamiltonianError("Invalid Pauli gate.")
gate_dict[gate] | circuit(qid)
hamilton_circuits.append(circuit)
return hamilton_circuits
|
from_pauli_str
classmethod
from_pauli_str(pauli_str: list)
Instantiate the Hamiltonian class instance with a Pauli string.
Parameters:
-
pauli_str
(list)
–
A list of Hamiltonian information.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| @classmethod
def from_pauli_str(cls, pauli_str: list):
"""Instantiate the Hamiltonian class instance with a Pauli string.
Args:
pauli_str (list): A list of Hamiltonian information.
"""
pauli_terms = []
coefficients = []
for pauli_operator in pauli_str:
coefficients.append(pauli_operator[0])
pauli_terms.append(pauli_operator[1:])
return cls(pauli_terms, coefficients)
|
get_hamilton_matrix
get_hamilton_matrix(n_qubits)
Construct a matrix form of the Hamiltonian.
Parameters:
Returns:
-
–
np.array: The Hamiltonian matrix.
Source code in QuICT/core/hamiltonian/hamiltonian.py
| def get_hamilton_matrix(self, n_qubits):
"""Construct a matrix form of the Hamiltonian.
Args:
n_qubits (int): The number of qubits.
Returns:
np.array: The Hamiltonian matrix.
"""
hamilton_matrix = np.zeros((1 << n_qubits, 1 << n_qubits), dtype=np.complex128)
hamilton_circuits = self.construct_hamilton_circuit(n_qubits)
for coeff, circuit in zip(self._coefficients, hamilton_circuits):
hamilton_matrix += coeff * circuit.matrix()
return hamilton_matrix
|