Lumaktaw sa pangunahing nilalaman
Ang proyektong ito ay nasa beta. Nakakita ng bug? Mag-bukas ng GitHub issue. May tanong o ideya? Magtanong sa Discussions — gusto naming marinig ang iyong feedback!
Gaano kaganda ang kalidad ng pagsasalin sa pahinang ito?

Mga prinsipyo sa disenyo ng mga operator representation

Ipinapaliwanag ng gabay na ito ang mga karaniwang prinsipyo sa disenyo at pangunahing konsepto na ibinabahagi ng lahat ng operator representation sa operators module.

Pangkalahatang-ideya​

Ang mga operator representation na ibinibigay ng module na ito ay may iisang ilang pangunahing prinsipyo sa disenyo:

  • Sparse data structure: Ang mga operator ay nag-e-encode lang ng mga operasyong hindi identity. Ang panloob na layout ng data ay karaniwang hango sa mga sparse matrix data format, na nagbibigay-daan sa episyenteng storage at computation para sa mga sistemang maraming mode pero kaunti lang ang makabuluhang kontribusyon.

  • Term iteration at reconstruction: Anuman ang panloob na sparse storage, nagbibigay ang mga operator ng pare-parehong iteration interface, kaya maaari mong siyasatin, i-filter, at i-transform ang mga term nang hindi kailangang unawain ang pinagbabatayang istruktura ng data, at saka bumuo ng mga bagong operator mula sa mga binagong term.

  • Mode-based indexing: Gumagamit ang mga operator ng abstract na mode index para i-label ang mga fermionic degree of freedom, na nagbibigay-daan sa flexible na pag-map mula sa mga pisikal na sistema papunta sa operator representation.

  • Term grouping at mga ugnayan ng commutation: Native na sinusuportahan ng mga operator ang grouping information na nag-uugnay sa mga term sa mga group index. Nagbibigay-daan ito sa mga optimization at pagpapanatili ng pisikal na istruktura nang hindi nangangailangan ng hiwalay na mga data structure. Tingnan ang grouping guide para sa praktikal na paggamit.

  • Arithmetic at mga mathematical na operasyon: Nagpapatupad ang lahat ng operator ng pare-parehong set ng mga arithmetic na operasyon (tulad ng addition, multiplication, at composition) at mga mathematical function gamit ang OperatorTrait protocol, na nagbibigay-daan sa pare-parehong code sa iba't ibang uri ng operator.

  • Pagkakasunod-sunod ng term ng operator at mga normal form: Ang mga operator na katumbas sa matematika ay maaaring may napakaibang representasyon at pag-uugali sa mga quantum algorithm. Sinusuportahan ng lahat ng operator representation ang iba't ibang normal form (batay sa mga commutation relation na partikular sa algebra) para makamit ang canonical, predictable, at ma-optimize na mga operator representation.

Istruktura ng sparse data​

Gumagamit ang lahat ng operator ng sparse na representasyon kung saan sinusubaybayan lang ang mga operasyong hindi identity. Ang bawat operasyong hindi identity ay binubuo ng isang coefficient (complex number) at isang sequence ng mga action sa mga partikular na mode.

Lubos na binabawasan ng pamamaraang ito ang paggamit ng memory at oras ng computation, lalo na para sa mga sistemang maraming mode pero kaunti lang ang makabuluhang kontribusyon. Dahil nag-e-encode lang ng mga operasyong hindi identity, nakatuon lang ang mga operasyon sa mahalaga, na nagbibigay-daan sa pagtatrabaho sa malalaking sistema na hindi magagawa gamit ang dense na representasyon. Bukod pa rito, natural na nag-i-scale ang mga operator sa anumang bilang ng mode; ang operator na kumikilos sa mga mode na {0, 1} ay gumagana nang walang pagbabago sa mga sistemang mas maraming mode dahil ang mga hindi apektadong mode ay implicit na identity.

Ang magkakaparehong term ay pinananatiling hiwalay sa mga arithmetic na operasyon at kailangang isama nang tahasan kung kinakailangan.

Panloob na format ng storage​

Sa loob, iniimbak ang mga operator sa mga array na hango sa mga sparse matrix data format:

  • Coefficients array: Ang complex coefficient ng bawat term

  • Mode indices array: Ang mga fermionic mode na kinikilos ng bawat action

  • Boundaries array: Mga index na nagmamarka kung saan nagsisimula at nagtatapos ang mga mode ng bawat term sa mode array

Important

