This notebook scans the directory in which it lives to find all jupyter notebooks (other than itself) in that directory. It then prints for every notebook it finds (1) a hyperlink to the notebook, and (2) the first cell (which is always markdown) of the notebook. This way you can read a nice, automatically generated summary of all the notebooks without having to open all of them. If you find a notebook that you want to explore further, you can simply click on its link to open it.

In [1]:

```
import os
import json
from IPython.display import display, Markdown
# the name of this file
this_fname = 'SUMMARY.ipynb'
fname_to_md = {}
for fname in os.listdir('./'):
if fname[-6:] == '.ipynb' and fname != this_fname:
# print('------------', fname)
with open(fname, 'r', encoding="utf-8") as f:
fdata = json.load(f)
fname_to_md[fname] = ''.join(fdata['cells'][0]['source'])
# print(fname_to_md)
pre_sep = '\n\n<span style="color:red">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>\n\n'
full_md = ''
k = 1
num_nb = len(fname_to_md)
for fname, md in fname_to_md.items():
sep = pre_sep
sep += '[<a href="' + fname + '" target= "_blank">' + fname + '</a>] ' \
+ str(k) + '/' + str(num_nb) + '\n\n'
full_md += sep + md
k += 1
display(Markdown(full_md))
```

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[autograd_experiments.ipynb] 1/27

**References**

- https://github.com/HIPS/autograd/blob/master/docs/tutorial.md
- https://github.com/HIPS/autograd/blob/master/docs/updateguide.md

abbreviations:

- ax= axis
- dwrt= derivative with respect to

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Bell_and_CHSH_inequalities.ipynb] 2/27

