loading...

Quantum libraries are wonderful

cgranade profile image Chris Granade ・8 min read

In my first FAQ# post, I described a bit about my life as a quantum developer, and how I came to work on developing quantum computing libraries.

That raises a few more questions, though, that I'd like to start answering today: what is a quantum library, anyway, and what libraries are already out there? In future posts, I'd also like to share some As usual, I find it helps to start by taking a step back and thinking about what might be analogous in traditional software development.

What is a library?

Computers aren't that old in the history of things, but they've definitely changed a lot since they first came around. At some point not too far in the past, a skilled programmer or a small team of programmers could write all the software that ran on a computer.

Margaret Hamilton standing next to a print out of her and her teams' code for the Apollo project

As computers have grown and proliferated over the decades, however, they've very quickly reached the point where it simply isn't possible to understand all the software powering a particular application, let alone to write it. In much the way that science must be a social enterprise to deal with the limits of what any one human can do, software development thus has to be a similarly social enterprise. To help out, we've developed a variety of different abstractions to help us share our work and build stuff together as a community.

Software libraries are one really great example of that kind of social abstraction: rather than writing an entire software stack from the ground up, you can leverage what other members of your community have done before you. For instance, the NumPy library for Python has helped out physicists, data scientists, statisticians, machine learning developers, and any other number of other people get stuff done that they care about.

>>> import numpy as np
>>> H = np.array([[1, 1], [1, 1]]) / np.sqrt(2)
>>> zero_state = np.array([[1], [0]])
>>> H @ zero_state
array([[0.70710678],
       [0.70710678]])

At its core, a software library is a way of packaging up a bunch of code in a way that makes it easy for other developers to reuse, whether that code gets packaged as a Python wheel, an npm package, or as a NuGet package.

Make it quantum

OK, so let's bring it back to quantum computing. Already, we're past the days where a single person can understand every single step in a quantum application — and that's a great thing! It means we have that much more to learn from each other, and that much more of an opportunity to build off each others' work.

When you write a quantum program in Q#, you can call functions and operations from different Q# libraries to make your life easier and to help you focus on the quantum application in front of you. For example, in Chapter 9 of our book (coming soon!), Sarah Kaiser and I use the Q# libraries to help our readers focus on what a quantum program to simulate chemistry problems might look like:

operation EstimateH2Energy(idxBondLength : Int) : Double {
    let nQubits = 2;
    let trotterStepSize = 1.0;
    let trotterStep = ApplyHamiltonian(idxBondLength, trotterStepSize, _);
    let estPhase = EstimateEnergy(nQubits, 
                                  PrepareInitalState, 
                                  trotterStep, 
                                  RobustPhaseEstimation(6, _, _));
    return estPhase / trotterStepSize + H2IdentityCoeff(idxBondLength);
}

In this snippet, EstimateEnergy and RobustPhaseEstimation are both provided by the standard libraries that come with the Q# language, and provide us with a lot of the infrastructure we need to quickly build and explore quantum chemistry applications.

GitHub logo microsoft / QuantumLibraries

Q# libraries for the Quantum Development Kit

Microsoft Quantum Development Kit Libraries

Welcome to the Microsoft Quantum Development Kit!

This repository contains open-source libraries for the Quantum Development Kit:

New to Quantum?

See the introduction to quantum computing provided with the Quantum Development Kit.

Getting Started

The libraries provided in this repository are built using .NET Core and the Quantum Development Kit Please see the installation guide for how to get up and running.

You may also visit our Quantum repository, which offers…

Of course, it's not just quantum subroutines like phase estimation and amplitude amplification that come along with Q#. The forthcoming samples for the quantum machine learning library for Q# show how the Q# standard libraries make it easy for you to use functional programming concepts in your QML workflow:

function WithOffset(offset : Double, sample : Double[]) : Double[] {
    return Mapped(TimesD(offset, _), sample);
}

function WithProductKernel(scale : Double, sample : Double[]) : Double[] {
    return sample + [scale * Fold(TimesD, 1.0, sample)];
}

function Preprocessed(samples : Double[][]) : Double[][] {
    let offset = 0.75;
    let scale = 1.0;

    return Mapped(
        Compose(
            WithOffset(offset, _),
            WithProductKernel(scale, _)
        ),
        samples
    );
}

The functions that the Q# standard library provides for working with arrays makes it really easy to quickly build up the kind of data processing that we need to work with quantum devices, as I talked about on Twitter a little while ago.

Things get really cool, though, when you use these kinds of classical development concepts together with quantum ideas to build up quantum programs in a quick and powerful way. For instance, if someone asks you to prepare some qubits in a state like (|0000⟩ + |1111⟩) / √2 (a so-called "cat state," really useful in doing error correction), you could do that by hand simply enough in Q#:

operation PrepareCatState(register : Qubit[]) : Unit is Adj + Ctl {
    H(register[0]);
    CNOT(register[0], register[1]);
    CNOT(register[0], register[2]);
    CNOT(register[0], register[3]);
}

This looks a lot like an unrolled loop, though, so you could also just... write the loop!

operation PrepareCatState(register : Qubit[]) : Unit is Adj + Ctl {
    H(register[0]);
    for (target in register[1...]) {
        CNOT(register[0], target);
    }
}

Using functional concepts and partial application together, you can make it even easier still:

open Microsoft.Quantum.Arrays;

operation PrepareCatState(register : Qubit[]) : Unit is Adj + Ctl {
    H(Head(register));
    ApplyToEachCA(
        CNOT(Head(register), _),
        Rest(register)
    );
}

By using ApplyToEachCA, together with array functions like Head and Rest, your cat state preparation operation works no matter how many qubits are in register, and is easy-to-read to boot.

Using the Q# together with Jupyter Notebooks, it's pretty easy to explore how this all works, too (you can even run this example online!):

The Quantum Development Kit libraries

In Q#, quantum libraries are distributed using NuGet, an open-source package manager from the .NET Foundation. If you've used C#, PowerShell, or Chocolatey, you've probably already worked with NuGet, but at a high-level, NuGet is pretty similar to PyPI, npm, or other package management systems.

TIP

The main difference between how Python and Q# handle packages is that in Q#, packages and namespaces are separate concepts; a package can contain however many namespaces, and namespaces can even be split across packages.

If you're using Q# from Python, you can import NuGet packages into your session with the qsharp.packages.add method. For example:

import qsharp

print("Loading the numerics library...")
qsharp.packages.add("Microsoft.Quantum.Numerics")
print("Done. Running program...")
qsharp.reload()

from Microsoft.Quantum.Numerics.Samples import CustomModAdd

On the other hand, if you're using Q# from C#, you can include new Q# libraries by adding them as <PackageReference /> elements in your project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.10.1912.501" />
    <PackageReference Include="Microsoft.Quantum.Standard" Version="0.10.1912.501" />
    <PackageReference Include="Microsoft.Quantum.Numerics" Version="0.10.1912.501" />
  </ItemGroup>

</Project>

Looking at the list of Quantum Development Kit packages on nuget.org, you can see a bunch of different packages, many of which are used to provide the Q# compiler, simulators, Jupyter integration, and so forth. There's also four different Q# libraries in the list so far:

If you've written any Q# program, you've probably used the Microsoft.Quantum.Standard package, as it provides the standard libraries for Q#, including a wide variety of both basic classical and quantum functionality; for example:

The standard library provides all the basics you need to write quantum programs, just like standard libraries in languages like Python and C# give you the basics you need to write traditional programs.

Moving on from the standard library, the Microsoft.Quantum.Chemistry and Microsoft.Quantum.Numerics packages use the standard library to address specific problem domains. For instance, Microsoft.Quantum.Chemistry provides powerful tools for solving quantum chemistry problems with quantum computing. Similarly, the Microsoft.Quantum.Numerics package provides tools needed to work with integer and fixed-point numbers represented by registers of qubits, and even to evaluate polynomials on quantum devices. Both the chemistry and numerics libraries differ from the standard library in that they more specifically target and support specific kinds of quantum applications.

The last of the Q# libraries provided with the Quantum Development Kit is the Microsoft.Quantum.Research package. As the name suggests, this package is a bit more focused on research usage of the Quantum Development Kit, providing implementations of Microsoft's cutting-edge research contributions in chemistry and phase estimation.

Conclusion

Both the Q# standard and domain-specific libraries are examples of how traditional software development concepts like libraries and packages can help make quantum development easier. If there's something you'd like to see out of the Q# libraries, go on and suggest it on GitHub, or even take a stab at contributing new library features!

After all, quantum computing is a community effort that takes developers with a wide range of different skills; what you uniquely bring is part of what makes this a great community!


If you like this post, read more at my blog, or read Learn Quantum Computing with Python and Q#, now available in early access from Manning Publications.

Discussion

pic
Editor guide