Lewati ke konten utama
Proyek ini masih dalam tahap beta. Menemukan bug? Buat isu GitHub. Punya pertanyaan atau ide? Tanya di Discussions — kami sangat menghargai masukan kamu!
Bagaimana kualitas terjemahan di halaman ini?

Kelompokkan suku operator: manfaatkan struktur operator

Pengelompokan adalah salah satu operasi di bawah qiskit_fermions.operators.terms, yang mengumpulkan rutin-rutin untuk mempartisi suku-suku operator berdasarkan strukturnya.

Seperti dijelaskan di panduan operator, operator bisa menyimpan groups array, bagian opsional dari struktur data sparse yang mengaitkan tiap suku dengan indeks grup. Suku-suku dengan indeks grup yang sama membentuk satu grup. Ini memungkinkanmu memanfaatkan struktur tersebut secara sistematis di pemrosesan selanjutnya.

Dengan mengelompokkan suku-suku yang berkaitan (entah berdasarkan sifat fisik, hubungan aljabar, atau simetri khusus masalah), kamu bisa mendapatkan beberapa manfaat:

  • Sintesis circuit yang dioptimalkan: Suku yang dikelompokkan membawa informasi khusus masalah sepanjang stack, sehingga optimasi circuit hasil sintesis jadi lebih mudah. Hasilnya, depth circuit dan jumlah gate berkurang.

  • Struktur fisik tetap terjaga: Grup menyandikan struktur bermakna dari masalah aslinya (misalnya pola interaksi atau simetri) yang bisa dipakai untuk dekomposisi yang lebih bermakna secara fisik.

  • Pemilihan flow set: Pengelompokan secara alami bisa menyandikan flow set dan struktur teori graf lain yang relevan untuk simulasi kuantum, seperti ditunjukkan di [1].

  • Stabilitas algoritma yang lebih baik: Seperti ditunjukkan di rutin SqDRIFT, beberapa algoritma bisa mendapat manfaat berupa stabilitas atau performa yang lebih baik berkat terjaganya sifat-sifat fisik.

  • Faktor product-formula: Product formula fermionik memecah operator menjadi grup-grupnya, jadi pengelompokan menentukan biaya sekaligus error Trotter dari sebuah evolusi waktu. Lihat Sintesis Evolution gate di ruang fermionik.

Penggunaan​

Cara paling sederhana untuk mendefinisikan pengelompokan operator adalah dengan mengatur atribut groups dari operator target. Di bawah ini contoh pengelompokan suku berdasarkan line flow set seperti pada Gambar 1c di [1].

Petunjuk

Modul qiskit_fermions.operators.terms.grouping menyediakan metode praktis untuk mengidentifikasi struktur dalam operator secara otomatis dan memberi indeks grup yang sesuai.

>>> import rustworkx as rx
>>> graph = rx.PyDiGraph()
>>> _ = graph.add_nodes_from(range(6))
>>> edges = [(0, 1), (1, 2), (3, 0), (1, 4), (5, 2), (5, 4), (4, 3)]
>>> groups = [0, 0, 1, 2, 1, 3, 3]
>>> edges_with_group_as_payload = [(i, j, g) for (i, j), g in zip(edges, groups)]
>>> _ = graph.add_edges_from(edges_with_group_as_payload)
>>> from rustworkx.visualization import mpl_draw
>>> mpl_draw(
... graph,
... pos={i: (i % 3, i // 3) for i in range(6)},
... edge_labels=str,
... with_labels=True,
... )
<Figure size ... with 1 Axes>

A simple directed graph on which to define a MajoranaOperator.

Ini adalah lattice dua kali tiga dari mode Majorana yang dihubungkan oleh edge berarah. Tiap edge mewakili satu suku dalam operator yang bekerja pada dua mode yang terhubung. Tujuannya adalah mengelompokkan suku-suku ini berdasarkan label edge-nya (ditampilkan di graf). Suku yang dihubungkan oleh edge berlabel sama ditempatkan di grup yang sama. Kode berikut menunjukkan caranya:

>>> from qiskit_fermions.operators import MajoranaOperator
>>>
>>> # Construct operator directly using sparse arrays
>>> # 7 terms, each with coefficient 1.0, modes from edge endpoints
>>> op = MajoranaOperator(
... coeffs=[1.0] * 7,
... modes=[node for edge in edges for node in edge],
... boundaries=[0, 2, 4, 6, 8, 10, 12, 14],
... )
>>>
>>> # Assign group indices to terms (groups is part of the sparse data structure)
>>> op.groups = groups
>>>
>>> # Partition operator by groups
>>> grouped_ops = op.split_out_groups()
>>>
>>> # Inspect each group
>>> for i, g in enumerate(grouped_ops):
... print(f"Group {i}: {list(sorted(g.iter_terms()))}")
Group 0: [([0, 1], (1+0j)), ([1, 2], (1+0j))]
Group 1: [([3, 0], (1+0j)), ([5, 2], (1+0j))]
Group 2: [([1, 4], (1+0j))]
Group 3: [([4, 3], (1+0j)), ([5, 4], (1+0j))]

Menganalisis sebuah pengelompokan​

Grup tidak punya makna sendiri: groups array hanya mencatat suku mana yang termasuk bersama, bukan alasannya. Tidak ada rutin di library ini yang melaporkan apakah sebuah pengelompokan itu "benar", karena memang tidak ada satu pengertian kebenaran yang bisa dijadikan acuan. Meski begitu, konsumen di hilir mengasumsikan sifat-sifat tertentu dari pengelompokan, dan fungsi-fungsi di bagian ini memungkinkanmu memeriksa asumsi semacam itu di awal, alih-alih membayarnya di setiap pemanggilan.

Konvensi yang paling umum adalah bahwa setiap grup bersifat Hermitian secara terpisah. Inilah yang membuat product formula acak fermionik mungkin dilakukan: suku ap†aqa^\dagger_p a_q sendirian dengan p≠qp \neq q tidak Hermitian, jadi evolusi waktunya tidak unitary dan tidak bisa di-sampling sendiri. Memasangkannya dengan aq†apa^\dagger_q a_p menghasilkan grup yang bisa.

>>> from qiskit_fermions.operators import FermionOperator
>>> from qiskit_fermions.operators.terms.grouping import (
... group_coeff_means,
... groups_are_hermitian,
... groups_have_uniform_coeffs,
... )
>>>
>>> # a conjugate pair, plus one unpaired term. The operator is built from the sparse
>>> # arrays rather than from a dictionary, because only the former fixes the term order
>>> # that the group indices below are paired with.
>>> pair_and_single = FermionOperator(
... [1.0, 1.0, 1.0],
... [True, False, True, False, True, False],
... [0, 1, 1, 0, 2, 3],
... [0, 2, 4, 6],
... )
>>> pair_and_single.groups = [0, 0, 1]
>>>
>>> groups_are_hermitian(pair_and_single) # group 1 is unpaired
[True, False]
>>> group_coeff_means(pair_and_single)
[1.0, 1.0]

Satu indeks grup per suku diberlakukan secara ketat​

Groups array menyimpan satu indeks per suku, dan menetapkan array dengan panjang berbeda akan memunculkan error. Tidak ada yang memeriksa ulang invarian ini di hilir, jadi invarian ini dijaga di titik indeks masuk ke operator: array yang terlalu pendek akan diam-diam membuang suku di bagian akhir, dan yang terlalu panjang akan mengarang grup yang tidak dimiliki suku mana pun.

>>> pair_and_single.groups = [0, 0] # one index short, on a three-term operator
Traceback (most recent call last):
ValueError: expected one group index per term, but got 2 for 3 terms

Menghapus indeks grup dengan menetapkan None selalu diperbolehkan.

Kedua pemeriksaan itu independen​

groups_have_uniform_coeffs() melaporkan apakah koefisien dalam satu grup sama, yang merupakan asumsi yang dibuat group_coeff_means() saat merata-ratakan magnitudo. Ini bukan versi yang lebih lemah dari pemeriksaan Hermitian: tidak ada satu pemeriksaan pun yang menyiratkan yang lain, ke arah mana pun.

>>> from qiskit_fermions.operators.terms.grouping import (
... groups_are_hermitian,
... groups_have_uniform_coeffs,
... )
>>> # uniform coefficients, but not Hermitian: the terms are not each other's adjoint
>>> uniform = FermionOperator(
... [1.0, 1.0],
... [True, False, True, False],
... [0, 1, 2, 3],
... [0, 2, 4],
... )
>>> uniform.groups = [0, 0]
>>> groups_have_uniform_coeffs(uniform), groups_are_hermitian(uniform)
([True], [False])
>>> # Hermitian, but with mixed magnitudes: two conjugate pairs at different scales
>>> mixed = FermionOperator(
... [1.0, 1.0, 5.0, 5.0],
... [True, False, True, False, True, False, True, False],
... [0, 1, 1, 0, 2, 3, 3, 2],
... [0, 2, 4, 6, 8],
... )
>>> mixed.groups = [0, 0, 0, 0]
>>> groups_are_hermitian(mixed), groups_have_uniform_coeffs(mixed)
([True], [False])

Secara default, magnitudo yang dibandingkan, karena itulah yang dirata-ratakan oleh group_coeff_means(). Pasangan konjugat Hermitian dengan koefisien kompleks punya magnitudo yang sama tapi koefisien yang tidak sama, jadi hanya memenuhi bentuk default.

>>> conjugate = FermionOperator(
... [1.0j, -1.0j],
... [True, False, True, False],
... [0, 1, 1, 0],
... [0, 2, 4],
... )
>>> conjugate.groups = [0, 0]
>>> groups_have_uniform_coeffs(conjugate)
[True]
>>> groups_have_uniform_coeffs(conjugate, abs=False)
[False]
Catatan

groups_are_hermitian() mewarisi jaminan satu sisi dari is_hermitian(): entri True selalu bisa diandalkan, sedangkan entri False hanya bisa diandalkan untuk tipe operator yang normal form-nya benar-benar bentuk kanonik. Cek tipe operator yang spesifik untuk tahu mana yang berlaku.

[1] (1,2)

A. Gandon et al., Stabilizer-based quantum simulation of fermion dynamics with local qubit encodings, arXiv:2512.11418v2.