Note
இந்தப் பக்கம் tutorials/operators/01_operator_flow.ipynb லிருந்து உருவாக்கப்பட்டது.
ஆபரேட்டர் ஓட்டம்¶
முன்னுரை¶
Qiskit நிலைகள் மற்றும் ஆபரேட்டர்கள் மற்றும் தொகைகள், டென்சர் ப்ராடக்ட்கள் மற்றும் அதன் கலவைகளை குறிக்கும் வகுப்புகளை வழங்குகிறது. இந்த இயற்கணித கட்டமைப்புகள் ஆபரேட்டர்களைக் குறிக்கும் வெளிப்பாடுகளை உருவாக்க எங்களை அனுமதிக்கின்றன.
Pauli ஆபரேட்டர்களிடமிருந்து அவற்றை உருவாக்குவதன் மூலம் வெளிப்பாடுகளை அறிமுகப்படுத்துகிறோம். அடுத்தடுத்த பிரிவுகளில், ஆபரேட்டர்கள் மற்றும் நிலைகள், அவை எவ்வாறு குறிப்பிடப்படுகின்றன, அவற்றுடன் நாம் என்ன செய்ய முடியும் என்பதை விரிவாக ஆராய்வோம். கடைசி பிரிவில் நாம் ஒரு நிலையை உருவாக்குகிறோம், அதை ஒரு ஹாமில்டோனியனுடன் உருவாக்குகிறோம், மேலும் கவனிக்கத்தக்க எதிர்பார்ப்பு மதிப்புகளைக் கணக்கிடுகிறோம்.
Pauli ஆபரேட்டர்கள், தொகைகள், கலவை மற்றும் டென்சர் ப்ராடக்ட்கள்¶
மிக முக்கியமான அடிப்படை ஆபரேட்டர்கள் Pauli ஆபரேட்டர்கள். Pauli ஆபரேட்டர்கள் இதுபோன்று குறிப்பிடப்படுகிறார்கள்.
[1]:
from qiskit.opflow import I, X, Y, Z
print(I, X, Y, Z)
I X Y Z
இந்த ஆபரேட்டர்கள் ஒரு குணகத்தையும் கொண்டு செல்லக்கூடும்.
[2]:
print(1.5 * I)
print(2.5 * X)
1.5 * I
2.5 * X
இந்த குணகங்கள் ஆபரேட்டர்களை ஒரு தொகையாக சொற்களாகப் பயன்படுத்த அனுமதிக்கின்றன.
[3]:
print(X + 2.0 * Y)
1.0 * X
+ 2.0 * Y
டென்சர் ப்ராடக்ட்கள் இது போன்ற ஒரு caret உடன் குறிக்கப்படுகின்றன.
[4]:
print(X^Y^Z)
XYZ
கலவை என்பது @
சின்னத்தால் குறிக்கப்படுகிறது.
[5]:
print(X @ Y @ Z)
iI
முந்தைய இரண்டு எடுத்துக்காட்டுகளில், Pauli ஆபரேட்டர்களின் டென்சர் ப்ராடக்ட் மற்றும் கலவை உடனடியாக சமமான (சாத்தியமான பல-கியூபிட்) Pauli ஆபரேட்டராக குறைக்கப்பட்டது. நாம் மிகவும் சிக்கலான ஆப்ஜெக்ட்களை டென்சர் செய்தால் அல்லது உருவாக்கினால், இதன் விளைவு மதிப்பிடப்படாத செயல்பாடுகளைக் குறிக்கும் ஆப்ஜெக்ட்கள். அதாவது, இயற்கணித வெளிப்பாடுகள்.
உதாரணமாக, இரண்டு தொகைகளை உருவாக்கினால், இவ்வாறு அளிக்கும்
[6]:
print((X + Y) @ (Y + Z))
1j * Z
+ -1j * Y
+ 1.0 * I
+ 1j * X
மற்றும் இரண்டு தொகைகளை டென்சார் செய்வது, இப்படியாகும்
[7]:
print((X + Y) ^ (Y + Z))
1.0 * XY
+ 1.0 * XZ
+ 1.0 * YY
+ 1.0 * YZ
Let’s take a closer look at the types introduced above. First the Pauli operators.
[8]:
(I, X)
[8]:
(PauliOp(Pauli('I'), coeff=1.0), PauliOp(Pauli('X'), coeff=1.0))
ஒவ்வொரு Pauli ஆபரேட்டரும் PauliOp
இன் ஒரு எடுத்துக்காட்டு, இது qiskit.quantum_info.Pauli
இன் ஒரு நிகழ்வை மடக்கி, ஒரு குணகம் coeff
ஐ சேர்க்கிறது. பொதுவாக, PauliOp
என்பது Pauli ஆபரேட்டர்களின் எடையுள்ள டென்சர் ப்ராடக்ட்டைக் குறிக்கிறது.
[9]:
2.0 * X^Y^Z
[9]:
PauliOp(Pauli('XYZ'), coeff=2.0)
Pauli ஆபரேட்டர்களை பூலியன் மதிப்புகளின் ஜோடிகளாக குறியாக்க, qiskit.quantum_info.Pauli
க்கான ஆவணங்களைக் காண்க.
All of the objects representing operators, whether as "primitive"s such as PauliOp
, or algebraic expressions carry a coefficient
[10]:
print(1.1 * ((1.2 * X)^(Y + (1.3 * Z))))
1.2 * (
1.1 * XY
+ 1.4300000000000002 * XZ
)
In the following we take a broader and deeper look at Qiskit’s operators, states, and the building blocks of quantum algorithms.
பகுதி I: நிலை செயல்பாடுகள் மற்றும் அளவீடுகள்¶
குவாண்டம் நிலைகள் StateFn
வகுப்பின் துணைப்பிரிவுகளால் குறிப்பிடப்படுகின்றன. குவாண்டம் நிலைகளின் நான்கு பிரதிநிதித்துவங்கள் உள்ளன: DicStateFn
என்பது கணக்கீட்டு அடிப்படையில் ஒரு சிதறிய பிரதிநிதித்துவமாகும், இது dict
ஆல் ஆதரிக்கப்படுகிறது. VectorStateFn
என்பது கணக்கீட்டு அடிப்படையில் அடர்த்தியான பிரதிநிதித்துவமாகும். CircuitStateFn
ஒரு சர்க்யூட் மூலம் ஆதரிக்கப்படுகிறது மற்றும் அனைத்து பூஜ்ஜிய கணக்கீட்டு அடிப்படையிலான நிலையில் சர்க்யூட்டை இயக்குவதன் மூலம் பெறப்பட்ட நிலையை குறிக்கிறது. OperatorStateFn
என்பது டென்சிட்டி மேட்ரிக்ஸ் வழியாக கலப்பு நிலைகளைக் குறிக்கிறது. (பின்னர் பார்ப்போம், அவதானிப்புகளைக் குறிக்க OperatorStateFn
பயன்படுத்தப்படுகிறது.)
பல StateFn
நிகழ்வுகள் வசதிக்காக வழங்கப்படுகின்றன. உதாரணத்திற்கு Zero, One, Plus, Minus
.
[11]:
from qiskit.opflow import (StateFn, Zero, One, Plus, Minus, H,
DictStateFn, VectorStateFn, CircuitStateFn, OperatorStateFn)
Zero
மற்றும் One
குவாண்டம் நிலைகளைக் குறிக்கும் \(|0\rangle\) மற்றும் \(|1\rangle\). அவை DictStateFn
வழியாக குறிப்பிடப்படுகின்றன.
[12]:
print(Zero, One)
DictStateFn({'0': 1}) DictStateFn({'1': 1})
Plus
மற்றும் Minus
, நிலைகளை குறிக்கும் \((|0\rangle + |1\rangle)/\sqrt{2}\) மற்றும் \((|0\rangle - |1\rangle)/\sqrt{2}\) சர்க்யூட்கள் வழியாக குறிப்பிடப்படுகின்றன. H
என்பது Plus
என்பதற்கு ஒரு பொருளாகும்.
[13]:
print(Plus, Minus)
CircuitStateFn(
┌───┐
q: ┤ H ├
└───┘
) CircuitStateFn(
┌───┐┌───┐
q: ┤ X ├┤ H ├
└───┘└───┘
)
குவாண்டம் நிலைகளுக்குள் இடைவெளி eval
முறையுடன் செய்யப்படுகிறது. இந்த உதாரணங்கள் 0
மற்றும் 1
அடிப்படை நிலைகளின் கோட்பாடு திரும்பும். (கீழே, நாம் அதைப் பார்ப்போம் eval
முறை மற்ற கணக்கீடுகளுக்கும் பயன்படுத்தப்படுகிறது.)
[14]:
print(Zero.eval('0'))
print(Zero.eval('1'))
print(One.eval('1'))
print(Plus.eval('0'))
print(Minus.eval('1'))
1.0
0.0
1.0
(0.7071067811865475+0j)
(-0.7071067811865475+8.7e-17j)
ஒரு குவாண்டம் நிலையில் இரட்டை திசையன், அதாவது ket உடன் தொடர்புடைய bra என்பது adjoint
முறை மூலம் பெறப்படுகிறது. StateFn
ஒரு flag is_measurement
கொண்டு செல்கிறது, இது ஆப்ஜெக்ட் ஒரு ket ஆக இருந்தால் False
மற்றும் அது bra வாக இருந்தால் True
.
இங்கே, நாங்கள் கட்டமைக்கிறோம் \(\langle 1 |\).
[15]:
One.adjoint()
[15]:
DictStateFn({'1': 1}, coeff=1.0, is_measurement=True)
வசதிக்காக, ஒருவர் இரட்டை திசையனை ஒரு tilde உடன் பெறலாம், இது போல
[16]:
~One
[16]:
DictStateFn({'1': 1}, coeff=1.0, is_measurement=True)
இயற்கணித செயல்பாடுகள் மற்றும் கணிப்புகள்¶
பல இயற்கணித செயல்பாடுகள் மற்றும் StateFn
களுக்கு இடையே உள்ள கணிப்புகள் துணைபுரிகின்றன, இதில் அடங்கும்:
+
- கூட்டல்-
- கழித்தல், மறுப்பு (ஸ்கேலார் பெருக்கல் -1)*
- அளவிடல் பெருக்கல்/
- அளவிடல் வகுத்தல்@
- தொகுத்தல்^
- டென்சர் தயாரிப்பு அல்லது டென்சர் பவர் (செல்ஃப் n முறைகளுடன் கூடிய டென்சர்)**
- தொகுத்தல் சக்தி (தன்னுடன் n முறை எழுதவும்)==
- சமநிலை~
- ஒரு நிலை செயல்பாடு மற்றும் அளவீட்டுக்கு இடையில் மாறி
இந்த ஆபரேட்டர்கள் ஆபரேட்டர் முன்னுரிமைக்கான பைதான் விதிகளுக்குக் கீழ்ப்படிகிறார்கள் என்பதை கவனத்தில் கொள்ளவும், இது நீங்கள் கணித ரீதியாக எதிர்பார்க்கவில்லை. எடுத்துக்காட்டாக, I^X + X^I
உண்மையில் I ^ (X + X) ^ I == 2 * (I^X^I)
என அலசப்படும், ஏனெனில் பைதான் +
ஐ மதிப்பிடுகிறது. ^
க்கு முன். இந்த சந்தர்ப்பங்களில், நீங்கள் முறைகள் (.tensor()
, etc) அல்லது அடைப்புக்குறிகளைப் பயன்படுத்தலாம்.
StateFn
கள் ஒரு குணகத்தைக் கொண்டு செல்கின்றன. இது நிலைகளை ஒரு அளவுகோலால் பெருக்க அனுமதிக்கிறது, மேலும் தொகைகளை உருவாக்குகிறது.
இங்கே, நாங்கள் \((2 + 3i)|0\rangle\) கட்டமைக்கிறோம்.
[17]:
(2.0 + 3.0j) * Zero
[17]:
DictStateFn({'0': 1}, coeff=(2+3j), is_measurement=False)
இங்கே, இரண்டைச் சேர்ப்பதைக் காண்கிறோம் DictStateFn
s அதே வகை ஒரு ஆப்ஜெக்ட்டை வழங்குகிறது. நாங்கள் \(|0\rangle + |1\rangle\) கட்டமைக்கிறோம்.
[18]:
print(Zero + One)
DictStateFn({'0': 1.0, '1': 1.0})
நீங்கள் கையால் நிலைகளை இயல்பாக்க வேண்டும் என்பதை நினைவில் கொள்க. உதாரணமாக, \((|0\rangle + |1\rangle)/\sqrt{2}\) கட்டமைக்க, நாம் இவ்வாறு எழுதுகிறோம்
[19]:
import math
v_zero_one = (Zero + One) / math.sqrt(2)
print(v_zero_one)
DictStateFn({'0': 1.0, '1': 1.0}) * 0.7071067811865475
மற்ற சந்தர்ப்பங்களில், இதன் விளைவாக ஒரு தொகையின் குறியீட்டு பிரதிநிதித்துவம் ஆகும். எடுத்துக்காட்டாக, இங்கே ஒரு பிரதிநிதித்துவம் உள்ளது \(|+\rangle + |-\rangle\).
[20]:
print(Plus + Minus)
SummedOp([
CircuitStateFn(
┌───┐
q: ┤ H ├
└───┘
),
CircuitStateFn(
┌───┐┌───┐
q: ┤ X ├┤ H ├
└───┘└───┘
)
])
கலவை ஆபரேட்டர் ஒரு உள் தயாரிப்பைச் செய்யப் பயன்படுகிறது, இது இயல்பாகவே மதிப்பிடப்படாத வடிவத்தில் வைக்கப்படுகிறது. இங்கே ஒரு பிரதிநிதித்துவம் \(\langle 1 | 1 \rangle\).
[21]:
print(~One @ One)
ComposedOp([
DictMeasurement({'1': 1}),
DictStateFn({'1': 1})
])
is_measurement
flag (bra) நிலையை ~One
ஐ DictMeasurement
என அச்சிட காரணமாகிறது என்பதை நினைவில் கொள்க.
குறியீட்டு வெளிப்பாடுகள் eval
முறை மூலம் மதிப்பீடு செய்யப்படலாம்.
[22]:
(~One @ One).eval()
[22]:
1.0
[23]:
(~v_zero_one @ v_zero_one).eval()
[23]:
0.9999999999999998
இங்கே \(\langle - | 1 \rangle = \langle (\langle 0| - \langle 1|)/\sqrt{2} | 1\rangle\).
[24]:
(~Minus @ One).eval()
[24]:
(-0.7071067811865475-8.7e-17j)
கலவை ஆபரேட்டர் @
என்று அழைப்பதற்கு சமம் compose
முறை.
[25]:
print((~One).compose(One))
ComposedOp([
DictMeasurement({'1': 1}),
DictStateFn({'1': 1})
])
ComposedOp
ஐ உருவாக்காமல், நேரடியாக eval
முறையைப் பயன்படுத்தி உள் தயாரிப்புகளையும் கணக்கிடலாம்.
[26]:
(~One).eval(One)
[26]:
1.0
குறியீட்டு டென்சர் ப்ராடக்ட்கள் பின்வருமாறு கட்டப்பட்டுள்ளன. இங்கே \(|0\rangle \otimes |+\rangle\).
[27]:
print(Zero^Plus)
TensoredOp([
DictStateFn({'0': 1}),
CircuitStateFn(
┌───┐
q: ┤ H ├
└───┘
)
])
இது ஒரு எளிய (கலவை அல்ல) CircuitStateFn
என குறிப்பிடப்படலாம்.
[28]:
print((Zero^Plus).to_circuit_op())
CircuitStateFn(
┌───┐
q_0: ┤ H ├
└───┘
q_1: ─────
)
பின்வருமாறு ^
என்ற caret பயன்படுத்தி டென்சர் அதிகாரங்கள் கட்டமைக்கப்படுகின்றன. இங்கே உள்ளவை \(600 (|11111\rangle + |00000\rangle)\), மற்றும் \(|10\rangle^{\otimes 3}\).
[29]:
print(600 * ((One^5) + (Zero^5)))
print((One^Zero)^3)
DictStateFn({'11111': 1.0, '00000': 1.0}) * 600.0
DictStateFn({'101010': 1})
to_matrix_op
முறை VectorStateFn
க்கு மாற்றுகிறது.
[30]:
print(((Plus^Minus)^2).to_matrix_op())
print(((Plus^One)^2).to_circuit_op())
print(((Plus^One)^2).to_matrix_op().sample())
VectorStateFn(Statevector([ 0.25-6.1e-17j, -0.25+6.1e-17j, 0.25-6.1e-17j,
-0.25+6.1e-17j, -0.25+6.1e-17j, 0.25-6.1e-17j,
-0.25+6.1e-17j, 0.25-6.1e-17j, 0.25-6.1e-17j,
-0.25+6.1e-17j, 0.25-6.1e-17j, -0.25+6.1e-17j,
-0.25+6.1e-17j, 0.25-6.1e-17j, -0.25+6.1e-17j,
0.25-6.1e-17j],
dims=(2, 2, 2, 2)))
CircuitStateFn(
┌───┐
q_0: ┤ X ├
├───┤
q_1: ┤ H ├
├───┤
q_2: ┤ X ├
├───┤
q_3: ┤ H ├
└───┘
)
{'1101': 0.2734375, '0111': 0.2509765625, '1111': 0.24609375, '0101': 0.2294921875}
StateFn அமைப்பது எளிதானது. StateFn
வர்க்கம் ஒரு தொழிற்சாலையாகவும் செயல்படுகிறது, மேலும் அதன் கட்டமைப்பாளருக்கு பொருந்தக்கூடிய எந்தவொரு primitives சையும் எடுத்து சரியான StateFn துணைப்பிரிவை திருப்பித் தரலாம். தற்போது பின்வரும் primitives களை constructor ருக்கு அனுப்பலாம், அதனுடன் பட்டியலிடப்பட்டுள்ளது StateFn
தயாரிக்கும் துணைப்பிரிவு:
str (சில அடிப்படை பிட்ஸ்ட்ரிங்கிற்கு சமம்) -> DictStateFn
dict -> DictStateFn
Qiskit Result object -> DictStateFn
list -> VectorStateFn
np.ndarray -> VectorStateFn
Statevector -> VectorStateFn
QuantumCircuit -> CircuitStateFn
Instruction -> CircuitStateFn
OperatorBase - > OperatorStateFn
[31]:
print(StateFn({'0':1}))
print(StateFn({'0':1}) == Zero)
print(StateFn([0,1,1,0]))
from qiskit.circuit.library import RealAmplitudes
print(StateFn(RealAmplitudes(2)))
DictStateFn({'0': 1})
True
VectorStateFn(Statevector([0.+0.j, 1.+0.j, 1.+0.j, 0.+0.j],
dims=(2, 2)))
CircuitStateFn(
┌──────────────────────────────────────────────────────────┐
q_0: ┤0 ├
│ RealAmplitudes(θ[0],θ[1],θ[2],θ[3],θ[4],θ[5],θ[6],θ[7]) │
q_1: ┤1 ├
└──────────────────────────────────────────────────────────┘
)
பகுதி II: PrimitiveOp
s¶
அடிப்படை ஆபரேட்டர்கள் PrimitiveOp
இன் துணைப்பிரிவுகள். StateFn
போலவே, PrimitiveOp
என்பது ஒரு குறிப்பிட்ட பழமையானவருக்கு சரியான வகை PrimitiveOp
ஐ உருவாக்குவதற்கான ஒரு தொழிற்சாலையாகும். தற்போது, பின்வரும் பழமையானவைகளை அவர்கள் உருவாக்கும் PrimitiveOp
துணைப்பிரிவுடன் பட்டியலிடப்பட்ட கன்ஸ்ட்ரக்டருக்கு அனுப்பலாம்:
Terra’s Pauli -> PauliOp
Instruction -> CircuitOp
QuantumCircuit -> CircuitOp
2d List -> MatrixOp
np.ndarray -> MatrixOp
spmatrix -> MatrixOp
Terra’s quantum_info.Operator -> MatrixOp
[32]:
from qiskit.opflow import X, Y, Z, I, CX, T, H, S, PrimitiveOp
மேட்ரிக்ஸ் உறுப்புகள்¶
eval
முறை ஒரு ஆபரேட்டரிடமிருந்து ஒரு நெடுவரிசையைத் தருகிறது. எடுத்துக்காட்டாக, Pauli \(X\) ஆபரேட்டர் PauliOp
ஆல் குறிப்பிடப்படுகிறது. ஒரு நெடுவரிசையைக் கேட்பது சிதறிய பிரதிநிதித்துவத்தின் ஒரு உதாரணத்தை அளிக்கிறது, DictStateFn
.
[33]:
X
[33]:
PauliOp(Pauli('X'), coeff=1.0)
[34]:
print(X.eval('0'))
DictStateFn({'1': (1+0j)})
ஒரு மேட்ரிக்ஸ் உறுப்பைப் பெறும் ஒரு ஆபரேட்டரில் குறியீட்டு முறை eval
முறைக்கு இரண்டு அழைப்புகளுடன் செய்யப்படுகிறது.
நம்மிடம் \(X = \left(\begin{matrix} 0 & 1 \\ 1 & 0 \end{matrix} \right)\) உள்ளது. மற்றும் மேட்ரிக்ஸ் உறுப்பு \(\left\{X \right\}_{0,1}\) ஆனது
[35]:
X.eval('0').eval('1')
[35]:
(1+0j)
இரண்டு கியூபிட் ஆபரேட்டரைப் பயன்படுத்தி ஒரு எடுத்துக்காட்டு இங்கே CX
, கட்டுப்படுத்தப்பட்ட X
, இது ஒரு சர்க்யூட் மூலம் குறிக்கப்படுகிறது.
[36]:
print(CX)
print(CX.to_matrix().real) # The imaginary part vanishes.
q_0: ──■──
┌─┴─┐
q_1: ┤ X ├
└───┘
[[1. 0. 0. 0.]
[0. 0. 0. 1.]
[0. 0. 1. 0.]
[0. 1. 0. 0.]]
[37]:
CX.eval('01') # 01 is the one in decimal. We get the first column.
[37]:
VectorStateFn(Statevector([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
dims=(2, 2)), coeff=1.0, is_measurement=False)
[38]:
CX.eval('01').eval('11') # This returns element with (zero-based) index (1, 3)
[38]:
(1+0j)
ஒரு நிலை திசையனுக்கு ஒரு ஆபரேட்டரைப் பயன்படுத்துதல்¶
ஒரு நிலை திசையனுக்கு ஒரு ஆபரேட்டரைப் பயன்படுத்துவது compose
முறை மூலம் செய்யப்படலாம் (equivalently, @
operator). இங்கே ஒரு பிரதிநிதித்துவம் \(X | 1 \rangle = |0\rangle\).
[39]:
print(X @ One)
ComposedOp([
X,
DictStateFn({'1': 1})
])
ஒரு எளிய பிரதிநிதித்துவம், DictStateFn
பிரதிநிதித்துவம் \(|0\rangle\), eval
உடன் பெறப்படுகிறது.
[40]:
(X @ One).eval()
[40]:
DictStateFn({'0': (1+0j)}, coeff=(1+0j), is_measurement=False)
eval
ஐ நேரடியாகப் பயன்படுத்துவதன் மூலம் இடைநிலை ComposedOp
வழியைத் தவிர்க்கப்படலாம்.
[41]:
X.eval(One)
[41]:
DictStateFn({'0': (1+0j)}, coeff=(1+0j), is_measurement=False)
ஆபரேட்டர்கள் கலவை மற்றும் டென்சர் தயாரிப்பு @
மற்றும் ^
. இங்கே சில உதாரணங்கள்.
[42]:
print(((~One^2) @ (CX.eval('01'))).eval())
print(((H^5) @ ((CX^2)^I) @ (I^(CX^2)))**2)
print((((H^5) @ ((CX^2)^I) @ (I^(CX^2)))**2) @ (Minus^5))
print(((H^I^I)@(X^I^I)@Zero))
(1+0j)
┌───┐ ┌───┐
q_0: ──■──┤ H ├───────■──┤ H ├─────
┌─┴─┐└───┘┌───┐┌─┴─┐└───┘┌───┐
q_1: ┤ X ├──■──┤ H ├┤ X ├──■──┤ H ├
└───┘┌─┴─┐├───┤└───┘┌─┴─┐├───┤
q_2: ──■──┤ X ├┤ H ├──■──┤ X ├┤ H ├
┌─┴─┐└───┘├───┤┌─┴─┐└───┘├───┤
q_3: ┤ X ├──■──┤ H ├┤ X ├──■──┤ H ├
└───┘┌─┴─┐├───┤└───┘┌─┴─┐├───┤
q_4: ─────┤ X ├┤ H ├─────┤ X ├┤ H ├
└───┘└───┘ └───┘└───┘
CircuitStateFn(
┌───┐┌───┐ ┌───┐ ┌───┐
q_0: ┤ X ├┤ H ├──■──┤ H ├───────■──┤ H ├─────
├───┤├───┤┌─┴─┐└───┘┌───┐┌─┴─┐└───┘┌───┐
q_1: ┤ X ├┤ H ├┤ X ├──■──┤ H ├┤ X ├──■──┤ H ├
├───┤├───┤└───┘┌─┴─┐├───┤└───┘┌─┴─┐├───┤
q_2: ┤ X ├┤ H ├──■──┤ X ├┤ H ├──■──┤ X ├┤ H ├
├───┤├───┤┌─┴─┐└───┘├───┤┌─┴─┐└───┘├───┤
q_3: ┤ X ├┤ H ├┤ X ├──■──┤ H ├┤ X ├──■──┤ H ├
├───┤├───┤└───┘┌─┴─┐├───┤└───┘┌─┴─┐├───┤
q_4: ┤ X ├┤ H ├─────┤ X ├┤ H ├─────┤ X ├┤ H ├
└───┘└───┘ └───┘└───┘ └───┘└───┘
)
CircuitStateFn(
┌─────────────┐
q_0: ┤0 ├─────
│ │
q_1: ┤1 Pauli(XII) ├─────
│ │┌───┐
q_2: ┤2 ├┤ H ├
└─────────────┘└───┘
)
[43]:
print(~One @ Minus)
ComposedOp([
DictMeasurement({'1': 1}),
CircuitStateFn(
┌───┐┌───┐
q: ┤ X ├┤ H ├
└───┘└───┘
)
])
பகுதி III: ListOp
மற்றும் துணைப்பிரிவுகள்¶
ListOp
¶
ListOp
என்பது ஆபரேட்டர்கள் மற்றும் நிலைகளின் பட்டியலில் செயல்பாடுகளை திறம்பட திசையமைப்பதற்கான ஒரு கொள்கலன்.
[44]:
from qiskit.opflow import ListOp
print((~ListOp([One, Zero]) @ ListOp([One, Zero])))
ComposedOp([
ListOp([
DictMeasurement({'1': 1}),
DictMeasurement({'0': 1})
]),
ListOp([
DictStateFn({'1': 1}),
DictStateFn({'0': 1})
])
])
எடுத்துக்காட்டாக, மேலே உள்ள கலவையை reduce
என்னும் எளிமைப்படுத்தும் முறையைப் பயன்படுத்தி பட்டியல்களில் (ListOp
) விநியோகிக்கப்படுகிறது.
[45]:
print((~ListOp([One, Zero]) @ ListOp([One, Zero])).reduce())
ListOp([
ListOp([
ComposedOp([
DictMeasurement({'1': 1}),
DictStateFn({'1': 1})
]),
ComposedOp([
DictMeasurement({'1': 1}),
DictStateFn({'0': 1})
])
]),
ListOp([
ComposedOp([
DictMeasurement({'0': 1}),
DictStateFn({'1': 1})
]),
ComposedOp([
DictMeasurement({'0': 1}),
DictStateFn({'0': 1})
])
])
])
ListOp
s: SummedOp
, ComposedOp
, TensoredOp
¶
ListOp
, introduced above, is useful for vectorizing operations. But, it also serves as the superclass for list-like composite classes. If you’ve already played around with the above, you’ll notice that you can easily perform operations between OperatorBase
s which we may not know how to perform efficiently in general (or simply haven’t implemented an efficient procedure for yet), such as addition between CircuitOp
s. In those cases, you may receive a ListOp
result (or subclass
thereof) from your operation representing the lazy execution of the operation. For example, if you attempt to add together a DictStateFn
and a CircuitStateFn
, you’ll receive a SummedOp
representing the sum of the two. This composite State function still has a working eval
(but may need to perform a non-scalable computation under the hood, such as converting both to vectors).
இந்த கலப்பு OperatorBase
s பெருகிய முறையில் சிக்கலான மற்றும் சிறந்த கணக்கீட்டை எவ்வாறு உருவாக்குகிறோம் என்பதுதான் PrimitiveOp
மற்றும் StateFn
கட்டுமான தொகுதிகள்.
ஒவ்வொரு லிஸ்ட்Op
க்கும் நான்கு பண்புகள் உள்ளன:
oplist
- விதிமுறைகள், காரணிகள் போன்றவற்றைக் குறிக்கக்கூடியOperatorBase
களின் பட்டியல்.combo_fn
-oplist
உருப்படிகளின் வெளியீடுகளை எவ்வாறு இணைப்பது என்பதை வரையறுக்கும் ஒரு வெளியீட்டு மதிப்புக்குக் கலப்பு எண்களின் பட்டியலை எடுக்கும் செயல்பாடு. ஒளிபரப்பு எளிமைக்காக, இந்தச் செயல்பாடு NumPy வரிசைகளில் வரையறுக்கப்படுகிறது.coeff
- பழமையானதைப் பெருக்கும் குணகம்.coeff
int, float, complex அல்லது இலவசParameter
பொருளாக இருக்கலாம் (Terra இல்qiskit.circuit
இலிருந்து) பின்னர்my_op.bind_parameters
ஐப் பயன்படுத்தி பிணைக்கப்படும்.abelian
-oplist
இல் உள்ள ஆபரேட்டர்கள் பரஸ்பரம் பயணிக்கத் தெரிந்தவர்களா என்பதைக் குறிக்கிறது (பொதுவாகAbelianGrouper
மாற்றிமூலம் மாற்றப்பட்ட பிறகு அமைக்கப்படும்).
ListOp
வழக்கமான வரிசை ஓவர்லோடுகளை ஆதரிக்கிறது, எனவே oplist
இல் OperatorBase
களை அணுக my_op[4]
போன்ற அட்டவணையைப் பயன்படுத்தலாம்.
OperatorStateFn
¶
OperatorStateFn
ஒரு அடர்த்தி ஆபரேட்டரைக் குறிக்கிறது என்பதை நாங்கள் மேலே குறிப்பிட்டோம். ஆனால், is_measurement
flag True
எனில், OperatorStateFn
என்பது கவனிக்கத்தக்கதைக் குறிக்கிறது. இந்த அனுசரிப்புக்கான எதிர்பார்ப்பு மதிப்பு பின்னர் ComposedOp
வழியாக உருவாக்கப்படலாம். அல்லது, நேரடியாக, eval
ஐப் பயன்படுத்துதல். adjoint
முறை வழியாக is_measurement
flag (property) அமைக்கப்பட்டுள்ளது என்பதை நினைவில் கொள்க.
Pauli \(Z\) ஆபரேட்டருக்கு ஒத்ததாகக் காணக்கூடியதை இங்கே உருவாக்குகிறோம். அச்சிடும் போது, அது OperatorMeasurement
என்று அழைக்கப்படுகிறது என்பதை நினைவில் கொள்க.
[46]:
print(StateFn(Z).adjoint())
StateFn(Z).adjoint()
OperatorMeasurement(Z)
[46]:
OperatorStateFn(PauliOp(Pauli('Z'), coeff=1.0), coeff=1.0, is_measurement=True)
இங்கே, நாம் \(\langle 0 | Z | 0 \rangle\), \(\langle 1 | Z | 1 \rangle\), மற்றும் \(\langle + | Z | + \rangle\) கணக்கிடுகிறோம், இதில் \(|+\rangle = (|0\rangle + |1\rangle)/\sqrt{2}\).
[47]:
print(StateFn(Z).adjoint().eval(Zero))
print(StateFn(Z).adjoint().eval(One))
print(StateFn(Z).adjoint().eval(Plus))
(1+0j)
(-1+0j)
0j
பகுதி IV: மாற்றிகள்¶
Converters are classes that manipulate operators and states and perform building blocks of algorithms. Examples include changing the basis of operators and Trotterization. Converters traverse an expression and perform a particular manipulation or replacement, defined by the converter’s convert()
method, of the Operators within. Typically, if a converter encounters an OperatorBase
in the recursion which is irrelevant to its conversion purpose, that OperatorBase
is left unchanged.
[48]:
import numpy as np
from qiskit.opflow import I, X, Y, Z, H, CX, Zero, ListOp, PauliExpectation, PauliTrotterEvolution, CircuitSampler, MatrixEvolution, Suzuki
from qiskit.circuit import Parameter
from qiskit import Aer
பரிணாமங்கள், exp_i ()
, மற்றும் EvolvedOp
¶
Every PrimitiveOp
and ListOp
has an .exp_i()
function such that H.exp_i()
corresponds to \(e^{-iH}\). In practice, only a few of these Operators have an efficiently computable exponentiation (such as MatrixOp and the PauliOps with only one non-identity single-qubit Pauli), so we need to return a placeholder, or symbolic representation, (similar to how SummedOp
is a placeholder when we can’t perform addition). This placeholder is called EvolvedOp
, and it holds the
OperatorBase
to be exponentiated in its .primitive
property.
Qiskit operators fully support parameterization, so we can use a Parameter
for our evolution time here. Notice that there’s no "evolution time" argument in any function. The Operator flow exponentiates whatever operator we tell it to, and if we choose to multiply the operator by an evolution time, \(e^{-iHt}\), that will be reflected in our exponentiation parameters.
Pauli ஆபரேட்டர்களின் எடையுள்ள தொகை¶
மல்டி-கியூபிட் Pauli ஆபரேட்டர்களின் நேரியல் கலவையாக வெளிப்படுத்தப்பட்ட ஒரு ஹாமில்டோனியன் இதுபோன்று கட்டமைக்கப்படலாம்.
[49]:
two_qubit_H2 = (-1.0523732 * I^I) + \
(0.39793742 * I^Z) + \
(-0.3979374 * Z^I) + \
(-0.0112801 * Z^Z) + \
(0.18093119 * X^X)
wo_qubit_H2
என்பது SummedOp
எனக் குறிப்பிடப்படுகிறது, இதன் சொற்கள் PauliOp
s.
[50]:
print(two_qubit_H2)
-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX
அடுத்து, ஹாமில்டோனியனை Parameter
மூலம் பெருக்குகிறோம். இந்த Parameter
SummedOp
இன் coeff
பண்பில் சேமிக்கப்படுகிறது. முடிவில் exp_i()
என்று அழைப்பது, அதை EvolvedOp
போர்த்தி, அடுக்காகக் குறிக்கிறது.
[51]:
evo_time = Parameter('θ')
evolution_op = (evo_time*two_qubit_H2).exp_i()
print(evolution_op) # Note, EvolvedOps print as exponentiations
print(repr(evolution_op))
e^(-i*1.0*θ * (
-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX
))
EvolvedOp(PauliSumOp(SparsePauliOp(['II', 'IZ', 'ZI', 'ZZ', 'XX'],
coeffs=[-1.0523732 +0.j, 0.39793742+0.j, -0.3979374 +0.j, -0.0112801 +0.j,
0.18093119+0.j]), coeff=1.0*θ), coeff=1.0)
h2_measurement
ஐ உருவாக்குகிறோம், இது two_qubit_H2
ஐக் காணக்கூடியதாகக் குறிக்கிறது.
[52]:
h2_measurement = StateFn(two_qubit_H2).adjoint()
print(h2_measurement)
OperatorMeasurement(-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX)
நாங்கள் ஒரு பெல் நிலையை உருவாக்குகிறோம் \(|\Phi_+\rangle\) via \(\text{CX} (H\otimes I) |00\rangle\).
[53]:
bell = CX @ (I ^ H) @ Zero
print(bell)
CircuitStateFn(
┌───┐
q_0: ┤ H ├──■──
└───┘┌─┴─┐
q_1: ─────┤ X ├
└───┘
)
இங்கே வெளிப்பாடு \(H e^{-iHt} |\Phi_+\rangle\).
[54]:
evo_and_meas = h2_measurement @ evolution_op @ bell
print(evo_and_meas)
ComposedOp([
OperatorMeasurement(-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX),
e^(-i*1.0*θ * (
-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX
)),
CircuitStateFn(
┌───┐
q_0: ┤ H ├──■──
└───┘┌─┴─┐
q_1: ─────┤ X ├
└───┘
)
])
பொதுவாக, தோராயமாக மதிப்பிட விரும்புகிறோம் \(e^{-iHt}\) இரண்டு-கியூபிட்டு கேட்களைப் பயன்படுத்துதல். PauliTrotterEvolution
இன் convert
முறையால் இதை நாங்கள் அடைகிறோம், இது எதிர்கொள்ளும் அனைத்து EvolvedOp
s ட்ரொட்டரைசேஷனைப் பயன்படுத்துவதற்கான வெளிப்பாடுகளைக் கடந்து செல்கிறது. நாம் இங்கே PauliTrotterEvolution
ஐப் பயன்படுத்தினாலும், MatrixEvolution
போன்ற பிற சாத்தியக்கூறுகள் உள்ளன, அவை அதிவேகத்தை சரியாகச் செய்கின்றன.
[55]:
trotterized_op = PauliTrotterEvolution(trotter_mode=Suzuki(order=2, reps=1)).convert(evo_and_meas)
# We can also set trotter_mode='suzuki' or leave it empty to default to first order Trotterization.
print(trotterized_op)
ComposedOp([
OperatorMeasurement(-1.0523732 * II
+ 0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ
+ 0.18093119 * XX),
CircuitStateFn(
global phase: 1.0523732*θ
┌───┐ ┌───┐┌───┐┌──────────────────┐┌───┐┌───┐┌───┐»
q_0: ┤ H ├──■──┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├┤ X ├»
└───┘┌─┴─┐├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤└─┬─┘»
q_1: ─────┤ X ├┤ H ├──■────────────────────────■──┤ H ├──■──»
└───┘└───┘ └───┘ »
« ┌──────────────────┐┌───┐┌──────────────────┐┌──────────────────┐┌───┐»
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ Rz(0.39793742*θ) ├┤ Rz(0.39793742*θ) ├┤ X ├»
« └──────────────────┘└─┬─┘├──────────────────┤├──────────────────┤└─┬─┘»
«q_1: ──────────────────────■──┤ Rz(-0.3979374*θ) ├┤ Rz(-0.3979374*θ) ├──■──»
« └──────────────────┘└──────────────────┘ »
« ┌──────────────────┐┌───┐┌───┐┌───┐┌──────────────────┐┌───┐┌───┐
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├
« └──────────────────┘└─┬─┘├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤
«q_1: ──────────────────────■──┤ H ├──■────────────────────────■──┤ H ├
« └───┘ └───┘
)
])
trotterized_op
இல் Parameter
உள்ளது. bind_parameters
முறை, dict
வழியாக குறிப்பிடப்பட்டுள்ளபடி, வெளிப்பாடு பிணைப்பு மதிப்புகளை அளவுரு பெயர்களுக்குச் செல்கிறது. இந்த வழக்கில், ஒரே ஒரு அளவுரு மட்டுமே உள்ளது.
[56]:
bound = trotterized_op.bind_parameters({evo_time: .5})
bound
is a ComposedOp
. The second factor is the circuit. Let’s draw it to verify that the binding has taken place.
[57]:
bound[1].to_circuit().draw()
[57]:
global phase: 0.52619 ┌───┐ ┌───┐┌───┐┌─────────────────┐┌───┐┌───┐┌───┐┌─────────────────┐» q_0: ┤ H ├──■──┤ H ├┤ X ├┤ Rz(0.090465595) ├┤ X ├┤ H ├┤ X ├┤ Rz(-0.00564005) ├» └───┘┌─┴─┐├───┤└─┬─┘└─────────────────┘└─┬─┘├───┤└─┬─┘└─────────────────┘» q_1: ─────┤ X ├┤ H ├──■───────────────────────■──┤ H ├──■─────────────────────» └───┘└───┘ └───┘ » « ┌───┐┌────────────────┐┌────────────────┐┌───┐┌─────────────────┐┌───┐» «q_0: ┤ X ├┤ Rz(0.19896871) ├┤ Rz(0.19896871) ├┤ X ├┤ Rz(-0.00564005) ├┤ X ├» « └─┬─┘├────────────────┤├────────────────┤└─┬─┘└─────────────────┘└─┬─┘» «q_1: ──■──┤ Rz(-0.1989687) ├┤ Rz(-0.1989687) ├──■───────────────────────■──» « └────────────────┘└────────────────┘ » « ┌───┐┌───┐┌─────────────────┐┌───┐┌───┐ «q_0: ┤ H ├┤ X ├┤ Rz(0.090465595) ├┤ X ├┤ H ├ « ├───┤└─┬─┘└─────────────────┘└─┬─┘├───┤ «q_1: ┤ H ├──■───────────────────────■──┤ H ├ « └───┘ └───┘
எதிர்பார்ப்புகள்¶
Expectation
s மாற்றக்கூடியவை, அவை அவதானிக்கக்கூடியவர்களின் எதிர்பார்ப்பு மதிப்புகளைக் கணக்கிட உதவும். அவை ஒரு ஆபரேட்டர் மரத்தில் பயணிக்கின்றன, OperatorStateFn
s (அவதானிக்கக்கூடியவை) சமமான வழிமுறைகளுடன் குவாண்டம் அல்லது கிளாசிக்கல் வன்பொருளில் கணக்கிடுவதற்கு மிகவும் ஏற்றது. எடுத்துக்காட்டாக, சில மாநில செயல்பாடுகளைப் பொறுத்து Paulis-ன் தொகையாக வெளிப்படுத்தப்பட்ட ஒரு ஆபரேட்டரின் எதிர்பார்ப்பு மதிப்பை அளவிட விரும்பினால், ஆனால் குவாண்டம் வன்பொருளில் மூலைவிட்ட அளவீடுகளை மட்டுமே அணுக முடியும் என்றால், நாம் கவனிக்கத்தக்க o
ஐ உருவாக்க முடியும். ~StateFn(o)
மற்றும் ஒரு PauliExpectation
ஐப் பயன்படுத்தி அதை ஒரு மூலைவிட்ட அளவீடு மற்றும் சர்க்யூட்டுக்கு முந்தைய சுழற்சிகளாக மாற்றவும்.
மற்றொரு சுவாரஸ்யமான Expectation
என்பது AerPauliExpectation
ஆகும், இது கவனிக்கத்தக்கதை CircuitStateFn
ஆக மாற்றுகிறது, இது ஒரு சிறப்பு எதிர்பார்ப்பு ஸ்னாப்ஷாட் அறிவுறுத்தலைக் கொண்டுள்ளது, இது Ae
உயர் செயல்திறனுடன் இயல்பாக இயக்க முடியும்.
[58]:
# Note that XX was the only non-diagonal measurement in our H2 Observable
print(PauliExpectation(group_paulis=False).convert(h2_measurement))
SummedOp([
ComposedOp([
OperatorMeasurement(-1.0523732 * II),
II
]),
ComposedOp([
OperatorMeasurement(0.39793742 * IZ),
II
]),
ComposedOp([
OperatorMeasurement(-0.3979374 * ZI),
II
]),
ComposedOp([
OperatorMeasurement(-0.0112801 * ZZ),
II
]),
ComposedOp([
OperatorMeasurement(0.18093119 * ZZ),
┌───┐
q_0: ┤ H ├
├───┤
q_1: ┤ H ├
└───┘
])
])
இயல்பாகவே group_paulis=True
, இது SummedOp
ஐ பரஸ்பர கியூபிட் வாரியாக பயணிக்கும் பவுலிஸின் குழுக்களாக மாற்ற AbelianGrouper
பயன்படுத்தும். இது சர்க்யூட் செயல்பாட்டை மேல்நோக்கி குறைக்கிறது, ஏனெனில் ஒவ்வொரு குழுவும் ஒரே சர்க்யூட் செயல்பாட்டை பகிர்ந்து கொள்ளலாம்.
[59]:
print(PauliExpectation().convert(h2_measurement))
SummedOp([
ComposedOp([
OperatorMeasurement(0.18093119 * ZZ
- 1.0523732 * II),
┌───┐
q_0: ┤ H ├
├───┤
q_1: ┤ H ├
└───┘
]),
ComposedOp([
OperatorMeasurement(0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ),
II
])
])
மாற்றிகள் மீண்டும் மீண்டும் செயல்படுகின்றன என்பதை நினைவில் கொள்க, அதாவது, அவை முடிந்தவரை மட்டுமே தங்கள் செயலைப் பயன்படுத்தும் ஒரு வெளிப்பாட்டைக் கடந்து செல்கின்றன. எனவே நமது முழு பரிணாமத்தையும் அளவீட்டு வெளிப்பாட்டையும் மாற்றலாம். மாற்றப்பட்ட h2_measurement
ஐ நமது பரிணாம வளர்ச்சியுடன் CircuitStateFn
உடன் சமமாக இயற்றியிருக்கலாம். முழு வெளிப்பாட்டிலும் மாற்றத்தைப் பயன்படுத்துவதன் மூலம் நாங்கள் தொடர்கிறோம்.
[60]:
diagonalized_meas_op = PauliExpectation().convert(trotterized_op)
print(diagonalized_meas_op)
SummedOp([
ComposedOp([
OperatorMeasurement(0.18093119 * ZZ
- 1.0523732 * II),
CircuitStateFn(
global phase: 1.0523732*θ
┌───┐ ┌───┐┌───┐┌──────────────────┐┌───┐┌───┐┌───┐»
q_0: ┤ H ├──■──┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├┤ X ├»
└───┘┌─┴─┐├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤└─┬─┘»
q_1: ─────┤ X ├┤ H ├──■────────────────────────■──┤ H ├──■──»
└───┘└───┘ └───┘ »
« ┌──────────────────┐┌───┐┌──────────────────┐┌──────────────────┐┌───┐»
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ Rz(0.39793742*θ) ├┤ Rz(0.39793742*θ) ├┤ X ├»
« └──────────────────┘└─┬─┘├──────────────────┤├──────────────────┤└─┬─┘»
«q_1: ──────────────────────■──┤ Rz(-0.3979374*θ) ├┤ Rz(-0.3979374*θ) ├──■──»
« └──────────────────┘└──────────────────┘ »
« ┌──────────────────┐┌───┐┌───┐┌───┐┌──────────────────┐┌───┐┌───┐┌───┐
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├┤ H ├
« └──────────────────┘└─┬─┘├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤├───┤
«q_1: ──────────────────────■──┤ H ├──■────────────────────────■──┤ H ├┤ H ├
« └───┘ └───┘└───┘
)
]),
ComposedOp([
OperatorMeasurement(0.39793742 * IZ
- 0.3979374 * ZI
- 0.0112801 * ZZ),
CircuitStateFn(
global phase: 1.0523732*θ
┌───┐ ┌───┐┌───┐┌──────────────────┐┌───┐┌───┐┌───┐»
q_0: ┤ H ├──■──┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├┤ X ├»
└───┘┌─┴─┐├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤└─┬─┘»
q_1: ─────┤ X ├┤ H ├──■────────────────────────■──┤ H ├──■──»
└───┘└───┘ └───┘ »
« ┌──────────────────┐┌───┐┌──────────────────┐┌──────────────────┐┌───┐»
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ Rz(0.39793742*θ) ├┤ Rz(0.39793742*θ) ├┤ X ├»
« └──────────────────┘└─┬─┘├──────────────────┤├──────────────────┤└─┬─┘»
«q_1: ──────────────────────■──┤ Rz(-0.3979374*θ) ├┤ Rz(-0.3979374*θ) ├──■──»
« └──────────────────┘└──────────────────┘ »
« ┌──────────────────┐┌───┐┌───┐┌───┐┌──────────────────┐┌───┐┌───┐
«q_0: ┤ Rz(-0.0112801*θ) ├┤ X ├┤ H ├┤ X ├┤ Rz(0.18093119*θ) ├┤ X ├┤ H ├
« └──────────────────┘└─┬─┘├───┤└─┬─┘└──────────────────┘└─┬─┘├───┤
«q_1: ──────────────────────■──┤ H ├──■────────────────────────■──┤ H ├
« └───┘ └───┘
)
])
])
இப்போது பல அளவுரு மதிப்புகளை ListOp
ஆக பிணைக்கிறோம், அதன்பிறகு முழு வெளிப்பாட்டை மதிப்பீடு செய்ய eval
. நாம் முன்பே கட்டுப்பட்டிருந்தால் eval
ஐ முன்னர் பயன்படுத்தியிருக்கலாம், ஆனால் அது திறமையாக இருக்காது. இங்கே, eval
எங்கள் CircuitStateFn
களை உள்நாட்டில் உருவகப்படுத்துதல் மூலம் VectorStateFn
களாக மாற்றும்.
[61]:
evo_time_points = list(range(8))
h2_trotter_expectations = diagonalized_meas_op.bind_parameters({evo_time: evo_time_points})
எதிர்பார்ப்பு மதிப்புகள் இங்கே \(\langle \Phi_+| e^{iHt} H e^{-iHt} |\Phi_+\rangle\) அளவுருவின் வெவ்வேறு மதிப்புகளுடன் தொடர்புடையது.
[62]:
h2_trotter_expectations.eval()
[62]:
array([-0.88272211+0.0e+00j, -0.88272211+0.0e+00j, -0.88272211+0.0e+00j,
-0.88272211+0.0e+00j, -0.88272211+0.0e+00j, -0.88272211+0.0e+00j,
-0.88272211+5.6e-17j, -0.88272211+0.0e+00j])
CircuitSampler
உடன் CircuitStateFn
s ஐ செயல்படுத்துகிறோம்¶
CircuitSampler
ஒரு ஆபரேட்டரைக் கடந்து எந்த CircuitStateFn
களை ஒரு குவாண்டம் பின்தளத்தைப் பயன்படுத்தி DictStateFn` அல்லது ``VectorStateFn
மூலம் விளைந்த நிலை செயல்பாட்டின் தோராயமாக மாற்றுகிறது. CircuitStateFn
இன் மதிப்பை தோராயமாக மதிப்பிடுவதற்கு, அது 1) நிலை செயல்பாட்டை நீக்கும் சேனல் மூலம் அனுப்ப வேண்டும், இது அனைத்து கட்ட தகவல்களையும் அழிக்கும் மற்றும் 2) மாதிரி அதிர்வெண்களை சதுர வேர்கள் மூலம் மாற்றும் மாதிரியின் மூல நிகழ்தகவை விட அதிர்வெண் (இது பார்ன் விதியின்படி, மாநில செயல்பாட்டின் சதுர மாதிரிக்கு சமமாக இருக்கும்).
[63]:
sampler = CircuitSampler(backend=Aer.get_backend('aer_simulator'))
# sampler.quantum_instance.run_config.shots = 1000
sampled_trotter_exp_op = sampler.convert(h2_trotter_expectations)
sampled_trotter_energies = sampled_trotter_exp_op.eval()
print('Sampled Trotterized energies:\n {}'.format(np.real(sampled_trotter_energies)))
Sampled Trotterized energies:
[-0.88272211 -0.88272211 -0.88272211 -0.88272211 -0.88272211 -0.88272211
-0.88272211 -0.88272211]
சர்க்யூட் மாதிரி நிகழ்தகவுகளின் square roots உடன் சர்க்யூட்கள் மாற்றப்படுகின்றன என்பதை மீண்டும் கவனியுங்கள். மாற்றத்திற்கு முன்னும் பின்னும் ஒரு துணை வெளிப்பாட்டைப் பாருங்கள்:
[64]:
print('Before:\n')
print(h2_trotter_expectations.reduce()[0][0])
print('\nAfter:\n')
print(sampled_trotter_exp_op[0][0])
Before:
ComposedOp([
OperatorMeasurement(0.18093119 * ZZ
- 1.0523732 * II),
CircuitStateFn(
┌───┐ ┌───┐┌───┐┌───────┐┌───┐┌───┐┌───┐┌───────┐┌───┐┌───────┐»
q_0: ┤ H ├──■──┤ H ├┤ X ├┤ Rz(0) ├┤ X ├┤ H ├┤ X ├┤ Rz(0) ├┤ X ├┤ Rz(0) ├»
└───┘┌─┴─┐├───┤└─┬─┘└───────┘└─┬─┘├───┤└─┬─┘└───────┘└─┬─┘├───────┤»
q_1: ─────┤ X ├┤ H ├──■─────────────■──┤ H ├──■─────────────■──┤ Rz(0) ├»
└───┘└───┘ └───┘ └───────┘»
« ┌───────┐┌───┐┌───────┐┌───┐┌───┐┌───┐┌───────┐┌───┐┌───┐┌───┐
«q_0: ┤ Rz(0) ├┤ X ├┤ Rz(0) ├┤ X ├┤ H ├┤ X ├┤ Rz(0) ├┤ X ├┤ H ├┤ H ├
« ├───────┤└─┬─┘└───────┘└─┬─┘├───┤└─┬─┘└───────┘└─┬─┘├───┤├───┤
«q_1: ┤ Rz(0) ├──■─────────────■──┤ H ├──■─────────────■──┤ H ├┤ H ├
« └───────┘ └───┘ └───┘└───┘
)
])
After:
ComposedOp([
OperatorMeasurement(0.18093119 * ZZ
- 1.0523732 * II),
DictStateFn({'00': 0.7167090588237321, '11': 0.6973723001381686})
])
[65]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.19.0.dev0+fe3eb3f |
qiskit-aer | 0.10.0.dev0+b78f265 |
qiskit-ignis | 0.7.0.dev0+0eb9dcc |
qiskit-ibmq-provider | 0.17.0.dev0+15d2dfe |
System information | |
Python version | 3.9.5 |
Python compiler | Clang 10.0.0 |
Python build | default, May 18 2021 12:31:01 |
OS | Darwin |
CPUs | 4 |
Memory (Gb) | 32.0 |
Fri Oct 29 16:10:45 2021 BST |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.