你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

程序的结构Q#

本文探讨构成程序的常规 Q# 组件。 请注意, Q# 在 Jupyter Notebooks 中编写的程序不使用其中一些组件 - 每个部分都介绍了这些差异。

考虑以下 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 中运行此程序,请参阅程序和 VS Code 入门Q#

用户命名空间

Q# 程序通常以用户命名的命名空间开头,例如

namespace Superposition {
    // Your code goes here.
}

命名空间有助于组织相关功能。 命名空间是用户命名的,每个 qsharp (*.qs) 文件只能有一个 namespace

Q#标准库具有预定义的命名空间,这些命名空间包含可在量子程序中使用的函数和操作。 有关详细信息,请参阅 内置命名空间

Jupyter Notebook 不使用用户命名空间。

EntryPoint ()

特性 @EntryPoint() 告知 Q# 编译器从何处开始执行程序。 在具有多个函数和操作定义的程序中, @EntryPoint() 可以将 放在任何函数或操作和程序流从那里开始并按顺序继续。

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

Jupyter Notebook 不使用入口点。

%%qsharp 命令

默认情况下, Q# Jupyter Notebook 中的程序使用 ipykernel Python 内核。 若要将代码添加到 Q# 笔记本单元格,需要使用 %%qsharp 命令,该命令通过 qsharp Python 包启用。 例如,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(),而 Jupyter Notebook 则不需要这些命名空间。 操作不是入口点,而是直接在最后一行中调用。 另请注意,Message已将 语句添加到Jupyter Notebook代码以显示结果。 在 VS Code 中运行早期 Q# 程序时,内置模拟器默认显示结果。

使用 %%qsharp 命令时:

  • 必须先运行 import qsharp 才能启用 %%qsharp 命令。
  • 命令 %%qsharp 的范围限定为显示命令的整个单元格。 请注意,它会将笔记本单元格类型从 Python 更改为 Q#
  • 命令后面的 Q# 代码必须遵循标准的 Q# 编码语法。 例如,使用 而不是#单元格内的 %%qsharp 注释来表示注释//,并且代码行必须以分号 ;结尾。
  • %%qsharp 命令在其单元格中不能位于 Python 语句之前或之后。

有关使用Jupyter Notebook程序的示例,请参阅程序和 VS Code 入门Q#

类型

Q# 提供了许多大多数语言通用 的内置类型 ,包括 IntDoubleBoolString,以及特定于量子计算的类型。 例如, Result 类型表示任何量子比特度量的结果,并且可以具有两个可能定义的值之一: OneZero。 在示例程序中,运算 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 关键字分配量子比特。

我们的示例定义单个量子比特:

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

但也可以分配多个量子比特,并通过其索引访问每个量子比特:

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

默认情况下,使用 use 关键字分配的每个量子位最初都为 0 态。 在程序结束时释放每个量子比特之前, 必须 重置回零状态。 未能重置量子比特将触发运行时错误。

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

量子操作

分配后,可以将量子比特传递到操作和函数,也称为可调用对象运算是 Q# 程序的基本构建基块。 Q# 操作是量子子例程。 也就是说,它是一个可调用例程,其中包含用于修改量子位寄存器状态的量子操作。

要定义 Q# 运算,你需要指定运算的名称及其输入和输出。 在我们的示例中,单个操作实质上是整个程序。 它不采用任何参数,并且预期返回类型 Result为 :

operation MeasureOneQubit() : Result {
    ...
}

下面是一个基本示例,它不采用任何参数,并且不需要返回值。 该值 Unit 等效于 NULL 其他语言。

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

标准 Q# 库还提供可在程序中使用的操作,例如 Hadamard 或 H 示例程序中使用的操作。 在 Z 基指定一个量子比特,H 操作会将量子比特置于平均叠加中。 在叠加中,量子比特被测量为 0 或 1 的几率是 50%。

测量量子比特

有许多类型的量子测量,但 Q# 侧重于单个量子比特(也称为 Pauli 测量)的投影测量。 在给定基(例如计算基 $\ket{0},\ket{1}$)上进行测量时,量子比特状态将投影到所测量的任何基状态,从而破坏两者之间的任何叠加。

我们的示例程序使用 M 运算,该运算对 Pauli Z 基中的单个量子比特执行测量并返回类型 Result

内置命名空间

标准 Q# 库使用内置命名空间,这些命名空间包含可在量子程序中使用的函数和操作。 例如,命名空间 Microsoft.Quantum.Intrinsic 包含常用的操作和函数,例如 M,用于度量结果和 Message,用于在程序中的任意位置显示用户消息。

可以通过指定完整命名空间来调用函数或操作,或使用 open 语句使该命名空间的所有函数和操作都可用,并使代码更易于阅读。 这两个示例调用相同的操作:

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

请注意,在示例程序中,没有 open 具有完整命名空间的语句或调用。 这是因为 Q# 开发环境默认 Microsoft.Quantum.Core 自动加载两个包含常用函数和操作的命名空间和 Microsoft.Quantum.Intrinsic 命名空间。

可以利用 Microsoft.Quantum.Measurement 命名空间并使用 MResetZ 操作来优化示例程序中的代码。 MResetZ 将度量和重置操作合并为一个步骤,如以下示例所示:

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);
    }
    
}