Maaaring may mga karagdagang array depende sa uri ng operator. Halimbawa, ang mga instance ng FermionOperator ay may kasamang actions array ng mga boolean na tumutukoy sa uri ng fermionic action na kumikilos sa kaukulang mode index. Sa kabilang banda, hindi nangangailangan ng pagkakaibang ito ang MajoranaOperator class dahil ine-encode nito ang impormasyong iyon sa parity ng mode index. Tingnan ang API documentation ng uri ng iyong operator para maunawaan ang buong storage format.

Ipinapakita ng mga sumusunod na halimbawa kung paano inaayos ang mga array na ito. Una ang direktang konstruksyon gamit ang mga sparse array:

>>> from qiskit_fermions.operators import FermionOperator
>>>
>>> # Construct operators directly using sparse arrays
>>> # First operator: 1.0 * +0 -1
>>> op1 = FermionOperator(
... coeffs=[1.0],
... actions=[True, False],
... modes=[0, 1],
... boundaries=[0, 2],
... )
>>>
>>> # Second operator: 1.0 * +2 -3
>>> op2 = FermionOperator(
... coeffs=[1.0],
... actions=[True, False],
... modes=[2, 3],
... boundaries=[0, 2],
... )
>>>
>>> # Combine the sparse operators
>>> op1 += op2
>>> print(format(op1))
1.000000e0 +0.000000e0j * (+0 -1)
1.000000e0 +0.000000e0j * (+2 -3)

Mga convenient na paraan ng pagbuo​

Para sa mga Python developer, may ilang convenient na paraan ng pagbuo na nagtatago ng mga detalye ng sparse storage. Mas madali nitong mabubuo ang mga operator nang hindi mo na kailangang asikasuhin ang mga array ng coefficient, mode, at boundary:

>>> from qiskit_fermions.operators import FermionOperator, cre, ann
>>>
>>> # Construct operators using operator algebra notation
>>> op1 = FermionOperator.from_dict({(cre(0), ann(1)): 1.0})
>>> op2 = FermionOperator.from_dict({(cre(2), ann(3)): 1.0})
>>>
>>> # The result is sparse even when combining them
>>> op1 += op2
>>> print(format(op1))
1.000000e0 +0.000000e0j * (+0 -1)
1.000000e0 +0.000000e0j * (+2 -3)
Hint

Maaaring may karagdagang mga paraan ng pagbuo ang bawat implementasyon ng operator na akma sa partikular nitong gamit. Tingnan ang API documentation ng uri ng operator mo para makita ang lahat ng available na opsyon sa pagbuo.

Pag-iterate ng mga term at muling pagbuo​

Nagbibigay ang mga operator ng pare-parehong interface sa pag-iterate gamit ang OperatorTrait.iter_terms(), kahit ano pa ang internal na sparse representation nila. Kaya puwede mong suriin, i-filter, o baguhin ang mga term nang hindi kailangang intindihin ang pinagbabatayang estruktura ng data. Pagkatapos, puwede kang bumuo ng bagong operator mula sa mga binagong term gamit ang OperatorTrait.from_terms().

>>> from qiskit_fermions.operators import FermionOperator, cre, ann
>>>
>>> # Construct an operator with terms of different orders
>>> op = FermionOperator.from_dict({
... (): 0.5, # constant term (order 0)
... (cre(0), ann(1)): 1.0, # two-body term (order 2)
... (cre(0), cre(1), ann(1), ann(0)): 0.25 # four-body term (order 4)
... })
>>>
>>> # Filter to keep only terms of order 2
>>> order_two_terms = [
... (term, coeff) for term, coeff in op.iter_terms()
... if len(term) == 2
... ]
>>>
>>> # Reconstruct operator from filtered terms
>>> filtered_op = FermionOperator.from_terms(order_two_terms)
>>> print(f"Original operator has {len(op)} terms")
Original operator has 3 terms
>>> print(f"Filtered operator has {len(filtered_op)} term")
Filtered operator has 1 term

Mode-based na pag-index​

Tinatawag na mode ng lahat ng representasyon ng operator ang mga index na ginagalawan ng kanilang mga term. Ang mode ay isang index lang na tumutukoy sa isang fermionic degree of freedom sa sistema mo. Ikaw na ang bahala sa pag-map ng mga pisikal na degree of freedom (tulad ng spatial orbital, spin state, o iba pang quantum number) papunta sa mga mode index, kaya sobrang flexible nito.

Nandito rin ang abstraksiyong ito sa module na qiskit_fermions.circuit, kung saan ang FermionicCircuit ay gumagana sa isang register ng mga fermionic mode. Sa parehong representasyon ng operator at circuit, nagbibigay ang mga mode ng pare-parehong paraan, na hindi nakadepende sa algebra, para tukuyin kung aling mga degree of freedom ang kasali sa isang operasyon.

