这篇文章在我的GitHub上还有一个英文版,欢迎指正。
Q#是微软开发的专门运行量子算法的编程语言,需要用C#驱动。这篇文章是基于微软的Q#Document完成的,我在运行微软给的demo过程中遇到了一些问题,写这篇文章记录一下的的解决过程,和用到的一些知识。
1 检查CPU是否支持AVX指令
Q#语言的模拟器应用了AVX指令集,如果你的CPU不支持AVX,运算效果会打折扣。
可以通过下载CPU-Z这个软件查看自己的CPU是否支持AVX,如下图所示:
2 安装Visual Studio,配置环境
Q#需要安装的是Visual Studio 2017,在官网下载后安装即可。需要注意的是,安装前一定要确保选上了Universal Windows Platform development 和 .NET desktop development。
装好Visual Studio之后,还需要安装一个Q#的开发工具包,在链接中下载,双击安装即可。
3 新建你的第一个Q#程序(Step1 2 3 4)
在Visual Studio 2017中file-new-project,然后选择Q# Application。
这时候会得到一个qs和一个cs文件。qs是Q#文件,cs是用来驱动Q#的C#文件。
按照微软给的step1到step4做,会得到两个文件的完整代码分别如下:
Bell.qs:
namespace Quantum.Bell
{
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;
operation Set (desired: Result, q1: Qubit) : ()
{
body
{
let current = M(q1); // The 'let' keyword binds mutable variables
if (desired != current)
{
X(q1); // NOT gate
}
}
}
operation BellTest (count : Int, initial : Result) : (Int, Int)
{
body
{
mutable numOnes = 0;
using (qubits = Qubit[1])
{
for (test in 1..count)
{
Set (initial, qubits[0]);
let res = M (qubits[0]);
// Count the number of ones we saw:
if (res == One)
{
set numOnes = numOnes + 1;
}
}
Set(Zero, qubits[0]);
}
// Return number of times we saw a |0> and number of times we saw a |1>
return (count-numOnes, numOnes);
}
}
}
Driver.cs:
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
namespace Quantum.Bell
{
class Driver
{
static void Main(string[] args)
{
using (var sim = new QuantumSimulator()) // sim is the Q# quantum similator
{
// Try initial values
Result[] initials = new Result[] { Result.Zero, Result.One };
foreach (Result initial in initials)
{
var res = BellTest.Run(sim, 1000, initial).Result; // Run is the method to run the quantum simulation
var (numZeros, numOnes) = res;
System.Console.WriteLine($"Init:{initial,-4} 0s={numZeros,-4} 1s={numOnes,-4}");
}
}
System.Console.WriteLine("Press any key to continue...");
System.Console.ReadKey();
}
}
}
但是我们在编译的时候可能会出现问题(the name XX does not exist in the current context unity),即使这些代码只是一点copy/paste的工作。我觉得这是因为整个project中的references可能有问题:
我的建议是在我的GitHub上下载整个工程,然后只对qs和cs两个文件做修改。
此时运行正确的结果是:
这个结果的意思是当最初的值设为Zero时,最终数一下0的个数为1000,1的个数是0,同理初始值为1时。
这个程序是数|0>和|1>的个数。此时没有创造叠加状态,|0>有百分之百的可能性是|0>,|1>有百分之百的可能性是|1>。
4 创造叠加状态
4.1 X门
在qs文件的第27和29行之间加入这样一行:
X(qubits[0]);
他在quantum computing里的作用相当于一个非门。所以我们得到的结果是:
与之前的结果刚好相反。 |
4.2 H门
在qs文件的第27和29行之间加入这样一行:
H(qubits[0]); // Create superpositions
它是一个Hadamard门,一个重要作用就是创造叠加态,
这时整个qs文件变成了:
namespace Quantum.Bell
{
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;
operation Set (desired: Result, q1: Qubit) : ()
{
body
{
let current = M(q1); // The 'let' keyword binds mutable variables
if (desired != current)
{
X(q1); // NOT gate
}
}
}
operation BellTest (count : Int, initial : Result) : (Int, Int)
{
body
{
mutable numOnes = 0;
using (qubits = Qubit[1])
{
for (test in 1..count)
{
Set (initial, qubits[0]);
H(qubits[0]); // Create superpositions
let res = M (qubits[0]);
// Count the number of ones we saw:
if (res == One)
{
set numOnes = numOnes + 1;
}
}
Set(Zero, qubits[0]);
}
// Return number of times we saw a |0> and number of times we saw a |1>
return (count-numOnes, numOnes);
}
}
}
运行结果为:
每次运行的结果会有出入,但差别不大。这是因为经过H门之后,|0>有0.5的可能性是|0>,0.5的可能性是|1>; |1>有0.5的可能性是|0>,0.5的可能性是|1>。