LoginSignup
3
1

More than 1 year has passed since last update.

Parameterを利用したBuilder構文

Last updated at Posted at 2021-06-02

はじめに

Builder構文はParameterクラスと併用することで威力を発揮する構文です。この記事ではParameterクラスを使ったBuilder構文の書き方を紹介したいと思います。

まず、Qiskit Pulseを動かすために必要な記述をまとめておきます。

import numpy as np
from qiskit import QuantumCircuit, transpile, Aer, IBMQ
from qiskit.visualization import *
from qiskit.circuit import Gate
from qiskit.circuit import Parameter
from qiskit import pulse

IBMQ.load_account()

provider = IBMQ.get_provider(hub='ibm-q', group='open', project='main')
backend = provider.get_backend('ibmq_armonk')
backend_defaults = backend.defaults()
backend_config = backend.configuration()

Parameterクラスを使ったBuilder構文

Parameterクラスは変数パラメーターのためのクラスとなります。

これだけだとよくわからないのでソースコードを記述してみます。
試しにQiskit Textbookにある、周波数の校正のソースコードを例にして紹介したいと思います。

import numpy as np

GHz = 1.0e9 # Gigahertz
MHz = 1.0e6 # Megahertz

# サンプル数は16の倍数である必要があります
def get_closest_multiple_of_16(num):
    return int(num + 8 ) - (int(num + 8 ) % 16)

qubit=0
mem_slot=0

# 1 周波数領域の決定
center_frequency_Hz = backend_defaults.qubit_freq_est[qubit] 
frequency_span_Hz = 40 * MHz
frequency_step_Hz = 1 * MHz
frequency_min = center_frequency_Hz - frequency_span_Hz / 2
frequency_max = center_frequency_Hz + frequency_span_Hz / 2
frequencies_GHz = np.arange(frequency_min / GHz, 
                            frequency_max / GHz, 
                            frequency_step_Hz / GHz)

# 2 パルスに必要な値の設定
drive_sigma_sec = 0.075e-6
drive_duration_sec = drive_sigma_sec * 8
drive_amp = 0.05

# 3 Parameterクラスの定義
freq = Parameter('freq')
# 4 Builder構文
with pulse.build(backend=backend, default_alignment='sequential') as parametrized_sched:
    # 5 Parameterクラスで定義した変数を周波数に設定
    pulse.set_frequency(freq, pulse.drive_channel(qubit))
    pulse.play(pulse.Gaussian(duration=get_closest_multiple_of_16(pulse.seconds_to_samples(drive_duration_sec)),
                              amp=drive_amp,
                              sigma=pulse.seconds_to_samples(drive_sigma_sec),
                              name='spect_pulse'), pulse.drive_channel(qubit))
    pulse.measure(qubits=[qubit], registers=[pulse.MemorySlot(mem_slot)])

# 6 周波数領域とParameterクラスを使って定義したScheduleをバインド
frequencies_Hz = frequencies_GHz*GHz
schedules = [parametrized_sched.assign_parameters({freq: f}, inplace=False) for f in frequencies_Hz]

schedules[0].draw(backend=backend)

無題.png

  1. 周波数領域の決定
    sweepする周波数を設定します。ここでは中心となる周波数の値をbackend_defaultsから取得しています。
  2. パルスに必要な値の設定
    パルスに必要な値の設定を行います。
  3. Parameterクラスの定義
    Parameterクラスを定義します。ここでは変数となる値freqをクラスに渡しています。
  4. Builder構文
    Builder構文を利用してScheduleを作成します。
  5. Parameterクラスで定義した変数を周波数に設定
    set_frequency()を利用してScheduleで利用する周波数を定義します。ここでは実際の値を定義するのではなくParameterクラスを定義しておきます。
  6. 周波数領域とParameterクラスを使って定義したScheduleをバインド
    ここではじめて実際の周波数の値とScheduleを紐づけることになります。

今回の例以外にもParameterクラスに振幅などを変数にしてsweepさせることもできますし、Parameterクラスを複数使用することもできます。

freq = Parameter('freq')
amp = Parameter('amp')
with pulse.build(backend=backend, default_alignment='sequential') as parametrized_sched2:
    pulse.set_frequency(freq, pulse.drive_channel(qubit))
    pulse.play(pulse.Gaussian(duration=get_closest_multiple_of_16(pulse.seconds_to_samples(drive_duration_sec)),
                              amp=amp,
                              sigma=pulse.seconds_to_samples(drive_sigma_sec),
                              name='spect_pulse'), pulse.drive_channel(qubit))
    pulse.measure(qubits=[qubit], registers=[pulse.MemorySlot(mem_slot)])

何が便利かというと、ここで定義したScheduleを似た実験で使いまわすことができます。例えば低エネルギーと高エネルギーで周波数をスイープしたい場合、上記のSchedule「parametrized_sched2」を以下のように再利用できます。

# 周波数領域と振幅(low power)をParameterクラスを使って定義したScheduleとバインド
frequencies_Hz = frequencies_GHz*GHz
schedules = [parametrized_sched2.assign_parameters({freq: f, amp: 0.1}, inplace=False) for f in frequencies_Hz]
# 周波数領域と振幅(high power)をParameterクラスを使って定義したScheduleとバインド
frequencies_Hz = frequencies_GHz*GHz
schedules = [parametrized_sched2.assign_parameters({freq: f, amp: 1.0}, inplace=False) for f in frequencies_Hz]

まとめ

この記事ではParameterを利用したBuilder構文について紹介しました。Parameterクラスを利用することでScheduleをfor文の中に入れて制御する必要がなくなりソースコードをすっきりさせることができます。また変数を制御フロー(Schedule)と別に定義できることから、Scheduleを使いまわすことが可能で再利用性が高くなっています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1