ブログ

国家準備の枠にとらわれず考える - Classiqを使って深さの対数正規分布回路を生成する1 

28
7月
,
2022

このノートでは、Classiqプラットフォームを利用して、最近のコーディング・コンペティションで出題された対数正規状態準備問題を解く方法を説明します。この状態準備を生成するための2つの方法と、回路深度1の状態準備を生成するために必要なトリックを検証します。 

すべての量子アルゴリズムのステップ-1

状態の準備は量子計算にとって不可欠な要素であり、ほとんどの量子アプリケーションは、量子レジスタに状態を準備することから始まる。例えば金融では、ポートフォリオ最適化アルゴリズムの一環として、ある資産の価格分布を表すことがある。化学分野では、分子の基底状態の初期推定値であったり、量子機械学習では、分析対象の特徴ベクトルであったりする。

状態準備とは、量子ゲートを用いて量子ビットを初期化し、その測定出力が所望の確率分布に対応するようにすることである。この初期化された状態は、後続の量子回路が計算を実行するために利用することができます。これから説明する対数正規状態は、多くのファイナンス計算でよく使われる初期化状態である。 

対数正規状態準備問題

最近のコーディング・コンペティションでは、競技者は10量子ビット以下を使用して、平均(μ)が0、標準偏差(σ)が0.1の対数正規分布を生成する回路を設計するよう求められました。回路は、0.01以内の誤差で対数正規分布に近似しなければならず、「u」と「CX」のゲートのみを含むことができる。優勝作品は、前述の基準をすべて満たしながら、最も深さの浅い回路となる。

この問題は、我々が設計した4つのコンペティション問題の中で、最も解答が難しく、最も計算が簡単な量子回路であった。競技者にこの問題へのアプローチのヒントを提供するため、量子回路と採用した離散化手法の両方を提出させた。

Classiqでステート・プレパレーションを解く

Classiqで状態準備を生成するには、"StatePreparation "関数を呼び出し、回路の確率、量子ビット数、上限誤差を指定します。最大量子ビット数は10であること、対数正規分布を入力する必要があること、回路の総誤差(対数正規分布を近似する際の数学的誤差と量子回路に変換する際の誤差)が0.01を超えないことが分かっています。これらのパラメータが定義されると、Classiqプラットフォームが量子回路を実装する。以下はClassiqのPython SDKを使ってこの回路を生成するコードですが、Visual Studio CodeのClassiqエクステンションでも同等の回路を生成することができます。 


import classiq
from classiq import ModelDesigner
from classiq.builtin_functions import StatePreparation

# Given variables
TARGET_ERR = 1e-2
SIGMA = 0.1
N_QUBITS = 10

# Calculated probability distribution and error bound
# Set flag to False for unequal partition of the 'x' axis
lognorm_probabilities, _, l2_error_upper_bound, _ = partition(n_qubits=N_QUBITS, flag=True) 

# State preparation parameters
sp_params = StatePreparation(probabilities=lognorm_probabilities, 
                             num_qubits=N_QUBITS, 
                             error_metric={"L2": {"upper_bound": l2_error_upper_bound}})

# Circuit Synthesis
model_designer = ModelDesigner()
model_designer.StatePreparation(params=sp_params)
circuit = model_designer.synthesize()

この問題を解決する鍵は、この分布を実装するアプローチにあります。この問題に対する単純明快な解決策は、分布の平均を中心とする領域の部分集合を選択し、この領域内の利用可能なビン(10量子ビットの場合、210個のビンがある)にわたって離散化を均等に配置し、領域の残りを無視することである。この210ビンの領域内の確率は、対数正規分布に一致するように修正することができます。回路を定義するには、この確率質量関数をClassiqプラットフォームにロードし、エラーしきい値を選択するだけです。この方法に従い、Classiqプラットフォーム(バージョン0.15を使用)は242の深さの回路を実装してくれました。以下のインタラクティブな回路はこちらからご覧いただけます。

