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?

Pagtatrabaho sa mga bosonic circuit

Ang isang BosonicCircuit ay nagpapahayag ng computation nang direkta sa mga bosonic mode. Wala itong truncation, encoding, o bilang ng qubit: pumapasok ang mga iyon sa ibang pagkakataon, sa transpilation, kaya naka-lower ang isang circuit sa ilang encoding at ilang truncation nang hindi binubuo muli.

Sadyang mas maliit ang API na inilalantad nito kumpara sa QuantumCircuit ng Qiskit, para hindi makapag-apply ng mga qubit gate sa isang bosonic mode, na hindi magiging well-defined na operasyon. Sinasaklaw ng gabay na ito ang mga operasyong inilalantad para sa pagbuo ng mas malalaking circuit mula sa mas maliliit.

Bakit gagamit ng mga bosonic circuit​

Isaalang-alang ang tradisyonal na workflow para ilagay ang time evolution ng isang bosonic Hamiltonian sa qubit-based na architecture:

  1. Idefine ang bosonic Hamiltonian, halimbawa H=−∑ijbi†bjH = -\sum_{ij} b^\dagger_i b_j.

  2. Pumili ng truncation at encoding, at i-map ang Hamiltonian sa isang qubit operator gamit ang mga iyon.

  3. Ipatupad ang time evolution sa qubit space, sa pamamagitan ng Trotterization o ibang method.

Maaga ang ikalawang hakbang, at gumagawa ito ng dalawang desisyong magastos bawiin. Itinatakda ng truncation kung ilang level ang pinapanatili ng bawat mode, at itinatakda ng encoding kung ilang qubit ang kailangan niyon, kaya parehong naka-fix sa qubit operator bago pa magawa ang anupaman sa circuit. Para makita ang parehong physics sa ibang cutoff o ibang encoding, ima-map mo ulit ang Hamiltonian at bubuuin ulit ang circuit. Ang itinatapon din ng mapping ay ang bosonic na estruktura: kung aling mga term ang magkakasama, at na ang mga term ng isang hopping pair ay adjoint ng isa't isa.

Inililipat ng isang BosonicCircuit ang mga desisyong iyon sa dulo:

  1. Idefine ang bosonic Hamiltonian.

  2. Ipahayag ang time evolution nang direkta sa mga bosonic mode, gamit ang mga bosonic gate.

  3. Piliin ang truncation at ang encoding bilang bahagi ng transpilation.

Inilalarawan ng circuit kung anong computation ang gagawin, at ang transpilation ang nagpapasya kung paano ito ilalagay sa mga qubit. Ang parehong circuit ay ilo-lower sa bawat cutoff at sa bawat encoding, at nariyan pa rin ang grouping ng operator para sa mga pass na makakagamit nito. Ipinapakita ng mga susunod na seksyon kung paano binubuo ang ganoong circuit; ipinapakita ng I-transpile ang mga bosonic circuit kung paano ito ilo-lower.

Generic na mode indexing​

Ang operators module at ang circuit ay may iisang convention para sa mga mode. Ang mode ay index lang na nagla-label ng isang bosonic degree of freedom, at wala itong sariling kahulugan. Kaya maaari mong i-evolve ang anumang operator na nagpapatupad ng OperatorTrait protocol, anuman ang kinakatawan nito, at hindi kailangang malaman ng circuit kung ano ang kinakatawan ng mode 2. Ganoon din sa laki ng mode: walang occupation cutoff ang circuit, kaya walang nagsasabi rito kung ilang level mayroon ang isang mode.

Magdagdag ng mga gate​

Ang mga gate ay idinadagdag sa mga mode. Mga instance lang ng BosonicGate ang tinatanggap:

>>> from qiskit_bosons.circuit import BosonicCircuit
>>> from qiskit_bosons.circuit.library import Evolution, InitializeModes
>>> from qiskit_bosons.operators import BosonOperator, ann, cre
>>>
>>> hopping = BosonOperator.from_dict({(cre(0), ann(1)): -1.0, (cre(1), ann(0)): -1.0})
>>> hopping.groups = [0] * len(hopping) # the pair is Hermitian, its terms alone are not
>>>
>>> prepare = BosonicCircuit(2)
>>> prepare.append(InitializeModes([2, 0]), prepare.modes)
>>> step = BosonicCircuit(2)
>>> step.append(Evolution(2, hopping, time=0.1), step.modes)

Tinatanggihan ang anupamang iba, at pinapangalanan ng error ang may-sala na uri:

>>> from qiskit.circuit.library import HGate
>>> try:
... prepare.append(HGate(), [0])
... except ValueError as error:
... print(error)
Unsupported instruction type: <class '...HGate'>

I-compose ang mga circuit​

