إسقاط مؤثرات باولي على فضاءات هيلبرت الجزئية
نعرض طرقًا مختلفة لإسقاط تركيبة خطية موزونة من سلاسل باولي على فضاء جزئي يحدده مجموعة جزئية بحجم من حالات الأساس الحسابي. يُخزَّن المؤثر المُسقَط على شكل scipy.sparse.coo_matrix بحجم .
كمثال، نعتبر هاميلتونيان نموذج هايزنبرغ أحادي البُعد بشروط حدّية دورية و سبين:
توفّر هذه الحزمة أداتين لإجراء هذا الإسقاط:
-
qiskit_addon_sqd.qubit.matrix_elements_from_pauli(): دالة منخفضة المستوى تُرجع العناصر غير الصفرية لمصفوفة سلسلة باولي والفهارس المقابلة لهذه العناصر. -
qiskit_addon_sqd.qubit.project_operator_to_subspace(): a higher-level function that directly returns ascipy.sparsematrix.
يوضح هذا الدليل كيفية استخدام هاتين الأداتين للحصول على المؤثر المتناثر نفسه.
تعريف الفضاء الجزئي
في هذا المثال نولّد سلاسل بتات عشوائية بطول 22. لكي تعمل دوال الإسقاط كما هو متوقع، من الضروري أن تكون سلاسل البتات التي تعرّف الفضاء الجزئي فريدة ومرتبة تصاعديًا بحسب تمثيلها كعدد صحيح بلا إشارة.
يمكن تحقيق ذلك باستخدام الدالة qiskit_addon_sqd.qubit.sort_and_remove_duplicates().
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_addon_sqd": "qiskit-addon-sqd", "qiskit_addon_utils": "qiskit-addon-utils", "scipy": "scipy"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit_addon_sqd.qubit import sort_and_remove_duplicates
num_spins = 22
rand_seed = 22
np.random.seed(rand_seed)
def random_bitstrings(n_samples, n_qubits):
return (
np.round(np.random.rand(n_samples, n_qubits))
.astype("int")
.astype("bool")
)
bitstring_matrix = random_bitstrings(50_000, num_spins)
# NOTE: It is essential for the projection code to have the bitstrings sorted!
bitstring_matrix = sort_and_remove_duplicates(bitstring_matrix)
print("Subspace dimension: " + str(bitstring_matrix.shape[0]))
print("Full Hilbert space dimension: " + str(2**num_spins))
Subspace dimension: 49718
Full Hilbert space dimension: 4194304
الطريقة الأولى: العناصر والفهارس غير الصفرية للمصفوفة
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
coupling_map = CouplingMap.from_ring(num_spins)
hamiltonian = generate_xyz_hamiltonian(coupling_map)
print(hamiltonian)
SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIXX', 'IIIIIIIIIIIIIIIIIIIIYY', 'IIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIXXII', 'IIIIIIIIIIIIIIIIIIYYII', 'IIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIXXIIII', 'IIIIIIIIIIIIIIIIYYIIII', 'IIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIXXIIIIII', 'IIIIIIIIIIIIIIYYIIIIII', 'IIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIXXIIIIIIII', 'IIIIIIIIIIIIYYIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIXXIIIIIIIIII', 'IIIIIIIIIIYYIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIXXIIIIIIIIIIII', 'IIIIIIIIYYIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIII', 'IIIIIIXXIIIIIIIIIIIIII', 'IIIIIIYYIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIII', 'IIIIXXIIIIIIIIIIIIIIII', 'IIIIYYIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIII', 'IIXXIIIIIIIIIIIIIIIIII', 'IIYYIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIII', 'XXIIIIIIIIIIIIIIIIIIII', 'YYIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIII', 'XIIIIIIIIIIIIIIIIIIIIX', 'YIIIIIIIIIIIIIIIIIIIIY', 'ZIIIIIIIIIIIIIIIIIIIIZ', 'IIIIIIIIIIIIIIIIIIIXXI', 'IIIIIIIIIIIIIIIIIIIYYI', 'IIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIXXIII', 'IIIIIIIIIIIIIIIIIYYIII', 'IIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIXXIIIII', 'IIIIIIIIIIIIIIIYYIIIII', 'IIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIXXIIIIIII', 'IIIIIIIIIIIIIYYIIIIIII', 'IIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIXXIIIIIIIII', 'IIIIIIIIIIIYYIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIXXIIIIIIIIIII', 'IIIIIIIIIYYIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIXXIIIIIIIIIIIII', 'IIIIIIIYYIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIII', 'IIIIIXXIIIIIIIIIIIIIII', 'IIIIIYYIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIII', 'IIIXXIIIIIIIIIIIIIIIII', 'IIIYYIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIII', 'IXXIIIIIIIIIIIIIIIIIII', 'IYYIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIII'],
coeffs=[1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j])
from qiskit_addon_sqd.qubit import matrix_elements_from_pauli
from scipy.sparse import coo_matrix
d = bitstring_matrix.shape[0]
# Initialize the coo_matrix object
operator_from_matrix_elements = coo_matrix((d, d), dtype="complex128")
for pauli in hamiltonian.paulis:
matrix_elements, row_indices, col_indices = matrix_elements_from_pauli(
bitstring_matrix, pauli
)
operator_from_matrix_elements += coo_matrix(
(matrix_elements, (row_indices, col_indices)), (d, d)
)
التنفيذ عالي المستوى
from qiskit_addon_sqd.qubit import project_operator_to_subspace
operator = project_operator_to_subspace(
bitstring_matrix, hamiltonian, verbose=True
)
Projecting term 1 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIIXX ...
Projecting term 2 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIIYY ...
Projecting term 3 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIIZZ ...
Projecting term 4 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIXXII ...
Projecting term 5 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIYYII ...
Projecting term 6 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIZZII ...
Projecting term 7 out of 66: (1+0j) * IIIIIIIIIIIIIIIIXXIIII ...
Projecting term 8 out of 66: (1+0j) * IIIIIIIIIIIIIIIIYYIIII ...
Projecting term 9 out of 66: (1+0j) * IIIIIIIIIIIIIIIIZZIIII ...
Projecting term 10 out of 66: (1+0j) * IIIIIIIIIIIIIIXXIIIIII ...
Projecting term 11 out of 66: (1+0j) * IIIIIIIIIIIIIIYYIIIIII ...
Projecting term 12 out of 66: (1+0j) * IIIIIIIIIIIIIIZZIIIIII ...
Projecting term 13 out of 66: (1+0j) * IIIIIIIIIIIIXXIIIIIIII ...
Projecting term 14 out of 66: (1+0j) * IIIIIIIIIIIIYYIIIIIIII ...
Projecting term 15 out of 66: (1+0j) * IIIIIIIIIIIIZZIIIIIIII ...
Projecting term 16 out of 66: (1+0j) * IIIIIIIIIIXXIIIIIIIIII ...
Projecting term 17 out of 66: (1+0j) * IIIIIIIIIIYYIIIIIIIIII ...
Projecting term 18 out of 66: (1+0j) * IIIIIIIIIIZZIIIIIIIIII ...
Projecting term 19 out of 66: (1+0j) * IIIIIIIIXXIIIIIIIIIIII ...
Projecting term 20 out of 66: (1+0j) * IIIIIIIIYYIIIIIIIIIIII ...
Projecting term 21 out of 66: (1+0j) * IIIIIIIIZZIIIIIIIIIIII ...
Projecting term 22 out of 66: (1+0j) * IIIIIIXXIIIIIIIIIIIIII ...
Projecting term 23 out of 66: (1+0j) * IIIIIIYYIIIIIIIIIIIIII ...
Projecting term 24 out of 66: (1+0j) * IIIIIIZZIIIIIIIIIIIIII ...
Projecting term 25 out of 66: (1+0j) * IIIIXXIIIIIIIIIIIIIIII ...
Projecting term 26 out of 66: (1+0j) * IIIIYYIIIIIIIIIIIIIIII ...
Projecting term 27 out of 66: (1+0j) * IIIIZZIIIIIIIIIIIIIIII ...
Projecting term 28 out of 66: (1+0j) * IIXXIIIIIIIIIIIIIIIIII ...
Projecting term 29 out of 66: (1+0j) * IIYYIIIIIIIIIIIIIIIIII ...
Projecting term 30 out of 66: (1+0j) * IIZZIIIIIIIIIIIIIIIIII ...
Projecting term 31 out of 66: (1+0j) * XXIIIIIIIIIIIIIIIIIIII ...
Projecting term 32 out of 66: (1+0j) * YYIIIIIIIIIIIIIIIIIIII ...
Projecting term 33 out of 66: (1+0j) * ZZIIIIIIIIIIIIIIIIIIII ...
Projecting term 34 out of 66: (1+0j) * XIIIIIIIIIIIIIIIIIIIIX ...
Projecting term 35 out of 66: (1+0j) * YIIIIIIIIIIIIIIIIIIIIY ...
Projecting term 36 out of 66: (1+0j) * ZIIIIIIIIIIIIIIIIIIIIZ ...
Projecting term 37 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIXXI ...
Projecting term 38 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIYYI ...
Projecting term 39 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIIIZZI ...
Projecting term 40 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIXXIII ...
Projecting term 41 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIYYIII ...
Projecting term 42 out of 66: (1+0j) * IIIIIIIIIIIIIIIIIZZIII ...
Projecting term 43 out of 66: (1+0j) * IIIIIIIIIIIIIIIXXIIIII ...
Projecting term 44 out of 66: (1+0j) * IIIIIIIIIIIIIIIYYIIIII ...
Projecting term 45 out of 66: (1+0j) * IIIIIIIIIIIIIIIZZIIIII ...
Projecting term 46 out of 66: (1+0j) * IIIIIIIIIIIIIXXIIIIIII ...
Projecting term 47 out of 66: (1+0j) * IIIIIIIIIIIIIYYIIIIIII ...
Projecting term 48 out of 66: (1+0j) * IIIIIIIIIIIIIZZIIIIIII ...
Projecting term 49 out of 66: (1+0j) * IIIIIIIIIIIXXIIIIIIIII ...
Projecting term 50 out of 66: (1+0j) * IIIIIIIIIIIYYIIIIIIIII ...
Projecting term 51 out of 66: (1+0j) * IIIIIIIIIIIZZIIIIIIIII ...
Projecting term 52 out of 66: (1+0j) * IIIIIIIIIXXIIIIIIIIIII ...
Projecting term 53 out of 66: (1+0j) * IIIIIIIIIYYIIIIIIIIIII ...
Projecting term 54 out of 66: (1+0j) * IIIIIIIIIZZIIIIIIIIIII ...
Projecting term 55 out of 66: (1+0j) * IIIIIIIXXIIIIIIIIIIIII ...
Projecting term 56 out of 66: (1+0j) * IIIIIIIYYIIIIIIIIIIIII ...
Projecting term 57 out of 66: (1+0j) * IIIIIIIZZIIIIIIIIIIIII ...
Projecting term 58 out of 66: (1+0j) * IIIIIXXIIIIIIIIIIIIIII ...
Projecting term 59 out of 66: (1+0j) * IIIIIYYIIIIIIIIIIIIIII ...
Projecting term 60 out of 66: (1+0j) * IIIIIZZIIIIIIIIIIIIIII ...
Projecting term 61 out of 66: (1+0j) * IIIXXIIIIIIIIIIIIIIIII ...
Projecting term 62 out of 66: (1+0j) * IIIYYIIIIIIIIIIIIIIIII ...
Projecting term 63 out of 66: (1+0j) * IIIZZIIIIIIIIIIIIIIIII ...
Projecting term 64 out of 66: (1+0j) * IXXIIIIIIIIIIIIIIIIIII ...
Projecting term 65 out of 66: (1+0j) * IYYIIIIIIIIIIIIIIIIIII ...
Projecting term 66 out of 66: (1+0j) * IZZIIIIIIIIIIIIIIIIIII ...
تحقّق من أن كلا التنفيذين يعطيان coo_matrix نفسها:
print((operator.power(2) - operator_from_matrix_elements.power(2)).sum())
0j