hamiltonian#
Functionality#
The following programs implement the Hamiltonian evolution with the duration \(t(t>0)\) for the position operator \(\hat{x}\) in the coordinate representation.
diagonal_hamiltonian.py#
Callee: DiagonalZHamiltonian
This circuit implements the exact time evolution under a diagonal, non-interacting \(Z\)-type Hamiltonian for an \(n\)-qubit system:
Note the \(Z_j\) is the Pauli-\(Z\) operator acting on the \(j\)-th qubit, where \(Z\ket{0} = \ket{0}\) and \(Z\ket{1} = -\ket{1}\), thus the form \(Z=I-2\ket{1}\bra{1}\).
Given the evolution time \(t\) for an \(n\)-qubit quantum system initialized as the computational basis state \(\ket{x}_n\) (i.e., \(\ket{x}_n = \ket{q_{n-1} \cdots q_1 q_0}\) and \(x\) is the decimal value of the binary string \(q_{n-1} \cdots q_0\)), the program performs the unitary transformation
resulting in the phase mapping:
Specifically, in Qiskit, the single-qubit \(Z\)-rotation is defined as
making the transformation
For each qubit,
Hence,
Finally, the transformation can cause:
Test expectations:
The results are stored in the phase of the corresponding basis state \(\ket{x}\), which can be verified by a state-vector backend during test. Note that it is necessary to consider the complete phase \(e ^ {-i\frac{t}{2}(2^n-1)} e^{ixt}\) when comparing the state vector.
Doc references: [5]
adder_hamiltonian_mixture.py#
Callee: AdderHamiltonianMixture
This is a general oracle quantum program (qubit-phase-mixed) by combining the behaviors of QuantumAdder and DiagonalZHamiltonian.
Given two \(n\)-qubit computational basis states \(\ket{x}_n\) and \(\ket{y}_n\), the program performs the following mapping:
The input states are defined as \(\ket{x}_n = \ket{q_{n-1} \cdots q_1 q_0}\) and \(\ket{y}_n = \ket{q_{2n-1} \cdots q_{n+1} q_n}\), where \(x\) and \(y\) are the decimal values of the binary strings \(q_{n-1} \cdots q_0\) and \(q_{2n-1} \cdots q_n\), respectively.
Test expectations:
The state of \(\ket{y}\) register will be transformed as \(\ket{(x + y) \text{ mod } 2^n}_n\), with an additional phase. Note that during test, the phase is computed as \(e ^ {-i\frac{t}{2}(2^n-1)} e^{iyt}\) on state-vector backend.
Doc references: [5]
sparse_hamiltonian.py#
Callee: SparseHamiltonian
This circuit implements the Hamiltonian simulation for a 2-sparse Hamiltonian matrix \(H\).
When
controlled_veris set toFalse, the program implements the non-controlled Hamiltonian simulation. The registers and their indexing are as follows:Index
\(0 \sim (n-1)\)
\(n \sim (2n-1)\)
\(2n\)
Register
State qubits
Oracle qubits
Ancilla qubit
Given the evolution time \(t\) for an \(n\)-qubit quantum system initialized as \(\ket{\psi}_n\) (here, we only care about the system qubits), the program performs the unitary transformation
\[ U(t): \ket{\psi}_n \mapsto e^{-i H t} \ket{\psi}_n. \]When
controlled_veris set toTrue, the program implements the controlled Hamiltonian simulation. The registers and their indexing are as follows:Index
\(0 \sim (n-1)\)
\(n \sim (2n-1)\)
\(2n\)
\(2n+1\)
Register
State qubits
Oracle qubits
Control qubit
Ancilla qubit
Given the evolution time \(t\) for an \(n\)-qubit quantum system initialized as \(\ket{\psi}_n\) and a control qubit initialized as \(\ket{c}_1\), the program performs the unitary transformation:
\[\begin{split} U_{c}(t): \ket{c}_1 \ket{\psi}_n \mapsto \begin{cases} \ket{0}_1 \ket{\psi}_n, & \text{if } c=0 \\ \ket{1}_1 e^{-i H t} \ket{\psi}_n, & \text{if } c=1 \end{cases} \end{split}\]
Notes:
Considering the intended functionality of this program, a valid input sparse Hamiltonian matrix \(H\) specified by the argument H must satisfy the following conditions:
\(H\) is a real-valued Hermitian matrix of size \(N \times N\), where \(N = 2^n\).
\(H\) is 2-sparse with exactly one off-diagonal non-zero entry per row, i.e., for each row \(i\), there exists at most one index \(j \neq i\) such that \(H_{i,j} \neq 0\).
\(H\) contains at least one off-diagonal non-zero entry (i.e., it is not a purely diagonal matrix).
All off-diagonal non-zero entries of \(H\) have the same coupling strength, i.e., there exists a real constant \(g \neq 0\) such that for all indices \(i \neq j\),
\[ H_{i,j} \neq 0 \;\Longrightarrow\; H_{i,j} = g . \]The off-diagonal structure of \(H\) is globally consistent, i.e., there exists a fixed bitmask \(k\) such that for all \(i\),
\[ H_{i,j} \neq 0 \iff j = i \oplus k . \]When
controlled_ver = False, all diagonal entries of \(H\) must be zero. Diagonal terms are only supported in the controlled version of the circuit.
Input instances:
Several Instances for Valid \(H\)
import numpy as np
def h_instance_0():
return np.array([
[0.0, 1.0],
[1.0, 0.0],
])
def h_instance_1():
return np.array([
[0, 1, 0, 0],
[1, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
], dtype=float)
def h_instance_2():
return np.array([
[0, 0, 1, 0],
[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0],
], dtype=float)
def h_instance_3():
H = np.zeros((8, 8))
k = 5 # 101₂
g = 1.0
for i in range(8):
j = i ^ k
H[i, j] = g
H[j, i] = g
return H
def h_instance_4():
return np.array([
[0.3, 1.0, 0.0, 0.0],
[1.0, 0.3, 0.0, 0.0],
[0.0, 0.0, 0.3, 1.0],
[0.0, 0.0, 1.0, 0.3],
])
Doc references: [5]
API#
qolumbina.programs.hamiltonian.adder_hamiltonian_mixture#
- class AdderHamiltonianMixture(input_qubits, t, name=None)[source]#
Bases:
QuantumCircuitMixture of Draper Adder and Hamiltonian evolution for position operator.
- Parameters:
input_qubits (int) – Number of qubits in each register, i.e., \(n\) for both addends \(\ket{x}_n\) and \(\ket{y}_n\).
t (float) – Evolution time \(t\) (\(t > 0\)).
name (str | None) – Optional name for the circuit.
- Raises:
ValueError – If
tis negative.
qolumbina.programs.hamiltonian.diagonal_hamiltonian#
- class DiagonalZHamiltonian(input_qubits, t, name=None)[source]#
Bases:
QuantumCircuitImplements the Hamiltonian evolution exp(-i * H * t) using only single-qubit Rz gates.
- Parameters:
input_qubits (int) – Number of qubits in the system (\(n\)).
t (float) – Evolution time \(t\) (\(t > 0\)).
name (str | None) – Optional name for the circuit.
- Raises:
ValueError – If
tis negative.
qolumbina.programs.hamiltonian.sparse_hamiltonian#
- class SparseHamiltonian(H, t, controlled_ver, name=None)[source]#
Bases:
QuantumCircuitSparse Hamiltonian Simulation Circuit
- Parameters:
H (ndarray) – the sparse Hamiltonian matrix \(H\) of size \(N \times N\) where \(N = 2^n\), and \(n\) is the number of qubits.
t (float) – Evolution time \(t\).
controlled_ver (bool) – Whether to build the controlled version of the Hamiltonian simulation.
name (str | None) – Optional name for the circuit.
- Raises:
ValueError – If
tis negative.ValueError – If
Hdoes not satisfy the required properties (real-valued, Hermitian, 2-sparse with a consistent global XOR structure and uniform coupling strengths).
- V_gate(qc, H, qreg_a, qreg_b)[source]#
Hamiltonian oracle \(V\ket{a,b} = \ket{a,b+v(a)}\)
- Parameters:
qc (QuantumCircuit) – Quantum Circuit
H (ndarray) – Sparse matrix
qreg_a (QuantumRegister) – Quantum register
qreg_b (QuantumRegister) – Quantum register
- Return type:
QuantumCircuit