Inilalagay ng compose() ang mga instruction ng isang circuit sa isa pa. Ini-inline ang mga ito, hindi binabalot sa isang gate, kaya ang resulta ay karaniwang circuit na maaari mong ipagpatuloy sa pag-decompose at pag-transpile.

>>> program = prepare.compose(step)
>>> program.draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A composed BosonicCircuit.

Bilang default, isang bagong circuit ang ibinabalik at hindi ginagalaw ang parehong operand. Ipasa ang inplace=True para baguhin na lang ang una, at front=True para ilagay ang operand bago ang mga kasalukuyang instruction:

>>> step.compose(prepare, front=True)._inner.data == program._inner.data
True

Ang mas makitid na circuit ay maaaring ilagay sa napiling subset ng mga mode:

>>> single = BosonicCircuit(1)
>>> single.append(Evolution(1, BosonOperator.from_dict({(cre(0), ann(0)): 1.0}), 0.1), single.modes)
>>> wide = BosonicCircuit(3).compose(single, [2])
>>> wide.draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A narrow-composed BosonicCircuit.

Isa pang BosonicCircuit lang ang tinatanggap bilang operand, dahil ang sariling compose ng Qiskit ay mag-i-inline ng mga qubit gate at lalampasan ang check na ipinapatupad ng append.

Ulitin ang isang circuit​

Inuulit ng repeat() ang isang circuit mula simula hanggang dulo. Pinapatag ang mga repetition: hawak ng resulta ang mga instruction nang reps beses nang sunod-sunod sa halip na isang gate na bumabalot sa circuit. Kaya, lumalaki ang bilang ng operasyon ayon sa reps, at ang decompose ay umaaksyon sa inuulit na katawan sa halip na magtanggal ng isang repetition.

>>> len(step.repeat(0)._inner.data) # zero repetitions is the identity
0
>>> step.repeat(5).draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A repeated BosonicCircuit.

Ito ang paraan sa circuit level para mag-Trotterize: mag-evolve sa maikling oras, at ulitin. Tingnan ang Mag-synthesize ng Evolution gate sa bosonic space para sa alternatibong pagpili ng product formula sa mismong gate, at kung bakit magkaiba ang dalawa kahit pareho ang salitang “repetitions”.

Paghiwalayin ang mga hakbang gamit ang mga barrier​

Ang barrier ay nagmamarka ng synchronization point na hindi tinatawid ng mga optimization pass sa pag-fuse ng mga gate. Naglalagay ang barrier() ng isa sa lahat ng mode, o sa mga mode na pinangalanan mo:

>>> program = BosonicCircuit(2)
>>> program.append(InitializeModes([2, 0]), program.modes)
>>> program.barrier()
>>> program.barrier(program.modes[0], label="zero")
>>> program.draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A BosonicCircuit with barriers.

Naglalagay ang repeat(..., insert_barriers=True) ng isa sa pagitan ng magkakasunod na repetition, at wala pagkatapos ng huli:

>>> step.repeat(3, insert_barriers=True).draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A repeated BosonicCircuit with barriers.

Mga barrier at ang encoding​

Kailangan ng encoding ng ilang qubit bawat mode, kaya magkaiba ang laki ng register ng mga mode at register ng mga qubit, at nag-uugnay ang layout ng buong register. Kaya walang sariling qubit ang mode para paliitin ang barrier. Sa boson-to-qubit synthesis, ang barrier ay ima-map sa bawat qubit ng bawat register na hinawakan nito, na tama sa anumang layout:

>>> from qiskit_bosons.mappers import LevelSpec
>>> from qiskit_bosons.transpiler.presets import generate_preset_occupation_pass_manager
>>> lowered = generate_preset_occupation_pass_manager(LevelSpec(2, "unary_projected")).run(program)
>>> lowered.draw("mpl", fold=-1)
<Figure size ... with 1 Axes>

A QuantumCircuit showing the expansion of barrier to cover the entire qubit register.

I-read out ang isang bosonic circuit​

Walang measure o measure_all ang isang BosonicCircuit. Nakadepende sa encoding ang kahulugan ng isang nasukat na bit. Sa unary encoding, ang occupation ng isang mode ay nakakalat sa ilang qubit at kailangang basahin mula sa pattern ng mga bit, at sa compact naman ay binary number ito, kaya ang measurement na nagpapangalan ng mode ay kailangang alam ang encoding, na sadyang hindi alam ng bosonic circuit. Sa halip, sukatin ang na-transpile na QuantumCircuit, at i-decode ang mga bitstring gamit ang LevelEncoding.level_to_bits() at ang mga offset ng LevelSpec na ginamit mo sa pag-lower. Ginagawa ito ng I-simulate ang Bose-Hubbard dynamics gamit ang pagpili ng encoding para sa kumpletong modelo.

>>> hasattr(BosonicCircuit, "measure_all")
False

Mga susunod na hakbang​