跳转至

Hamiltonian

QuICT.core.hamiltonian.Hamiltonian

Hamiltonian(pauli_terms: list, coefficients: list)

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

coefficients

The coefficient of each term in the Hamiltonian, i.e. [0.4, 0.6].

operators property

operators

The pauli operators of the Hamiltonian, i.e. {'X1 Y0': 0.4, '': 0.6}

pauli_str property

pauli_str

The pauli string of the Hamiltonian, i.e. [[0.4, 'Y0', 'X1'], [0.6]].

__add__

__add__(other)

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__

__eq__(other)

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__

__getitem__(indexes)

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__

__mul__(multiplier)

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__

__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__

__sub__(other)

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:

  • n_qubits (int) –

    The number of qubits.

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:

  • n_qubits (int) –

    The number of qubits.

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