নোট
এই পৃষ্ঠাটি tutorials/circuits_advanced/1_advanced_circuits.ipynb থেকে উৎপন্ন হয়েছে।
উন্নত সার্কিটসমূহ¶
[1]:
import numpy as np
from qiskit import *
অস্বচ্ছ গেটসমূহ¶
[2]:
from qiskit.circuit import Gate
my_gate = Gate(name='my_gate', num_qubits=2, params=[])
[3]:
qr = QuantumRegister(3, 'q')
circ = QuantumCircuit(qr)
circ.append(my_gate, [qr[0], qr[1]])
circ.append(my_gate, [qr[1], qr[2]])
circ.draw()
[3]:
┌──────────┐ q_0: ┤0 ├──────────── │ my_gate │┌──────────┐ q_1: ┤1 ├┤0 ├ └──────────┘│ my_gate │ q_2: ────────────┤1 ├ └──────────┘
সংমিশ্রিত গেটসমূহ¶
[5]:
# Build a sub-circuit
sub_q = QuantumRegister(2)
sub_circ = QuantumCircuit(sub_q, name='sub_circ')
sub_circ.h(sub_q[0])
sub_circ.crz(1, sub_q[0], sub_q[1])
sub_circ.barrier()
sub_circ.id(sub_q[1])
sub_circ.u(1, 2, -2, sub_q[0])
# Convert to a gate and stick it into an arbitrary place in the bigger circuit
sub_inst = sub_circ.to_instruction()
qr = QuantumRegister(3, 'q')
circ = QuantumCircuit(qr)
circ.h(qr[0])
circ.cx(qr[0], qr[1])
circ.cx(qr[1], qr[2])
circ.append(sub_inst, [qr[1], qr[2]])
circ.draw()
[5]:
┌───┐ q_0: ┤ H ├──■──────────────────── └───┘┌─┴─┐ ┌───────────┐ q_1: ─────┤ X ├──■──┤0 ├ └───┘┌─┴─┐│ sub_circ │ q_2: ──────────┤ X ├┤1 ├ └───┘└───────────┘
বিমূর্ততার উচ্চ স্তরে সার্কিট ডিজাইনে সাহায্যে করার জন্য to_instruction
- এ রূপান্তর করার পরে সার্কিটগুলি সাথে সাথে ডিকম্পোজ হয় না।
[6]:
decomposed_circ = circ.decompose() # Does not modify original circuit
decomposed_circ.draw()
[6]:
┌─────────┐ q_0: ┤ U2(0,π) ├──■───────────────────────────────────── └─────────┘┌─┴─┐ ┌───┐ ░ ┌───────────┐ q_1: ───────────┤ X ├──■──┤ H ├────■─────░─┤ U(1,2,-2) ├ └───┘┌─┴─┐└───┘┌───┴───┐ ░ └───┬───┬───┘ q_2: ────────────────┤ X ├─────┤ Rz(1) ├─░─────┤ I ├──── └───┘ └───────┘ ░ └───┘
প্যারামিটারাইজড সার্কিটসমূহ¶
[7]:
from qiskit.circuit import Parameter
theta = Parameter('θ')
n = 5
qc = QuantumCircuit(5, 1)
qc.h(0)
for i in range(n-1):
qc.cx(i, i+1)
qc.barrier()
qc.rz(theta, range(5))
qc.barrier()
for i in reversed(range(n-1)):
qc.cx(i, i+1)
qc.h(0)
qc.measure(0, 0)
qc.draw('mpl')
[7]:

We can inspect the circuit’s parameters
[8]:
print(qc.parameters)
ParameterView([Parameter(θ)])
প্যারামিটারের মানগুলি একত্রিত করা¶
সার্কিটটিকে ব্যাকএন্ডে প্রেরণের আগে সমস্ত প্যারামিটারগুলি আবদ্ধ করা দরকার। এটি ২ ভাবে করা যায় - bind_parameters
ব্যবহার করে যাহা একটি dictionary (Python প্রোগ্রামিং এ একটি তথ্য কাঠামো) সাহায্যে Parameter
গুলোকে তাদের উপযুক্ত মান এ একত্রিত করে এবং প্রতিটি প্যারমিটারের সাথে সম্পর্কিত মান দ্বারা প্রতিস্থাপিত করে একটি নতুন সার্কিট ফিরিয়ে দেয়। এখানে আংশিক একত্রিত করা সম্ভব কিন্তু সেটা করলে যেই সার্কিট পাওয়া যাবে তাতে `Parameter
সম্পর্কিত মান প্রতিস্থাপিত করা থাকবে না।
[9]:
import numpy as np
theta_range = np.linspace(0, 2 * np.pi, 128)
circuits = [qc.bind_parameters({theta: theta_val})
for theta_val in theta_range]
circuits[-1].draw()
[9]:
┌───┐ ░ ┌────────┐ ░ ┌───┐┌─┐ q_0: ┤ H ├──■──────────────────░─┤ Rz(2π) ├─░──────────────────■──┤ H ├┤M├ └───┘┌─┴─┐ ░ ├────────┤ ░ ┌─┴─┐└───┘└╥┘ q_1: ─────┤ X ├──■─────────────░─┤ Rz(2π) ├─░─────────────■──┤ X ├──────╫─ └───┘┌─┴─┐ ░ ├────────┤ ░ ┌─┴─┐└───┘ ║ q_2: ──────────┤ X ├──■────────░─┤ Rz(2π) ├─░────────■──┤ X ├───────────╫─ └───┘┌─┴─┐ ░ ├────────┤ ░ ┌─┴─┐└───┘ ║ q_3: ───────────────┤ X ├──■───░─┤ Rz(2π) ├─░───■──┤ X ├────────────────╫─ └───┘┌─┴─┐ ░ ├────────┤ ░ ┌─┴─┐└───┘ ║ q_4: ────────────────────┤ X ├─░─┤ Rz(2π) ├─░─┤ X ├─────────────────────╫─ └───┘ ░ └────────┘ ░ └───┘ ║ c: 1/═══════════════════════════════════════════════════════════════════╩═ 0
[12]:
backend = BasicAer.get_backend('qasm_simulator')
job = backend.run(transpile(circuits, backend))
counts = job.result().get_counts()
উদাহরণরত সার্কিটে, আমরা পাঁচ-কিউবিট বিভক্ত অবস্থায় একটি গ্লোবাল \(R_z(\theta)\) প্রয়োগ করি, সুতরাং কিউবিট-0 তে \(5\theta\) অবস্থাতে ওসিলেশন দেখার সম্ভাবনা বাড়ে।
[13]:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
ax.plot(theta_range, list(map(lambda c: c.get('0', 0), counts)), '.-', label='0')
ax.plot(theta_range, list(map(lambda c: c.get('1', 0), counts)), '.-', label='1')
ax.set_xticks([i * np.pi / 2 for i in range(5)])
ax.set_xticklabels(['0', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'], fontsize=14)
ax.set_xlabel('θ', fontsize=14)
ax.set_ylabel('Counts', fontsize=14)
ax.legend(fontsize=14)
[13]:
<matplotlib.legend.Legend at 0x7f8fcb307710>

সংকলন ব্যয় কমানো¶
কিছু ক্ষেত্রে বাঁধাই না করা প্যারামিটার-যুক্ত সার্কিটের সংকলনে দেখা যায় যে সেটি বাঁধাই করা সার্কিট এর চেয়েও দ্রুত সংকলিত হচ্ছে।
[14]:
import time
from itertools import combinations
from qiskit.compiler import assemble
from qiskit.test.mock import FakeVigo
start = time.time()
qcs = []
theta_range = np.linspace(0, 2*np.pi, 32)
for n in theta_range:
qc = QuantumCircuit(5)
for k in range(8):
for i,j in combinations(range(5), 2):
qc.cx(i,j)
qc.rz(n, range(5))
for i,j in combinations(range(5), 2):
qc.cx(i,j)
qcs.append(qc)
compiled_circuits = transpile(qcs, backend=FakeVigo())
qobj = assemble(compiled_circuits, backend=FakeVigo())
end = time.time()
print('Time compiling over set of bound circuits: ', end-start)
Time compiling over set of bound circuits: 2.4267938137054443
[16]:
start = time.time()
qc = QuantumCircuit(5)
theta = Parameter('theta')
for k in range(8):
for i,j in combinations(range(5), 2):
qc.cx(i,j)
qc.rz(theta, range(5))
for i,j in combinations(range(5), 2):
qc.cx(i,j)
transpiled_qc = transpile(qc, backend=FakeVigo())
qobj = assemble([transpiled_qc.bind_parameters({theta: n})
for n in theta_range], backend=FakeVigo())
end = time.time()
print('Time compiling over parameterized circuit, then binding: ', end-start)
Time compiling over parameterized circuit, then binding: 1.4472951889038086
গঠন(Composition)¶
সাধারণ "কোয়ান্টাম সার্কিট" যেভাবে বানানো যায় ঠিক সেইভাবে প্যারামিটার-যুক্ত সার্কিটগুলো কেও বানানো যায়। যদি একটি প্যারামিটার-যুক্ত সার্কিট দুটি ভিন্ন প্যারামিটার-যুক্ত সার্কিট দ্বারা গঠিত হয়ে থাকে তাহলে সেটির প্যারামিটারগুলির মান সেই দুটি সার্কিট এর মিলন দ্বারা পরিচালিত হবে।
কিন্তু প্যারামিটার এর নাম একটি সার্কিটে অনন্য হাওয়া দরকার। যদি উত্স এবং লক্ষ্য সার্কিটগুলি একই প্যারামিটার
উদাহরণটি ভাগ করে তাহলে একই নামের প্যারামিটার সার্কিটিতে যোগ করবার সময়ে সেগুলি একটাই প্যারামিটার হিসাবে ধরা হবে। তা না হলে ত্রুটি উত্থাপিত হবে।
[17]:
phi = Parameter('phi')
sub_circ1 = QuantumCircuit(2, name='sc_1')
sub_circ1.rz(phi, 0)
sub_circ1.rx(phi, 1)
sub_circ2 = QuantumCircuit(2, name='sc_2')
sub_circ2.rx(phi, 0)
sub_circ2.rz(phi, 1)
qc = QuantumCircuit(4)
qr = qc.qregs[0]
qc.append(sub_circ1.to_instruction(), [qr[0], qr[1]])
qc.append(sub_circ2.to_instruction(), [qr[0], qr[1]])
qc.append(sub_circ2.to_instruction(), [qr[2], qr[3]])
print(qc.draw())
# The following raises an error: "QiskitError: 'Name conflict on adding parameter: phi'"
# phi2 = Parameter('phi')
# qc.u3(0.1, phi2, 0.3, 0)
┌────────────┐┌────────────┐
q_0: ┤0 ├┤0 ├
│ sc_1(phi) ││ sc_2(phi) │
q_1: ┤1 ├┤1 ├
├────────────┤└────────────┘
q_2: ┤0 ├──────────────
│ sc_2(phi) │
q_3: ┤1 ├──────────────
└────────────┘
একটি পৃথক প্যারামিটারাইজেশনের অধীনে একটি সাবসারকিট প্রবেশ করানো to_instruction
পদ্ধতিটির চ্ছিক বিকল্প``parameter_map`` দ্বারা সম্ভব যাহা নতুন পরামিতি দ্বারা প্রতিস্থাপিত উত্স পরামিতি সহ নির্দেশাবলী উত্পন্ন করবে।
[18]:
p = Parameter('p')
qc = QuantumCircuit(3, name='oracle')
qc.rz(p, 0)
qc.cx(0, 1)
qc.rz(p, 1)
qc.cx(1, 2)
qc.rz(p, 2)
theta = Parameter('theta')
phi = Parameter('phi')
gamma = Parameter('gamma')
qr = QuantumRegister(9)
larger_qc = QuantumCircuit(qr)
larger_qc.append(qc.to_instruction({p: theta}), qr[0:3])
larger_qc.append(qc.to_instruction({p: phi}), qr[3:6])
larger_qc.append(qc.to_instruction({p: gamma}), qr[6:9])
print(larger_qc.draw())
print(larger_qc.decompose().draw())
┌────────────────┐
q24_0: ┤0 ├
│ │
q24_1: ┤1 oracle(theta) ├
│ │
q24_2: ┤2 ├
└┬──────────────┬┘
q24_3: ─┤0 ├─
│ │
q24_4: ─┤1 oracle(phi) ├─
│ │
q24_5: ─┤2 ├─
┌┴──────────────┴┐
q24_6: ┤0 ├
│ │
q24_7: ┤1 oracle(gamma) ├
│ │
q24_8: ┤2 ├
└────────────────┘
┌───────────┐
q24_0: ┤ Rz(theta) ├──■─────────────────────────────────
└───────────┘┌─┴─┐┌───────────┐
q24_1: ─────────────┤ X ├┤ Rz(theta) ├──■───────────────
└───┘└───────────┘┌─┴─┐┌───────────┐
q24_2: ───────────────────────────────┤ X ├┤ Rz(theta) ├
┌─────────┐ └───┘└───────────┘
q24_3: ─┤ Rz(phi) ├───■─────────────────────────────────
└─────────┘ ┌─┴─┐ ┌─────────┐
q24_4: ─────────────┤ X ├─┤ Rz(phi) ├───■───────────────
└───┘ └─────────┘ ┌─┴─┐ ┌─────────┐
q24_5: ───────────────────────────────┤ X ├─┤ Rz(phi) ├─
┌───────────┐ └───┘ └─────────┘
q24_6: ┤ Rz(gamma) ├──■─────────────────────────────────
└───────────┘┌─┴─┐┌───────────┐
q24_7: ─────────────┤ X ├┤ Rz(gamma) ├──■───────────────
└───┘└───────────┘┌─┴─┐┌───────────┐
q24_8: ───────────────────────────────┤ X ├┤ Rz(gamma) ├
└───┘└───────────┘
[19]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.19.0.dev0+be0ed5f |
qiskit-aer | 0.8.2 |
qiskit-ignis | 0.6.0 |
qiskit-ibmq-provider | 0.16.0.dev0+4e20edc |
System information | |
Python | 3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)] |
OS | Darwin |
CPUs | 6 |
Memory (Gb) | 32.0 |
Sat Jul 31 01:02:16 2021 EDT |
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.
[ ]: