2 “Hello World,” quantum computing style

This chapter covers

  • Introducing Strange, a quantum computing library in Java
  • Trying the high-level and low-level APIs in Strange
  • A basic visualization of a quantum circuit

This chapter introduces Strange, an open source quantum computing project including a quantum simulator and a library that exposes a Java API you can use in regular Java applications. Throughout the book, we discuss concepts of quantum computing (QC) and their relevance to Java developers, and we show how Java developers can benefit from these concepts.

Strange contains a pure Java implementation of the required quantum concepts. When discussing the concepts, we point you to the relevant code implementation of the concept in Strange. This is part of a low-level API.

Most Java developers will not have to deal with low-level quantum concepts. However, some may benefit from algorithms that take advantage of these concepts. For this group, Strange provide a set of high-level algorithms that can be used in regular Java applications. These algorithms are what we call the high-level Java API.

2.1 Introducing Strange

Figure 2.1 shows a high-level overview of the components of Strange. The Java Quantum API provides an implementation for a number of typical quantum algorithms. These are the high-level algorithms that you can use in regular Java applications. No knowledge of QC is required to use them.

Figure 2.1 High-level overview of the Strange architecture

The quantum core layer contains the low-level API, which provides deeper access to the real quantum aspects. The high-level API does not contain a concept specific to QC, but its implementation uses the low-level quantum core layer. Whereas the high-level API shields you from the quantum concepts, the low-level API exposes those concepts to you.

The high-level API provides you with a ready-to-use interface to quantum algorithms. By using it, you can benefit from the gains realized by QC. However, if you want to be able to create your own algorithms or modify existing algorithms, the low-level API is the starting point.

2.2 Running a first demo with Strange

This book comes with a repository containing a number of examples that use Strange. You can find this repository on GitHub at https://github.com/johanvos/quantumjava. The requirements and instructions for running the examples are explained in appendix A. The first demo example is located in the hellostrange folder in the ch02 directory.

Note Keep in mind that all our examples require Java 11 or newer. In appendix A, you can find instructions for installing the required Java software.

Building and running the examples can be done using the Gradle build tool as well as the Maven build tool. The examples contain a build.gradle file that allows them to be handled by Gradle and a pom.xml file that allows them to be handled by Maven.

We recommend that you run the examples using your favorite IDE (IntelliJ, Eclipse, or NetBeans). The instructions for how to run Java applications are different for each IDE. In this book, we use the Gradle and Maven build systems from the command line; using the provided Gradle and Maven configuration files implicitly makes sure that all required code dependencies are downloaded. The code is compiled and executed as illustrated in figure 2.2.

Figure 2.2 Using Gradle or Maven to run Java applications

Note When running the examples using the command-line interface, we take a slightly different approach between Maven and Gradle. When using Maven, you need to cd into the example-specific directory (that contains a pom.xml file). When using Gradle, you stay at the root level (which contains a build .gradle file), and you run the examples by providing the chapter and project name. We will explain this with the HelloStrange example.

If you want to use the Maven build system to run the basic HelloStrange application, you need to move into the ch02/hellostrange directory. There, execute

mvn clean javafx:run

which will result in output similar to the following:

mvn clean javafx:run
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------------------------------------------------
[INFO] Building hellostrange 1.0-SNAPSHOT
[INFO] ---------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ helloquantum ---
[INFO] Deleting /home/johan/quantumcomputing/manning/public/quantumjava/ch02
/hellostrange/target
[INFO]
[INFO] >>> javafx-maven-plugin:0.0.6:run (default-cli) > process-classes @ h
elloquantum >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloq
uantum ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/johan/quantumcomputing/mann
ing/public/quantumjava/ch02/hellostrange/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloquantu
m ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/johan/quantumcomputing/manning/publi
c/quantumjava/ch02/hellostrange/target/classes
[INFO]
[INFO] <<< javafx-maven-plugin:0.0.6:run (default-cli) < process-classes @ h
elloquantum <<<
[INFO]
[INFO] --- javafx-maven-plugin:0.0.6:run (default-cli) @ helloquantum ---
[INFO] Toolchain in javafx-maven-plugin null
Using high-level Strange API to generate random bits
----------------------------------------------------
Generate one random bit, which can be 0 or 1. Result = 1
Generated 10000 random bits, 4967 of them were 0, and 5033 were 1.
[INFO] ---------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ---------------------------------------------------------------------
[INFO] Total time: 1.790 s
[INFO] Finished at: 2021-08-18T14:52:58+02:00
[INFO] Final Memory: 13M/54M
[INFO] ---------------------------------------------------------------------

Note Experienced Maven users might wonder why we don’t simply use mvn exec:java, which would use Maven’s Java plugin. We recommend using mvn javafx:run because that involves the Maven JavaFX plugin. This plugin allows us to run standard Java applications as well as JavaFX applications. We use the latter in a number of examples where a user interface is generated. Rather than switching between the Java and JavaFX plugins, it is more convenient to always invoke the JavaFX plugin, even if it is not strictly needed when we run Java applications without a user interface.

When using Gradle, you run Gradle from the root directory and need to pass the name of the project. You can inspect the contents of the settings.gradle file, which contains the name of all projects in the repository.

Running the example in Linux and macOS is done via

./gradlew ch02:hellostrange:run

If you are using Windows, you have to run it as follows:

gradlew.bat ch02:hellostrange:run

Both commands will result in the following output:

> Task :run
Using high-level Strange API to generate random bits
----------------------------------------------------
Generate one random bit, which can be 0 or 1. Result = 1
Generated 10000 random bits, 4961 of them were 0, and 5039 were 1.
 
BUILD SUCCESSFUL in 3s

Note Gradle may add more output, especially if this is the first time you’re using this Gradle version or when required dependencies are not yet installed on your system.

Congratulations! You just executed a program that involves quantum computing.

2.3 Inspecting the code for HelloStrange

To understand the output of the HelloStrange demo application, we recommend that you look at the source code for the application. Before we investigate the Java code, we have to look at the build.gradle and pom.xml files in the root directory of the example. The build.gradle file contains the instructions that allow Gradle to compile the Java classes, download and install dependencies, and run the application. The pom.xml file has the same goals, allowing us to deal with the application using Maven.

2.3.1 The build procedures

Typically, you shouldn’t worry about the structure of the build.gradle file or the pom.xml file unless you plan to create applications or projects yourself. In that case, you can find great resources about using Gradle and Maven online.

Building with Maven

The pom.xml file that contains the instructions for Maven to compile and run the application is shown in the following listing.

Listing 2.1 pom.xml file for the HelloStrange example

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.
 org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.
 org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>                    
  <groupId>org.redfx.javaqc</groupId>
  <artifactId>helloquantum</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>grover</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.redfx</groupId>
      <artifactId>strange</artifactId>                   
      <version>0.1.1</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-maven-plugin</artifactId>     
        <version>0.0.4</version>
        <configuration>
          <mainClass>
              org.redfx.javaqc.ch02.hellostrange.Main    
          </mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

The pom file requires some general information about the project. The properties defined here are standard Maven properties and have nothing specific for our application, but they need to be defined.

The project depends on org.redfx.strange.

The life-cycle management of the project (compiling and running) is handled by the javafx-maven plugin, as described here.

The main class name needs to be specified so that the plugin can run it.

Users familiar with Maven can easily modify this .pom file, but in general, doing so is not necessary.

Building with Gradle

For clarity, the build.gradle file is shown next.

Listing 2.2 build.gradle file for the HelloStrange example

plugins {                                                  
    id 'application'
}
 
repositories {                                             
    mavenCentral();
}
 
dependencies {                                             
    compile 'org.redfx:strange:0.1.1'
}
 
mainClassName = 'org.redfx.javaqc.ch02.hellostrange.Main'  

Declares what plugins Gradle should use. Gradle is a build system that allows third parties to provide plugins to make it easier to build and deploy applications. The demo application is an application and therefore uses the application plugin. Strange requires Java 11 and the modularity concepts introduced in Java 9. Our demo applications don’t require knowledge of the modular system in Java. However, for the build tools to use the modularity, we also declare the use of the javamodularity Gradle plugin.

Declares where to download dependencies. Because our demo application is using a Java library, Gradle needs to know where to find this library to use it for compiling and running the demo application. The Strange library is uploaded to the mavenCentral repository, so we declare that in the repositories section.

Declares the dependencies. The HelloStrange demo application uses the Strange library. Here we declare that we need version 0.1.1 of the Strange library, which is defined by the combination of a package name (org.redfx) and an artifact name (strange). The compile keyword tells Gradle that this library is needed to compile the application, and by default, it will also use this library to run the application.

Declares the main class that should be executed when running the demo. We need to tell Gradle where it can find the main entry point to our application. In this case, the project has a single Java source file with a main method; hence, this is the entry point.

The build.gradle file is interesting to developers and code maintainers who are working on project development, deployment, testing, and distribution.

2.3.2 The code

The Java source files in a project are relevant to all developers. Maven and Gradle by default require that Java source files be placed in a folder whose name is src/main/java followed by the package name and the name of the Java source file. In the case of the HelloStrange application, the single source file is located at src/main/java/org/redfx/javaqc/ch02/hellostrange/Main.java. Note that every example has its own src directory so that it can easily be seen in isolation.

Before we show the code, we will briefly explain what we want to achieve. In this first example, we invoke a method on the high-level Strange API. This method is called randomBit() and generates a classic bit that is either 0 or 1. We discuss the randomBit() method call shortly. Apart from this call, all Java code used in the example uses only the standard APIs that are part of the JDK.

The flow for the example is shown in figure 2.3. You can see that the Java class we create depends on the high-level Strange API. We don’t have to worry about how it is implemented in the lower layers of Strange.

Figure 2.3 High-level overview of the first Java example

The complete source code for the application is shown in the following listing. We analyze this source code next.

Listing 2.3 Main.java file for the HelloStrange example

package org.redfx.javaqc.ch02.hellostrange;
 
import org.redfx.strange.algorithm.Classic;
 
public class Main {
 
    public static void main (String[] args) {
        System.out.println("Using high-level Strange API to generate random
 bits");
        System.out.println("--------------------------------------------");
        int randomBit = Classic.randomBit();              
        System.out.println("Generate one random bit, which can be 0 or 1."+
                           " Result = "+randomBit);
        int cntZero = 0;
        int cntOne = 0;
        for (int i = 0; i < 10000; i++) {                 
            if (Classic.randomBit() > 0) {
                cntOne ++;
            } else {
                cntZero ++;
            }
        }
        System.out.println("Generated 10000 random bits, " + cntZero +
                           " of them were 0, and "+cntOne+" were 1.");
    }
}

Calls the Strange high-level API to generate one random bit

Generates 10,000 random bits

This Java code follows the basic Java conventions, which we assume you are familiar with. For this example, we briefly mention the typical concepts in a Java application.

The Java code in this source file belongs to the package org.redfx.javaqc.ch02 .hellostrange, which is declared at the top of the file. We rely on functionality provided by the Strange library, and we import the Java class that provides the functionality we need:

import org.redfx.strange.algorithm.Classic

We take a deeper look at this Classic class later. For now, we simply assume that it provides the functionality we need.

The name of our example Java class is Main, as it has to match the name of the file. In Java, entry points in files need to be declared with a method public static void main(String[] args). Build tools like Maven and Gradle invoke this method when asked to execute an application. When the main method is invoked, it first prints some information:

System.out.println("Using high-level Strange API to generate random bits");
System.out.println("----------------------------------------------------");

In the next line of code in listing 2.3, we call a method on the Classic class that is part of the Strange library that we imported: Classic.randomBit(), which returns a Java integer that holds the value 0 or the value 1. After the statement

int randomBit = Classic.randomBit();

the value of randomBit is thus 0 or 1.

Note The classname Classic indicates that Strange offers this class for classic invocations. By this, we mean that code calling this class is not expected to contain any quantum-specific objects or functions. The calling code can be part of a project or a library that is entirely written using classic code. However, the implementation of the Classic class itself contains quantum implementations. Therefore, the implementation of Classic.randomBit() is not simply returning a default Java random bit but also using a quantum circuit to do so, as we show later in this chapter.

The next line prints this value. Note that when you execute the application, there is a 50% chance you will see a 0 printed and a 50% chance that you will see a 1 printed. As we said before, Classic.randomBit() is a Java method that under the hood uses quantum principles. We discuss the implementation later; for now, we assume that there is an equal chance for this method to return 0 and 1.

To demonstrate this, the next part of listing 2.3 calls Classic.randomBit() 10,000 times and keeps track of how many times a 0 is returned and how many times a 1 is returned. Two variables are introduced to keep track of this occurrence:

int cntZero = 0;
int cntOne = 0;

Clearly, cntZero holds the number of times the returned value is 0 and cntOne holds the count for the calls that return 1.

We create a loop in which the inner code calls the randomBit() method and increments the appropriate variable. This is done in the following code snippet:

for (int i = 0; i < 10000; i++) {
    if (Classic.randomBit() > 0) {
        cntOne ++;
    } else {
        cntZero ++;
    }
}

Finally, the results are printed. Because the random values are truly random, the final results will likely be different every time you run the application. The sum of the cntOne and cntZero values will always be 10,000, and it is expected that the cntZero and cntOne values will both be in the neighborhood of 5000.

2.3.3 Java APIs vs. implementations

If you are familiar with Java development, the code we have shown and used so far should be familiar. No specific knowledge of quantum physics or QC has been required. We used Classic.randomBit(), which is a method similar to all the Java methods you see in Java applications. Under the hood, however, Classic.randomBit() is using either a quantum simulator or a real quantum computer. The Java developer is not confronted with the implementation, though, one of the great things about Java is that the implementation is typically hidden for developers who program their applications using APIs. In this case, Classic.randomBit() is an API called by the developer.

Although you don’t need to know the details of the underlying implementations, it often helps to have at least some insight into those details. This is not only the case for algorithms in QC but is applicable to many fields. Although documentation (such as Javadoc) is typically helpful for general cases, it may help to understand some of the details if you want to keep track of performance, for example. In the case of QC, it is recommended that Java developers have at least some basic knowledge of the underlying implementation of the quantum APIs, as this provides useful information that can be used to judge whether a quantum algorithm applies to a specific use case and what the performance impact will be.

Also, without this basic knowledge, you may worry about the initial performance of some of the algorithms. Indeed, if a quantum algorithm is executed on a quantum simulator, its performance will probably be worse than if a classic algorithm were used. However, if the quantum algorithm is well written and the problem applies to quantum speedup, its performance will dramatically improve when real quantum hardware is used.

2.4 Obtaining and installing the Strange code

As explained in the previous section, you typically don’t need to understand the implementation details of an algorithm. However, in this book, we explain the basic concepts of QC by showing code snippets of quantum algorithms. By looking at the implementations of some algorithms, you’ll learn more about the concepts of QC and become more knowledgeable about the areas where QC can make a big difference.

The Strange library we use throughout this book is written in Java. This allows you to use the quantum APIs in your own applications and enables you to have a deeper look at the implementations and modify or extend them when needed. If you are using a particular IDE (such as NetBeans, IntelliJ, or Eclipse), you should have no problem opening the library and reading the files.

2.4.1 Downloading the code

Similar to the examples and demos used in this book, the code for the Strange library can be downloaded from GitHub. The following command will provide you with a local copy of the Strange library:

git clone https://github.com/redfx-quantum/strange.git

Note that if you want to use the Strange library in your application, you don’t need to download the source code. Binary releases of Strange are uploaded to Maven Central, and build tools like Gradle and Maven will retrieve them from this uploaded location.

If for some reason you want to make modifications to Strange and test them locally, you can easily compile the whole project. Similar to our demo application in the previous section, Strange uses the Gradle build system to create the library.

The following Maven command can be used to build the library:

mvn install

The result of this operation is a local copy of the Strange library, which you can use in local applications. Before you can use your own library, you need to take into account two things:

  • The pom.xml file contains a version parameter. You can change that to whatever you want, but you have to be sure to use the same version in the dependencies section of your application.

  • Your application needs to include mavenLocal() in the list of its repositories.

2.4.2 A first look at the library

You can open the code in your IDE, or you can browse through the files. For example, you can open the Classic.java file that we discussed in the previous section. The source code for the Classic class is in Classic.java, which is in the src/main/java/org/redfx/ strange/algorithm folder under the directory where you cloned the Git repository. We will discuss this file in detail in chapter 7, but the following snippet shows the link between the Classic.randomBit() call from the previous section to the implementation using a quantum computer or a quantum simulator:

public static int randomBit() {
    Program program = new Program(1);
    Step s0 = new Step();
    s0.addGate(new Hadamard(0));
    program.addStep(s0);
    QuantumExecutionEnvironment qee =
            new SimpleQuantumExecutionEnvironment();
    Result result = qee.runProgram(program);
    Qubit[] qubits = result.getQubits();
    int answer = qubits[0].measure();
    return answer;
}

This snippet shows that the random bit returned by the randomBit() method is not simply generated by a classic random function but involves steps specific to QC. Again, Java developers typically don’t need to know much about the implementation, but by looking at it, you can learn a lot about QC.

2.5 Next steps

Now that you’ve downloaded the Strange library and run your first Java application using QC, it is time to learn more about the basic concepts of quantum computing. If you want to look into more code first, you’re welcome to browse the files in the Strange library. However, we recommended that you read about the basic concepts first. Whenever we introduce a concept, we will point to code in Strange where the concept is applied. By design, we avoid the high-level APIs in Strange, which contain quantum-specific concepts. In the following chapters, we explain the core concepts of QC by using the Strange low-level APIs.

Summary

  • Strange is a quantum computing simulator with high-level and low-level APIs.

  • You can easily create a HelloWorld application using the high-level API of Strange, and it will use quantum computing concepts under the hood.

  • The implementation of high-level APIs requires low-level APIs. Typically, you do not have to be bothered about those low-level APIs, but if you want to get a deeper understanding about quantum computing concepts, they are very helpful.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.89.24