Important

Spinless na mode ang gamit ng mga kasalukuyang implementasyon: Itinuturing ng lahat ng representasyon ng operator na ibinibigay ngayon ng module na ito ang mga mode bilang spinless na fermionic degree of freedom. Ibig sabihin, kung may spin-up at spin-down na electron o fermion ang sistema mo, kailangan mo silang tahasang i-map sa magkakaibang mode (halimbawa, mode 0-3 para sa spin-up ng apat na spatial orbital, mode 4-7 para sa spin-down, o anumang ibang convention na piliin mo).

Pinananatili ng disenyong ito na simple at pangkalahatan ang mga pangunahing representasyon habang iniiwasang magpataw ng partikular na convention sa pag-order ng spin. Ang mga utility module tulad ng qiskit_fermions.operators.library ay nagbibigay ng mga convenience function (halimbawa, FCIDump.from_file()) na nag-aasikaso ng mga ganitong mapping para sa iyo kapag naglo-load ng electronic structure data.

Hint

Habang umuunlad ang package, maaaring madagdagan ng mga spinful na representasyon ng operator na natively sumusuporta sa mga spin degree of freedom sa kanilang data model. Malinaw silang ihihiwalay sa mga kasalukuyang spinless na implementasyon at magkakasama sila sa module.

Pag-grupo ng mga term at mga ugnayan ng commutation​

Tulad ng mga coefficient at mode index, puwedeng mag-imbak ang mga operator ng groups array bilang opsyon, na iniuugnay ang bawat term sa isang group index. Dahil nakasama na ang pag-grupo sa representasyon ng operator bilang bahagi ng sparse na estruktura ng data, natural na sumasama ang impormasyon ng pag-grupo sa operator sa bawat transformation. Nagbibigay-daan ito sa sistematikong paggamit ng estruktura, galing man sa mga pisikal na katangian, algebraic na ugnayan, o simetriya na partikular sa problema. Magagamit ang estrukturang impormasyong ito sa mga susunod na operasyon tulad ng circuit synthesis at decomposition gamit ang mga paraan tulad ng OperatorTrait.split_out_groups().

Para sa detalyadong gabay kung paano i-grupo ang mga term ng operator sa mga workflow mo, tingnan ang gabay sa pag-grupo.

>>> from qiskit_fermions.operators import MajoranaOperator, gamma
>>> op = MajoranaOperator.from_dict({
... (gamma(0, False),): 1.0,
... (gamma(1, False),): 1.0,
... (gamma(2, False), gamma(3, False)): 1.0
... })
>>> # Assign group indices to terms
>>> op.groups = [0, 0, 1]
>>> # Partition operator by groups
>>> grouped_ops = op.split_out_groups()

Mga operasyong aritmetika at matematikal​

Ipinapatupad ng lahat ng operator ang protocol na OperatorTrait, na nagbibigay ng pinag-isang hanay ng mga operasyon sa iba't ibang uri ng operator. Tinitiyak nito na ang code na isinulat para sa isang representasyon ng operator ay gumagana rin nang pareho sa iba. Tingnan ang qiskit_fermions.protocols para malaman kung paano nauugnay ang protocol na ito sa iba pang tinutukoy ng package na ito.

Kasama sa protocol ang mga operasyong aritmetika (tulad ng addition, multiplication, at composition), mga estrukturang operasyon (pag-iterate ng term, pagsusuri ng mode support, relabeling), mga matematikal na function (normal ordering, simplification, pagsusuri ng equivalence), at iba pa. Tingnan ang documentation ng OperatorTrait para sa kumpletong reference ng lahat ng available na operasyon.

>>> from qiskit_fermions.operators import FermionOperator, cre, ann
>>>
>>> # Construct a Hermitian operator: H = +0 -1 + +1 -0
>>> op = FermionOperator.from_dict({
... (cre(0), ann(1)): 1.0,
... (cre(1), ann(0)): 1.0
... })
>>>
>>> # Check if the operator is Hermitian
>>> print(f"Operator is Hermitian: {op.is_hermitian(atol=1e-10)}")
Operator is Hermitian: True
Tandaan

Bine-verify ng is_hermitian() na H−H†=0H - H^\dagger = 0 sa pamamagitan ng pagpapababa ng pagkakaibang iyon sa normal form at paghahambing nito sa zero(). Kung isusulat gamit ang iba pang operasyon ng protocol, ito ang ginagawa nito:

>>> difference = (op - op.adjoint()).normal_ordered().simplify(atol=1e-10)
>>> difference.equiv(FermionOperator.zero(), atol=1e-10)
True

Nakadepende sa uri ng operator ang lakas ng pagsusuring ito, dahil nakasalalay ito sa kung gaano kakumpleto ang pag-contract ng normal form ng uring iyon sa magkakatabing generator. Laging maaasahan ang resultang True, pero sa ilang uri, konserbatibo ang resultang False: tingnan ang is_hermitian() para sa mga detalye.

Important

Gumagamit ang halimbawa ng atol=1e-10. Ang parameter na atol (absolute tolerance) ay nagtatakda ng threshold. Ang mga coefficient na mas maliit ang magnitude kaysa sa atol ay itinuturing na zero at itinatapon. Mahalaga ito para sa numerical stability sa paghahambing ng mga operator, dahil ang floating-point arithmetic ay maaaring magdulot ng maliliit na rounding error na hahadlang sa pagkilala sa magkakapantay na operator bilang magkapantay.

Hint

Bagama't nagbibigay ang protocol na OperatorTrait ng karaniwang interface, maaaring mag-alok ang bawat implementasyon ng operator ng mga karagdagang convenience method na hindi bahagi ng protocol. Halimbawa, ang FermionOperator at MajoranaOperator ay nagbibigay ng method na max_rank() na nag-uulat ng haba ng pinakamahabang term nila. Lagi mong basahin ang API documentation ng uri ng operator mo para malaman ang lahat ng available na functionality.

Pag-order ng term ng operator at mga normal form​

Isang pangunahing hamon sa quantum operator algebra ay ang magkakapantay na operator sa matematika ay maaaring katawanin sa maraming magkakaibang paraan, na bawat isa ay may iba't ibang implikasyon para sa mga quantum algorithm. Maisusulat ang iisang operator sa mga algebraically equivalent na anyo (halimbawa, ang a†ba^\dagger b ay maaaring ipahayag bilang ba†+[a†,b]ba^\dagger + [a^\dagger,b]), pero ang mga representasyong ito ay humahantong sa magkakaibang behavior sa circuit synthesis, simplification, at mga numerical algorithm.

Sinusuportahan ng mga representasyon ng operator ang mga operasyong normal ordering na nagta-transform ng mga operator sa mga canonical form na partikular sa algebra gamit ang mga commutation relation. Nagbibigay-daan ito sa maaasahang paghahambing (ang dalawang magkapantay na operator ay may magkaparehong normal-ordered na anyo), nagbubunyag ng mga simplification (ang mga commutation relation ay nagiging dahilan ng pagkansela o pagsasama ng mga term), at sumusuporta sa mga algorithm na nangangailangan ng partikular na anyo ng operator para sa tamang resulta at kahusayan.

Important

Maaaring ipatupad ng magkakaibang representasyon ng operator ang normal ordering batay sa iba't ibang commutation relation na angkop sa kanilang algebra. Halimbawa, gumagamit ang fermionic normal ordering ng mga anticommutation relation ({ci,cj†}=δij\{c_i, c_j^\dagger\} = \delta_{ij}), habang ang Majorana normal ordering ay gumagamit ng ibang convention ng algebra ({γi,γj}=2δij\{\gamma_i, \gamma_j\} = 2\delta_{ij}). Lagi mong basahin ang documentation ng uri ng operator mo para maintindihan kung paano ipinatutupad ang normal ordering.

>>> from qiskit_fermions.operators import FermionOperator, cre, ann
>>>
>>> # Two different representations of the same operator
>>> op1 = FermionOperator.from_dict({(ann(0), cre(0)): 1.0})
>>> op2 = FermionOperator.from_dict({(): 1.0, (cre(0), ann(0)): -1.0})
>>>
>>> # Direct comparison fails due to different forms
>>> op1.equiv(op2, atol=1e-10)
False
>>>
>>> # Normal-order both and compare again
>>> op1_normal = op1.normal_ordered()
>>> op2_normal = op2.normal_ordered()
>>> op1_normal.equiv(op2_normal, atol=1e-10)
True
Hint

Sadyang hindi tinutukoy ng protocol method na OperatorTrait.normal_ordered() ang mga positional at keyword argument nito, kaya puwedeng magtakda ang mga konkretong implementasyon ng operator ng mga adjustable na parameter na kumokontrol sa eksaktong canonical form na nagagawa. Nagbibigay-daan ito sa mga optimization na partikular sa operator at mga variant ng normal form na akma sa kanilang algebra o gamit. Tingnan ang API documentation ng uri ng operator mo para makita ang mga available na parameter.