プログラムの Q# 構造

この記事では、プログラムを構成する一般的なコンポーネントについて Q# 説明します。 Q# Jupyter Notebook で記述されたプログラムでは、これらのコンポーネントの一部が使用されないことに注意してください。これらの違いについては、各セクションで説明します。

次の Q# プログラムについて検討します。

namespace Superposition {

    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);      
        // Now we measure the qubit in Z-basis.
        let result = M(q);
        // We reset the qubit before releasing it.
        Reset(q);
        // Finally, we return the result of the measurement.
        return result;
    }
}

コメント (//) を読むだけで、このプログラムが量子ビットを割り当て、重ね合わせに配置する操作を適用し、量子ビットの状態を測定し、それをリセットして結果を返すという指示を得ることができます。

Visual Studio Code でこのプログラムを実行するには、「 プログラムの概要 Q# 」と「VS Code」を参照してください。

ユーザー名前空間

Q# プログラムは通常、ユーザー名の名前空間で始まります。たとえば、

namespace Superposition {
    // Your code goes here.
}

名前空間は、関連する機能を整理するのに役立ちます。 名前空間はユーザー名で、qsharp (*.qs) ファイルごとに 1 つだけ namespace 指定できます。

Q#標準ライブラリには、量子プログラムで使用できる関数と操作を含む定義済みの名前空間があります。 詳細については、「 組み込みの名前空間」を参照してください。

Jupyter Notebook では、 ユーザー名前空間は使用されません。

EntryPoint()

属性は @EntryPoint() 、プログラムの実行を Q# 開始する場所をコンパイラに指示します。 複数の関数と操作の定義を持つプログラムでは、 @EntryPoint() は関数または操作の前に配置でき、プログラム フローはそこから開始され、順番に続行されます。

    ...
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        ...

Jupyter Notebook ではエントリ ポイントは 使用されません。

%%qsharp コマンド

既定では、 Q# Jupyter Notebook のプログラムでは ipykernel Python カーネルが使用されます。 ノートブック セルにコードを追加 Q# するには、 コマンドを %%qsharp 使用する必要があります。このコマンドは Python パッケージで qsharp 有効になっています。 たとえば、Jupyter Notebookの前のサンプル コードは次のようになります。

import qsharp
%%qsharp

    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);      
        // Now we measure the qubit in Z-basis.
        let result = M(q);
        // We reset the qubit before releasing it.
        Reset(q);
        // Display the result
        Message($"Result is {result}");
        // Finally, we return the result of the measurement.
        return result;
    
    }
    MeasureOneQubit();

Jupyter Notebook には必要ないユーザー名前空間または @EntryPoint()が存在しないことに注意してください。 エントリ ポイントの代わりに、操作は最後の行で直接呼び出されます。 また、結果をMessage表示するために、Jupyter Notebook コードに ステートメントが追加されていることにも注意してください。 VS Code で以前 Q# のプログラムを実行すると、組み込みのシミュレーターによって既定で結果が表示されます。

コマンドを使用する場合:%%qsharp

  • %%qsharp コマンドを有効にするには、最初に import qsharp を実行する必要があります。
  • コマンドの %%qsharp スコープは、表示されるセル全体に設定されます。 ノートブックのセルの種類が Python から に Q#変更されることに注意してください。
  • コマンドの後に続く Q# コードは、標準の Q# コーディング構文に準拠している必要があります。 たとえば、セル内%%qsharpではなく # を使用してコメントを//示し、コード行はセミコロン ;で終わる必要があります。
  • %%qsharp コマンドの前後に、そのセル内でに Python ステートメントを付けることはできません。

Jupyter Notebook プログラムの使用例については、「プログラムと VS Code の概要Q#」を参照してください。

種類

Q#には、 など、BoolIntDoubleほとんどの言語に共通する多くの組み込み型とString、量子コンピューティングに固有の型が用意されています。 たとえば、 型はResult量子ビット測定の結果を表し、 と Zeroの 2 つの可能な定義値Oneのいずれかを持つことができます。 サンプル プログラムでは、演算 MeasureOneQubit() は の戻り値の Result 型を想定し、演算によって M 量子ビットが測定され、 が返されます Result