$\newcommand{\bra}[1]{\left\langle{#1}\right|}$ $\newcommand{\ket}[1]{\left|{#1}\right\rangle}$

The purpose of this notebook is to simulate the CHSH experiment described in the IBM Quantum Experience tutorial in the section entitled

Multiple Qubits, Gates, and Entangled States/Entanglement and Bell Tests

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[examples_of_placeholder_usage.ipynb] 3/27

The word "Placeholder" is used in Qubiter (we are in good company, Tensorflow uses this word in the same way) to mean a variable for which we delay/postpone assigning a numerical value (evaluating it) until a later time. In the case of Qubiter, it is useful to define gates with placeholders standing for angles. One can postpone evaluating those placeholders until one is ready to call the circuit simulator, and then pass the values of the placeholders as an argument to the simulator’s constructor. Placeholders of this type can be useful, for example, with quantum neural nets (QNNs). In some QNN algorithms, the circuit gate structure is fixed but the angles of the gates are varied many times, gradually, trying to lower a cost function each time.

In Qubiter, legal variable names must be of form

`#3`

or`-#3`

or`#3*.5`

or`-#3*.5`

where 3 can be replaced by any non-negative int, and .5 can be replaced by anything that can be an argument of float() without throwing an exception. In this example, the 3 that follows the hash character is called the variable numberNEW! (functional placeholder variables) Now legal variable names can ALSO be of the form

`my_fun#1#2`

or`-my_fun#1#2`

, where

- the 1 and 2 can be replaced by any non-negative integers and there might be any number > 0 of hash variables. Thus, there need not always be precisely 2 hash variables as in the example.
`my_fun`

can be replaced by the name of any function with one or more input floats (2 inputs in the example), as long as the first character of the function's name is a lower case letter.The strings

`my_fun#1#2`

or`-my_fun#1#2`

indicate than one wants to use for the angle being replaced, the values of`my_fun(#1, #2)`

or`-my_fun(#1, #2)`

, respectively, where the inputs #1 and #2 are floats standing for radians and the output is also a float standing for radians.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Fedortchenko-paper.ipynb] 4/27

This notebook uses Qubiter to illustrate a pedagogical Teleportation experiment performed by S. Fedortchencko on IBM Quantum Experience, and described by him in the paper

$$\newcommand{\bra}[1]{\left\langle{#1}\right|}$$$$\newcommand{\ket}[1]{\left|{#1}\right\rangle}$$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[forbidden_cnot_expansions.ipynb] 5/27

Most chips are not fully connected (not all pairs of qubits are
physically connected). Furthermore, even if two qubits are connected,
one of them may be forbidden as a target of a CNOT between
the 2 qubits. The Qubiter file `ForbiddenCNotExpander.py`

contains an "expander" class of the same name that is
designed to circumvent this chip limitation.

The class reads an English file and outputs a new English file and corresponding Picture file. The new English file differs from the initial English file in that each forbbiden CNOT is expanded into a sequence of Hadamards and allowed, elementary CNOTs.

This notebook shows 2 examples of the usage of this class.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[gate-expansions.ipynb] 6/27

This notebook is intended to illustrate various gate expansions. Qubiter allows one to write on a single line in an English file many types of U(2) matrices with 0, 1, or more controls attached to it. However, there are well known identities for expanding such gates into a sequence of (1) single qubit rotations and (2) CNOTs with a single control. This is useful because most quantum computers (for example, IBM Quantum Experience) can only perform (1) and (2). Expansions into (1) and (2) can be performed automatically by Qubiter. Here is how.

The expansions used by Qubiter were all discovered long ago. They can all be found in the following 1995 quantum computing paper:

https://arxiv.org/abs/quant-ph/9503016

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[ghz_state.ipynb] 7/27

$\newcommand{\bra}[1]{\left\langle{#1}\right|}$ $\newcommand{\ket}[1]{\left|{#1}\right\rangle}$

The purpose of this notebook is to simulate the GHZ experiment described in the IBM Quantum Experience tutorial in the section entitled

Multiple Qubits, Gates, and Entangled States/GHZ states

If you understand our "Bell_and_CHSH_inequalities" notebook, this notebook uses very similar math.

It uses the following results whose proofs use techniques already covered in our "Bell_and_CHSH_inequalities" notebook

$\bra{ b_X} = \bra{ b_Z} H$

$\bra{ b_Y} = \bra{ b_Z} H S^\dagger$

for $b=0, 1$.

$\bra{\psi} \sigma_A(0) \sigma_B(1) \sigma_C(2)\ket{\psi} = \sum_{b_0 + b_1 + b_2 = 0, 2} Prob(b_0, b_1, b_2) - \sum_{b_0 + b_1 + b_2 = 1, 3} Prob(b_0, b_1, b_2)$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[loops_at_english_file_level_using_loop_files.ipynb] 8/27

Before reading this notebook, we recommend that you first learn how to use placeholders in Qubiter,
because placeholders and loops at the English file level are both used heavily in this notebook. They both go naturally together. Placeholder usage is illustrated in the notebook called `examples_of_placeholder_usage.ipynb`

located in the same folder as this one.

You can have loops at either the Python library level or the machine language level (i.e., English file). Both accomplish the same purpose. This notebook is only important to you if you want to use loops in an English file. The following talk explains some of the motivation and pros and cons of doing this.

http://www.ar-tiste.com/jan2019QubiterPlaceholderAndLoops.pdf

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_native_scipy.ipynb] 9/27

The purpose of this notebook is to describe a naive but pedagogical, first baby step, in the implementation of what is called in Qubiter the Mean Hamiltonian Minimization problem.

The qc history of this problem started with quantum chemists planning to use on a qc the phase estimation algo invented by Kitaev? (an algo that is also implemented in Qubiter) to estimate the energy levels ( eigenvalues) of simple molecules, initially H2. Then a bunch of people realized, heck, rather than trying to estimate the eigenvalues of a Hamiltonian by estimating the phase changes it causes, we can estimate those eigenvalues more efficiently by estimating the mean value of that Hamiltonian as measured empirically on a qc. Basically, just the Rayleigh-Ritz method, one of the oldest tricks in the book. One of the first papers to propose this mean idea is https://arxiv.org/abs/1304.3061 Their algo is commonly referred to by the ungainly name VQE (Variational Quantum Eigensolver) VQE was originally applied to do quantum chemistry with a qc. But now Rigetti and others have renamed it hybrid quantum-classical quantum computing and pointed out that it's an algo that has wide applicability, not just to quantum chemistry.

The idea behind hybrid quantum-classical is very simple. One has a classical box CBox and a quantum box QBox. The gates of QBox depend on N gate parameters. QBox sends info to CBox. CBox sends back to QBox N new gate parameters that will lower some cost function. This feedback process between CBox and QBox continues until the cost is minimized. The cost function is the mean value of a Hamiltonian which is estimated empirically from data obtained from the qc which resides inside the QBox.

To minimize a function of N continuous parameters, one can use some methods like simulated annealing and Powell that do not require calculating derivatives, or one can use methods that do use derivatives. Another possible separation is between methods that don't care which local minimum they find, as long as they find one of them, and those methods that try to find the best local minimum of them all, the so called global minimum. Yet another separation is between methods that allow constraints and those that don't.

Among the methods that do use derivatives, the so called gradient based methods only use the 1st derivative, whereas other methods use both first (Jacobian) and second (Hessian) derivatives. The performance of those that use both 1st and 2nd derivatives degrades quickly as N grows. Besides, calculating 2nd derivatives is very expensive. Hence, methods that use the 2nd derivatives are practically useless in the neural network field where N is usually very large. In that field, gradient based methods rule.

A method that uses no derivatives is Powell. A gradient based method that is designed to have a fast convergence rate is the Conjugate Gradient (CG) method. Another gradient based method is back-propagation (BP). BP can be implemented as distributed computing much more easily than other gradient based methods so it is favored by the most popular computer programs for doing distributed AI, such as PyTorch and Tensorflow.

Qubiter can perform minimization using various minlibs (minimization software libraries) such as 'scipy', 'autograd', 'pytorch', 'tflow'. It can also use various devices (aka simulators or backends), either virtual or real, to do the minimization.

Non-scipy minlibs implement backprop.

The 'scipy' minlib is a wrapper for the scipy function
`scipy.optimize.minimize`

. This scipy umbrella method implements many
minimization methods, including Powell and CG.

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html

By a native device, we mean one that uses Qubiter native simulators like SEO_simulator.

So, without further ado, here is an example of the use of
class `MeanHamilMinimizer`

with a scipy minlib and native device.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_native_without_autograd.ipynb] 10/27

This notebook is a counterpart to the notebook `MeanHamilMinimizer_native_with_autograd`

.
The first problem in both notebooks is identical and done all natively, but here it is done with scipy instead of autograd.

- Feedback loop between Qubiter and Qubiter
- minimization via scipy

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_native_with_autograd.ipynb] 11/27

- Feedback loop between Qubiter and Qubiter
- minimization via autograd

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_native_with_tf.ipynb] 12/27

- Feedback loop between Qubiter and Qubiter
- minimization via tensorflow

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_rigetti_autograd.ipynb] 13/27

- Feedback loop between Qubiter and Rigetti QVM
- minimization via autograd

This notebook calls Rigetti's method QVMConnection() which only works if you first:

- install the Rigetti Forest SDK available at https://www.rigetti.com/forest
- open a second terminal (besides the one that runs this notebook) and type "qvm -S" in it
- open a third terminal and type "quilc -S" in it

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[MeanHamilMinimizer_rigetti_scipy.ipynb] 14/27

- Feedback loop between Qubiter and Rigetti QVM
- minimization via scipy.optimize.minimize

This notebook calls Rigetti's method QVMConnection() which only works if you first:

- install the Rigetti Forest SDK available at https://www.rigetti.com/forest
- open a second terminal (besides the one that runs this notebook) and type "qvm -S" in it
- open a third terminal and type "quilc -S" in it

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[phase_est_examples.ipynb] 15/27

This notebook gives some examples of how to use Qubiter to write and simulate a quantum circuit that does quantum phase estimation (qPE).

Even though qPE was invented by Kitaev, it can be understood (See IBM Quantum Experience Tutorial for the details) as a quantum computer version of a much earlier model, namely, the von Neumann Pointer-System model for a quantum mechanical measurement.

In the case of quantum computers, the Pointer in von Neumann's model is represented by several "pointer qubits" and the System by several "system qubits". The matrix U whose eigenvalues we wish to find acts on the System qubits.

In Qubiter, we call the "pointer qubits" the "probes", and the qbits that U acts on the "atom qbits". We call U the "atom matrix". $\newcommand{\bra}[1]{\left\langle{#1}\right|}$ $\newcommand{\ket}[1]{\left|{#1}\right\rangle}$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[phase_est_iterative.ipynb] 16/27

$\newcommand{\bra}[1]{\left\langle{#1}\right|}$ $\newcommand{\ket}[1]{\left|{#1}\right\rangle}$

To economize in qubits, the References below advocate using the so called iterative Quantum Phase Estimation (iterative qPE). Whereas the usual qPE uses multiple pointer qubits and gives the answer in one shot (passage through a single circuit), the iterative qPE uses only a single pointer qubit but requires passage through multiple circuits, with the parameters of each circuit depending on the final pointer measurement of the previous circuit. This works because the kickback phases which each power of U sends to the pointers in the nomal qPE are cummulative: the k'th pointer gets a kickback phase which includes the kickback phases accrued by all previous pointer qubits.

In this example, we use

$U = e^{i*rads*\sigma_Z}$

for some Real number $rads$ and we use initial state $\ket{0}$, so $e^{i*rads}$ is the eigenvalue we seek.

Here are some of the equations used in the code below

```
for k in range(num_reps):
| H
| exp(i*alpha(k)*sigz)
U^(2^k)[email protected]
| H
| measure n(k) here
```

$\alpha(0) = n(0) =0$

$\alpha(k+1) = 2\alpha(k) + \frac{\pi}{2} n(k)$

$\alpha(k) = \pi 2^{k-2}\sum_{b=0}^{k-1} \frac{n(b)}{2^{b}}$

$rads = \frac{\alpha(num\_reps-1)}{2^{num\_reps-2}}$

https://arxiv.org/abs/1512.06860 by Google team

https://arxiv.org/abs/1605.03590 by Microsoft team

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[quantum_CSD_compiler_intro.ipynb] 17/27

The purpose of this notebook is to give a quick introduction to Qubiter's CSD quantum compiler capabilities.

By a quantum complier, we mean a computer program that takes as input an arbitrary unitary matrix $U$ of dimension $N=2^n$ and returns a SEO (sequence of elementary operations, in this case CNOTs and single qubit rotations) that equals $U$. There are various kinds of quantum compilers. Suppose $U$ is of the form $U=e^{-itH}$, where $t$ is time and $H$ is the Hamiltonian operator. If $H$ has a form which is known a priori, a situation that is common in Physics and Chemistry, then a popular way of expanding $U$ is by using the Trotter-Suzuki approximation. If the form of $H$ is not known a priori as is common in Artificial Intelligence, then we recommend using the CS (Cosine-Sine) decomposition of Linear Algebra. Both methods are already implemented in Qubiter, but this notebook is about the CSD.

Doing CSD quantum compiling with Qubiter requires using the classes in the quantum_CSD_compiler folder, which will only work properly if you install, besides all the Qubiter Python files and a Python distro that includes numpy and scipy (for example, Anaconda), some binary libraries prepared by Artiste-q.net which include a Python wrapper for a LAPACK subroutine called cuncsd.f that performs CSDs. How to install those binary libraries is explained elsewhere in this site. Henceforth, we will assume all the necessary files have been installed on your computer if you want to redo the calculations.

The quantum_CSD_compiler folder includes a pdf called csd-intro.pdf that gives an introduction to the CSD.

Some external references:

R.R. Tucci, A Rudimentary Quantum Compiler(2cnd Ed.) https://arxiv.org/abs/quant-ph/9902062

Qubiter 1.11, a C++ program whose first version was released together with Ref.1 above. Qubiter 1.11 is included in the quantum_CSD_compiler/LEGACY folder of this newer, pythonic version of Qubiter

R.R. Tucci, Quantum Fast Fourier Transform Viewed as a Special Case of Recursive Application of Cosine-Sine Decomposition, https://arxiv.org/abs/quant-ph/0411097

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[quantum_CSD_compiler_intro_CN.ipynb] 18/27

本文档介绍 *Qubiter* 所用的正余弦分解（CSD, Cosine-Sine decomposition）量子编译器及其性能。

量子编译器指以任意 $N=2^n$ 维的幺正矩阵 $U$ 作为输入，能够输出等价于矩阵 $U$ 的基本操作序列（比如 CNOT 受控反门和单量子比特旋转门）的计算机程序，可以有很多种。通常幺正矩阵 $U$ 的形式为 $U=e^{-itH}$，其中 $t$ 和 $H$ 分别代表时间和哈密顿算符。在物理学和量子化学领域中，$H$ 的具体形式往往可以先验已知，通常的做法是用 Trotter-Suzuki 近似对 $U$ 进行展开。而在人工智能等领域，哈密顿量 $H$ 的具体形式一般不能先验已知，这时候则推荐使用线性代数中正余弦分解（CSD）来处理矩阵。这两种不同的编译方式都可以使用 *Qubiter* 实现，此文档着重介绍正余弦分解编译方法。

使用 *Qubiter* 进行 CSD 量子编译需要调用 'quantum_CSD_compiler' 文件夹中的类文件。这些类的使用除了需要 *Qubiter* 的 Python 文件包和安装了 numpy、scipy 库的 Python 环境（例如 Anaconda ）外，还需要安装由 Artiste-qb.net 提供的二进制库。此库包括了 Python 封装的进行正余弦分解的 LAPACK 子程序 'cuncsd.f'。复述本文档中的计算需要安装所有必要的文件和库。

在 'quantum_CSD_compiler' 文件夹中的 'csd-intro.pdf' 文件提供了 CSD（正余弦分解）的介绍。其他参考文献有：

Qubiter 1.11: 基于 C++ 的原始

*Qubiter*版本。最初一版*Qubiter 1.11*和文献1同步发布。在新的*Qubiter*版本（基于 Python）的 'quantum_CSD_compiler/LEGACY' 文件夹中包含了*Qubiter 1.11*原始程序。R.R. Tucci,《量子快速傅立叶变换 - 正余弦分解递归应用举例》

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Say_Hello_World_With_Qubiter.ipynb] 19/27

The purpose of this notebook is to illustrate how to use Qubiter to simulate ( i.e., predict the outcome of) a simple quantum circuit with a few basic gates

Below, we won't always give the precise definition of each gate. You can find the precise analytical/numerical definition of all gates implemented by Qubiter in the document entitled

`qubiter_rosetta_stone.pdf`

included with the Qubiter distribution.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Stairs_circuit_and_its_gradients_in_native.ipynb] 20/27

A "quantum cost function" is the mean value of a Hermitian operator, wherein that mean value is calculated empirically from the data yielded by a physical quantum computer. (In this notebook, however, we fake that data with a Qubiter simulator. Just warming up. Brrmm! Brrmm! Everything is setup so that calls to a real physical qc such as Rigetti's qc can be easily substituted for the calls to the Qubiter simulator)

A Stairs circuit is a quantum circuit that in its full generality can parametrize a completely general quantum state vector.

In this notebook, we consider a special quantum cost function in which a Stairs circuit provides the state vector with which the mean values are calculated. I like to say that the Stairs circuit is the kernel of the quantum cost function. Our ultimate intention is to minimize this cost function using gradient descent. But to do that, we must first calculate the derivatives (gradients) of the cost function. That is what we will do in this notebook: calculate all the derivatives of a quantum cost function whose kernel is a Stairs circuit.

In particular, this notebook runs through their paces 4 Qubiter classes that increasingly build on each other

`StairsCkt_writer`

, writes English and Picture files for a Stairs quantum circuit`StairsDeriv_writer`

, writes English and Picture files for several quantum circuits that are needed to evaluate the derivatives of a Stairs circuit`StairsDeriv_native`

, evaluates the 4 derivatives of a single gate of a Stairs circuit. It uses native Qubiter simulators to do this. Qubiter also has an analogous class`StairsDeriv_rigetti`

that uses Rigetti simulators or their real physical qc. We will demo that class in a future notebook.`StairsAllDeriv_native`

, evaluates all the derivatives, for all the gates of a Stairs circuit. It uses native Qubiter simulators to do this. Qubiter also has an analogous class`StairsAllDeriv_rigetti`

that uses Rigetti simulators or their real physical qc. We will demo that class in a future notebook.

For an explanation of the theory behind the software that is being demo-ed in this notebook, see the following pdf included with the Qubiter distribution.

Title: Calculation of the Gradient of a Quantum Cost Function using "Threading". Application of these "threaded gradients" to a Quantum Neural Net inspired by Quantum Bayesian Networks,

https://github.com/artiste-qb-net/qubiter/blob/master/adv_applications/threaded_grad.pdf

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Stairs_ckt_its_gradients_in_rigetti.ipynb] 21/27

Before reading this Jupyter notebook, we recommend that you first read the earlier notebook named

`Stairs_circuit_and_its_gradients_in_native.ipynb`

located in the same folder in the Qubiter repo as this notebook. In that earlier notebook, we use the Qubiter (i.e., native) simulator to evaluate the gradients of a special quantum cost function. In this notebook, we evaluate the same gradients, but, instead of the native simulator, we use the Rigetti QVM (quantum virtual machine), which is a bit more complicated than using the native simulator.

Qubiter supports, as a single gate, a general U(2) operation with any number of controls, of either the T (full circle) or F (empty circle) kind. Such gates are fundamental to the Stairs circuit that we are considering. For now at least, Rigetti doesn't support such gates in a single step, so we have figured out a work-around until they do. Programmers are masters at figuring out work-arounds.

What we do is use Qubiter's class `CGateExpander`

to expand all
multi-controlled U(2) gates into simple CNOTs and
single qubit rotation gates. This is a very basic set of gates that
Rigetti's real and virtual machines can handle.
(Also,
right before the expansion, we substitute each placeholder
variable (aka parameter) by its float value.)
But `CGateExpander`

takes as input a quantum circuit written in Qubiter's language and
returns a new,
expanded, quantum circuit also written in Qubiter's language.
So further processing is required.
We then use Qubiter's class `Qubiter_to_RigettiPyQuil`

to translate the expanded quantum circuit from Qubiter's to Rigetti's language.
Once we have translated all the quantum circuits
to Rigetti's language, we are home free. From there on,
we just follow very similar steps to
those performed in the earlier, all-native notebook.

This notebook demos 2 Qubiter classes:

`StairsDeriv_rigetti`

, evaluates the 4 derivatives of a single gate of a Stairs circuit. It uses Rigetti simulators or their real physical qc to do this.`StairsAllDeriv_rigetti`

, evaluates all the derivatives, for all the gates of a Stairs circuit. It uses Rigetti simulators or their real physical qc to do this.

This notebook calls Rigetti's method QVMConnection() which only works if you first:

- install the Rigetti Forest SDK available at https://www.rigetti.com/forest
- open a second terminal (besides the one that runs this notebook) and type "qvm -S" in it
- open a third terminal and type "quilc -S" in it

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Teleportation-showcasing-IF_M-blocks.ipynb] 22/27

This notebook uses Qubiter to illustrate quantum Teleportation of the pure state of one qubit (at 0) to another qubit (at 2) with the help of an ancilla qubit (at 1).

The purpose of this notebook is not to teach about the "theory" behind quantum Teleportation. For that, the reader can go to numerous sources on the internet (Wikipedia, course notes, etc.) The purpose is to showcase some of the features of Qubiter, especially IF_M blocks (and also PRINT statements and calculations and plotting of various density matrices associated with any quantum circuit).

For a full inventory of Qubiter English file commands, see Qubiter's Rosetta Stone pdf

IBM has posted at https://github.com/QISKit/qiskit-tutorial, a jupyter notebook similar to this one, analysing the same quantum circuit for quantum Teleportation from one qubit to another. Their notebook uses IBM's qasm language instead of Qubiter's language so you might profit from comparing their notebook to this one to decide which qc language you prefer. Qubiter includes subroutines that can translate its language to IBM qasm that can then be run on IBM qc hardware.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Teleportation-showcasing-IF_M-blocks_CN.ipynb] 23/27

在此我们用Qubiter编译/模拟器来展示如何通过一个中间量子比特（比特1）的协助，将一个量子比特（比特0）的纯态传输到另一个量子比特（比特2）。

本文并不旨在讨论或展示量子传输背后的理论。对此感兴趣的读者可以很方便地在网上（维基或者课件）找到对于量子传输的简单推导。以量子传输为例，我们重点展示Qubiter的一些功能，例如测量模块（IF_M blocks）、打印输出，以及量子线路中各种密度矩阵的计算和画图功能。

QUbiter也支持自动生成量子线路的语言文件。感兴趣的读者可以在此找到 Qubiter语言文件的详解。

在IBM公司一系列量子计算的展示文档中，也有文档分析了量子态传送的量子传输过程及其量子线路。这些文档是用IBM推出的 qasm 语言组织的，读者可以对qasm语言和Qubiter语言结构进行比较并选用自己喜欢的程序。另外，除了量子编译和量子仿真之外，Qubiter提供了将自身语言转换为IBM qasm语言的子程序，这样通过Qubiter编译后的量子线路可以直接在IBM的量子计算硬件上运行。对其他（例如Rigetti）编译语言和硬件的支持也正在进行中。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[translating-qubiter-english-file-to-AnyQasm.ipynb] 24/27

aqasm= a quantum assembly language, a low level quantum language, containing a small but universal set of quantum gates such as CNOTs and single qubit rotations.

Note that in the `device_specific`

folder, Qubiter contains an abstract class called `Qubiter_to_AnyQasm`

. This abstract class is the parent to 3 other classes in the same folder called `Qubiter_to_IBMqasm`

, `Qubiter_to_GoogleCirq`

and `Qubiter_to_RigettiPyQuil`

. In this notebook, we will give examples of usage of these 3 child classes.
These 3 child classes translate Qubiter "English files" to "target" quantum languages IBM qasm, Google Cirq and Rigetti PyQuil,
respectively. These target quantum languages were chosen because they are very popular and their companies currently offer quantum computing devices on the cloud.
The parent class `Qubiter_to_AnyQasm`

does most of the hard work, so it will be easy in future to add child classes to Qubiter for other target quantum languages.

For all 3 target quantum languages, you can write a Jupyter notebook that translates a Qubiter English file into a bridge file in the target quantum language, and then automatically transmits that bridge file to the target company's cloud service, and gets a response back from that cloud service. That way you can run a q circuit on the target company's hardware directly from a Jupyter notebook on your computer.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Translating_from_Qubiter_to_Xanadu_PennyLane.ipynb] 25/27

The purpose of this notebook is to illustrate how to translate a Qubiter English file for a quantum circuit, into a Xanadu Pennylane "qnode"

Next, we will create 2 Qubiter English files and then translate them to Pennylanese

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[unusual_gates_like_generalized_swap.ipynb] 26/27

The purpose of this notebook is to illustrate 2 new members in the set of gates that Qubiter recognizes. The 2 gates are

- an arbitrary matrix U2 in U(2), parametrized as $U2 = \exp(i[ \theta_0 + \theta_1\sigma_X + \theta_2\sigma_Y + \theta_3\sigma_Z])$ for real $\theta_j$, where $\sigma_X, \sigma_Y, \sigma_Z$ are the Pauli matrices.
- a generalization of SWAP(0, 1) which I call SWAY(0, 1). SWAY includes SWAP, sqrt(SWAP), iSWAP, sqrt(iSWAP) etc. I discuss SWAY more precisely below.

The Qubiter simulator can now handle both of these gates with any number of controls of type T or F

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[widget_adjustable_parametric_circuit.ipynb] 27/27

Suppose you are interested in printing out the state vector of a quantum circuit at various times (points) in its evolution, as well as at the end of the circuit. Qubiter can do that.

Furthermore, suppose that the circuit is a parametric one, and you want to vary its parameters using sliders on a gui (graphical user interface). Qubiter can do that too, via a jupyter notebook with widgets. This notebook is one such notebook.

A jupyter notebook with widgets gives you the best of both worlds, the gui world and the notebooks world.

Gui's excel at reducing the possibility of user errors, increasing the ease of use for the user, and reducing the amount of understanding of the code that is demanded from the user in order for him or her to use the code correctly.

Notebooks excel at providing a robust, flexible, ready made, familiar method of documenting and saving your work for multiple use cases. They are also great for explaining your work to others with great detail and precision.

In [ ]:

```
```