练习 - 使用 Q# 创建量子纠缠
在上一单元中,你了解了量子纠缠和贝尔状态的概念。
现在,让我们使用 Q# 和 Azure Quantum Development Kit 创建量子纠缠。 若要创建纠缠,需要应用两个量子运算:Hadamard 门和受控-NOT (CNOT) 门。
受控非 (CNOT) 运算
当两个量子比特纠缠时,一个量子比特的状态取决于另一个量子比特的状态。 因此,若要纠缠两个量子比特,需要提供一个同时作用于两个量子比特的运算。 这称为“多量子比特运算”。
若要创建量子纠缠,需要提供多量子比特 CNOT
运算(表示受控非)。 此运算采用两个量子比特作为输入,一个充当控制量子比特,另一个是 target 量子比特。 当且仅当第一个量子比特(控制量子比特)的状态为 $|1\rangle$ 时,CNOT
运算才会翻转第二个量子比特(target 量子比特)的状态。
输入 | 输出 |
---|---|
$\ket{00}$ | $\ket{00}$ |
$\ket{01}$ | $\ket{01}$ |
$\ket{10}$ | $\ket{11}$ |
$\ket{11}$ | $\ket{10}$ |
在 Q# 中,CNOT
运算作用于两个量子比特的数组,如果第一个量子比特为 One
,则它会翻转第二个量子比特。
与 CNOT 运算的纠缠
通过应用 Hadamard (H
) 运算和受控 NOT (CNOT
) 运算,可以将状态 $|00\rangle$ 的两个量子比特转换为贝尔状态 $\ket{\phi^+}=\frac1{\sqrt2}(|00\rangle+|11\rangle)$。
以下是其工作原理:
取状态为 $|00\rangle$ 的两个量子比特。 第一个量子比特是控制量子比特,第二个量子比特是 target 量子比特。
通过应用 $H$ 来仅在控制量子比特中创建叠加状态。
$$H |0_c\rangle=\frac{1}{\sqrt{{2}}(|0_c\rangle+|1_c\rangle)$$
提示
下标 ${}_c$ 和 ${}_t$ 指定控制和 target 量子比特。
将 $CNOT$ 运算符应用于处于叠加状态的控制量子比特和处于状态 $|0_t\rangle$ 的 target 量子比特。
$$ CNOT \frac{1}{\sqrt{2}}(\ket{0_c}+\ket{1_c})\ket{0}_t = CNOT \frac{1}{\sqrt2}(\ket{0_c 0_t}+|\ket{1_c 0_t})=$$$$=\frac{{1}{\sqrt2}(CNOT \ket{0_c 0_t} + CNOT \ket{1_c 0_t})=$$$$=\frac{1}{\sqrt2}(\ket{0_c 0_t}+\ket{1_c 1_t})$$
创建新的 Q# 文件
- 打开 Visual Studio Code。
- 选择“文件 > 新建文本文件”并将其另存为“Main.qs”。
- 选择“视图”->“命令面板”并键入“Q#:设置 Azure Quantum QIR target 配置文件”。 按 Enter。
- 选择“Q#:无限制”。
创建贝尔状态 $\ket{\phi^+}$
我们首先创建贝尔状态 $\ket{\phi^+}=\frac1{\sqrt2}(|00\rangle+|11\rangle)$。
首先,你需要从标准库导入
Microsoft.Quantum.Diagnostics
命名空间,该命名空间包含DumpMachine
函数。 此函数显示量子比特的当前状态。 将以下 Q# 代码复制并粘贴到 Main.qs 文件中。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*;
提示
还可以通过将
Microsoft.Quantum
替换为Std
来导入标准库。 例如,import Std.Diagnostics.*
等效于import Microsoft.Quantum.Diagnostics.*
。创建返回两个
Result
类型值的Main
运算,这些值是量子比特的度量结果。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { // Your code goes here }
在
Main
运算中,你分配两个将纠缠在一起量子比特(q1
和q2
)。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); }
将 Hadamard 门 (
H
) 应用于第一个量子比特q1
,使其处于叠加状态。 然后,使用CNOT
运算纠缠两个量子比特。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); }
使用
DumpMachine
函数显示量子比特的当前状态。 这不同于对量子比特进行度量。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); }
使用
M
运算度量量子比特,并将结果存储在m1
和m2
中。 然后,使用Reset
运算重置量子比特。 在 Q# 中,你必须始终将量子比特重置为 $|0\rangle$ 状态。import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); let (m1, m2) = (M(q1), M(q2)); Reset(q1); Reset(q2); }
最后,使用
return
语句返回量子比特的度量结果。 你的 Main.qs 文件应如下所示:import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); CNOT(q1, q2); DumpMachine(); let (m1, m2) = (M(q1), M(q2)); Reset(q1); Reset(q2); return (m1, m2); }
若要在内置模拟器中运行程序,请在
Main
操作上方单击“运行”,或按 Ctrl+F5。 输出会显示在调试控制台中。度量结果是相关的,因此在程序结束时,你将收到概率相同的
(Zero, Zero)
或(One, One)
结果。可以通过在
Main
运算上方的命令列表中单击“线路”来可视化线路图。 线路图显示了应用于第一个量子比特的阿达马门和应用于两个量子比特的 CNOT 门。
创建其他贝尔态
若要创建其他贝尔状态,需要对量子比特应用额外的泡利 $X$ 和 $Z$ 运算。
例如,若要创建贝尔状态 $\ket{\phi^-}=\frac1{\sqrt2}(|00\rangle-|11\rangle)$,可以在应用阿达马门后对控制量子比特应用泡利 $Z$ 运算。 $Z$ 运算将状态 $\ket{+}$ 翻转为 $\ket{-}$。
提示
状态 $\frac{{1}{\sqrt{2}}(|0\rangle+|1\rangle)$ 和 $\frac{1}{\sqrt{{2}}(|0\rangle -|1\rangle)$ 也分别称为 $\ket{+}$ 和 $\ket{{-}$。
以下是其工作原理:
取状态为 $|00\rangle$ 的两个量子比特。
通过应用 $H$ 来仅在控制量子比特中创建叠加状态。
$$H |0_c\rangle=\frac{{1}{\sqrt{2}}(|0_c\rangle+|1_c\rangle) =\ket{+}_c$$
对控制量子比特应用 $Z$ 运算。
$$Z \frac{{1}{\sqrt{{2}}(|0_c\rangle+|1_c\rangle)=\frac{1}{\sqrt{{2}}(|0_c\rangle-|1_c\rangle)=\ket{{-}_c$$
对控制量子比特和处于 $|0_t\rangle$ 状态的 target 量子比特应用 $CNOT$ 运算符。
$$ CNOT \frac{1}{\sqrt{2}}(\ket{0_c}-\ket{1_c})\ket{0}_t = CNOT \frac{1}{\sqrt2}(\ket{0_c 0_t}-|\ket{1_c 0_t})=$$$$=\frac{{1}{\sqrt2}(CNOT \ket{0_c 0_t} - CNOT \ket{1_c 0_t})=$$$$=\frac{1}{\sqrt2}(\ket{0_c 0_t}-\ket{1_c 1_t})$$
同样,可以通过对量子比特应用泡利 $X$ 和 $Z$ 运算来创建贝尔状态 $\ket{\psi^+}$ 和 $\ket{\psi^-}$。
- 在应用阿达马门后,可以通过对 target 量子比特应用泡利 $X$ 运算来创建贝尔状态 $\ket{\psi^+}=\frac1{\sqrt2}(|01\rangle+|10\rangle)$。
- 在应用阿达马门后,可以通过对控制量子比特应用泡利 $Z$ 运算,对 target 量子比特应用泡利 $X$ 运算,来创建贝尔状态 $\ket{\psi^-}=\frac1{\sqrt2}(|01\rangle-|10\rangle)$。
在 Q# 中创建贝尔状态 $\ket{\phi^-}$
修改 Q# 代码以创建贝尔状态 $\ket{\phi^-}$。 你的 Main.qs 文件应如下所示:
import Microsoft.Quantum.Diagnostics.*; // Aka Std.Diagnostics.*; operation Main() : (Result, Result) { use (q1, q2) = (Qubit(), Qubit()); H(q1); Z(q1); // Apply the Pauli Z operation to the control qubit CNOT(q1, q2); DumpMachine(); let (m1, m2) = (M(q1), M(q2)); Reset(q1); Reset(q2); return (m1, m2); }
若要在内置模拟器中运行程序,请在
Main
操作上方单击“运行”,或按 Ctrl+F5。 输出会显示在调试控制台中。可以通过在
Main
运算上方的命令列表中单击“线路”来可视化线路图。 线路图显示了应用于第一个量子比特的 Hadamard 门、应用于第一个量子比特的 Pauli $Z$ 门,和应用于两个量子比特的 CNOT 门。
在下一单元中,你将了解如何使用纠缠来传送量子信息。