如何用Q#完成第一个量子计算程序

这篇文章在我的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里的作用相当于一个非门。所以我们得到的结果是:

image.png

与之前的结果刚好相反。

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

运行结果为:

image.png

每次运行的结果会有出入,但差别不大。这是因为经过H门之后,|0>有0.5的可能性是|0>,0.5的可能性是|1>; |1>有0.5的可能性是|0>,0.5的可能性是|1>。

猜你喜欢

转载自blog.csdn.net/m0_37622530/article/details/82889260