...
// operation definition expecting a return type of Result
operation MeasureOneQubit() : Result {
    ...
    // Now we measure the qubit in Z-basis, returning a Result type
    let result = M(q);
    ...
}

Q# には、範囲、配列、タプルを定義する型も用意されています。 独自のカスタム型を定義することもできます。

量子ビットの割り当て

Q# では、量子ビットは use キーワードを使用して割り当てられます。

この例では、1 つの量子ビットを定義します。

// Allocate a qubit.
use q = Qubit();
...

ただし、複数の量子ビットを割り当てて、インデックスを介して各量子ビットにアクセスすることもできます。

...
use qubits = Qubit[2];
X(qubits[1]);
H(qubits[0]);
...

既定では、use キーワードを使用して割り当てたすべての量子ビットはゼロの状態で開始されます。 各量子ビットは、プログラムの終了時に解放される前に、ゼロ状態にリセットする 必要があります 。 量子ビットのリセットに失敗すると、ランタイム エラーがトリガーされます。

// Reset a qubit.
Reset(q);
...

量子演算

割り当てられた後、callable とも呼ばれる演算や関数に量子ビットを渡すことができます。 演算は Q# プログラムを構成する基本要素です。 Q# 操作は、量子のサブルーチンです。 つまり、量子レジスタの状態を変更する量子演算を格納する呼び出し可能なルーチンです。

Q# 演算を定義するには、演算の名前とその入力および出力を指定します。 この例では、1 つの操作は基本的にプログラム全体です。 パラメーターを受け取る必要はなく、 の戻り値の Result型が必要です。

operation MeasureOneQubit() : Result {
    ...
}

パラメーターを受け取らないし、戻り値を期待しない基本的な例を次に示します。 値は Unit 、他の言語の と同じです NULL

operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

標準ライブラリには Q# 、プログラムで使用できる操作 (Hadamard や H サンプル プログラムで使用される操作など) も用意されています。 Z 基底の量子ビットを指定すると、H 演算によって量子ビットが "均一" の重ね合わせになります。 重ね合わせ状態では、量子ビットは 0 または 1 として測定される確率が 50% になります。

量子ビットの測定

量子測定には多くの種類がありますが Q# 、 パウリ測定とも呼ばれる単一量子ビットの射射測定に焦点を当てています。 特定の基底 (たとえば、計算基底 $\ket{0},\ket{1}$) での測定に基づいて、量子ビット状態は、状態が測定された基底に投影されるので、この 2 つの間の重ね合わせは破棄されます。

このサンプル プログラムでは、 演算を M 使用します。この演算は、Pauli Z 基準で 1 つの量子ビットの測定を実行し、型を Result 返します。

組み込みの名前空間

標準 Q# ライブラリでは、量子プログラムで使用できる関数と操作を含む組み込みの名前空間を使用します。 たとえば、 名前空間 Microsoft.Quantum.Intrinsic には、 などの M一般的に使用される操作と関数が含まれており、結果を測定し、 Messageプログラム内の任意の場所にユーザー メッセージを表示します。

関数または操作を呼び出すには、完全な名前空間を指定するか、 ステートメントを open 使用して、その名前空間のすべての関数と操作を使用できるようにし、コードを読みやすくすることができます。 次の 2 つの例では、同じ操作を呼び出します。

 Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
open Microsoft.Quantum.Intrinsic;
Message("Hello quantum world!");

サンプル プログラムには、完全な名前空間を持つステートメントや呼び出しがないこと open に注意してください。 これは、開発環境ではQ#、一般的に使用される関数と操作を含む 2 つの名前空間 (およびMicrosoft.Quantum.Intrinsic) が既定Microsoft.Quantum.Coreで自動的に読み込まれるためです。

名前空間を利用し、 操作をMicrosoft.Quantum.MeasurementMResetZ使用してサンプル プログラムのコードを最適化できます。 MResetZ では、次の例のように、測定操作とリセット操作が 1 つのステップに結合されます。

namespace Superposition {

    // open the namespace for the MResetZ operation
    open Microsoft.Quantum.Measurement;

    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit, by default it is in zero state      
        use q = Qubit();  
        // We apply a Hadamard operation H to the state
        // It now has a 50% chance of being measured 0 or 1  
        H(q);   
        // Measure and reset the qubit, and return the result value   
        return MResetZ(q);
    }
    
}