নোট
এই পৃষ্ঠাটি tutorials/circuits/3_summary_of_quantum_operations.ipynb থেকে নেয়া হয়েছে।
কোয়ান্টাম প্রক্রিয়ার সারমর্ম¶
এই অংশে Qiskit টেরা তে ব্যবহৃত কয়েকটি কার্যকারকের বর্ণনা দেয়া হবেঃ
একক কিউবিট যুক্তি বর্তনী
বহু কিউবিট প্রায়োগিক যুক্তি বর্তনী
পরিমাপ
পুনস্থাপন (রিসেট)
শর্তসাপেক্ষ
অবস্থা (স্টেট) সূচিতকরণ
কিভাবে তিনটি ভিন্ন ভিন্ন সিমুলেটর ব্যবহার করতে হয় তার প্রয়োগ দেখানো হবে:
unitary_simulator
qasm_simulator
statevector_simulator
[1]:
# Useful additional packages
import matplotlib.pyplot as plt
import numpy as np
from math import pi
[2]:
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, transpile
from qiskit.tools.visualization import circuit_drawer
from qiskit.quantum_info import state_fidelity
from qiskit import BasicAer
backend = BasicAer.get_backend('unitary_simulator')
একক কিউবিট কোয়ান্টাম অবস্থা (স্টেট)¶
একটি একক কিউবিট কোয়ান্টাম অবস্থা (স্টেট) নিম্নরূপে লেখা যায়
যেখানে \(\alpha\) এবং \(\beta\) জটিল সংখ্যা। এখানে \(\left|0\right\rangle\) দশা পরিমাপণের সম্ভাব্যতা হচ্ছে \(|\alpha|^2\) এবং \(\left|1\right\rangle\) দশা পরিমাপণের সম্ভাব্যতা হচ্ছে \(|\beta|^2\)। দিকরাশি হিসেবে যা
টীকা, যেহেতু সম্ভাবনার সংরক্ষনশীলতা অনুযায়ী \(|\alpha|^2+|\beta|^2 = 1\) এবং গ্লোবাল ফেজ অনির্ণেয়, সেহেতু একটি একক কিউবিট কণার দশা \(\left|\psi\right\rangle := e^{i\delta} \left|\psi\right\rangle\) প্রকাশে আমাদের শুধুমাত্র দুইটি বাস্তব সংখ্যা প্রয়োজন।
একটি সার্বজনীন সাংকেতিক প্রকাশ হচ্ছে
যেখানে \(0\leq \phi < 2\pi\) এবং \(0\leq \theta \leq \pi\)। এ থেকে, এটি স্পষ্ট যে কিউবিট মানগুলির (\(\mathbb{C}^2\)) এবং একক গোলকের পৃষ্ঠের পয়েন্টগুলির (\(\mathbb{R}^3\)) মধ্যে একক সম্পর্ক রয়েছে। একে বলা হয় ব্লক গোলক যা একটি কিউবিট অবস্থার (স্টেট) প্রতিনিধি।
কোয়ান্টাম গেটগুলি / অপারেশনগুলি সাধারণত ম্যাট্রিক্স হিসাবে উপস্থাপিত হয়। একটি গেট যা একটি কিউবিটে কাজ করে \(2\times 2\) ইউনিটারি ম্যাট্রিক্স \(U\) দ্বারা প্রতিনিধিত্ব করে। কোয়ান্টাম গেটের কার্যকারিতা কোয়ান্টাম মানের প্রতিনিধিত্বকারী ভেক্টরগুলির সাথে গেটের ম্যাট্রিক্সকে গুণ করে পাওয়া যায়।
একটি সাধারণ একক ক্রিয়াকলাপ অবশ্যই \(\left|0\right\rangle\) থেকে উল্লিখিত অবস্থা (স্টেট) পেতে সক্ষম হবে। যার অর্থ হচ্ছে
যেখানে \(a\) এবং \(b\) এমন জটিল সংখ্যা যা \(U^\dagger U = I\) সমস্ত \(0\leq\theta\leq\pi\) এবং \(0\leq \phi<2\pi\) এর জন্য সীমাবদ্ধ। এটি 3 টি সীমাবদ্ধতা (কনস্ট্রেইন্টস) দেয় এবং যেমন \(a\rightarrow -e^{i\lambda}\sin(\theta/2)\) এবং \(b\rightarrow e^{i\lambda+i\phi}\cos(\theta/2)\) যেখানে \(0\leq \lambda<2\pi\) দেয়
এটি একটি একক কিউবিট ঐকিকের (ইউনিটারি) সর্বাধিক সাধারণ রূপ।
একক-কিউবিট যুক্তিবর্তনীগুলি (গেইট)¶
The single-qubit gates available are: - U gate - P gate - Identity gate - Pauli gates - Clifford gates - \(C3\) gates - Standard rotation gates
একক ম্যাট্রিক্সগুলো গণনার জন্য আমরা unitary_simulator
নামক একটি ব্যাকএন্ড সরবরাহ করেছি।
[3]:
q = QuantumRegister(1)
U gate¶
In Qiskit we give you access to the general unitary using the \(u\) gate, which has the following matrix form
[4]:
qc = QuantumCircuit(q)
qc.u(pi/2,pi/4,pi/8,q)
qc.draw()
[4]:
┌────────────────┐ q0: ┤ U(π/2,π/4,π/8) ├ └────────────────┘
[5]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[5]:
array([[ 0.707+0.j , -0.653-0.271j],
[ 0.5 +0.5j , 0.271+0.653j]])
Note on U gate deprecation
The QuantumCircuit methods \(u1\), \(u2\) and \(u3\) are now deprecated. Instead, the following replacements should be used.
\(u1(\lambda) = p(\lambda) = u(0, 0, \lambda)\)
\(u2(\phi, \lambda) = u(\frac{\pi}{2}, \phi, \lambda) = p(\frac{\pi}{2} + \phi) \cdot sx \cdot p(\frac{\pi}{2} - \lambda)\)
\(u3(\theta, \phi, \lambda) = u(\theta, \phi, \lambda) = p(\phi + \pi) \cdot sx \cdot p(\theta + \pi) \cdot sx \cdot p(\lambda)\)
# qc.u1(lambda) is now:
qc.p(lambda)
# qc.u2(phi, lambda) is now:
qc.u(pi/2, phi, lambda)
# qc.u3(theta, phi, lambda) is now:
qc.u(theta, phi, lambda)
P gate¶
\(p(\lambda)= u(0, 0, \lambda)\) যুক্তিবর্তনীর ম্যাট্রিক্স রূপ হল
এটি কার্যকর কারণ এটি আমাদের কোয়ান্টাম দশা প্রয়োগ করতে দেয়।
[13]:
qc = QuantumCircuit(q)
qc.p(pi/2,q)
qc.draw()
[13]:
┌────────┐ q0: ┤ P(π/2) ├ └────────┘
[14]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[14]:
array([[1.+0.j, 0.+0.j],
[0.+0.j, 0.+1.j]])
অভেদক (আইডেন্টিটি) যুক্তিবর্তনী (গেইট)¶
The identity gate is \(Id = p(0)\).
[15]:
qc = QuantumCircuit(q)
qc.id(q)
qc.draw()
[15]:
┌───┐ q0: ┤ I ├ └───┘
[16]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[16]:
array([[1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j]])
পাউলি যুক্তিবর্তনী (গেইট)¶
\(X\): বিট-ফ্লিপ বা মান পরিবর্তন যুক্তিবর্তনী (গেইট)¶
\(X\) মান পরিবর্তন (বিট-ফ্লিপ) যুক্তিবর্তনীর (গেইট) সংজ্ঞা হল:
[17]:
qc = QuantumCircuit(q)
qc.x(q)
qc.draw()
[17]:
┌───┐ q0: ┤ X ├ └───┘
[18]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[18]:
array([[0.+0.j, 1.+0.j],
[1.+0.j, 0.+0.j]])
\(Y\): bit- and phase-flip gate¶
\(Y\) যুক্তিবর্তনীর সংজ্ঞায়ন হচ্ছে:
[19]:
qc = QuantumCircuit(q)
qc.y(q)
qc.draw()
[19]:
┌───┐ q0: ┤ Y ├ └───┘
[20]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[20]:
array([[ 0.+0.j, -0.-1.j],
[ 0.+1.j, 0.+0.j]])
\(Z\): দশা পরিবর্তনকারী যুক্তিবর্তনী (গেইট)¶
দশা পরিবর্তনকারী যুক্তিবর্তনী (গেইট) \(Z\) এর সংজ্ঞায়ন হচ্ছেঃ:
[21]:
qc = QuantumCircuit(q)
qc.z(q)
qc.draw()
[21]:
┌───┐ q0: ┤ Z ├ └───┘
[23]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[23]:
array([[ 1.+0.j, 0.+0.j],
[ 0.+0.j, -1.+0.j]])
ক্লিফোর্ড যুক্তিবর্তনী¶
হাদামার্দ যুক্তিবর্তনী¶
[22]:
qc = QuantumCircuit(q)
qc.h(q)
qc.draw()
[22]:
┌───┐ q0: ┤ H ├ └───┘
[23]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[23]:
array([[ 0.707+0.j, 0.707-0.j],
[ 0.707+0.j, -0.707+0.j]])
\(S\) ( অথবা, :math:`sqrt{Z} দশা) যুক্তিবর্তনী (গেইট)¶
[24]:
qc = QuantumCircuit(q)
qc.s(q)
qc.draw()
[24]:
┌───┐ q0: ┤ S ├ └───┘
[29]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[29]:
array([[1.+0.j, 0.+0.j],
[0.+0.j, 0.+1.j]])
\(S^{\dagger}\) (অথবা, \(\sqrt{Z}\) এর অনুবন্ধী দশা) যুক্তিবর্তনী (গেইট)¶
[25]:
qc = QuantumCircuit(q)
qc.sdg(q)
qc.draw()
[25]:
┌─────┐ q0: ┤ Sdg ├ └─────┘
[26]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[26]:
array([[1.+0.j, 0.+0.j],
[0.+0.j, 0.-1.j]])
:math:`C3 যুক্তিবর্তনী (গেইট)¶
\(T\) (অথবা, \(\sqrt{S}\) দশা) যুক্তিবর্তনী (গেইট)¶
[27]:
qc = QuantumCircuit(q)
qc.t(q)
qc.draw()
[27]:
┌───┐ q0: ┤ T ├ └───┘
[28]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[28]:
array([[1. +0.j , 0. +0.j ],
[0. +0.j , 0.707+0.707j]])
\(T^{\dagger}\) (অথবা, \(\sqrt{S}\) এর অনুবন্ধী দশা) যুক্তিবর্তনী (গেইট)¶
[29]:
qc = QuantumCircuit(q)
qc.tdg(q)
qc.draw()
[29]:
┌─────┐ q0: ┤ Tdg ├ └─────┘
[30]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[30]:
array([[1. +0.j , 0. +0.j ],
[0. +0.j , 0.707-0.707j]])
প্রামাণিক (স্টান্ডার্ড) ঘূর্ণন¶
প্রামাণিক ঘুর্ণনশীল যুক্তিবর্তনী সেগুলো যারা পাউলী \(P=\{X,Y,Z\}\) কেন্দ্র করে ঘুর্ণন করে। এদের সংজ্ঞা হল
X-অক্ষ ঘিরে আবর্তন¶
[31]:
qc = QuantumCircuit(q)
qc.rx(pi/2,q)
qc.draw()
[31]:
┌─────────┐ q0: ┤ Rx(π/2) ├ └─────────┘
[32]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[32]:
array([[ 0.707+0.j , -0. -0.707j],
[ 0. -0.707j, 0.707+0.j ]])
Y-অক্ষ ঘিরে আবর্তন¶
[33]:
qc = QuantumCircuit(q)
qc.ry(pi/2,q)
qc.draw()
[33]:
┌─────────┐ q0: ┤ Ry(π/2) ├ └─────────┘
[34]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[34]:
array([[ 0.707+0.j, -0.707+0.j],
[ 0.707+0.j, 0.707+0.j]])
Z-অক্ষ ঘিরে আবর্তন¶
Note that here we have used an equivalent as it is different to \(p\) by a global phase \(e^{-i \phi/2}\).
[35]:
qc = QuantumCircuit(q)
qc.rz(pi/2,q)
qc.draw()
[35]:
┌─────────┐ q0: ┤ Rz(π/2) ├ └─────────┘
[36]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[36]:
array([[0.707-0.707j, 0. +0.j ],
[0. +0.j , 0.707+0.707j]])
এই দশা শুধুমাত্র সার্বজনীন (গ্লোবাল) দশার সংজ্ঞায়নের কারণে ভিন্নতর।
বহু কিউবিট যুক্তিবর্তনী¶
গাণিতিক প্রারম্ভিক আবশ্যতা¶
The space of a quantum computer grows exponentially with the number of qubits. For \(n\) qubits the complex vector space has dimension \(d=2^n\). To describe states of a multi-qubit system, the tensor product is used to "glue together" operators and basis vectors.
Let’s start by considering a 2-qubit system. Given two operators \(A\) and \(B\) that each act on one qubit, the joint operator \(A \otimes B\) acting on two qubits is
যেখানে \(A_{jk}\) এবং \(B_{lm}\) হচ্ছে যথাক্রমে \(A\) এবং \(B\) এর ম্যাট্রিক্স উপাদান।
প্রসঙ্গত, ২-কিউবিট সিস্টেমের বেসিস দিকরাশি (ভেক্টর) গঠন করা হয় একক কিউবিটের বেসিস দিকরাশির টেন্সর গুণনের মাধ্যমে:
Note we’ve introduced a shorthand for the tensor product of basis vectors, wherein \(\left|0\right\rangle \otimes \left|0\right\rangle\) is written as \(\left|00\right\rangle\). The state of an \(n\)-qubit system can be described using the \(n\)-fold tensor product of single-qubit basis vectors. Notice that the basis vectors for a 2-qubit system are 4-dimensional; in general, the basis vectors of an \(n\)-qubit system are \(2^{n}\)-dimensional, as noted earlier.
Qiskit-এ একক দিকরাশির ক্রমবিন্যাস¶
Within the physics community, the qubits of a multi-qubit systems are typically ordered with the first qubit on the left-most side of the tensor product and the last qubit on the right-most side. For instance, if the first qubit is in state \(\left|0\right\rangle\) and second is in state \(\left|1\right\rangle\), their joint state would be \(\left|01\right\rangle\). Qiskit uses a slightly different ordering of the qubits, in which the qubits are represented from the most significant bit (MSB) on the left to the least significant bit (LSB) on the right (little-endian). This is similar to bitstring representation on classical computers, and enables easy conversion from bitstrings to integers after measurements are performed. For the example just given, the joint state would be represented as \(\left|10\right\rangle\). Importantly, this change in the representation of multi-qubit states affects the way multi-qubit gates are represented in Qiskit, as discussed below.
Qiskit এ বেসিস দিকরাশি গুলোকে এমনভাবে প্রকাশ করা হয় যাতে তাদের ক্রম পুর্ণসংখ্যার মত ক্রমিক হয়। যেমন, একটি ২-কিউবিট ব্যবস্থার ক্রম হবে যথাক্রমে \(\left|00\right\rangle\), \(\left|01\right\rangle\), \(\left|10\right\rangle\), \(\left|11\right\rangle\)। এই বেসিস দিকরাশিগুলোকে বিট স্ট্রিঙের সাথে তুলনা করা যায় এবং এদের ০,১,২,৩ এই ক্রম অনুসারে চিহ্নিত করা হয়।
কিউবিটের উপরে নিয়ন্ত্রিত ক্রিয়াকলাপ (অপারেশন)¶
একটি কিউবিটের উপরে কার্যরত একটি যুক্তিবর্তনী, যা আরেকটি কিউবিটের অবস্থার সাপেক্ষে শর্তাধীন, নিয়ে একটি সাধারণ একাধিক কিউবিট যুক্তিবর্তনী (গেইট) তৈরি হয়। যেমন, আমরা হয়ত দ্বিতীয় কিউবিটের অবস্থা উল্টে দিতে চাই যখন প্রথম কিউবিটের মান \(\left|0\right\rangle\)। এরকম যুক্তিবর্তনীকে (গেইট) নিয়ন্ত্রিত যুক্তিবর্তনী বলা হয়। আদর্শ একাধিক কিউবিট যুক্তিবর্তনীতে দ্বি-কিউবিট এবং ত্রি-কিউবিট যুক্তিবর্তনী থাকে। দ্বি-কিউবিট যুক্তিবর্তনীগুলো হলো: - নিয়ন্ত্রিত পাউলি যুক্তিবর্তনী (গেইট) - নিয়ন্ত্রিত হ্যাডামার্ড হ্যাডামার্ড যুক্তিবর্তনী - নিয়ন্ত্রিত ঘূর্ণন হ্যাডামার্ড যুক্তিবর্তনী - নিয়ন্ত্রিত দশা যুক্তিবর্তনী (গেইট)- নিয়ন্ত্রিত U3 যুক্তিবর্তনী - অদলবদল (সোয়াপ) যুক্তিবর্তনী (গেইট)।
তিন-কিউবিট যুক্তিবর্তনী (গেইট) - টফোলি যুক্তিবর্তনী (গেইট) - ফ্রেডকিন যুক্তিবর্তনী (গেইট)
দ্বি-কিউবিট যুক্তিবর্তনীসমূহ (গেইট)¶
দ্বি-কিউবিট যুক্তিবর্তনীগুলোর (গেইট) বেশিরভাগ হচ্ছে নিয়ন্ত্রিত ধরণের (অদলবদল (সোয়াপ) যুক্তিবর্তনী বাদে)। সাধারণত, একটি নিয়ন্ত্রিত দ্বি-কিউবিট যুক্তিবর্তনী (গেইট) \(C_{U}\) দ্বিতীয় কিউবিটে একটি একক কিউবিট ঐকিক (ইউনিটারি) \(U\) প্রয়োগ করে প্রথম কিউবিট \(\left|1\right\rangle\) অবস্থায় থাকে। যেমন, \(U\) এর একটি ম্যাট্রিক্স রূপ হল
We can work out the action of \(C_{U}\) as follows. Recall that the basis vectors for a two-qubit system are ordered as \(\left|00\right\rangle, \left|01\right\rangle, \left|10\right\rangle, \left|11\right\rangle\). Suppose the control qubit is qubit 0 (which, according to Qiskit’s convention, is one the right-hand side of the tensor product). If the control qubit is in \(\left|1\right\rangle\), \(U\) should be applied to the target (qubit 1, on the left-hand side of the tensor product). Therefore, under the action of \(C_{U}\), the basis vectors are transformed according to
ম্যাট্রিক্সরূপে, \(C_{U}\) এর কাজ হচ্ছে
এইসকল ম্যাট্রিক্স উপাদানগুলোর কাজ করার জন্য, ধরা যাক
-এর কাজ (উপরের প্রদত্ত) \(C_{U}\) -এর পদক্ষেপ গণনা করতে দাও এবং অভ্যন্তরীন গুণফল গণনা করতে দাও।
নিম্নলিখিত উদাহরণে যেমনটি দেখানো হয়েছে, এই ক্রিয়াকলাপ (অপারেশন) Qiskit-এ এভাবে বাস্তবায়ন করা হয়েছে cU(q[0],q[1])
।
যদি কিউবিট ১ নিয়ন্ত্রক এবং কিউবিট ০ নিয়ন্ত্রিত হয়, তাহলে একক দিকরাশিসমূহ (বেসিস ভেক্টর) এভাবে পরিবর্তিত হবে
যা থেকে প্রতীয়মান হয়ে যে \(C_{U}\) এর ম্যাট্রিক্সরূপ হছে
[37]:
q = QuantumRegister(2)
নিয়ন্ত্রিত পাউলি যুক্তিবর্তনী¶
Controlled-X (or, Controlled-NOT) gate¶
The Controlled-NOT gate flips the target
qubit when the control qubit is in the state \(\left|1\right\rangle\). If we take the MSB as the control qubit (e.g. cx(q[1],q[0])
), then the matrix would look like
However, when the LSB is the control qubit, (e.g. cx(q[0],q[1])
), this gate is equivalent to the following matrix:
[38]:
qc = QuantumCircuit(q)
qc.cx(q[0],q[1])
qc.draw()
[38]:
q60_0: ──■── ┌─┴─┐ q60_1: ┤ X ├ └───┘
[39]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[39]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]])
কন্ট্রোল্ড \(Y\) যুক্তিবর্তনী (গেইট)¶
যদি নিয়ন্ত্রনকারী কিউবিট MSB হয়, তাহলে নিয়ন্ত্রিত কিউবিটে \(Y\) প্রয়োগ করা যাবে।
অথবা যখন এলএসবি নিয়ন্ত্রনকারী কিউবিট হবে।
[40]:
qc = QuantumCircuit(q)
qc.cy(q[0],q[1])
qc.draw()
[40]:
q60_0: ──■── ┌─┴─┐ q60_1: ┤ Y ├ └───┘
[41]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[41]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j]])
Controlled \(Z\) (or, controlled Phase-Flip) gate¶
একইভাবে, যদি নিয়ন্ত্রণকারী কিউবিট \(\left|1\right\rangle\) হয়, তাহলেই কন্ট্রোল্ড Z যুক্তিবর্তনীতে টার্গেট কিউবিটের দশা পরিবর্তন হবে। ম্যাট্রিক্সটি কন্ট্রোল কিউবিটের এমএসবি অথবা এলএসবি এর উপর নির্ভর করে না:
[42]:
qc = QuantumCircuit(q)
qc.cz(q[0],q[1])
qc.draw()
[42]:
q60_0: ─■─ │ q60_1: ─■─
[43]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[43]:
array([[ 1.-0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 1.-0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j]])
কন্ট্রোল্ড হ্যাডামার্ড যুক্তিবর্তনী (গেট)¶
যদি নিয়ন্ত্রণ কিউবিট \(\left|1\right\rangle\).হয় তাহলে \(H\) যুক্তিবর্তনী লক্ষ্য কিউবিটে প্রয়োগ করুন। কনট্রোল কিউবিট এলএসবি হলে নিচের পন্থা অবলম্বন করুন।
[44]:
qc = QuantumCircuit(q)
qc.ch(q[0],q[1])
qc.draw()
[44]:
q60_0: ──■── ┌─┴─┐ q60_1: ┤ H ├ └───┘
[45]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[45]:
array([[ 1. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],
[ 0. +0.j, 0.707+0.j, 0. +0.j, 0.707-0.j],
[ 0. +0.j, 0. +0.j, 1. -0.j, 0. +0.j],
[ 0. +0.j, 0.707+0.j, 0. +0.j, -0.707+0.j]])
কন্ট্রোল্ড পরামিতিক (রোটেশন বা ঘূর্ণন) যুক্তিবর্তনী¶
Z-অক্ষের চারপাশে নিয়ন্ত্রিত ঘূর্ণন¶
Z-অক্ষের চারপাশে ঘূর্ণন সম্পাদন করুন লক্ষ্য কিউবিটের উপর যদি নিয়ন্ত্রণ কিউবিট (এখানে এল এস বি) - \(\left|1\right\rangle\).
[46]:
qc = QuantumCircuit(q)
qc.crz(pi/2,q[0],q[1])
qc.draw()
[46]:
q60_0: ─────■───── ┌────┴────┐ q60_1: ┤ Rz(π/2) ├ └─────────┘
[47]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[47]:
array([[1. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],
[0. +0.j , 0.707-0.707j, 0. +0.j , 0. +0.j ],
[0. +0.j , 0. +0.j , 1. +0.j , 0. +0.j ],
[0. +0.j , 0. +0.j , 0. +0.j , 0.707+0.707j]])
নিয়ন্ত্রিত দশা (ফেজ) ঘূর্ণন¶
Z-অক্ষের চারপাশে ঘূর্ণন সম্পাদন করুন যদি দুটো কিউবিট \(\left|11\right\rangle\) অবস্থায় থাকে। এম এস বি কিংবা এল এস বি কে নিয়ন্ত্রিত বিট হিসেবে দেখলেও ম্যাট্রিক্সটা একই থাকে।
[48]:
qc = QuantumCircuit(q)
qc.cp(pi/2,q[0], q[1])
qc.draw()
[48]:
q60_0: ─■─────── │P(π/2) q60_1: ─■───────
[49]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[49]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+1.j]])
কন্ট্রোল্ড \(u\) ঘূর্ণন¶
Perform controlled-\(u\) rotation on the target qubit if the control qubit (here LSB) is \(\left|1\right\rangle\).
[53]:
qc = QuantumCircuit(q)
qc.cu(pi/2, pi/2, pi/2, 0, q[0], q[1])
qc.draw()
[53]:
q60_0: ─────────■────────── ┌────────┴─────────┐ q60_1: ┤ U(π/2,π/2,π/2,0) ├ └──────────────────┘
[54]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[54]:
array([[ 1. +0.j , 0. +0.j , 0. +0.j , 0. +0.j ],
[ 0. +0.j , 0.707+0.j , 0. +0.j , 0. -0.707j],
[ 0. +0.j , 0. +0.j , 1. -0.j , 0. +0.j ],
[ 0. +0.j , 0. +0.707j, 0. +0.j , -0.707+0.j ]])
অদলবদল (সোয়াপ) যুক্তিবর্তনী (গেইট)¶
অদলবদল (সোয়াপ) যুক্তিবর্তনী দু'টি কিউবিট বিনিময় করে। একক দিকরাশিকে এটি এভাবে পরিবর্তন করে
যা এই প্রকার একটি ম্যাট্রিক্স উপস্থাপনা দেয়
[55]:
qc = QuantumCircuit(q)
qc.swap(q[0], q[1])
qc.draw()
[55]:
q60_0: ─X─ │ q60_1: ─X─
[56]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[56]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]])
তিন-কিউবিট যুক্তিবর্তনী (গেইট)¶
সর্বাধিক ব্যবহৃত তিন-কিউবিট যুক্তিবর্তনী দু'টি আছে। তিন কিউবিটের জন্য, একক দিকরাশিকে এভাবে ক্রম করা হয়
বিটস্ট্রিং এ যা পুর্ণসংখ্যা আকারে প্রকাশ করা যাবে \(0,1,2,\cdots, 7\)। এইক্ষেত্রে Qiskit টেন্সর গুণনের সবচেয়ে ডানপাশকে প্রথম কিউবিট হিসেবে এবং সবচেয়ে বামপাশকে তৃতীয় কিউবিট হিসেবে বিবেচনা করেঃ:
টফোলি যুক্তিবর্তনী (গেইট) (\(ccx\) যুক্তিবর্তনী (গেইট))¶
টফোলি যুক্তিবর্তনী <https://en.wikipedia.org/wiki/Quantum_logic_gate#Toffoli_(CCNOT)_gate>__ তৃতীয় কিউবিটকে পালটায় যদি প্রথম দুটো কিউবিট (এল এস বি) দুটই \(\left|1\right\rangle\):
টফোলি যুক্তিবর্তনীর ম্যাট্রিক্স রূপ হচ্ছে
[57]:
q = QuantumRegister(3)
[58]:
qc = QuantumCircuit(q)
qc.ccx(q[0], q[1], q[2])
qc.draw()
[58]:
q105_0: ──■── │ q105_1: ──■── ┌─┴─┐ q105_2: ┤ X ├ └───┘
[59]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[59]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])
কন্ট্রোল্ড অদলবদল (সোয়াপ) যুক্তিবর্তনী (গেইট) (ফ্রেডকিন যুক্তিবর্তনী (গেইট))¶
ফ্রেডকিন যুক্তিবর্তনী <https://en.wikipedia.org/wiki/Quantum_logic_gate#Fredkin_(CSWAP)_gate>`__, অথবা নিয়ন্ত্রিত অদলবদল (সোয়াপ) যুক্তিবর্তনী (গেইট), যা দ্বিতীয় এবং তৃতীয় কিউবিটের জায়গা নিজেদের মধ্যে পরিবর্তন করে যদি প্রথম কিউবিট (এলএসবি) \(\left|1\right\rangle\) হয়:
ফ্রেডকিন যুক্তিবর্তনীর ম্যাট্রিক্স রূপ হচ্ছে
[60]:
qc = QuantumCircuit(q)
qc.cswap(q[0], q[1], q[2])
qc.draw()
[60]:
q105_0: ─■─ │ q105_1: ─X─ │ q105_2: ─X─
[61]:
job = backend.run(transpile(qc, backend))
job.result().get_unitary(qc, decimals=3)
[61]:
array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.-0.j]])
অনৈকিক ক্রিয়াকলাপ (অপারেশন)¶
এখন আমরা কোয়ান্টাম বর্তনীর সকম একক কার্যক্রম সংক্রান্ত যুক্তিবর্তনীর সাথে পরিচিত ফলে কোয়ান্টাম বর্তনীর নন-ইউনিটারী কার্যক্রমও আমরা সদ্য পরিচিত হওয়া যুক্তিবর্তনী দিয়ে করতে পারব। এই নন-ইউনিটারি কার্যক্রমের মধ্যে আছে মেজারমেন্টস, কিউবিটকে প্রারম্ভিক অবস্থায় ফিরিয়ে আনা এবং ক্লাসিকাল শর্তাধীন কার্যক্রম (অপারেশনস)।
[62]:
q = QuantumRegister(1)
c = ClassicalRegister(1)
পরিমাপ¶
We don’t have access to all the information when we make a measurement in a quantum computer. The quantum state is projected onto the standard basis. Below are two examples showing a circuit that is prepared in a basis state and the quantum computer prepared in a superposition state.
[63]:
qc = QuantumCircuit(q, c)
qc.measure(q, c)
qc.draw()
[63]:
┌─┐ q124: ┤M├ └╥┘ c0: 1/═╩═ 0
[64]:
backend = BasicAer.get_backend('qasm_simulator')
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[64]:
{'0': 1024}
এই সিমুলেটর ভবিষ্যদ্বাণী করে যে ১০০ শতাংশ বার ধ্রুপদি রেজিস্টার ০ দেবে।
[65]:
qc = QuantumCircuit(q, c)
qc.h(q)
qc.measure(q, c)
qc.draw()
[65]:
┌───┐┌─┐ q124: ┤ H ├┤M├ └───┘└╥┘ c0: 1/══════╩═ 0
[66]:
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[66]:
{'1': 532, '0': 492}
এই সিমুলেটর ভবিষ্যদ্বাণী করে যে সময় ৫০ শতাংশ সময় ধ্রুপদি রেজিস্টার ০ কিংবা ১ মান দেয়।
পুনস্থাপন (রিসেট)¶
কিউবিটগুলকে `পূর্বাবস্থা (রিসেট)`
অর্থাৎ \(\left|0\right\rangle\) অবস্থায় করা সম্ভব গণনা চলাকালীন। মনে রাখবেন যে `পূর্বাবস্থা (রিসেট)`
কিন্তু কোনও যুক্তিবর্তনী (গেইট) নয়, যেহেতু সেটা অপরিবর্তনীয়।
[67]:
qc = QuantumCircuit(q, c)
qc.reset(q[0])
qc.measure(q, c)
qc.draw()
[67]:
┌─┐ q124: ─|0>─┤M├ └╥┘ c0: 1/══════╩═ 0
[68]:
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[68]:
{'0': 1024}
[69]:
qc = QuantumCircuit(q, c)
qc.h(q)
qc.reset(q[0])
qc.measure(q, c)
qc.draw()
[69]:
┌───┐ ┌─┐ q124: ┤ H ├─|0>─┤M├ └───┘ └╥┘ c0: 1/═══════════╩═ 0
[70]:
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[70]:
{'0': 1024}
এইখানে আমরা দেখতে পাচ্ছি যে, সিমুলেটরটি শতভাগ ০ অবস্থার ফলাফল ভবিষ্যৎবাণী করে।.
শর্তাধীন কার্যক্রম¶
ধ্রুপদী রেজিস্টারের অবস্থা শর্তাধীন কার্যক্রম দ্বারা করা সম্ভব।
[71]:
qc = QuantumCircuit(q, c)
qc.x(q[0]).c_if(c, 0)
qc.measure(q,c)
qc.draw()
[71]:
┌───┐ ┌─┐ q124: ─┤ X ├─┤M├ └─╥─┘ └╥┘ ┌──╨──┐ ║ c0: 1/╡ 0x0 ╞═╩═ └─────┘ 0
এখানে ধ্রুপদি বিট সম সময় ০ মান ধারণ করে তাই তার কিউবিটের অবস্থা সবসময় উল্টানো থাকে।
[72]:
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[72]:
{'1': 1024}
[73]:
qc = QuantumCircuit(q, c)
qc.h(q)
qc.measure(q,c)
qc.x(q[0]).c_if(c, 0)
qc.measure(q,c)
qc.draw()
[73]:
┌───┐┌─┐ ┌───┐ ┌─┐ q124: ┤ H ├┤M├─┤ X ├─┤M├ └───┘└╥┘ └─╥─┘ └╥┘ ║ ┌──╨──┐ ║ c0: 1/══════╩═╡ 0x0 ╞═╩═ 0 └─────┘ 0
[74]:
job = backend.run(transpile(qc, backend))
job.result().get_counts(qc)
[74]:
{'1': 1024}
এখানে ধ্রুপদি বিটের প্রথম পরিমাপ এলোপাতাড়ি হয় কিন্তু কিউবিটের মধ্যে শর্তাধীন ক্রিয়াকলাপের মান স্থীরিকরনভাবেই \(\left|1\right\rangle\) লেখা যায়।
স্বেচ্ছাচারি সূচনা¶
কিভাবে আমরা কোয়ান্টাম রেজিস্টারকে ইচ্ছামুলক অবস্থা থেকে সুচনা করতে পারি? যেকোন \(n\) কিউবিট অবস্থাকে দিকারাশির \(2^n\) মান দ্বারা প্রকাশ করা সম্ভব, যেখানে মানগুলোর বর্গের যোগফল হবে ১। উদাহরনস্বরূপ, নিচে একটি তিন-কিউবিটের অবস্থা বিবেচনা করা হল:
[79]:
# Initializing a three-qubit quantum state
import math
desired_vector = [
1 / math.sqrt(16) * complex(0, 1),
1 / math.sqrt(8) * complex(1, 0),
1 / math.sqrt(16) * complex(1, 1),
0,
0,
1 / math.sqrt(8) * complex(1, 2),
1 / math.sqrt(16) * complex(1, 0),
0]
q = QuantumRegister(3)
qc = QuantumCircuit(q)
qc.initialize(desired_vector, [q[0],q[1],q[2]])
qc.draw()
[79]:
┌───────────────────────────────────────────────────────────────────┐ q233_0: ┤0 ├ │ │ q233_1: ┤1 Initialize(0.25j,0.35355,0.25+0.25j,0,0,0.35355+0.70711j,0.25,0) ├ │ │ q233_2: ┤2 ├ └───────────────────────────────────────────────────────────────────┘
[80]:
backend = BasicAer.get_backend('statevector_simulator')
job = backend.run(transpile(qc, backend))
qc_state = job.result().get_statevector(qc)
qc_state
[80]:
array([1.52655666e-16+2.50000000e-01j, 3.53553391e-01+5.55111512e-17j,
2.50000000e-01+2.50000000e-01j, 0.00000000e+00+0.00000000e+00j,
0.00000000e+00+0.00000000e+00j, 3.53553391e-01+7.07106781e-01j,
2.50000000e-01-9.02056208e-17j, 0.00000000e+00+0.00000000e+00j])
বিশ্বস্ততা দুটো অবস্থার মান সমান কিনা চেক করার জন্য গুরুত্বপূর্ণ। বিশুদ্ধ কোয়ান্টাম অবস্থার \(\left|\psi_1\right\rangle\) এবং \(\left|\psi_2\right\rangle\), এদের বিশ্বস্ততা হল
পরিমাপণ সুক্ষতা \(1\) হবে কেবল এবং কেবলমাত্র যদি দুইটি দশা সমান থাকে।
[81]:
state_fidelity(desired_vector,qc_state)
[81]:
1.0000000000000004
পরবর্তী ব্যাখাঃ:¶
কিভাবে একটি প্রত্যাশিত ফলাফল পাওয়া যাবে? বিভিন্ন উপায় আছে। Qiskit, Shende et al প্রস্তাবিত পদ্ধতি অনুসরণ করে। এইক্ষেত্রে, আমাদের প্রত্যাশিত অবস্থার মান পুর্বেই কোয়ান্টাম রেজিস্টারে অনুমান করে নেয়া হয় এবং বর্তনী তৈরী করা হয় যা একে \(\left|00..0\right\rangle\) অবস্থায় নিয়ে যায়। ফলে বর্তনীর প্রারম্ভিক অবস্থা উল্টো হয়।
একটি কোয়ান্টাম অবস্থা কে শুন্য অবস্থায় নিয়ে গাণিতিক কার্যক্রম সম্পাদন করতে হবে, আমাদের বেশ কয়েকবার একটি একটি করে পরিসাংখ্যিক যোগাযোগমুক্ত (ডিজএনট্যাঙ্গেলড) কিউবিট কে হিসেব করতে হয়। আমরা জানি যেকোন কিউবিটের অবস্থা \(\left|\rho\right\rangle\) থেকে \(\left|0\right\rangle\) প্রকাশ করা যাবে। এর জন্য প্রয়োজন একটি \(\phi\) ডিগ্রী পরিমাণ Z অক্ষ ঘিরে আবর্তন ও এরপর \(\theta\)- ডিগ্রী Y- অক্ষ বরাবর আবর্তন:
যেহেতু আমরা এখন ১টির বদলে \(n\) সংখ্যক কিউবিট নিয়ে কাজ করছি, আমাদের অবশ্যই সর্বনিম্ন গুরুত্বের বিট (এলএসবি) আলাদা করার জন্য অবস্থা দিকরাশিকে (স্টেট ভেক্টর) গুণণীয়কে বিভক্ত করতে হবে।
এখন একক কিউবিটের সকল অবস্থাসমূহ \(\left|\rho_0\right\rangle, ..., \left|\rho_{2^{n-1}-1}\right\rangle\), উপরিউক্ত প্রত্যেক সমীকরণের জন্য সঠিক \(\phi\) এবং \(\theta\) কোণ বের করার মাধ্যমে \(\left|0\right\rangle\)- এ রূপান্তর করা সম্ভব। যা একযোগে সকল অবস্থায় প্রয়োগ করলে তা নিম্নলিখিত ঐকিকের (ইউনিটারি) সমান হবে, যা সর্বনিম্ন গুরুত্বের বিটকে (এলএসবি) বিচ্ছিন্ন (ডিসএন্ট্যাঙ্গাল) করে দেয়:
হেতু,
U can be implemented as a "quantum multiplexor" gate, since it is a block diagonal matrix. In the quantum multiplexor formalism, a block diagonal matrix of size \(2^n \times 2^n\), and consisting of \(2^s\) blocks, is equivalent to a multiplexor with \(s\) select qubits and \(n-s\) data qubits. Depending on the state of the select qubits, the corresponding blocks are applied to the data qubits. A multiplexor of this kind can be implemented after recursive decomposition to primitive gates of cx, rz and ry.
[82]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.20.2 |
qiskit-aer | 0.10.4 |
qiskit-ignis | 0.7.1 |
qiskit-ibmq-provider | 0.19.1 |
qiskit | 0.36.2 |
qiskit-optimization | 0.3.2 |
qiskit-machine-learning | 0.4.0 |
System information | |
Python version | 3.10.4 |
Python compiler | MSC v.1916 64 bit (AMD64) |
Python build | main, Mar 30 2022 08:38:02 |
OS | Windows |
CPUs | 6 |
Memory (Gb) | 15.869640350341797 |
Sat May 28 10:03:32 2022 Eastern Daylight Time |
This code is a part of Qiskit
© Copyright IBM 2017, 2022.
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.
[ ]: