Japanese

English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

# 高度な回路¶

[1]:

import numpy as np
from qiskit import *


## 抽象(Opaque) ゲート¶

[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         ├
└──────────┘

## 複合(Composite) ゲート¶

[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          ├
└───┘└───────────┘

[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]:


[8]:

print(qc.parameters)

ParameterView([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()


[13]:

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))

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


### コンポジション¶

パラメータ回路は標準の QuantumCircuit (複数) と同様、合成できます。一般的に、２つのパラメータ回路を合成する時には、結果の回路は入力回路のパラメータの結合としてパラメータ化されます。

しかしながら、パラメータ名は与えられた回路でユニークである必要があります。ターゲットの回路にすでに存在しているパラメータを追加しようとする時: 仮にソースとターゲットが同じ Parameter インスタンスを共有する場合には、パラメータは同じと見なされ結合されます。もし、ソースとターゲットが異なる Parameter インスタンスの場合にはエラーとなります。

[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           ├──────────────
└────────────┘


[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


### Version Information

Qiskit SoftwareVersion
qiskit-terra0.19.0.dev0+be0ed5f
qiskit-aer0.8.2
qiskit-ignis0.6.0
qiskit-ibmq-provider0.16.0.dev0+4e20edc
System information
Python3.7.7 (default, May 6 2020, 04:59:01) [Clang 4.0.1 (tags/RELEASE_401/final)]
OSDarwin
CPUs6
Memory (Gb)32.0
Sat Jul 31 01:02:16 2021 EDT

### This code is a part of Qiskit

[ ]: