Quantum libraries are wonderful
Tags: qsharp, quantumcomputing
Published: 2020-01-20 21:00:30

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.

{% link https://dev.to/cgranade/what-is-a-quantum-developer-anyway-38l %}

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](https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Margaret_Hamilton_-_restoration.jpg/1920px-Margaret_Hamilton_-_restoration.jpg)

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](http://numpy.scipy.org/) has helped out physicists, data scientists, statisticians, machine learning developers, and any other number of other people get stuff done that they care about.

```python
>>> 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](https://www.python.org/dev/peps/pep-0427/), an [npm package](https://www.npmjs.com/), or as a [NuGet package](https://nuget.org/).

## 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](https://www.sckaiser.com/) and I use the Q# libraries to help our readers focus on what a quantum program to simulate chemistry problems might look like:

```qsharp
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`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.simulation.estimateenergy) and [`RobustPhaseEstimation`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.characterization.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 https://github.com/microsoft/QuantumLibraries/ %}

Of course, it's not just quantum subroutines like [phase estimation](https://docs.microsoft.com/quantum/libraries/standard/characterization) and [amplitude amplification](https://docs.microsoft.com/quantum/libraries/standard/algorithms) that come along with Q#. The forthcoming samples for the [quantum machine learning library](https://github.com/microsoft/QuantumLibraries/tree/feature/qml/MachineLearning) for Q# show how the Q# standard libraries make it easy for you to use functional programming concepts in your QML workflow:

```qsharp
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.

{% twitter 1205260871393562624 %}

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#:

```qsharp
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!

```qsharp
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:

```qsharp
open Microsoft.Quantum.Arrays;

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

By using [`ApplyToEachCA`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.applytoeachca), together with array functions like [`Head`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.arrays.head) and [`Rest`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.arrays.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](https://mybinder.org/v2/gh/cgranade/36f960ba4e40f71cb2e658b6e1dc4897/master)!):

{% gist https://gist.github.com/cgranade/36f960ba4e40f71cb2e658b6e1dc4897 file=PrepareCatState.ipynb %}

## The Quantum Development Kit libraries

In Q#, quantum libraries are distributed using [NuGet](https://nuget.org/), an open-source package manager from the .NET Foundation. If you've used C#, [PowerShell](https://www.powershellgallery.com/), or [Chocolatey](https://chocolatey.org/), 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](https://docs.microsoft.com/python/qsharp/qsharp.packages.packages#add-package-name--str-----none). [For example](https://github.com/microsoft/Quantum/blob/master/samples/numerics/CustomModAdd/host.py):

```python
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:

```xml
<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](https://www.nuget.org/profiles/QuantumEngineering), you can see a bunch of different packages, many of which are used to provide the [Q# compiler](https://www.nuget.org/packages/Microsoft.Quantum.Compiler), [simulators](https://www.nuget.org/packages/Microsoft.Quantum.Simulators), [Jupyter integration](https://www.nuget.org/packages/Microsoft.Quantum.IQSharp), and so forth. There's also four different Q# libraries in the list so far:

- [Microsoft.Quantum.Standard](https://www.nuget.org/packages/Microsoft.Quantum.Standard)
- [Microsoft.Quantum.Chemistry](https://www.nuget.org/packages/Microsoft.Quantum.Chemistry)
- [Microsoft.Quantum.Numerics](https://www.nuget.org/packages/Microsoft.Quantum.Numerics)
- [Microsoft.Quantum.Research](https://www.nuget.org/packages/Microsoft.Quantum.Research)

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:

- [array functions](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.arrays)
- [math functions](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.math) (e.g.: [`Sin`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sin), [`Sqrt`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sqrt), [`ArcTanh`](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctanh)
- [state preparation operations](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.preparation)
- [measurement operations](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.measurement)
- [amplitude amplification operations](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.amplitudeamplification)

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](https://docs.microsoft.com/quantum/libraries/chemistry/). 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](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.arithmetic.evaluatepolynomialfxp). 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](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.research.chemistry) and [phase estimation](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.research.randomwalkphaseestimation).

## 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](https://github.com/microsoft/QuantumLibraries/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=), or even take a stab at [contributing new library features](http://docs.microsoft.com/quantum/contributing/)!

After all, quantum computing is a community effort that takes developers with [a wide range of different skills](https://dev.to/cgranade/some-useful-skills-for-quantum-computing-2hn2); what you uniquely bring is part of what makes this a great community!

---

_If you like this post, read more [at my blog](https://www.cgranade.com/blog), or read_ [Learn Quantum Computing with Python and Q#](https://bit.ly/qsharp-book)_, now available in early access from Manning Publications._

![](https://media.giphy.com/media/7aPevwPAgsBkQ/source.gif)