インタラクティブ・ビジュアライゼーション

クラシックのロゴ

スクリプトにエラーがありました

トリック

しかし、これには別のアプローチもある。それは、ロードする確率と、結果を計算するために使用する離散化方法である。以前の手法の離散化では、離散化に標準的な線形間隔を利用していた。そのため、望ましい対数正規分布に合うように確率をロードする必要があった。 

では、非線形の離散化間隔を選択した場合はどうなるだろうか?210個のビンの間隔を賢く選択することで、ロードされる確率がすべて同じになる回路を作ることができる。このことは、この量子回路のその後の計算を難しくするかもしれないが、状態準備のセットアップを些細なものにするだろう。これで、量子ビットの測定基底を自由に選択し、その基底で同じ確率で全ての量子ビットを準備することができる。例えば、$|+rangle$基底を選ぶと、ハダマードゲートで全ての量子ビットを準備することができ、深さ1の回路ができる

インタラクティブ・ビジュアライゼーション

クラシックのロゴ

このコンペティションの入賞者が、それぞれ独自の離散化選択法を用いて、このトリックを特定できたことを嬉しく思う。この問題は、効率的な量子回路を生成するには技術的な知識だけでなく、創造性も必要であることを示すために存在する。我々の離散化を生成するために、L2誤差を計算する関数と、L2誤差を考慮した離散化を生成する関数を定義する。以下にコードを追加する。


from scipy.stats import lognorm
from scipy.interpolate import interp1d
npとしてnumpyをインポート

# L2誤差の計算
def l2_error(pmf: np.array, x_grid: np.array, sigma=0.1):
    pmf = np.array(pmf)
    x_grid = np.array(x_grid)
    assert all(pmf >= 0)
    assert np.isclose(sum(pmf), 1)
    assert all(x_grid >= 0)
    assert all(np.diff(x_grid) > 0)
    assert len(pmf) + 1 == len(x_grid).

    n_point = 2 ** 22
    tail_value = (TARGET_ERR / 100) ** 2
    min_x = lognorm.ppf(tail_value, sigma)
    max_x = lognorm.ppf(1 - tail_value, sigma)
    x_middle = np.linspace(min_x, max_x, n_point)
    x_lower_tail = np.linspace(0, min_x, n_point // 1000)
    x_upper_tail = np.linspace(max_x, x_grid[-1], n_point // 1000) if x_grid[-1] > max_x else np.array([])

    x_approx = np.diff(x_grid) / 2 + x_grid[:-1].
    x_approx = np.concatenate(([x_approx[0]], x_approx, [x_approx[-1]))
    pdf_approx = pmf / np.diff(x_grid)
    pdf_approx = np.concatenate(([pdf_approx[0], pdf_approx, [pdf_approx[-1]]))

    fy = interp1d(x_approx, pdf_approx, kind='nearest', assume_sorted=True, fill_value=(0, 0), bounds_error=False).
    x_full = np.concatenate((x_lower_tail[:-1], x_middle, x_upper_tail[1:]))
    approx_pdf = fy(x_full)

    full_pdf = lognorm.pdf(x_full, sigma)
    dx = np.diff(x_full)
    dx = np.append(dx, 0)

    upper_tail_err_2_approx = lognorm.sf(x_full[-1], sigma)
    main_err_2 = sum((full_pdf - approx_pdf) ** 2 * dx)
    err = (upper_tail_err_2_approx + main_err_2) ** 0.5
    err を返す

# 選択した離散化手法に基づく確率分布計算
def partition(n_qubits=10, flag=True):
    ビン = 2 ** n_qubits
    tail_value = (TARGET_ERR / 10) ** 2
    if flag:
        x_discrete = np.linspace(lognorm.ppf(tail_value, SIGMA)、
                               lognorm.ppf(1 - tail_value, SIGMA), bins + 1)
    else:
        x_discrete = lognorm.ppf(np.linspace(tail_value, 1 - tail_value, bins + 1), SIGMA)
    pmf = np.diff(lognorm.cdf(x_discrete, SIGMA))
    pmf = pmf / sum(pmf)
    ERR = l2_error(pmf, x_discrete, sigma=SIGMA)
    マージン = TARGET_ERR - ERR
    マージン > 0
    return tuple(pmf), x_discrete, margin, ERR

競合他社が提供するソリューションとの比較については、こちらをご覧ください。

対数正規分布を超えて

Classiqは状態準備の作成を簡単にします。回路を開始させたい確率を定義すれば、あとはプラットフォームが処理します。Classiqは確率質量関数またはガウス混合として確率を柔軟に定義でき、KL、L1、L2、最大確率、Loss of Fidelityなど、回路の許容誤差を定義する複数の方法を提供します。ガウシアンモーメントを使用した状態準備の実装にClassiqを使用した例と、状態準備にガウシアンモーメントを使用した信用リスク分析アルゴリズムの例をご紹介 します。 

Classiqのステート・プリパレーションは柔軟でプログラムしやすく、学術論文の結果を再現する場合でも、新しい量子アルゴリズムを作成する場合でも、目的の回路を自動的に生成します。Classiqでは "定義するのは簡単だが、実装するのは難しい "と言っています。 Classiqのプラットフォームがお客様の定義した回路を実装します。Classiqの顧客はより高いレベルで仕事をします。Classiqプラットフォームは何十億もの設計空間の中から適切な実装を自動的に見つけます。

Classiqプラットフォームの ライブデモをご予約いただき、実際にご覧いただくか、または 弊社までお問い合わせください。

このノートでは、Classiqプラットフォームを利用して、最近のコーディング・コンペティションで出題された対数正規状態準備問題を解く方法を説明します。この状態準備を生成するための2つの方法と、回路深度1の状態準備を生成するために必要なトリックを検証します。 

すべての量子アルゴリズムのステップ-1

状態の準備は量子計算にとって不可欠な要素であり、ほとんどの量子アプリケーションは、量子レジスタに状態を準備することから始まる。例えば金融では、ポートフォリオ最適化アルゴリズムの一環として、ある資産の価格分布を表すことがある。化学分野では、分子の基底状態の初期推定値であったり、量子機械学習では、分析対象の特徴ベクトルであったりする。

状態準備とは、量子ゲートを用いて量子ビットを初期化し、その測定出力が所望の確率分布に対応するようにすることである。この初期化された状態は、後続の量子回路が計算を実行するために利用することができます。これから説明する対数正規状態は、多くのファイナンス計算でよく使われる初期化状態である。 

対数正規状態準備問題

最近のコーディング・コンペティションでは、競技者は10量子ビット以下を使用して、平均(μ)が0、標準偏差(σ)が0.1の対数正規分布を生成する回路を設計するよう求められました。回路は、0.01以内の誤差で対数正規分布に近似しなければならず、「u」と「CX」のゲートのみを含むことができる。優勝作品は、前述の基準をすべて満たしながら、最も深さの浅い回路となる。

この問題は、我々が設計した4つのコンペティション問題の中で、最も解答が難しく、最も計算が簡単な量子回路であった。競技者にこの問題へのアプローチのヒントを提供するため、量子回路と採用した離散化手法の両方を提出させた。

Classiqでステート・プレパレーションを解く

Classiqで状態準備を生成するには、"StatePreparation "関数を呼び出し、回路の確率、量子ビット数、上限誤差を指定します。最大量子ビット数は10であること、対数正規分布を入力する必要があること、回路の総誤差(対数正規分布を近似する際の数学的誤差と量子回路に変換する際の誤差)が0.01を超えないことが分かっています。これらのパラメータが定義されると、Classiqプラットフォームが量子回路を実装する。以下はClassiqのPython SDKを使ってこの回路を生成するコードですが、Visual Studio CodeのClassiqエクステンションでも同等の回路を生成することができます。 


import classiq
from classiq import ModelDesigner
from classiq.builtin_functions import StatePreparation

# Given variables
TARGET_ERR = 1e-2
SIGMA = 0.1
N_QUBITS = 10

# Calculated probability distribution and error bound
# Set flag to False for unequal partition of the 'x' axis
lognorm_probabilities, _, l2_error_upper_bound, _ = partition(n_qubits=N_QUBITS, flag=True) 

# State preparation parameters
sp_params = StatePreparation(probabilities=lognorm_probabilities, 
                             num_qubits=N_QUBITS, 
                             error_metric={"L2": {"upper_bound": l2_error_upper_bound}})

# Circuit Synthesis
model_designer = ModelDesigner()
model_designer.StatePreparation(params=sp_params)
circuit = model_designer.synthesize()

この問題を解決する鍵は、この分布を実装するアプローチにあります。この問題に対する単純明快な解決策は、分布の平均を中心とする領域の部分集合を選択し、この領域内の利用可能なビン(10量子ビットの場合、210個のビンがある)にわたって離散化を均等に配置し、領域の残りを無視することである。この210ビンの領域内の確率は、対数正規分布に一致するように修正することができます。回路を定義するには、この確率質量関数をClassiqプラットフォームにロードし、エラーしきい値を選択するだけです。この方法に従い、Classiqプラットフォーム(バージョン0.15を使用)は242の深さの回路を実装してくれました。以下のインタラクティブな回路はこちらからご覧いただけます。

インタラクティブ・ビジュアライゼーション

クラシックのロゴ

スクリプトにエラーがありました

トリック

しかし、これには別のアプローチもある。それは、ロードする確率と、結果を計算するために使用する離散化方法である。以前の手法の離散化では、離散化に標準的な線形間隔を利用していた。そのため、望ましい対数正規分布に合うように確率をロードする必要があった。 

では、非線形の離散化間隔を選択した場合はどうなるだろうか?210個のビンの間隔を賢く選択することで、ロードされる確率がすべて同じになる回路を作ることができる。このことは、この量子回路のその後の計算を難しくするかもしれないが、状態準備のセットアップを些細なものにするだろう。これで、量子ビットの測定基底を自由に選択し、その基底で同じ確率で全ての量子ビットを準備することができる。例えば、$|+rangle$基底を選ぶと、ハダマードゲートで全ての量子ビットを準備することができ、深さ1の回路ができる

インタラクティブ・ビジュアライゼーション

クラシックのロゴ

このコンペティションの入賞者が、それぞれ独自の離散化選択法を用いて、このトリックを特定できたことを嬉しく思う。この問題は、効率的な量子回路を生成するには技術的な知識だけでなく、創造性も必要であることを示すために存在する。我々の離散化を生成するために、L2誤差を計算する関数と、L2誤差を考慮した離散化を生成する関数を定義する。以下にコードを追加する。


from scipy.stats import lognorm
from scipy.interpolate import interp1d
npとしてnumpyをインポート

# L2誤差の計算
def l2_error(pmf: np.array, x_grid: np.array, sigma=0.1):
    pmf = np.array(pmf)
    x_grid = np.array(x_grid)
    assert all(pmf >= 0)
    assert np.isclose(sum(pmf), 1)
    assert all(x_grid >= 0)
    assert all(np.diff(x_grid) > 0)
    assert len(pmf) + 1 == len(x_grid).

    n_point = 2 ** 22
    tail_value = (TARGET_ERR / 100) ** 2
    min_x = lognorm.ppf(tail_value, sigma)
    max_x = lognorm.ppf(1 - tail_value, sigma)
    x_middle = np.linspace(min_x, max_x, n_point)
    x_lower_tail = np.linspace(0, min_x, n_point // 1000)
    x_upper_tail = np.linspace(max_x, x_grid[-1], n_point // 1000) if x_grid[-1] > max_x else np.array([])

    x_approx = np.diff(x_grid) / 2 + x_grid[:-1].
    x_approx = np.concatenate(([x_approx[0]], x_approx, [x_approx[-1]))
    pdf_approx = pmf / np.diff(x_grid)
    pdf_approx = np.concatenate(([pdf_approx[0], pdf_approx, [pdf_approx[-1]]))

    fy = interp1d(x_approx, pdf_approx, kind='nearest', assume_sorted=True, fill_value=(0, 0), bounds_error=False).
    x_full = np.concatenate((x_lower_tail[:-1], x_middle, x_upper_tail[1:]))
    approx_pdf = fy(x_full)

    full_pdf = lognorm.pdf(x_full, sigma)
    dx = np.diff(x_full)
    dx = np.append(dx, 0)

    upper_tail_err_2_approx = lognorm.sf(x_full[-1], sigma)
    main_err_2 = sum((full_pdf - approx_pdf) ** 2 * dx)
    err = (upper_tail_err_2_approx + main_err_2) ** 0.5
    err を返す

# 選択した離散化手法に基づく確率分布計算
def partition(n_qubits=10, flag=True):
    ビン = 2 ** n_qubits
    tail_value = (TARGET_ERR / 10) ** 2
    if flag:
        x_discrete = np.linspace(lognorm.ppf(tail_value, SIGMA)、
                               lognorm.ppf(1 - tail_value, SIGMA), bins + 1)
    else:
        x_discrete = lognorm.ppf(np.linspace(tail_value, 1 - tail_value, bins + 1), SIGMA)
    pmf = np.diff(lognorm.cdf(x_discrete, SIGMA))
    pmf = pmf / sum(pmf)
    ERR = l2_error(pmf, x_discrete, sigma=SIGMA)
    マージン = TARGET_ERR - ERR
    マージン > 0
    return tuple(pmf), x_discrete, margin, ERR

競合他社が提供するソリューションとの比較については、こちらをご覧ください。

対数正規分布を超えて

Classiqは状態準備の作成を簡単にします。回路を開始させたい確率を定義すれば、あとはプラットフォームが処理します。Classiqは確率質量関数またはガウス混合として確率を柔軟に定義でき、KL、L1、L2、最大確率、Loss of Fidelityなど、回路の許容誤差を定義する複数の方法を提供します。ガウシアンモーメントを使用した状態準備の実装にClassiqを使用した例と、状態準備にガウシアンモーメントを使用した信用リスク分析アルゴリズムの例をご紹介 します。 

Classiqのステート・プリパレーションは柔軟でプログラムしやすく、学術論文の結果を再現する場合でも、新しい量子アルゴリズムを作成する場合でも、目的の回路を自動的に生成します。Classiqでは "定義するのは簡単だが、実装するのは難しい "と言っています。 Classiqのプラットフォームがお客様の定義した回路を実装します。Classiqの顧客はより高いレベルで仕事をします。Classiqプラットフォームは何十億もの設計空間の中から適切な実装を自動的に見つけます。

Classiqプラットフォームの ライブデモをご予約いただき、実際にご覧いただくか、または 弊社までお問い合わせください。

"キュービット・ガイのポッドキャスト "について

The Qubit Guy(弊社最高マーケティング責任者ユヴァル・ボーガー)がホストを務めるこのポッドキャストは、量子コンピューティングのオピニオンリーダーをゲストに迎え、量子コンピューティングエコシステムに影響を与えるビジネスや技術的な疑問について議論します。ゲストは、量子コンピュータのソフトウェアやアルゴリズム、量子コンピュータのハードウェア、量子コンピューティングの主要なアプリケーション、量子産業の市場調査などについて興味深い見解を提供します。

ポッドキャストへのゲスト推薦をご希望の方は、こちらまでご連絡ください。

量子ソフトウェア開発を開始

お問い合わせ