Qulacs ドキュメンテーション

Qulacsは、高速な量子回路シミュレータであり、大きな量子回路やノイズがあったり、パラメトリックな量子回路にも対応しております。 Qulacsは、C/C++で実装されており、Pythonインターフェイスもあるため、高速回路シミュレーションと高い操作性の両立しました。

Qulacsは、藤井研究室 で開発され、QunaSysによる新機能の開発とメンテナンスが行われています。

インストール方法

pip install qulacs

トラブルシューティング: FAQ.

About Qulacs

Qulacs is a Python/C++ library for fast simulation of large, noisy, or parametric quantum circuits. Qulacs is developed at QunaSys, Osaka University, and NTT.

Qulacs is licensed under the MIT license.

Features

  • Fast quantum circuit simulation with parallelized C/C++ backend

  • Noisy quantum gate for simulation of NISQ devices

  • Parametric quantum gates for variational methods

  • Circuit compression for fast simulation

  • GPU support for fast simulation

  • Many utility functions for research

Performance

The time for simulating random quantum circuits is compared with several quantum circuit simulators in November 2020.

See the benchmark repository and Section VI and VII of our paper for the detail of this benchmark.

Note that the plots with names ending with "opt" and "heavy opt" perform circuit optimization for fast simulation, where the time for optimization is included in the execution time.

Single-thread benchmark

single thread benchmark

Multi-thread benchmark

multi thread benchmark

GPU benchmark

multi thread benchmark

Requirement

  • C++ compiler (gcc or VisualStudio)

    • gcc/g++ >= 7.0.0 (checked in Linux, MacOS, cygwin, MinGW, and WSL)

    • Microsoft VisualStudio C++ 2015 or 2017

  • Python 2.7 or 3.x

  • CMake >= 3.0

  • Git

  • (option) CUDA >= 8.0

  • (option) AVX2 support

If your system supports AVX2 instructions, SIMD optimization is automatically enabled. If you want to enable GPU simulator, install qulacs through qulacs-gpu package or build from source. Note that qulacs-gpu includes a CPU simulator. You don't need to install both.

If you encounter some troubles, see FAQ.

How to cite

Please cite this arXiv paper: Qulacs: a fast and versatile quantum circuit simulator for research purpose.

Installation

Quick Install

pip install qulacs

If your CPU is older than Intel Haswell architecture, the binary installed with the above command does not work. In this case, please install Qulacs with the following command. Even if your CPU is newer than Haswell, Qulacs installed with the below command shows better performance but takes a longer time. See "Install Python library from source" section for detail.

pip install git+https://github.com/qulacs/qulacs.git

If you have NVIDIA GPU and CUDA is installed, GPU-version can be installed with the following command:

pip install qulacs-gpu

Install Python library from source

To install Qulacs optimized for your system, we recommend the following install procedure for faster simulation of quantum circuits, while this requires a compiler and takes time for installation. In addition, you can enable or disable optimization features such as SIMD optimization, OpenMP parallelization, and GPU support.

A binary that is installed via pip command is optimized for Haswell architecture. Thus, Qulacs installed via pip command does not work with a CPU older than Haswell. If your CPU is newer than Haswell, Qualcs built from source shows the better performance.

Requirements
  • C++ compiler (gcc or VisualStudio)

    • gcc/g++ >= 7.0.0 (checked in Linux, MacOS, cygwin, MinGW, and WSL)

    • Microsoft VisualStudio C++ 2015 or 2017

  • Boost >= 1.71.0 (Minimum version tested in CI)

  • Python 2.7 or 3.x

  • CMake >= 3.0

  • Git

  • (option) CUDA >= 8.0

  • (option) AVX2 support

If your system supports AVX2 instructions, SIMD optimization is automatically enabled. If you want to enable GPU simulator, install qulacs through qulacs-gpu package or build from source. Note that qulacs-gpu includes a CPU simulator. You don't need to install both.

Qulacs is tested on the following systems.

  • Ubuntu 20.04

  • macOS Big Sur 11

  • Windows Server 2019

If you encounter some troubles, see FAQ.

How to install

Install with default options (Multi-thread without GPU):

pip install .

If AVX2 instructions are not supported, SIMD optimization is automatically disabled.

Install with GPU support (CUDA is required):

USE_GPU=Yes pip install .

Install single-thread Qulacs:

USE_OMP=No pip install .

The number of threads used in Qulacs installed with default options can be controlled via the environment variable OMP_NUM_THREADS. However, typically this option also affects the parallelization of other libraries. If you want to force only Qulacs to use a single thread, You can install single-thread Qulacs with the above command.

For development purpose, optional dependencies can be installed as follows.

# Install development tools
pip install .[dev]
# Install dependencies for document generation
pip install .[doc]

Uninstall Qulacs:

pip uninstall qulacs
Build C++ and Python library
Build with GCC

Static libraries of Qulacs can be built with the following command:

git clone https://github.com/qulacs/qulacs.git
cd qulacs
./script/build_gcc.sh

To build shared libraries, execute make shared at ./qulacs/build folder. When you want to build with GPU, use build_gcc_with_gpu.sh instead of build_gcc.sh.

When you want to build with GPU, use build_gcc_with_gpu.sh.

Build with MSVC

Static libraries of Qulacs can be built with the following command:

git clone https://github.com/qulacs/qulacs.git
cd qulacs
script/build_msvc_2017.bat

When you want to build with GPU, use build_msvc_2017_with_gpu.bat. If you use MSVC with other versions, use build_msvc_2015.bat or edit the generator name in build_msvc_2017.bat.

FAQ

Trouble-shootings

Compile error in C/C++
When I try to compile the C++ library, I get compile errors.

Codes might not be compiled with gcc or g++ version>=7.0.0. Please check codes are compiled with gcc and g++ and its version is greater or equal to 7.0.0.

For macOS Users: The default backend of gcc or g++ command is clang, which is not supported in Qulacs.

When I compile Qulacs with MinGW, the compiler says header files such as crypt.h or sys/select.h was not found. When objects are linked, the linker says library -lintl was not found.

This may occur when you try to build the 32bit Python library withthe 64bit compiler, or when you try to build the 64bit Python library with the 32bit compiler. If you compile the C++ library with 32bit/64bit, the Python library must be 32bit/64bit, respectively.

Error in Python library
I have many versions of Python, and I want to build Qulacs for a specific one.

Qulacs is built using the default Python. Please set the version of Python you want to use with pyenv or conda as the default. Then build Qulacs.

You can also specify a Python binary when building with CMake by adding -D PYTHON_EXECUTABLE:FILEPATH=/usr/bin/pythonx.x.

When I import the library, Python says there is no init function.

If you use Qulacs from Python and call functions directly using dll/pyd, do not change the name of the Python library. If you have changed the dll/pyd name of the Python library, you will see this error.

If you import the dll/pyd built with a different version of Python, you may see this error.

When I import the library, I get a Segmentation fault error.
Why does Python immediately exit when I import the library?
Why does Python miss functions that start with Py_?
Though there exist dll files, Python says there is no dll/pyd.

If you import dll/pyd built with a different version of Python, you will see these errors. Error messages depend on the version of Python.

Usage

See the following documents for more detail.

C++ Libraries

Add ./<qulacs_path>/include/ to include path, and ./<qulacs_path>/lib/ to library path.

Example of C++ code:

#include <iostream>
#include <cppsim/state.hpp>
#include <cppsim/circuit.hpp>
#include <cppsim/observable.hpp>

int main(){
    QuantumState state(3);
    state.set_Haar_random_state();

    QuantumCircuit circuit(3);
    circuit.add_X_gate(0);
    auto merged_gate = gate::merge(gate::CNOT(0,1),gate::Y(1));
    circuit.add_gate(merged_gate);
    circuit.add_RX_gate(1,0.5);
    circuit.update_quantum_state(&state);

    Observable observable(3);
    observable.add_operator(2.0, "X 2 Y 1 Z 0");
    observable.add_operator(-3.0, "Z 2");
    auto value = observable.get_expectation_value(&state);
    std::cout << value << std::endl;
    return 0;
}
GCC

You can build your codes with the following gcc commands:

g++ -O2 -I ./<qulacs_path>/include -L ./<qulacs_path>/lib <your_code>.cpp -lvqcsim_static -lcppsim_static -lcsim_static -fopenmp

If you want to run your codes with GPU, include cppsim/state_gpu.hpp and use QuantumStateGpu instead of QuantumState and build with the following command:

nvcc -O2 -I ./<qulacs_path>/include -L ./<qulacs_path>/lib <your_code>.cu -lvqcsim_static -lcppsim_static -lcsim_static -lgpusim_static -D _USE_GPU -lcublas -Xcompiler -fopenmp
MSVC

Your C++ codes can be built with Qulacs with the following process:

  1. Create an empty project.

  2. Select x64 as an active solution platform.

  3. Right Click your project name in Solution Explorer, and select Properties.

  4. At VC++ Directories section, add the full path to ./qulacs/include to Include Directories

  5. At VC++ Directories section, add the full path to ./qulacs/lib to Library Directories

  6. At C/C++ -> Code Generation section, change Runtime library to Multi-threaded (/MT).

  7. At Linker -> Input section, add vqcsim_static.lib;cppsim_static.lib;csim_static.lib; to Additional Dependencies.

Python Libraries

You can use features by simply importing qulacs.

Example of Python code:

from qulacs import Observable, QuantumCircuit, QuantumState
from qulacs.gate import Y,CNOT,merge

state = QuantumState(3)
state.set_Haar_random_state()

circuit = QuantumCircuit(3)
circuit.add_X_gate(0)
merged_gate = merge(CNOT(0,1),Y(1))
circuit.add_gate(merged_gate)
circuit.add_RX_gate(1,0.5)
circuit.update_quantum_state(state)

observable = Observable(3)
observable.add_operator(2.0, "X 2 Y 1 Z 0")
observable.add_operator(-3.0, "Z 2")
value = observable.get_expectation_value(state)
print(value)

Python 教材

量子状態

量子状態の生成

量子状態は QuantumState クラスを用いて生成します。生成した量子状態は \(|0\rangle^{\otimes n}\) に初期化されています。 量子状態を print することで量子状態の情報を表示できます。

from qulacs import QuantumState

# 2-qubitの状態を生成
n = 2
state = QuantumState(n)
print(state)
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(1,0)
(0,0)
(0,0)
(0,0)

一般的なノートパソコンやデスクトップPCでは26,27量子ビット程度がメモリ容量から作成できる限界です。

量子状態の初期化

生成した量子状態は set_computational_basis 関数で計算基底に初期化したり、set_Haar_random_state 関数でランダムな状態に初期化することが出来ます。 なお、Qulacsでは量子ビットの添え字は0から始まり、かつ \(\ket{0000}\) と書いたときに一番右のビットが0-th qubitになります(他のライブラリや教科書では一番左が0-th qubitであることもあります)。

from qulacs import QuantumState

n = 2
state = QuantumState(n)

# |00>に初期化
state.set_zero_state()

# 基底を二進数と見た時の整数値を入れて、その状態に初期化
state.set_computational_basis(0b01)
print(state)

# シードを指定してランダムな初期状態を生成
# (シードを省略した場合は時刻を用いてシードを決定します。)
seed = 0
state.set_Haar_random_state(seed)
print(state)
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(0,0)
(1,0)
(0,0)
(0,0)

 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
  (0.0531326,0.551481)
    (0.382474,0.10121)
(-0.499658,-0.0931227)
  (0.474029,-0.231262)
状態ベクトルの取得と設定

量子状態の状態ベクトルは get_vector 関数でnumpy arrayとして取得できます。また、load 関数でnumpy arrayやlistを与えることで量子状態を設定できます。

import numpy as np
from qulacs import QuantumState

n = 2
state = QuantumState(n)

# 状態ベクトルを取得
vec = state.get_vector()
print(type(vec), vec.dtype)
print(vec)

# 状態ベクトルを設定
myvec = np.array([0.5,0.5,0.5,0.5])
state.load(myvec)
print(state)
<class 'numpy.ndarray'> complex128
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(0.5,0)
(0.5,0)
(0.5,0)
(0.5,0)
量子状態に関する情報の計算

量子状態に対して、量子状態の状態を変えずに量子状態に関する情報を計算できます。例えば、指定した添え字のqubitを測定した時に、0を得る確率は get_zero_probability 関数で計算できます。

from qulacs import QuantumState

n = 5
state = QuantumState(n)
state.set_Haar_random_state(0)

# 指定した添え字のqubitをZ基底で測定して0を得る確率の計算
index = 3
zero_probability = state.get_zero_probability(index)
print("prob_meas_3rd : ",zero_probability)
prob_meas_3rd :  0.6015549753834679

量子状態を測定した時の結果をサンプリングするには sampling 関数が使えます。関数の引数はサンプリングするデータの個数です。

import numpy as np
from qulacs import QuantumState

n = 2
state = QuantumState(n)
state.load([1/np.sqrt(2), 0, 0.5, 0.5])
data = state.sampling(10)
print(data)
print([format(value, "b").zfill(2) for value in data]) # 二進数表示
[0, 3, 3, 3, 3, 0, 2, 3, 0, 3]
['00', '11', '11', '11', '11', '00', '10', '11', '00', '11']

このほかにも多くの関数が用意されています。詳しくはAdvancedの章を参照してください。

量子状態の内積

量子状態の内積は inner_product 関数で計算できます。

from qulacs import QuantumState
from qulacs.state import inner_product

n = 5
state_bra = QuantumState(n)
state_ket = QuantumState(n)
state_bra.set_Haar_random_state()
state_ket.set_computational_basis(0)

# 内積値の計算
value = inner_product(state_bra, state_ket)
print(value)
(0.1265907720817918+0.10220657039660046j)

量子ゲート

量子ゲートの生成

量子ゲートは qulacs.gate モジュールの中で定義されています。このモジュールでは幾つかの典型的な量子ゲートが既に定義されています。例えば、X-gateは以下のように生成できます。量子ゲートを print することでゲートの情報を表示できます。

from qulacs.gate import X

target_index = 1
x_gate = X(target_index)
print(x_gate)
 *** gate info ***
 * gate name : X
 * target    :
 1 : commute X
 * control   :
 * Pauli     : yes
 * Clifford  : yes
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
量子ゲートの作用

量子ゲートは update_quantum_state 関数で量子状態を更新できます。例えば、Xゲートを1st qubitに作用するには以下のようなコードを書きます。

from qulacs import QuantumState
from qulacs.gate import X

n = 2
state = QuantumState(n)
print(state)

index = 1
x_gate = X(index)
x_gate.update_quantum_state(state)
print(state)
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(1,0)
(0,0)
(0,0)
(0,0)

 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(0,0)
(0,0)
(1,0)
(0,0)
様々な量子ゲート

下記にしばしば使う名前の付いたゲートを紹介します。どのゲートも update_quantum_state 関数を用いて量子状態を更新できます。その他のゲートについては、Advancedの章を参照してください。

import numpy as np

# パウリゲート、アダマールゲート、Tゲート
from qulacs.gate import X, Y, Z, H, T
target = 2
x_gate = X(target)
y_gate = Y(target)
z_gate = Z(target)
h_gate = H(target)
t_gate = T(target)

# パウリ回転ゲート
from qulacs.gate import RX, RY, RZ
angle = np.pi / 4.0
rx_gate = RX(target, angle)
ry_gate = RY(target, angle)
rz_gate = RZ(target, angle)

# CNOT, CZ, SWAPゲート
from qulacs.gate import CNOT, CZ, SWAP
control = 1
target2 = 1
cnot_gate = CNOT(control, target)
cz_gate = CZ(control, target)
swap_gate = SWAP(target, target2)
一般的な量子ゲート

量子ゲートの行列をnumpy arrayで指定してゲートを生成するには、DenseMatrix クラスを用います。一つ目の引数が作用する添え字で、二つ目が行列です。1量子ビットゲートの場合は一つの整数と2×2行列を与えます。

from qulacs.gate import DenseMatrix

gate = DenseMatrix(1, [[0,1],[1,0]])
print(gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0)
(1,0) (0,0)

2量子ビット以上の大きさのゲートを作るには、一つ目の引数に対象となる添え字のリストを、二つ目に行列を与えます。\(n\) 量子ビットゲートを作るとき、 行列の大きさは \(2^n\) 次元でなければなりません。

from qulacs.gate import DenseMatrix

gate = DenseMatrix([0,1], [[0,1,0,0],[1,0,0,0],[0,0,0,1],[0,0,1,0]])
print(gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 5 : commute
 3 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0) (0,0) (0,0)
(1,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (1,0)
(0,0) (0,0) (1,0) (0,0)

なお、ゲート行列の列や行を数えるときに下位ビットとなる添え字は、ゲート生成時に与える添え字の順番に対応するため、上記の例で作用する添え字のリストが [0,1][1,0] では意味が異なることに注意してください。以下は添え字を入れ替えた時の違いを表しています。

from qulacs import QuantumState
from qulacs.gate import DenseMatrix

gate1 = DenseMatrix([0,1], [[0,1,0,0],[1,0,0,0],[0,0,0,1],[0,0,1,0]])
gate2 = DenseMatrix([1,0], [[0,1,0,0],[1,0,0,0],[0,0,0,1],[0,0,1,0]])
state = QuantumState(2)

state.set_zero_state()
gate1.update_quantum_state(state)
print(state.get_vector())

state.set_zero_state()
gate2.update_quantum_state(state)
print(state.get_vector())
[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
コントロールビットの追加

行列ゲートには、add_control_qubit 関数を用いてコントロールビットを追加できます。一つ目の引数はコントロールビットの添え字、二つ目の引数は0か1で、コントロールビットがその値だった時にtargetに操作を行います。例えばCNOTゲートではコントロールビットの値が1の時にtargetに走査を行うため、二つの目の引数は1になります。なお、Xゲートのような名前の付いた特殊なゲートはコントロールビットの追加が出来ません。これらにコントロールビットを追加するには、次のセクションの「一般的な行列ゲートへの変換」を参照してください。

from qulacs.gate import DenseMatrix

gate = DenseMatrix(1, [[0,1],[1,0]])
gate.add_control_qubit(3,1)
print(gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 1 : commute
 * control   :
 3 : value 1
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0)
(1,0) (0,0)
一般的な行列ゲートへの変換

Xゲートのような名前の付いた特殊なゲートは一般的な行列ゲートより高速に量子状態を更新できる一方、add_control_qubit 関数のような加工が行えません。特殊なゲートを元にしてゲートを加工するには、to_matrix_gate 関数を用いて特殊なゲートを一般的なゲートに変換します。

from qulacs.gate import X, to_matrix_gate

gate = X(1)
print(gate)
gate = to_matrix_gate(gate)
print(gate)
gate.add_control_qubit(3,1)
 *** gate info ***
 * gate name : X
 * target    :
 1 : commute X
 * control   :
 * Pauli     : yes
 * Clifford  : yes
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no

 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 1 : commute X
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0)
(1,0) (0,0)

変換によりゲート名が X から DenseMatrix に変わり陽にゲート行列を保持していることが分かります。

量子ゲートのゲート行列の取得

生成した量子ゲートのゲート行列は get_matrix 関数で取得できます。なお重要な注意点として、controlled-qubitがあるゲートの場合、controlled-qubitはゲート行列には含まれません。このため、例えばCNOTゲートのゲート行列は2x2行列になります。

from qulacs.gate import H, CNOT

h_gate = H(2)
matrix = h_gate.get_matrix()
print(matrix)
cnot_gate = CNOT(1,2)
matrix = cnot_gate.get_matrix()
print(matrix)
[[ 0.70710678+0.j  0.70710678+0.j]
 [ 0.70710678+0.j -0.70710678+0.j]]
[[0.+0.j 1.+0.j]
 [1.+0.j 0.+0.j]]

量子回路

量子回路の生成と構成

量子回路は QuantumCircuit クラスとして定義されています。QuantumCircuit クラスには add_<gatename>_gate としてゲートを追加するか、add_gate 関数を用いてゲートのインスタンスを追加できます。量子回路を print することで量子回路の情報が表示されます。

from qulacs import QuantumCircuit

n = 5
circuit = QuantumCircuit(n)
circuit.add_H_gate(0)
circuit.add_X_gate(2)

from qulacs.gate import X
gate = X(2)
circuit.add_gate(gate)

print(circuit)
*** Quantum Circuit Info ***
# of qubit: 5
# of step : 2
# of gate : 3
# of 1 qubit gate: 3
Clifford  : yes
Gaussian  : no
量子回路の作用

量子回路も量子ゲートのように update_quantum_state 関数を用いて量子状態を更新できます。

from qulacs import QuantumCircuit

n=3
circuit = QuantumCircuit(n)
circuit.add_H_gate(1)
circuit.add_RX_gate(2,0.1)

from qulacs import QuantumState
state = QuantumState(n)
circuit.update_quantum_state(state)
print(state)
 *** Quantum State ***
 * Qubit Count : 3
 * Dimension   : 8
 * State vector :
 (0.706223,0)
        (0,0)
 (0.706223,0)
        (0,0)
(0,0.0353406)
        (0,0)
(0,0.0353406)
        (0,0)

Python 教材 (上級)

この章は量子情報の用語をある程度知っていたり、数値計算のための細かなチューニングをしたい人のための解説です。 用語の詳細についてはM.A.Nielsenらによる教科書Quantum Computation and Quantum Information、または量子情報科学入門などを参照してください。

QuantumStateクラス

complex128 の精度で \(2^n\)個の複素配列をCPU/GPU上に確保し管理するクラスです。状態ベクトルの移動や変換の他、状態に関する情報の計算や変形をサポートします。

生成と破棄

インスタンス生成時に必要なメモリが確保されます。メモリはPythonがインスタンスを破棄した段階で解放されますが、メモリ解放のために明示的に破棄したい場合はdel で解放できます。

from qulacs import QuantumState
n = 2
state = QuantumState(n)
print(state)
del state
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(1,0)
(0,0)
(0,0)
(0,0)
量子状態とnumpy array間の変換

get_vector および load 関数で量子状態とnumpy arrayの相互変換が可能です。ノルムが保存しているかなどは原則チェックされません。 get_vector はすべての要素を配列で返しますが、get_amplitude を用いると単一の要素を高速に取得できます。

from qulacs import QuantumState

state = QuantumState(2)
vec = state.get_vector()
print(vec)
state.load([0,1,2,3])
print(state.get_vector())
print(state.get_amplitude(2))
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 2.+0.j 3.+0.j]
(2+0j)
量子状態間のコピー

量子状態は copy で自身と同じインスタンスを新たに生成できます。 また load 関数に量子状態を与えることで、既存の量子状態に新たに領域を確保することなく別の量子状態の量子ベクトルをコピーすることが出来ます。 これにより既に確保した領域を再利用できます。既に持っている量子状態と同じサイズの状態ベクトルを確保して、状態のコピーはしなくてよい場合は allocate_buffer 関数を使えます。

from qulacs import QuantumState

initial_state = QuantumState(3)
buffer = initial_state.allocate_buffer()
for ind in range(10):
    buffer.load(initial_state)
    # some computation and get results
量子状態の初期化

下記は量子状態を特定の状態に初期化する関数です。

from qulacs import QuantumState

n = 3
state = QuantumState(n)
# |0>状態へ初期化
state.set_zero_state()
print(state.get_vector())

# 指定値の二進数表記の計算基底へ初期化
state.set_computational_basis(0b101)
print(state.get_vector())

# 引数の値をシードとしてハール測度でランダムな純粋状態へ初期化
# 指定値が無い場合はtime関数がシードとして使われる。疑似乱数はxorshiftを利用。
state.set_Haar_random_state(0)
print(state.get_vector())
[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[ 0.02537775+0.26340418j  0.1826813 +0.04834094j -0.23865176-0.04447825j
  0.22641072-0.11045776j  0.07783625+0.24911921j  0.45253202+0.38419963j
  0.09236077-0.08936245j -0.5348115 -0.22094398j]
量子状態の検査

下記は量子状態を変えずに量子状態の情報を調べる関数の一覧です。

from qulacs import QuantumState

n = 5
state = QuantumState(n)
state.set_Haar_random_state(0)

# 量子ビットの数を得る。
qubit_count = state.get_qubit_count()
print("qubit_count", qubit_count)

# 指定番目の量子ビットが0に測定される確率を得る
prob = state.get_zero_probability(1)
print("zero_prob_1", prob)

# 任意の周辺確率を得る
# 引数は量子ビット数と同じ長さの配列
# 0,1,2を指定する。0,1はその添え字がその値で測定される確率、
# 2はそのビットを周辺化することを意味する。
# 例えば、3番目が0で、0番目が1と測定される確率の計算は下記
prob = state.get_marginal_probability([1,2,2,0,2])
print("marginal_prob", prob)

# Z基底で測定した時の確率分布のエントロピーを得る
ent = state.get_entropy()
print("entropy", ent)

# squared norm (<a|a>)の取得
# Trace preservingでない操作が可能なため、状態のノルムが1とは限らない
sq_norm = state.get_squared_norm()
print("sqaured_norm", sq_norm)

# 引数で与えた数の回数Z基底で全量子ビットを測定しサンプリングする。
# 得られるバイナリを整数値にしたもののリストを得る。
samples = state.sampling(10)
print("sampling", samples)

# 第2引数にseedを与えられる。
# 同じseedを指定すると常に同じサンプリング結果が返される。
samples_with_seed = state.sampling(10, 314)
print("sampling (with seed)", samples_with_seed)

# 状態ベクトルがCPU/GPUのどちらにあるかを文字列で取得する
dev_type = state.get_device_name()
print("device", dev_type)
qubit_count 5
zero_prob_1 0.46010755964245975
marginal_prob 0.20030608663813237
entropy 3.108273642412474
sqaured_norm 1.0
sampling [6, 22, 18, 7, 9, 6, 28, 28, 12, 17]
sampling (with seed) [23, 18, 28, 14, 17, 30, 9, 17, 16, 10]
device cpu
量子状態の変形

下記の関数は量子状態を書き換える関数です。

from qulacs import QuantumState
state = QuantumState(2)
state.set_computational_basis(0)
buffer = QuantumState(2)
buffer.set_computational_basis(2)
print("state" , state.get_vector())
print("buffer", buffer.get_vector())

# 量子状態間の和(state <- state+buffer)
# stateにbufferの状態を足し重ね合わせ状態を作ります。
# 操作後のノルムは一般に1ではありません。
state.add_state(buffer)
print("added", state.get_vector())

# 量子状態と複素数の積
# 引数の複素数を全要素に掛けます。
# 操作後のノルムは一般に1ではありません。
coef = 0.5 + 0.1j
state.multiply_coef(coef)
print("mul_coef", state.get_vector())

# 量子状態と、インデックスによって定められる複素数の積
# |00>方向にcoef_func(0),|01>方向にcoef_func(1),...を掛けます。
# 操作後のノルムは一般に1ではありません。
def coef_func(i: int) -> complex:
    assert 0 <= i < 2**2
    return 1j**i
state.multiply_elementwise_function(coef_func)
print("mul_elementwise_func", state.get_vector())

# 量子状態の正規化
# 引数として現在のsquared normを与える必要があります。
squared_norm = state.get_squared_norm()
print("sq_norm", squared_norm)
state.normalize(squared_norm)
print("normalized", state.get_vector())
print("sq_norm", state.get_squared_norm())
state [1.+0.j 0.+0.j 0.+0.j 0.+0.j]
buffer [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
added [1.+0.j 0.+0.j 1.+0.j 0.+0.j]
mul_coef [0.5+0.1j 0. +0.j  0.5+0.1j 0. +0.j ]
mul_elementwise_func [ 0.5+0.1j  0. +0.j  -0.5-0.1j  0. -0.j ]
sq_norm 0.52
normalized [ 0.69337525+0.13867505j  0.        +0.j         -0.69337525-0.13867505j
  0.        -0.j        ]
sq_norm 0.9999999999999998
古典レジスタの操作

量子状態は可変長の整数配列を古典レジスタを持ちます。 古典レジスタはInstrument操作の結果を書き込んだり、古典レジスタの結果を条件として実行するゲートを記述するのに用います。 まだ書き込まれていない古典レジスタの値は0です。なお、古典レジスタは copy, load 関数で量子状態を複製した際に同時に複製されます。

from qulacs import QuantumState
state = QuantumState(3)
position = 0
# position番目にvalueを書き込みます
value = 20
state.set_classical_value(position, value)
# position番目のレジスタ値を得ます
obtained = state.get_classical_value(position)
print(obtained)
20
量子状態間の計算

量子状態間の内積は inner_product() 、テンソル積は tensor_product() で得られます。

from qulacs import QuantumState
from qulacs.state import inner_product, tensor_product

n = 5
state_bra = QuantumState(n)
state_ket = QuantumState(n)
state_bra.set_Haar_random_state()
state_ket.set_computational_basis(0)

# 内積値の計算
value = inner_product(state_bra, state_ket)
print(value)

n1 = 1
state_ket1 = QuantumState(n1)
state_ket1.set_computational_basis(1)
n2 = 2
state_ket2 = QuantumState(n2)
state_ket2.set_computational_basis(2)

# テンソル積の計算
tensor_product_state = tensor_product(state_ket1, state_ket2)
print(tensor_product_state.get_vector())
(0.05141270657386601-0.076170974450624j)
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j]
量子ビットの入れ替えと削除

permutate_qubit() を使うと、量子ビットのインデックスを入れ替えることができます。 drop_qubit() を使うと、指定した量子ビットへの射影を得ることができます。

from qulacs import QuantumState
from qulacs.state import permutate_qubit, drop_qubit

n = 3
state = QuantumState(n)
state.set_Haar_random_state()
print("original:", state.get_vector())
# new qubit 0 is old qubit 1
# new qubit 1 is old qubit 2, 
# new qubit 2 is old qubit 0, 
permutate = permutate_qubit(state, [1, 2, 0])
print("permutate:", permutate.get_vector())
print()

n = 3
state = QuantumState(n)
state.set_Haar_random_state()
print("original:", state.get_vector())
state0 = drop_qubit(state, [1], [0])
print("projection to 0:", state0.get_vector()) # projection: qubit 1 is 0
state1 = drop_qubit(state, [1], [1])
print("projection to 1:", state1.get_vector()) # projection: qubit 1 is 1
original: [ 0.47596875+0.24786791j -0.48038246+0.34136556j  0.04879938-0.0561655j
 -0.12918592-0.19315999j -0.10305096-0.29802319j  0.30209327+0.18230977j
 -0.03063385+0.19866965j -0.01522536-0.20151271j]
permutate: [ 0.47596875+0.24786791j  0.04879938-0.0561655j  -0.10305096-0.29802319j
 -0.03063385+0.19866965j -0.48038246+0.34136556j -0.12918592-0.19315999j
  0.30209327+0.18230977j -0.01522536-0.20151271j]

original: [ 0.28277794-0.01961602j  0.13766219-0.37880092j  0.42393946-0.25863749j
  0.01986716-0.3834115j   0.21204559-0.12505476j -0.35120314+0.27877264j
 -0.06469476+0.08324203j  0.12606491+0.27299608j]
projection to 0: [ 0.28277794-0.01961602j  0.13766219-0.37880092j  0.21204559-0.12505476j
 -0.35120314+0.27877264j]
projection to 1: [ 0.42393946-0.25863749j  0.01986716-0.3834115j  -0.06469476+0.08324203j
  0.12606491+0.27299608j]
部分トレースの導出

partial_trace() を使うと、ある量子状態の指定した量子ビットでの部分トレースを密度行列として得ることができます。 変換後の量子ビットのインデックスは変換前の量子ビットの順番をもとに振り直されます。

from qulacs import QuantumState, DensityMatrix
from qulacs.gate import H, X
from qulacs.state import partial_trace

state = QuantumState(3)
state.set_computational_basis(0)
H(0).update_quantum_state(state)
X(1).update_quantum_state(state)
print(state.get_vector())

trace = partial_trace(state, [1])
print(trace.get_matrix())

dm_state = DensityMatrix(3)
dm_state.set_computational_basis(0)
H(0).update_quantum_state(dm_state)
X(1).update_quantum_state(dm_state)
print(dm_state.get_matrix())

trace = partial_trace(dm_state, [1])
print(trace.get_matrix())
[0.        +0.j 0.        +0.j 0.70710678+0.j 0.70710678+0.j
 0.        +0.j 0.        +0.j 0.        +0.j 0.        +0.j]
[[0.5+0.j 0.5+0.j 0. +0.j 0. +0.j]
 [0.5+0.j 0.5+0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]]
[[0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0.5+0.j 0.5+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0.5+0.j 0.5+0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j 0. +0.j]]
[[0.5+0.j 0.5+0.j 0. +0.j 0. +0.j]
 [0.5+0.j 0.5+0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]]
GPUを用いた計算

Qulacsをqulacs-gpuパッケージからインストールした場合、QuantumStateGpu クラスが使用できます。クラス名が異なる以外、利用方法は QuantumState と同じです。

from qulacs import QuantumStateGpu
state = QuantumStateGpu(2)
print(state)
print(state.get_device_name())
 *** Quantum State ***
 * Qubit Count : 2
 * Dimension   : 4
 * State vector :
(1,0)
(0,0)
(0,0)
(0,0)

gpu

使い方は QuantumState と同様ですが、二点留意点があります。

  1. get_vector 関数はGPU/CPU間のコピーを要するため長い時間がかかります。出来る限りこの関数の利用を回避して計算を行うべきです。

  2. CPU/GPUの状態間の inner_product は計算できません。GPUとCPUの状態ベクトルの間で状態ベクトルの load を行うことは可能ですが、時間がかかるので避けるべきです。

DensityMatrixクラス

密度行列として量子状態を保持するクラスです。 StateVector は純粋状態のみを保持できますが、DensityMatrix を用いると複数の状態が確率的に合わさった混合状態を表すことができます。 \(p_i\) の確率で \(\ket{\psi_i}\) であるとき、\(\sum_i p_i\ket{\psi_i}\bra{\psi_i}\) という密度行列を用います。 この章では複数状態が合成された状態は出てこないので冗長に見えますが、後述の Probabilistic ゲートなどを用いたときに有用となります。 DensityMatrix は基本的には QuantumState と同じように操作できます。

生成と破棄

インスタンス生成時に必要なメモリが確保されます。メモリはPythonがインスタンスを破棄した段階で解放されますが、メモリ解放のために明示的に破棄したい場合は del で解放できます。 print によって密度行列の要素を表示することができます。

from qulacs import DensityMatrix
n = 2
state = DensityMatrix(n)
print(state)
del state
 *** Density Matrix ***
 * Qubit Count : 2
 * Dimension   : 4
 * Density matrix :
(1,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0)
量子状態とnumpy array間の変換

get_matrix および load 関数で量子状態とnumpy arrayの相互変換が可能です。 arrayが1次元の場合は状態ベクトルから密度行列へ変換し、2次元の場合はそのまま密度行列として読み込みます。 ノルムが保存しているかなどは原則チェックされません。

from qulacs import DensityMatrix

state = DensityMatrix(2)
mat = state.get_matrix()
print(mat)
state.load([0,1,2,3])
print(state.get_matrix())
state.load([[0,1,2,3], [1,2,3,4], [2,3,4,5], [3,4,5,6]])
print(state.get_matrix())
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
[[0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 1.+0.j 2.+0.j 3.+0.j]
 [0.+0.j 2.+0.j 4.+0.j 6.+0.j]
 [0.+0.j 3.+0.j 6.+0.j 9.+0.j]]
[[0.+0.j 1.+0.j 2.+0.j 3.+0.j]
 [1.+0.j 2.+0.j 3.+0.j 4.+0.j]
 [2.+0.j 3.+0.j 4.+0.j 5.+0.j]
 [3.+0.j 4.+0.j 5.+0.j 6.+0.j]]
量子状態間のコピー

量子状態は copy で自身と同じインスタンスを新たに生成できます。 また load 関数に量子状態を与えることで、既存の量子状態に新たに領域を確保することなく別の量子状態の量子ベクトルや密度行列をコピーすることが出来ます。 これにより既に確保した領域を再利用できます。既に持っている量子状態と同じサイズの密度行列を確保して、状態のコピーはしなくてよい場合は allocate_buffer 関数を使えます。

from qulacs import QuantumState, DensityMatrix

initial_state = DensityMatrix(3)
copied_state = initial_state.copy()
buffer = initial_state.allocate_buffer()
buffer.load(initial_state)
state_vector = QuantumState(3)
buffer.load(state_vector)
量子状態の初期化

下記は量子状態を特定の純粋状態に初期化する関数です。

from qulacs import DensityMatrix

n = 2
state = DensityMatrix(n)
# |0>状態へ初期化
state.set_zero_state()
print(state.get_matrix())

# 指定値の二進数表記の計算基底へ初期化
state.set_computational_basis(0b10)
print(state.get_matrix())

# 引数の値をシードとしてハール測度でランダムな純粋状態へ初期化
# 指定値が無い場合はtime関数がシードとして使われる。疑似乱数はxorshiftを利用。
state.set_Haar_random_state(0)
print(state.get_matrix())
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
[[0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
[[ 0.06955138+0.j         -0.01203783+0.07302921j  0.10872467+0.04574116j
  -0.14160694+0.15896533j]
 [-0.01203783-0.07302921j  0.07876443+0.j          0.02921052-0.12207811j
   0.19142327+0.12117438j]
 [ 0.10872467-0.04574116j  0.02921052+0.12207811j  0.20004359+0.j
  -0.11681879+0.3416283j ]
 [-0.14160694-0.15896533j  0.19142327-0.12117438j -0.11681879-0.3416283j
   0.6516406 +0.j        ]]
量子状態の検査

下記は量子状態を変えずに量子状態の情報を調べる関数の一覧です。

from qulacs import DensityMatrix

n = 5
state = DensityMatrix(n)
state.set_Haar_random_state(0)

# 量子ビットの数を得る。
qubit_count = state.get_qubit_count()
print("qubit_count", qubit_count)

# 指定番目の量子ビットが0に測定される確率を得る
prob = state.get_zero_probability(1)
print("zero_prob_1", prob)

# 任意の周辺確率を得る
# 引数は量子ビット数と同じ長さの配列
# 0,1,2を指定する。0,1はその添え字がその値で測定される確率、
# 2はそのビットを周辺化することを意味する。
# 例えば、3番目が0で、0番目が1と測定される確率の計算は下記
prob = state.get_marginal_probability([1,2,2,0,2])
print("marginal_prob", prob)

# Z基底で測定した時の確率分布のエントロピーを得る
ent = state.get_entropy()
print("entropy", ent)

# squared norm (<a|a>)の取得
# Trace preservingでない操作が可能なため、状態のノルムが1とは限らない
sq_norm = state.get_squared_norm()
print("sqaured_norm", sq_norm)

# 引数で与えた数の回数Z基底で全量子ビットを測定しサンプリングする。
# 得られるバイナリを整数値にしたもののリストを得る。
samples = state.sampling(10)
print("sampling", samples)

# 第2引数にseedを与えられる。
# 同じseedを指定すると常に同じサンプリング結果が返される。
samples_with_seed = state.sampling(10, 314)
print("sampling (with seed)", samples_with_seed)

# 状態ベクトルがCPU/GPUのどちらにあるかを文字列で取得する
dev_type = state.get_device_name()
print("device", dev_type)
qubit_count 5
zero_prob_1 0.4601075596424598
marginal_prob 0.20030608663813237
entropy 3.1082736424124744
sqaured_norm 1.0000000000000002
sampling [11, 11, 14, 11, 22, 0, 19, 19, 3, 17]
sampling (with seed) [23, 18, 28, 14, 17, 30, 9, 17, 16, 10]
device cpu
量子状態の変形

下記の関数は量子状態を書き換える関数です。 add_statemultiply_coef は密度行列の各成分について演算を行います。

QuantumState での同名の演算と根本的に振る舞いの違うものになっています。

  • QuantumStateadd_state は量子重ね合わせ状態を作りますが、DensityMatrixadd_state は混合状態を作ります。

  • QuantumState での multiply_coef(z) に対応する操作は DensityMatrix では multiply_coef(abs(z)**2) になります。

これらの関数は QuantumState で生成されたものと混ざって混乱しやすいため、state.make_superposition() state.make_mixture() の使用を推奨します。

from qulacs import DensityMatrix
state = DensityMatrix(2)
state.set_computational_basis(0)
buffer = DensityMatrix(2)
buffer.set_computational_basis(2)
print("state" , state.get_matrix())
print("buffer", buffer.get_matrix())

# 量子状態間の和(state <- state+buffer)
# stateにbufferの状態を加えて混合状態を作ります。
# 操作後のノルムは一般に1ではありません。
state.add_state(buffer)
print("added", state.get_matrix())

# 量子状態と複素数の積
# 引数の複素数を全要素に掛けます。
# 操作後のノルムは一般に1ではありません。
coef = 3.0
state.multiply_coef(coef)
print("mul_coef", state.get_matrix())

# 量子状態の正規化
# 引数として現在のsquared normを与える必要があります。
squared_norm = state.get_squared_norm()
print("sq_norm", squared_norm)
state.normalize(squared_norm)
print("normalized", state.get_matrix())
print("sq_norm", state.get_squared_norm())
state [[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
buffer [[0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
added [[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
mul_coef [[3.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 3.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
sq_norm 6.0
normalized [[0.5+0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0.5+0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]]
sq_norm 1.0
古典レジスタの操作

DensityMatrix も可変長の整数配列の古典レジスタを持ちます。

from qulacs import DensityMatrix
state = DensityMatrix(3)
position = 0
# position番目にvalueを書き込みます
value = 20
state.set_classical_value(position, value)
# position番目のレジスタ値を得ます
obtained = state.get_classical_value(position)
print(obtained)
20
重ね合わせ状態・混合状態の作成

重ね合わせ状態や混合状態は state モジュールの make_superposition() make_mixture() を使うことで作成できます。 これらの状態は QuantumState DensityMatrixadd_state()multiply_coef() を適用することで作成することもできますが、可読性が低いため非推奨です。

from qulacs import QuantumState, DensityMatrix
from qulacs.state import make_superposition, make_mixture

# QuantumState |a> と |b> について、重ね合わせ状態 p|a> + q|b> を生成する
a = QuantumState(2)
a.set_computational_basis(0b00)
b = QuantumState(2)
b.set_computational_basis(0b11)
p = 1 / 2
q = 1 / 2
c = make_superposition(p, a, q, b)
print(c.get_vector())

# QuantumState |a> と DensityMatrix |b><b| について、混合状態 p|a><a| + q|b><b| を生成する
# QuantumState 同士や DensityMatrix 同士でも混合状態を生成することができる
a = QuantumState(2)
a.set_computational_basis(0b00)
b = DensityMatrix(2)
b.set_computational_basis(0b11)
p = 1 / 2
q = 1 / 2
c = make_mixture(p, a, q, b)
print(c.get_matrix())
[0.5+0.j 0. +0.j 0. +0.j 0.5+0.j]
[[0.5+0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0. +0.j]
 [0. +0.j 0. +0.j 0. +0.j 0.5+0.j]]

量子ゲート

量子ゲートに共通の操作
量子ゲートの種類

量子ゲートは特殊ゲートと一般ゲートの二種類にわかれます。なお、Qulacsではユニタリ演算子に限らず、InstrumentやCPTP-mapをはじめとする任意の量子状態を更新する操作をゲートと呼びます。

特殊ゲートは事前に指定されたゲート行列を持ち、量子ゲートに対し限定された変形しか行えないものを指します。例えば、パウリゲート、パウリでの回転ゲート、射影測定などが対応します。特殊ゲートの利点は、ゲートの特性が限定されているため量子状態の更新関数が一般ゲートに比べ効率的である点です。また、定義時に自身が各量子ビットで何らかのパウリの基底で対角化されるかの情報を保持しており、この情報は回路最適化の時に利用されます。特殊ゲートの欠点は上記の理由からゲートに対する可能な操作が限定されている点です。

作用するゲート行列を露に持つゲートを一般ゲートと呼びます。一般ゲートの利点はゲート行列を好きに指定できるところですが、欠点は特殊ゲートに比べ更新が低速である点です。

量子ゲートに共通の操作

生成した量子ゲートのゲート行列は get_matrix 関数で取得できます。 control量子ビットなどはゲート行列に含まれません。 特にゲート行列を持たない種類のゲート(例えば \(n\) qubitのパウリ回転ゲート)などは取得に非常に大きなメモリと時間を要するので気を付けてください。 print 関数を使用してゲートの情報を表示できます。

import numpy as np
from qulacs.gate import X
gate = X(2)
mat = gate.get_matrix()
print(mat)
print(gate)
[[0.+0.j 1.+0.j]
 [1.+0.j 0.+0.j]]
 *** gate info ***
 * gate name : X
 * target    :
 2 : commute X
 * control   :
 * Pauli     : yes
 * Clifford  : yes
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
特殊ゲート

下記に特殊ゲートを列挙します。

1量子ビットゲート

第一引数に対象ビットの添え字を取ります。

from qulacs.gate import Identity # 単位行列
from qulacs.gate import X, Y, Z # パウリ
from qulacs.gate import H, S, Sdag, sqrtX, sqrtXdag, sqrtY, sqrtYdag # クリフォード
from qulacs.gate import T, Tdag # Tゲート
from qulacs.gate import P0, P1 # 0,1への射影 (規格化はされない)
target = 3
gate = T(target)
print(gate)
 *** gate info ***
 * gate name : T
 * target    :
 3 : commute     Z
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : yes
 * Parametric: no
 * Diagonal  : yes

Identity は量子状態を更新しませんが、量子回路に入れると1stepを消費するゲートとしてカウントされます。

1量子ビット回転ゲート

第一引数に対象ビットの添え字を、第二引数に回転角を取ります。

import numpy as np
from qulacs.gate import RX, RY, RZ
target = 0
angle = 0.1
gate = RX(target, angle)
print(gate)
print(gate.get_matrix())
 *** gate info ***
 * gate name : X-rotation
 * target    :
 0 : commute X
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
[[0.99875026+0.j         0.        +0.04997917j]
[0.        +0.04997917j 0.99875026+0.j        ]]

回転操作の定義は \(R_X(\theta) = \exp(i\frac{\theta}{2} X)\) です。

IBMQの基底ゲート

IBMQのOpenQASMで定義されている、virtual-Z分解に基づくゲートです。

from qulacs.gate import U1,U2,U3
print(U3(0, 0.1, 0.2, 0.3))
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
            (0.99875,0) (-0.0477469,-0.0147699)
 (0.0489829,0.00992933)     (0.876486,0.478826)

定義はそれぞれ

  • \(U_1(\lambda) = R_Z(\lambda)\)

  • \(U_2(\phi, \lambda) = R_Z(\phi+\frac{\pi}{2}) R_X(\frac{\pi}{2}) R_Z(\lambda-\frac{\pi}{2})\)

  • \(U_3(\theta, \phi, \lambda) = R_Z(\phi+3\pi) R_X(\pi/2) R_Z(\theta+\pi) R_X(\pi/2) R_Z(\lambda)\)

になります。U3 は任意の1qubitユニタリ操作の自由度と一致します。

2量子ビットゲート

第1,2引数に対象ビットの添え字を取ります。CNOTゲートは第一引数がcontrol qubitになります。 残りのゲートは対称な操作です。

from qulacs.gate import CNOT, CZ, SWAP
control = 5
target = 2
target2 = 3
gate = CNOT(control, target)
print(gate)
gate = CZ(control, target)
gate = SWAP(target, target2)
 *** gate info ***
 * gate name : CNOT
 * target    :
 2 : commute X
 * control   :
 5 : value 1
 * Pauli     : no
 * Clifford  : yes
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
多ビットパウリ操作

多ビットパウリ操作はターゲット量子ビットのリストとパウリ演算子のリストを引数としてゲートを定義します。 \(n\)-qubitパウリ操作の更新測度は1-qubitパウリ操作の更新コストとオーダーが同じため、パウリのテンソル積はこの形式でゲートを定義した方が多くの場合得です。 パウリ演算子の指定は1,2,3がそれぞれX,Y,Zに対応します。

from qulacs.gate import Pauli
target_list = [0,3,5]
pauli_index = [1,3,1] # 1:X , 2:Y, 3:Z
gate = Pauli(target_list, pauli_index) # = X_0 Z_3 X_5
print(gate)
print(gate.get_matrix())
 *** gate info ***
 * gate name : Pauli
 * target    :
 0 : commute X
 3 : commute     Z
 5 : commute X
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
[[ 0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  1.+0.j  0.+0.j  0.+0.j]
 [ 0.+0.j  0.+0.j  0.+0.j  0.+0.j  1.+0.j  0.+0.j  0.+0.j  0.+0.j]
 [ 0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j -1.-0.j]
 [ 0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j -1.-0.j  0.+0.j]
 [ 0.+0.j  1.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j]
 [ 1.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j]
 [ 0.+0.j  0.+0.j  0.+0.j -1.-0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j]
 [ 0.+0.j  0.+0.j -1.-0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j]]
多ビットパウリ回転操作

多ビットパウリ演算子の回転操作です。多ビットのパウリ回転は愚直にゲート行列を計算すると大きいものになりますが、この形で定義すると効率的に更新が可能です。

from qulacs.gate import PauliRotation
target_list = [0,3,5]
pauli_index = [1,3,1] # 1:X , 2:Y, 3:Z
angle = 0.5
gate = PauliRotation(target_list, pauli_index, angle) # = exp(i angle/2 X_0 Z_3 X_5)
print(gate)
print(gate.get_matrix().shape)
 *** gate info ***
 * gate name : Pauli-rotation
 * target    :
 0 : commute X
 3 : commute     Z
 5 : commute X
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
(8, 8)
可逆回路

\(2^n\) 個の添え字に対する全単射関数を与えることで、基底間の置換操作を行います。 ゲート行列が置換行列になっていることと同義です。全単射でない場合正常に動作しないため注意してください。

from qulacs.gate import ReversibleBoolean
def upper(val, dim):
    return (val+1)%dim
target_list = [0,1]
gate = ReversibleBoolean(target_list, upper)
print(gate)
state = QuantumState(3)
state.load(np.arange(2**3))
print(state.get_vector())
gate.update_quantum_state(state)
print(state.get_vector())
 *** gate info ***
 * gate name : ReversibleBoolean
 * target    :
 0 : commute
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no

[0.+0.j 1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j 6.+0.j 7.+0.j]
[3.+0.j 0.+0.j 1.+0.j 2.+0.j 7.+0.j 4.+0.j 5.+0.j 6.+0.j]

上記のコードは対象の量子ビットの部分空間でベクトルの要素を一つずつ下に下げます(一番下の要素は一番上に動きます)。

状態反射

量子状態 \(|a\rangle\) を引数として定義される、\((2|a\rangle \langle a|-I)\) というゲートです。 これは \(|a\rangle\) という量子状態をもとに反射する操作に対応します。グローバー探索で登場するゲートです。 このゲートが作用する相手の量子ビット数は、引数として与えた量子状態の量子ビット数と一致しなければいけません。

from qulacs.gate import StateReflection
from qulacs import QuantumState
axis = QuantumState(2)
axis.set_Haar_random_state(0)
state = QuantumState(2)
gate = StateReflection(axis)
gate.update_quantum_state(state)
print("axis", axis.get_vector())
print("reflected", state.get_vector())
gate.update_quantum_state(state)
print("two reflection", state.get_vector())
axis [ 0.0531326 +0.55148118j  0.38247419+0.10120994j -0.49965781-0.09312274j
  0.47402911-0.231262j  ]
reflected [-0.38609087+0.j          0.15227445-0.41109954j -0.15580712+0.54120805j
 -0.20470048-0.54741137j]
two reflection [1.+0.j 0.+0.j 0.+0.j 0.+0.j]
一般ゲート

ゲート行列をあらわに持つ量子ゲートです。

密行列ゲート

密行列を元に定義されるゲートです。

from qulacs.gate import DenseMatrix

# 1-qubit gateの場合
gate = DenseMatrix(0, [[0,1],[1,0]])
print(gate)

# 2-qubit gateの場合
gate = DenseMatrix([0,1], [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
print(gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0)
(1,0) (0,0)

 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(1,0) (0,0) (0,0) (0,0)
(0,0) (1,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (1,0)
(0,0) (0,0) (1,0) (0,0)
疎行列ゲート

疎行列を元に定義されるゲートです。要素が十分疎である場合、密行列より高速に更新が可能です。 疎行列はscipyの csc_matrix を用いて定義してください。

from qulacs import QuantumState
from qulacs.gate import SparseMatrix
from scipy.sparse import csc_matrix
mat = csc_matrix((2,2))
mat[1,1] = 1
print("sparse matrix", mat)

gate = SparseMatrix([0], mat)
print(gate)

qs = QuantumState(2)
qs.load([1,2,3,4])
gate.update_quantum_state(qs)
print(qs.get_vector())
sparse matrix   (1, 1)  (1+0j)

 *** gate info ***
 * gate name : SparseMatrix
 * target    :
 0 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
0 0
0 (1,0)

[0.+0.j 2.+0.j 0.+0.j 4.+0.j]
コントロールビットの追加

一般ゲートは add_control_qubit 関数を用いてcontrol qubitを加えることが可能です。 control qubitが0,1のどちらの場合にtargetに作用が生じるかも指定できます。

import numpy as np
from qulacs.gate import to_matrix_gate, X

index = 0
x_gate = X(index)
x_mat_gate = to_matrix_gate(x_gate)

# 1st-qubitが0の場合だけゲートを作用
control_index = 1
control_with_value = 0
x_mat_gate.add_control_qubit(control_index, control_with_value)
print(x_mat_gate)

from qulacs import QuantumState
state = QuantumState(3)
state.load(np.arange(2**3))
print(state.get_vector())

x_mat_gate.update_quantum_state(state)
print(state.get_vector())
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute X
 * control   :
 1 : value 0
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0,0) (1,0)
(1,0) (0,0)

[0.+0.j 1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j 6.+0.j 7.+0.j]
[1.+0.j 0.+0.j 2.+0.j 3.+0.j 5.+0.j 4.+0.j 6.+0.j 7.+0.j]
複数のゲートから新たなゲートを作る操作
ゲートの積

続けて作用する量子ゲートを合成し、新たな単一の量子ゲートを生成できます。これにより量子状態へのアクセスを減らせます。

import numpy as np
from qulacs import QuantumState
from qulacs.gate import X, RY, merge

n = 3
state = QuantumState(n)
state.set_zero_state()

index = 1
x_gate = X(index)
angle = np.pi / 4.0
ry_gate = RY(index, angle)

# ゲートを合成して新たなゲートを生成
# 第一引数のゲートが先に作用する
x_and_ry_gate = merge(x_gate, ry_gate)
print(x_and_ry_gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
 (0.382683,0)   (0.92388,0)
  (0.92388,0) (-0.382683,0)
ゲートの和

複数のゲートの和を取り、新たなゲートを作ることが出来ます。 例えばパウリ演算子 \(P\) に対して \((I+P)/2\) といった+1固有値空間への射影を作るときに便利です。

import numpy as np
from qulacs.gate import P0,P1,add, merge, Identity, X, Z

gate00 = merge(P0(0),P0(1))
gate11 = merge(P1(0),P1(1))
# |00><00| + |11><11|
proj_00_or_11 = add(gate00, gate11)
print(proj_00_or_11)

gate_ii_zz = add(Identity(0), merge(Z(0),Z(1)))
gate_ii_xx = add(Identity(0), merge(X(0),X(1)))
proj_00_plus_11 = merge(gate_ii_zz, gate_ii_xx)
# ((|00>+|11>)(<00|+<11|))/2 = (II + ZZ)(II + XX)/4
proj_00_plus_11.multiply_scalar(0.25)
print(proj_00_plus_11)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(1,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (1,0)

 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 0 : commute
 1 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
(0.5,0)   (0,0)   (0,0) (0.5,0)
  (0,0)   (0,0)   (0,0)   (0,0)
  (0,0)   (0,0)   (0,0)   (0,0)
(0.5,0)   (0,0)   (0,0) (0.5,0)
ランダムユニタリ

ハール測度でランダムなユニタリ行列をサンプリングし、密行列ゲートを生成するには RandomUnitary 関数を用います。

from qulacs.gate import RandomUnitary
target_list = [2,3]
gate = RandomUnitary(target_list)
print(gate)
 *** gate info ***
 * gate name : DenseMatrix
 * target    :
 2 : commute
 3 : commute
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : no
 * Matrix
 (-0.259248,-0.150756)  (-0.622614,-0.539728) (-0.0289836,-0.154895)    (0.437381,0.122371)
  (0.0853439,0.215282)    (-0.157238,0.20972)   (-0.471882,-0.39828)   (-0.201449,0.675116)
   (0.780141,0.161283)  (-0.374972,-0.279089)  (-0.0835221,0.258196)  (-0.238478,-0.127904)
(-0.469496,-0.0370718)  (-0.123494,-0.136361)   (-0.304384,0.653894)    (-0.457639,0.12122)
確率的作用

Probabilistic 関数を用いて、複数のゲート操作と確率分布を与えて確率的な作用を作成します。 与える確率分布の総和が1に満たない場合、満たない確率で Identity が作用します。

from qulacs.gate import Probabilistic, H, Z
distribution = [0.2, 0.2, 0.2]
gate_list = [H(0), Z(0), X(1)]
gate = Probabilistic(distribution, gate_list)
print(gate)

from qulacs import QuantumState
state = QuantumState(2)
for _ in range(10):
    gate.update_quantum_state(state)
    print(state.get_vector())
 *** gate info ***
 * gate name : Generic gate
 * target    :
 * control   :
 * Pauli     : no
 * Clifford  : no
 * Gaussian  : no
 * Parametric: no
 * Diagonal  : yes

[ 1.+0.j -0.-0.j  0.+0.j -0.-0.j]
[ 1.+0.j -0.-0.j  0.+0.j -0.-0.j]
[ 1.+0.j -0.-0.j  0.+0.j -0.-0.j]
[ 1.+0.j -0.-0.j  0.+0.j -0.-0.j]
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
[0.        +0.j 0.        +0.j 0.70710678+0.j 0.70710678+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]

なお、確率的作用をするゲートとして、BitFlipNoise, DephasingNoise, IndependentXZNoise, DepolarizingNoise, TwoQubitDepolarizingNoise ゲートが定義されています。 それぞれ、エラー確率を入れることで Probabilistic のインスタンスが生成されます。

from qulacs.gate import BitFlipNoise, DephasingNoise, IndependentXZNoise, DepolarizingNoise, TwoQubitDepolarizingNoise
target = 0
second_target = 1
error_prob = 0.8
gate = BitFlipNoise(target, error_prob) # X: prob
gate = DephasingNoise(target, error_prob) # Z: prob
gate = IndependentXZNoise(target, error_prob) # X,Z : prob*(1-prob), Y: prob*prob
gate = DepolarizingNoise(target, error_prob) # X,Y,Z : prob/3
gate = TwoQubitDepolarizingNoise(target, second_target, error_prob) # {I,X,Y,Z} \times {I,X,Y,Z} \setminus {II} : prob/15

from qulacs import QuantumState
state = QuantumState(2)
for _ in range(10):
    gate.update_quantum_state(state)
    print(state.get_vector())
[0.-0.j 0.+0.j 0.-0.j 0.+1.j]
[0.-0.j 0.+0.j 0.-0.j 0.+1.j]
[0.+0.j 0.+1.j 0.+0.j 0.+0.j]
[0.-0.j 0.+0.j 0.+0.j 1.-0.j]
[-1.+0.j  0.+0.j  0.+0.j  0.+0.j]
[ 0.+0.j  0.+0.j -1.+0.j  0.+0.j]
[-1.+0.j -0.+0.j  0.+0.j -0.+0.j]
[-1.+0.j  0.-0.j  0.+0.j  0.-0.j]
[ 0.+0.j -1.+0.j  0.+0.j  0.+0.j]
[ 0.+0.j -1.+0.j  0.+0.j  0.+0.j]

環境から相互作用を受け、時間発展によって減衰させるゲートとして、NoisyEvolutionNoisyEvolution_fast があります。 これらは、以下の手順で利用できます。

  1. 環境から相互作用を受けるシステムをハミルトニアンとして設定し、相互作用の演算子を指定する。

  2. 時間発展させる値と微小変化させる時間を指定する。

  3. 微分方程式を解く。

    • NoisyEvolutionはルンゲクッタ法を使用して、微分方程式を解きます。

    • NoisyEvolution_fast は行列を抜き出して対角化で求めます。

NoisyEvolution_fast は微小変化させる時間の指定は不要で、処理も高速であることから、NoisyEvolution_fast を使用することを推奨します。

from qulacs import QuantumState, Observable, GeneralQuantumOperator
from qulacs.gate import NoisyEvolution, NoisyEvolution_fast, H

n = 2
observable = Observable(n)
observable.add_operator(1., "X 0")

# create hamiltonian and collapse operator
hamiltonian = Observable(n)
hamiltonian.add_operator(1., "Z 0 Z 1")

decay_rate_z = 0.2
decay_rate_p = 0.6
decay_rate_m = 0.1

# interacting operator
c_ops = [GeneralQuantumOperator(n) for _ in range(3*n)]
c_ops[0].add_operator(decay_rate_z, "Z 0")
c_ops[1].add_operator(decay_rate_z, "Z 1")
c_ops[2].add_operator(decay_rate_p/2, "X 0")
c_ops[2].add_operator(decay_rate_p/2*1j, "Y 0")
c_ops[3].add_operator(decay_rate_p/2, "X 1")
c_ops[3].add_operator(decay_rate_p/2*1j, "Y 1")
c_ops[4].add_operator(decay_rate_m/2, "X 0")
c_ops[4].add_operator(-decay_rate_m/2*1j, "Y 0")
c_ops[5].add_operator(decay_rate_m/2, "X 1")
c_ops[5].add_operator(-decay_rate_m/2*1j, "Y 1")

time = 2.
gate = NoisyEvolution_fast(hamiltonian, c_ops, time)
#dt = .1
#gate = NoisyEvolution(hamiltonian, c_ops, time, dt)

exp = 0.
n_samples = 1000
state = QuantumState(n)
for k in range(n_samples):
   state.set_zero_state()
   H(0).update_quantum_state(state)
   H(1).update_quantum_state(state)
   gate.update_quantum_state(state)
   exp += observable.get_expectation_value(state) / n_samples
   print(f"[{k}] exp: {exp}")
[0] exp: 0.0
[1] exp: -0.0006155544536970823
[2] exp: -2.168404344971009e-19
[3] exp: -2.168404344971009e-19
[4] exp: -2.168404344971009e-19
[5] exp: -0.0006155544536970825
[6] exp: -4.336808689942018e-19
(略)
[995] exp: -0.2967070487040435
[996] exp: -0.29720105798458607
[997] exp: -0.29720105798458607
[998] exp: -0.29781661243828317
[999] exp: -0.29781661243828317
CPTP写像

CPTP は完全性を満たすクラウス演算子のリストを与えて作成します。

from qulacs.gate import merge,CPTP, P0,P1

gate00 = merge(P0(0),P0(1))
gate01 = merge(P0(0),P1(1))
gate10 = merge(P1(0),P0(1))
gate11 = merge(P1(0),P1(1))

gate_list = [gate00, gate01, gate10, gate11]
gate = CPTP(gate_list)

from qulacs import QuantumState
from qulacs.gate import H,merge
state = QuantumState(2)
for _ in range(10):
    state.set_zero_state()
    merge(H(0),H(1)).update_quantum_state(state)
    gate.update_quantum_state(state)
    print(state.get_vector())
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]

なお、CPTP-mapとして AmplitudeDampingNoise ゲートが定義されています。

from qulacs.gate import AmplitudeDampingNoise
target = 0
damping_rate = 0.1
AmplitudeDampingNoise(target, damping_rate) # K_0: [[1,0],[0,sqrt(1-p)]], K_1: [[0,sqrt(p)], [0,0]]
Instrument

Instrumentは一般のCPTP-mapの操作に加え、ランダムに作用したクラウス演算子の添え字を取得する操作です。 例えば、Z基底での測定は P0P1 からなるCPTP-mapを作用し、どちらが作用したかを知ることに相当します。 cppsimでは Instrument 関数にCPTP-mapの情報と、作用したクラウス演算子の添え字を書きこむ古典レジスタのアドレスを指定することで実現します。

from qulacs import QuantumState
from qulacs.gate import merge,Instrument, P0,P1

gate00 = merge(P0(0),P0(1))
gate01 = merge(P1(0),P0(1))
gate10 = merge(P0(0),P1(1))
gate11 = merge(P1(0),P1(1))

gate_list = [gate00, gate01, gate10, gate11]
classical_pos = 0
gate = Instrument(gate_list, classical_pos)

from qulacs import QuantumState
from qulacs.gate import H,merge
state = QuantumState(2)
for index in range(10):
    state.set_zero_state()
    merge(H(0),H(1)).update_quantum_state(state)
    gate.update_quantum_state(state)
    result = state.get_classical_value(classical_pos)
    print(index, format(result,"b").zfill(2), state.get_vector())
0 11 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]
1 11 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]
2 00 [1.+0.j 0.+0.j 0.+0.j 0.+0.j]
3 01 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]
4 10 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
5 10 [0.+0.j 0.+0.j 1.+0.j 0.+0.j]
6 01 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]
7 01 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]
8 01 [0.+0.j 1.+0.j 0.+0.j 0.+0.j]
9 11 [0.+0.j 0.+0.j 0.+0.j 1.+0.j]

なお、Instrumentとして Measurement ゲートが定義されています。

from qulacs.gate import Measurement
target = 0
classical_pos = 0
gate = Measurement(target, classical_pos)
Adaptive操作

古典レジスタの値の可変長リストを引数としブール値を返す関数を用いて、古典レジスタから求まる条件に応じて操作を行うか決定するゲートです。条件はPythonの関数として記述することができます。 Pythonの関数は int 型のリストを引数として受け取り、bool 型を返す関数でなくてはなりません。

from qulacs.gate import Adaptive, X

def func(list):
    print("func is called! content is ",list)
    return list[0]==1


gate = Adaptive(X(0), func)

state = QuantumState(1)
state.set_zero_state()

# funcがFalseを返すため、Xは作用しない
state.set_classical_value(0,0)
gate.update_quantum_state(state)
print(state.get_vector())

# funcがTrueを返すため、Xが作用する
state.set_classical_value(0,1)
gate.update_quantum_state(state)
print(state.get_vector())
func is called! content is  [0]
[1.+0.j 0.+0.j]
func is called! content is  [1]
[0.+0.j 1.+0.j]

物理量

パウリ演算子

オブザーバブルは実係数を持つパウリ演算子の線形結合として表現されます。 PauliOperator クラスはその中のそれぞれの項を表す、\(n\)-qubitパウリ演算子の元に係数を付与したものを表現するクラスです。 ゲートと異なり、量子状態の更新はできません。

パウリ演算子の生成と状態の取得
from qulacs import PauliOperator
coef = 0.1
s = "X 0 Y 1 Z 3"
pauli = PauliOperator(s, coef)

# pauliの記号を後から追加
pauli.add_single_Pauli(3, 2)

# pauliの各記号の添え字を取得
index_list = pauli.get_index_list()

# pauliの各記号を取得 (I,X,Y,Z -> 0,1,2,3)
pauli_id_list = pauli.get_pauli_id_list()

# pauliの係数を取得
coef = pauli.get_coef()

# pauli演算子のコピーを作成
another_pauli = pauli.copy()

s = ["I","X","Y","Z"]
pauli_str = [s[i] for i in pauli_id_list]
terms_str = [item[0] + " " + str(item[1]) for item in zip(pauli_str,index_list)]
full_str = str(coef) + " " + " ".join(terms_str)
print(full_str)

# pauliの係数を変更・取得
pauli.change_coef(0.5)
coef = pauli.get_coef()

# pauliの文字列表現を取得
pauli_strings = pauli.get_pauli_string()

print(coef, pauli_strings)
(0.1+0j) X 0 Y 1 Z 3 Y 3
(0.5+0j) X 0 Y 1 Z 3 Y 3
パウリ演算子の期待値

状態に対してパウリ演算子の期待値や遷移モーメントを評価できます。

from qulacs import PauliOperator, QuantumState

n = 5
coef = 2.0
Pauli_string = "X 0 X 1 Y 2 Z 4"
pauli = PauliOperator(Pauli_string,coef)

# 期待値の計算 <a|H|a>
state = QuantumState(n)
state.set_Haar_random_state()
value = pauli.get_expectation_value(state)
print("expect", value)

# 遷移モーメントの計算 <a|H|b>
# 第一引数がブラ側に来る
bra = QuantumState(n)
bra.set_Haar_random_state()
value = pauli.get_transition_amplitude(bra, state)
print("transition", value)
expect (-0.013936248917618807-0j)
transition (-0.009179829550387531-0.02931360609180049j)
一般の線形演算子

線形演算子 GeneralQuantumOperator はパウリ演算子の複素数の線形結合で表されます。係数付きの PauliOperator を項として add_operator で追加することが出来ます。

from qulacs import GeneralQuantumOperator, PauliOperator, QuantumState

n = 5
operator = GeneralQuantumOperator(n)

# pauli演算子を追加できる
coef = 2.0+0.5j
Pauli_string = "X 0 X 1 Y 2 Z 4"
pauli = PauliOperator(Pauli_string,coef)
operator.add_operator(pauli)
# 直接係数と文字列から追加することもできる
operator.add_operator(0.5j, "Y 1 Z 4")

# 項の数を取得
term_count = operator.get_term_count()

# 量子ビット数を取得
qubit_count = operator.get_qubit_count()

# 特定の項をPauliOperatorとして取得
index = 1
pauli = operator.get_term(index)

# ハミルトニアンであるかどうかを判定
is_hermitian = operator.is_hermitian()

# 期待値の計算 <a|H|a>
## 一般に自己随伴ではないので複素が帰りうる
state = QuantumState(n)
state.set_Haar_random_state()
value = operator.get_expectation_value(state)
print("expect", value)

# オペレーターを作用させる
result = QuantumState(n)
work_state = QuantumState(n)
operator.apply_to_state(work_state, state, result)

# 遷移モーメントの計算 <a|H|b>
# 第一引数がブラ側に来る
bra = QuantumState(n)
bra.set_Haar_random_state()
value = operator.get_transition_amplitude(bra, state)
print("transition", value)
expect (0.01844802681960955+0.05946837146359432j)
transition (-0.00359496979054156+0.0640782452494485j)
OpenFermionを用いたオブザーバブルの生成

OpenFermionは化学計算で解くべきハミルトニアンをパウリ演算子の表現で与えてくれるツールです。このツールの出力をファイルまたは文字列の形で読み取り、演算子の形で使用することが可能です。

from qulacs.quantum_operator import create_quantum_operator_from_openfermion_file
from qulacs.quantum_operator import create_quantum_operator_from_openfermion_text

open_fermion_text = """
(-0.8126100000000005+0j) [] +
(0.04532175+0j) [X0 Z1 X2] +
(0.04532175+0j) [X0 Z1 X2 Z3] +
(0.04532175+0j) [Y0 Z1 Y2] +
(0.04532175+0j) [Y0 Z1 Y2 Z3] +
(0.17120100000000002+0j) [Z0] +
(0.17120100000000002+0j) [Z0 Z1] +
(0.165868+0j) [Z0 Z1 Z2] +
(0.165868+0j) [Z0 Z1 Z2 Z3] +
(0.12054625+0j) [Z0 Z2] +
(0.12054625+0j) [Z0 Z2 Z3] +
(0.16862325+0j) [Z1] +
(-0.22279649999999998+0j) [Z1 Z2 Z3] +
(0.17434925+0j) [Z1 Z3] +
(-0.22279649999999998+0j) [Z2]
"""

operator = create_quantum_operator_from_openfermion_text(open_fermion_text)
print(operator.get_term_count())
print(operator.get_qubit_count())
# create_quantum_operator_from_openfermion_fileの場合は上記が書かれたファイルのパスを引数で指定する。
エルミート演算子/オブザーバブル

エルミート演算子はパウリ演算子の実数での線形結合で表されます。 固有値と期待値が実数であることを保証される以外、GeneralQuatnumOperator クラスと等価です。

外部ファイルから読み込んで処理をする関数は quantum_operatorobservable に置き換えて create_observable_from_openfermion_file, create_observable_from_openfermion_text, create_split_observable, などの関数で可能です。

演算子を対角項と非対角な項に分離する

演算子をファイルからで読み込む際、create_split_observable 関数で対角成分と非対角成分に分離できます。

from qulacs.observable import create_split_observable, create_observable_from_openfermion_file

# 事前にH2.txtをopenfermonの形式で配置する必要があります。
operator = create_observable_from_openfermion_file("./H2.txt")
diag, nondiag = create_split_observable("./H2.txt")
print(operator.get_term_count(), diag.get_term_count(), nondiag.get_term_count())
print(operator.get_qubit_count(), diag.get_qubit_count(), nondiag.get_qubit_count())
基底状態を求める

power method あるいは arnoldi method を用いて演算子の基底状態を求めることができます。 計算後に引数の state には対応する基底状態が代入されます。

power method
from qulacs import Observable, QuantumState
from qulacs.observable import create_observable_from_openfermion_file

n = 4
operator = create_observable_from_openfermion_file("./H2.txt")
state = QuantumState(n)
state.set_Haar_random_state()
value = operator.solve_ground_state_eigenvalue_by_power_method(state, 50)
print(value)
Arnoldi method:
from qulacs import Observable, QuantumState
from qulacs.observable import create_observable_from_openfermion_file

n = 4
operator = create_observable_from_openfermion_file("./H2.txt")
state = QuantumState(n)
state.set_Haar_random_state()
value = operator.solve_ground_state_eigenvalue_by_arnoldi_method(state, 50)
print(value)
量子状態に適用する

演算子を量子状態に適用することができます。

from qulacs import Observable, QuantumState
from qulacs.observable import create_observable_from_openfermion_file

n = 4
operator = create_observable_from_openfermion_file("./H2.txt")
state = QuantumState(n)
state.set_Haar_random_state()
result = QuantumState(n)
work_state = QuantumState(n)
operator.apply_to_state(work_state, state, result)
print(result)

量子回路

量子回路の構成

量子回路は量子ゲートの集合として表されます。 例えば以下のように量子回路を構成できます。

from qulacs import QuantumState, QuantumCircuit
from qulacs.gate import Z
n = 3
state = QuantumState(n)
state.set_zero_state()

circuit = QuantumCircuit(n)

# 量子回路にhadamardゲートを追加
for i in range(n):
    circuit.add_H_gate(i)

# ゲートを生成し、それを追加することもできる。
for i in range(n):
    circuit.add_gate(Z(i))

# 量子回路を状態に作用
circuit.update_quantum_state(state)

print(state.get_vector())
[ 0.35355339+0.j -0.35355339-0.j -0.35355339-0.j  0.35355339+0.j
 -0.35355339-0.j  0.35355339+0.j  0.35355339+0.j -0.35355339-0.j]
量子回路のdepthの計算と最適化

量子ゲートをまとめて一つの量子ゲートとすることで、量子ゲートの数を減らすことができ、数値計算の時間を短縮できることがあります。 (もちろん、対象となる量子ビットの数が増える場合や、専用関数を持つ量子ゲートを合成して専用関数を持たない量子ゲートにしてしまった場合は、トータルで計算時間が減少するかは状況に依ります。)

下記のコードでは optimize 関数を用いて、量子回路の量子ゲートをターゲットとなる量子ビットが3つになるまで貪欲法で合成を繰り返します。

from qulacs import QuantumCircuit
from qulacs.circuit import QuantumCircuitOptimizer
n = 5
depth = 10
circuit = QuantumCircuit(n)
for d in range(depth):
    for i in range(n):
        circuit.add_H_gate(i)

# depthを計算(depth=10)
print(circuit.calculate_depth())

# 最適化
opt = QuantumCircuitOptimizer()
# 作成を許す最大の量子ゲートのサイズ
max_block_size = 3
opt.optimize(circuit, max_block_size)

# depthを計算(depth=1へ)
print(circuit.calculate_depth())
10
1
量子回路の情報デバッグ

量子回路を print すると、量子回路に含まれるゲートの統計情報などが表示されます。

from qulacs import QuantumCircuit
from qulacs.circuit import QuantumCircuitOptimizer
n = 5
depth = 10
circuit = QuantumCircuit(n)
for d in range(depth):
    for i in range(n):
        circuit.add_H_gate(i)

print(circuit)
*** Quantum Circuit Info ***
# of qubit: 5
# of step : 10
# of gate : 50
# of 1 qubit gate: 50
Clifford  : yes
Gaussian  : no

変分量子回路

量子回路を ParametricQuantumCircuit クラスとして定義すると、通常の QuantumCircuit クラスの関数に加え、変分法を用いて量子回路を最適化するのに便利ないくつかの関数を利用することができます。

変分量子回路の利用例

一つの回転角を持つ量子ゲート(RX, RY, RZ, multi_qubit_pauli_rotation)はパラメトリックな量子ゲートとして量子回路に追加することができます。 パラメトリックなゲートとして追加された量子ゲートについては、量子回路の構成後にパラメトリックなゲート数を取り出したり、後から回転角を変更することができます。

from qulacs import ParametricQuantumCircuit
from qulacs import QuantumState
import numpy as np

n = 5
depth = 10

# construct parametric quantum circuit with random rotation
circuit = ParametricQuantumCircuit(n)
for d in range(depth):
    for i in range(n):
        angle = np.random.rand()
        circuit.add_parametric_RX_gate(i,angle)
        angle = np.random.rand()
        circuit.add_parametric_RY_gate(i,angle)
        angle = np.random.rand()
        circuit.add_parametric_RZ_gate(i,angle)
    for i in range(d%2, n-1, 2):
        circuit.add_CNOT_gate(i,i+1)

# add multi-qubit Pauli rotation gate as parametric gate (X_0 Y_3 Y_1 X_4)
target = [0,3,1,4]
pauli_ids = [1,2,2,1]
angle = np.random.rand()
circuit.add_parametric_multi_Pauli_rotation_gate(target, pauli_ids, angle)

# get variable parameter count, and get current parameter
parameter_count = circuit.get_parameter_count()
param = [circuit.get_parameter(ind) for ind in range(parameter_count)]

# set 3rd parameter to 0
circuit.set_parameter(3, 0.)

# update quantum state
state = QuantumState(n)
circuit.update_quantum_state(state)

# output state and circuit info
print(state)
print(circuit)
 *** Quantum State ***
 * Qubit Count : 5
 * Dimension   : 32
 * State vector :
   (0.187449,0.0161955)
 (-0.179316,0.00524451)
 (0.00347095,0.0476141)
   (0.106624,0.0178808)
(-0.0577202,0.00342914)
    (0.101846,0.280231)
  (-0.187288,-0.210536)
  (0.0558002,0.0337467)
  (0.0180534,0.0594363)
     (0.06433,0.076302)
   (0.109149,-0.167976)
(0.00171454,-0.0767738)
   (0.128206,-0.107731)
   (0.273894,-0.122758)
   (0.0994833,0.151077)
   (0.112889,-0.313486)
(-0.00982741,0.0165689)
   (0.11043,-0.0646575)
(-0.0923695,-0.0794695)
  (-0.0198962,0.150974)
(-0.0580249,-0.0885592)
  (-0.048759,-0.196734)
 (-0.0940465,-0.215696)
   (0.106312,0.0912926)
  (-0.177757,-0.128979)
   (0.0940203,0.149268)
  (0.0702079,0.0503984)
 (-0.232558,0.00717037)
   (0.150701,0.0325937)
  (0.0645294,-0.164578)
   (-0.092721,0.178244)
(-0.0107883,-0.0478668)

*** Quantum Circuit Info ***
# of qubit: 5
# of step : 41
# of gate : 171
# of 1 qubit gate: 150
# of 2 qubit gate: 20
# of 3 qubit gate: 0
# of 4 qubit gate: 1
Clifford  : no
Gaussian  : no

*** Parameter Info ***
# of parameter: 151
変分回路の勾配を求める

GradCalculator または ParametricQuantumCircuit.backprop() を使うと、変分回路の勾配を求めることができます。

  • GradCalculator では、 CausalConeSimulator を使用して期待値を求め勾配を計算します。

  • ParametricQuantumCircuit.backprop() では、誤差逆伝播法により勾配を計算します。

from qulacs import ParametricQuantumCircuit, GradCalculator, Observable

n = 2
observable = Observable(n)
observable.add_operator(1.0, "X 0")
circuit = ParametricQuantumCircuit(n)

theta = [2.2, 1.4, 0.8]
circuit.add_parametric_RX_gate(0, theta[0])
circuit.add_parametric_RY_gate(0, theta[1])
circuit.add_parametric_RZ_gate(0, theta[2])

# GradCalculatorの場合
gcalc = GradCalculator()
print(gcalc.calculate_grad(circuit, observable))
# 第三引数に回転角を指定することも可能
print(gcalc.calculate_grad(circuit, observable, theta))
# Backpropを使って求めた場合
print(circuit.backprop(observable))
[(0.13292406112215058+0j), (0.06968868323709171+0j), (0.14726262077628174+0j)]
[(0.13292406112215058+0j), (0.06968868323709171+0j), (0.14726262077628174+0j)]
[0.1329240611221506, 0.06968868323709165, 0.14726262077628166]

シミュレータ

QuantumCircuitSimulator

QuantumCircuitSimulator を使用すると、回路と量子状態をあわせて管理することができます。 量子状態のバッファを1つ持っており、切り替えて使用することができます。

from qulacs import QuantumState, QuantumCircuit, QuantumCircuitSimulator, Observable
n = 3
state = QuantumState(n)

# 回路を作成
circuit = QuantumCircuit(n)
for i in range(n):
   circuit.add_H_gate(i)

# シミュレータクラスを作成
sim = QuantumCircuitSimulator(circuit, state)

# 基底を二進数と見た時の整数値を入れて、その状態に初期化
sim.initialize_state(0)

# ゲート数
print("gate_count: ", sim.get_gate_count())

# 実行
sim.simulate()

# 量子状態を表示
print(state)

# 期待値
observable = Observable(1)
observable.add_operator(1.0, "Z 0")
print("expectation_value: ", sim.get_expectation_value(observable))

# 量子状態を入れ替え
print("swap")
sim.swap_state_and_buffer()
# ランダムな純粋状態へ初期化
sim.initialize_random_state(seed=0)
sim.simulate()
print(state)

# 量子状態をコピー(バッファ->現状態)
sim.copy_state_from_buffer()
sim.simulate()
print(state)

# 量子状態をコピー(現状態->バッファ)
sim.copy_state_to_buffer()
sim.simulate()
print(state)
gate_count:  3
*** Quantum State ***
* Qubit Count : 3
* Dimension   : 8
* State vector :
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)

expectation_value:  0j
swap
*** Quantum State ***
* Qubit Count : 3
* Dimension   : 8
* State vector :
(-0.298916,0.160953)
(0.015405,-0.237144)
(-0.215765,0.171064)
(-0.257959,-0.0506326)
(-0.121612,0.0424348)
(-0.0329899,-0.400262)
(0.327376,-0.414262)
   (0.345253,0.327824)

*** Quantum State ***
* Qubit Count : 3
* Dimension   : 8
* State vector :
(1,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)

*** Quantum State ***
* Qubit Count : 3
* Dimension   : 8
* State vector :
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
(0.353553,0)
NoiseSimulator

NoiseSimulator を使用すると、ノイズをシミュレートした環境で回路を実行することができます。

ノイズを設定する場合、 add_noise_gate() を使用して、回路にゲートを追加する必要があります。 第一引数にゲートを指定し、第二引数に追加するノイズの種類("Depolarizing" / "BitFlip" / "Dephasing" / "IndependentXZ" / "AmplitudeDamping")、第三引数にノイズが発生する確率を指定します。 2量子ビットゲートの場合は、ノイズの種類は "Depolarizing" のみとなります。

import random
from qulacs import QuantumState, QuantumCircuit, NoiseSimulator
from qulacs.gate import sqrtX, sqrtY, T, CNOT, CZ

n = 3
depth = 10
one_qubit_noise = ["Depolarizing", "BitFlip", "Dephasing", "IndependentXZ", "AmplitudeDamping"]
circuit = QuantumCircuit(n)

for d in range(depth):
   for i in range(n):
      r = random.randint(0, 4)
      noise_type = random.randint(0, 4)
      if r == 0:
            circuit.add_noise_gate(sqrtX(i), one_qubit_noise[noise_type], 0.01)
      elif r == 1:
            circuit.add_noise_gate(sqrtY(i), one_qubit_noise[noise_type], 0.01)
      elif r == 2:
            circuit.add_noise_gate(T(i), one_qubit_noise[noise_type], 0.01)
      elif r == 3:
            if i + 1 < n:
               circuit.add_noise_gate(CNOT(i, i+1), "Depolarizing", 0.01)
      elif r == 4:
            if i + 1 < n:
               circuit.add_noise_gate(CZ(i, i+1), "Depolarizing", 0.01)

state = QuantumState(n)
state.set_Haar_random_state()
sim = NoiseSimulator(circuit, state)
sim.execute(100)
print(state)
*** Quantum State ***
* Qubit Count : 3
* Dimension   : 8
* State vector :
   (0.548785,0.102395)
(-0.0927749,0.419762)
(-0.256335,0.238385)
(0.134217,-0.154723)
(0.029416,-0.186135)
   (0.056051,0.354884)
(0.0261743,-0.0779107)
(0.282366,-0.296603)
CausalConeSimulator

CausalConeSimulatorを使用すると、指定したオブザーバブルに関連するゲートを回路を逆に辿って抽出します。 抽出したゲートのみを適用して物理量の期待値を求めることができます。

これにより回路の深さが浅ければ関連するゲートが少なくなるため、大きいサイズの量子ビットの回路の期待値を求めることができます。

from qulacs import QuantumState, ParametricQuantumCircuit, CausalConeSimulator, Observable
n = 100
observable = Observable(1)
observable.add_operator(1.0, "Z 0")
circuit = ParametricQuantumCircuit(n)
for i in range(n):
   circuit.add_parametric_RX_gate(i, 1.0)
   circuit.add_parametric_RY_gate(i, 1.0)

# CausalConeSimulatorの場合
ccs = CausalConeSimulator(circuit, observable)
print(ccs.get_expectation_value())

# # 通常の場合
# state = QuantumState(n)
# circuit.update_quantum_state(state)
# print(observable.get_expectation_value(state))
(0.2919265817264289+0j)

C++ 教材

量子状態

量子状態の生成

以下のコードで \(n\) qubitの量子状態を生成します。 生成した量子状態は \(|0\rangle^{\otimes n}\) に初期化されています。

#include <cppsim/state.hpp>

int main(){
    // 5-qubitの状態を生成
    unsigned int n = 5;
    QuantumState state(n);
    // |00000>に初期化
    state.set_zero_state();
    return 0;
}

メモリが不足している場合はプログラムが終了します。

量子状態のデータの取得

量子状態を表す \(2^n\) の長さの配列を取得します。 特にGPUで量子状態を作成したり、大きい \(n\) では非常に重い操作になるので注意してください。

#include <cppsim/state.hpp>

int main(){
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    // GNU C++の場合、double _Complex配列を取得
    // MSVCの場合はstd::complex<double>の配列を取得
    const CTYPE* raw_data_c = state.data_c();

    // std::complex<double>の配列を取得
    const CPPCTYPE* raw_data_cpp = state.data_cpp();
}

量子状態を直接指定の配列にセットしたい場合などは、該当する量子ゲートを作成し、量子ゲートの作用として行うことを推奨します。

量子状態の初期化

生成した量子状態は、計算基底に初期化したり、ランダムな状態に初期化することが出来ます。

#include <cppsim/state.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();
    // |00101>に初期化
    state.set_computational_basis(0b00101);
    // ランダムな初期状態を生成
    state.set_Haar_random_state();
    // シードを指定してランダムな初期状態を生成
    state.set_Haar_random_state(0);
    return 0;
}
量子状態のデータのコピーとロード

量子状態を複製したり、他の量子状態のデータをロードできます。

#include <cppsim/state.hpp>

int main(){
    unsigned int n = 5;
    QuantumState state(n);
    state.set_computational_basis(0b00101);

    // コピーして新たな量子状態を作成
    auto second_state = state.copy();

    // 量子状態を新たに生成し、既存の状態のベクトルをコピー
    QuantumState third_state(n);
    third_state.load(&state);
    return 0;
}
古典レジスタの操作

量子状態は古典レジスタを持っており、読み書きを行えます。

#include <cppsim/state.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    // registerの書き込み
    int register_position = 3;
    int register_value = 1;
    state.set_classical_bit(register_position, register_value);

    // registerの読み出し
    int obtained_value;
    obtained_value = state.get_classical_bit(register_position);
    return 0;
}
量子状態に関する計算

以下の処理は量子状態を変えません。 量子状態を変える計算は必ず量子ゲート、量子回路を介して行われます。

#include <cppsim/state.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    // normの計算
    double norm = state.get_squared_norm();
    // Z基底で測定した時のentropyの計算
    double entropy = state.get_entropy();

    // index-th qubitをZ基底で測定して0を得る確率の計算
    unsigned int index = 3;
    double zero_prob = state.get_zero_probability(index);

    // 周辺確率を計算 (以下は0,3-th qubitが0、1,2-th qubitが1と測定される確率の例)
    std::vector<unsigned int> value_list = { 0,1,1,0,2 };
    double marginal_prob = state.get_marginal_probability(value_list);
    return 0;
}
量子状態の内積

inner_product 関数で内積を計算できます。

#include <cppsim/state.hpp>

int main(){
    unsigned int n = 5;
    QuantumState state_ket(n);
    state_ket.set_zero_state();

    QuantumState state_bra(n);
    state_bra.set_Haar_random_state();

    std::complex<double> value = state::inner_product(&state_ket, &state_bra);
    return 0;
}

量子ゲート

量子ゲートの生成と作用

デフォルトで実装されている量子ゲートは gate_factory の関数を通じて生成され、量子状態のポインタを引数として作用させることができます。gate_factory で生成した量子ゲートは自動では解放されないため、ユーザが解放しなければいけません。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    // Xゲートの作用
    unsigned int index = 3;
    auto x_gate = gate::X(index);
    x_gate->update_quantum_state(&state);

    // YでのPI/2回転
    double angle = M_PI / 2.0;
    auto ry_gate = gate::RY(index, angle);
    ry_gate->update_quantum_state(&state);

    delete x_gate;
    delete ry_gate;
    return 0;
}

gate 名前空間で定義されているゲートは以下の通りです。

  • Single-qubit Pauli operation: Identity, X, Y, Z

  • Single-qubit Clifford operation: H, S, Sdag, T, Tdag, sqrtX, sqrtXdag, sqrtY, sqrtYdag

  • Two-qubit Clifford operation: CNOT, CZ, SWAP

  • Single-qubit Pauli rotation: RX, RY, RZ

  • General Pauli operation: Pauli, PauliRotation

  • IBMQ basis-gate: U1, U2, U3

  • General gate: DenseMatrix

  • Measurement: Measurement

  • Noise: BitFlipNoise, DephasingNoise, IndepenedentXZNoise, DepolarizingNoise

量子ゲートの合成

量子ゲートを合成し、新たな量子ゲートを生成できます。 合成したゲートは自身で解放しなければいけません。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    unsigned int index = 3;
    auto x_gate = gate::X(index);

    double angle = M_PI / 2.0;
    auto ry_gate = gate::RY(index, angle);

    // X, RYの順番に作用するゲートの作成
    auto x_and_ry_gate = gate::merge(x_gate, ry_gate);

    x_and_ry_gate->update_quantum_state(&state);

    delete x_gate;
    delete ry_gate;
    delete x_and_ry_gate;
    return 0;
}
量子ゲートのゲート行列の和

量子ゲートのゲート要素の和を取ることができます。 (control-qubitがある場合の和は現状動作が未定義なので利用しないでください。)

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>

int main() {
    auto gate00 = gate::merge(gate::P0(0), gate::P0(1));
    auto gate11 = gate::merge(gate::P1(0), gate::P1(1));
    // |00><00| + |11><11|
    auto proj_00_or_11 = gate::add(gate00, gate11);
    std::cout << proj_00_or_11 << std::endl;

    auto gate_ii_zz = gate::add(gate::Identity(0), gate::merge(gate::Z(0), gate::Z(1)));
    auto gate_ii_xx = gate::add(gate::Identity(0), gate::merge(gate::X(0), gate::X(1)));
    auto proj_00_plus_11 = gate::merge(gate_ii_zz, gate_ii_xx);
    // ((|00>+|11>)(<00|+<11|))/2 = (II + ZZ)(II + XX)/4
    proj_00_plus_11->multiply_scalar(0.25);
    std::cout << proj_00_plus_11 << std::endl;
    return 0;
}
特殊な量子ゲートと一般の量子ゲート

cppsimにおける基本量子ゲートは以下の二つに分けられます。

  • 特殊ゲート:そのゲートの作用について、専用の高速化がなされた関数があるもの。

  • 一般ゲート:ゲート行列を保持し、行列をかけて作用するもの。

前者は後者に比べ専用の関数が作成されているため高速ですが、コントロール量子ビットを増やすなど、量子ゲートの作用を変更する操作が後から行えません。 こうした変更をしたい場合、特殊ゲートを一般ゲートに変換してやらねばなりません。

これは gate::convert_to_matrix_gate で実現できます。 以下がその例になります。

#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    unsigned int index = 3;
    auto x_gate = gate::X(index);

    // 1st-qubitが0の場合だけ作用するようにcontrol qubitを追加
    auto x_mat_gate = gate::to_matrix_gate(x_gate);
    unsigned int control_index = 1;
    unsigned int control_with_value = 0;
    x_mat_gate->add_control_qubit(control_index, control_with_value);

    x_mat_gate->update_quantum_state(&state);

    delete x_gate;
    delete x_mat_gate;
    return 0;
}

専用の量子ゲートの一覧についてはAPIドキュメントをご覧ください。

量子ゲートのゲート行列の取得

生成した量子ゲートのゲート行列を取得できます。control量子ビットなどはゲート行列に含まれません。特にゲート行列を持たない種類のゲート(例えば \(n\)-qubitのパウリ回転ゲート)などは取得に非常に大きなメモリと時間を要するので気を付けてください。

#include <iostream>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>

int main(){
    unsigned int index = 3;
    auto x_gate = gate::X(index);

    // 行列要素の取得
    // ComplexMatrixはEigen::MatrixXcdでRowMajorにした複素行列型
    ComplexMatrix matrix;
    x_gate->set_matrix(matrix);
    std::cout << matrix << std::endl;
    return 0;
}
量子ゲートの情報の取得

ostream に流し込むことで、量子ゲートのデバッグ情報を表示できます。量子ゲートのゲート行列が非常に巨大な場合、とても時間がかかるので注意してください。専用関数を持つ量子ゲートは自身のゲート行列は表示しません。

#include <iostream>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>

int main(){

    unsigned int index = 3;
    auto x_gate = gate::X(index);

    std::cout << x_gate << std::endl;

    delete x_gate;
    return 0;
}
一般的な量子ゲートの実現

cppsimでは量子情報における種々のマップを以下の形で実現します。

ユニタリ操作

量子ゲートとして実現します。

射影演算子やクラウス演算子など

量子ゲートとして実現します。一般に作用後に量子状態のノルムは保存されません。DenseMatrix 関数により生成できます。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>
#include <cppsim/gate_general.hpp>

int main() {
    ComplexMatrix one_qubit_matrix(2, 2);
    one_qubit_matrix << 0, 1, 1, 0;
    auto one_qubit_gate = gate::DenseMatrix(0, one_qubit_matrix);
    std::cout << one_qubit_gate << std::endl;

    ComplexMatrix two_qubit_matrix(4,4);
    two_qubit_matrix <<
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 0, 1,
        0, 0, 1, 0;
    auto two_qubit_gate = gate::DenseMatrix({0,1}, two_qubit_matrix);
    std::cout << two_qubit_gate << std::endl;
    return 0;
}
確率的なユニタリ操作

Probabilistic 関数を用いて、複数のユニタリ操作と確率分布を与えて作成します。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>
#include <cppsim/gate_general.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    unsigned int index = 3;
    auto x_gate = gate::X(index);
    auto z_gate = gate::Z(index);

    auto probabilistic_xz_gate = gate::Probabilistic({ 0.1,0.2 } , { x_gate,z_gate });
    auto depolarizing_gate = gate::DepolarizingNoise(index, 0.3);

    depolarizing_gate->update_quantum_state(&state);
    probabilistic_xz_gate->update_quantum_state(&state);
    return 0;
}
CPTP-map

CPTP 関数に完全性を満たすクラウス演算子のリストとして与えて作成します。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>
#include <cppsim/gate_general.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    unsigned int index = 3;
    auto p0 = gate::P0(index);
    auto p1_fix = gate::merge(gate::P1(index), gate::X(index));

    auto correction = gate::CPTP({p0,p1_fix});
    auto noise = gate::BitFlipNoise(index,0.1);

    noise->update_quantum_state(&state);
    correction->update_quantum_state(&state);
    return 0;
}
POVM

数値計算上にはInstrumentと同じなので、Instrumentとして実現します。

Instrument

Instrumentは一般のCPTP-mapの操作に加え、ランダムに作用したクラウス演算子の添え字を取得する操作です。例えば、Z基底での測定は P0P1 からなるCPTP-mapを作用し、どちらが作用したかを知ることに相当します。 cppsimでは Instrument 関数にCPTP-mapの情報と、作用したクラウス演算子の添え字を書きこむ古典レジスタのアドレスを指定することで実現します。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>
#include <cppsim/gate_general.hpp>

int main() {
    auto gate00 = gate::merge(gate::P0(0), gate::P0(1));
    auto gate01 = gate::merge(gate::P0(0), gate::P1(1));
    auto gate10 = gate::merge(gate::P1(0), gate::P0(1));
    auto gate11 = gate::merge(gate::P1(0), gate::P1(1));

    std::vector<QuantumGateBase*> gate_list = { gate00, gate01, gate10, gate11 };
    unsigned int classical_pos = 0;
    auto gate = gate::Instrument(gate_list, classical_pos);

    QuantumState state(2);
    state.set_Haar_random_state();

    std::cout << state << std::endl;
    gate->update_quantum_state(&state);
    unsigned int result = state.get_classical_value(classical_pos);
    std::cout << state << std::endl;
    std::cout << result << std::endl;
    return 0;
}
Adaptive

古典レジスタに書き込まれた値に応じて操作を行ったり行わなかったりします。cppsimでは std::vector<unsigned int> 型のレジスタを引数として受け取り、bool 型を返す関数を指定し、これを実現します。

#define _USE_MATH_DEFINES
#include <cmath>
#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/gate_merge.hpp>
#include <cppsim/gate_matrix.hpp>
#include <cppsim/gate_general.hpp>

int main() {
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    unsigned int index = 3;
    auto h = gate::H(index);
    h->update_quantum_state(&state);

    auto meas = gate::Measurement(index,0);
    meas->update_quantum_state(&state);

    auto condition = [](const std::vector<UINT> reg){
        return reg[0]==1;
    };
    auto correction = gate::Adaptive(gate::X(index), condition);
    correction->update_quantum_state(&state);
    return 0;
}
CP-map

Kraus-rankが1の場合は、上記の単体のクラウス演算子として扱ってください。それ以外の場合は、TPになるようにクラウス演算子を調整した後、multiply_scalar 関数で定数倍にした Identity オペレータを作用するなどして調整してください。

量子回路

量子回路の構成

量子回路は量子ゲートの集合として表されます。 例えば以下のように量子回路を構成できます。

#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/circuit.hpp>

int main(){
    unsigned int n = 5;
    QuantumState state(n);
    state.set_zero_state();

    // 量子回路を定義
    QuantumCircuit circuit(n);

    // 量子回路にゲートを追加
    for(int i=0;i<n;++i){
        circuit.add_H_gate(i);
    }

    // 自身で定義したゲートも追加できる
    for(int i=0;i<n;++i){
        circuit.add_gate(gate::H(i));
    }

    // 量子回路を状態に作用
    circuit.update_quantum_state(&state);
    return 0;
}

なお、add_gate で追加された量子回路は量子回路の解放時に一緒に解放されます。従って、代入したゲートは再利用できません。 引数として与えたゲートを再利用したい場合は、add_gate_copy 関数を用いてください。ただしこの場合自身でゲートを解放する必要があります。

量子回路の最適化

量子ゲートをまとめて一つの量子ゲートとすることで、量子ゲートの数を減らすことができ、数値計算の時間を短縮できることがあります。(もちろん、対象となる量子ビットの数が増える場合や、専用関数を持つ量子ゲートを合成して専用関数を持たない量子ゲートにしてしまった場合は、トータルで計算時間が減少するかは状況に依ります。)

下記のコードでは optimize 関数を用いて、量子回路の量子ゲートをターゲットとなる量子ビットが3つになるまで貪欲法で合成を繰り返します。

#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/circuit.hpp>
#include <cppsim/circuit_optimizer.hpp>

int main() {
    unsigned int n = 5;
    unsigned int depth = 10;
    QuantumCircuit circuit(n);
    for (int d = 0; d < depth; ++d) {
        for (int i = 0; i < n; ++i) {
            circuit.add_gate(gate::H(i));
        }
    }

    // 量子回路の最適化
    QuantumCircuitOptimizer opt;
    unsigned int max_block_size = 3;
    opt.optimize(&circuit, max_block_size);
    return 0;
}
量子回路の情報デバッグ

量子ゲートと同様、量子回路も ostream に流し込むことでデバッグ情報を表示することができます。

#include <cppsim/state.hpp>
#include <cppsim/gate_factory.hpp>
#include <cppsim/circuit.hpp>

int main() {
    unsigned int n = 5;
    unsigned int depth = 10;
    QuantumCircuit circuit(n);
    for (int d = 0; d < depth; ++d) {
        for (int i = 0; i < n; ++i) {
            circuit.add_gate(gate::H(i));
        }
    }

    // 量子回路の情報を出力
    std::cout << circuit << std::endl;
    return 0;
}

オブザーバブル

オブザーバブルの生成

オブザーバブルはパウリ演算子の集合として表現されます。 パウリ演算子は下記のように定義できます。

#include <cppsim/observable.hpp>
#include <string>

int main() {
    unsigned int n = 5;
    double coef = 2.0;
    std::string Pauli_string = "X 0 X 1 Y 2 Z 4";
    Observable observable(n);
    observable.add_operator(coef,Pauli_string.c_str());
    return 0;
}
OpenFermionとの連携

また、OpenFermionを用いて生成された以下のようなフォーマットのファイルから、オブザーバブルを生成することができます。 このとき、オブザーバブルはそれを構成するのに必要最小限の大きさとなります。例えば、以下のようなOpenFermionを用いて得られたオブザーバブルを読み込み、オブザーバブルを生成することが可能です。

from openfermion.ops import FermionOperator
from openfermion.transforms import bravyi_kitaev

h_00 = h_11 = -1.252477
h_22 = h_33 = -0.475934
h_0110 = h_1001 = 0.674493
h_2332 = h_3323 = 0.697397
h_0220 = h_0330 = h_1221 = h_1331 = h_2002 = h_3003 = h_2112 = h_3113 = 0.663472
h_0202 = h_1313 = h_2130 = h_2310 = h_0312 = h_0132 = 0.181287

fermion_operator = FermionOperator('0^ 0', h_00)
fermion_operator += FermionOperator('1^ 1', h_11)
fermion_operator += FermionOperator('2^ 2', h_22)
fermion_operator += FermionOperator('3^ 3', h_33)

fermion_operator += FermionOperator('0^ 1^ 1 0', h_0110)
fermion_operator += FermionOperator('2^ 3^ 3 2', h_2332)
fermion_operator += FermionOperator('0^ 3^ 3 0', h_0330)
fermion_operator += FermionOperator('1^ 2^ 2 1', h_1221)

fermion_operator += FermionOperator('0^ 2^ 2 0', h_0220-h_0202)
fermion_operator += FermionOperator('1^ 3^ 3 1', h_1331-h_1313)

fermion_operator += FermionOperator('0^ 1^ 3 2', h_0132)
fermion_operator += FermionOperator('2^ 3^ 1 0', h_0132)

fermion_operator += FermionOperator('0^ 3^ 1 2', h_0312)
fermion_operator += FermionOperator('2^ 1^ 3 0', h_0312)

## Bravyi-Kitaev transformation
bk_operator = bravyi_kitaev(fermion_operator)

## output
fp = open("H2.txt", 'w')
fp.write(str(bk_operator))
fp.close()

このとき、上のPythonコードで生成された H2.txt ファイルは以下のような形式になっています。

(-0.8126100000000005+0j) [] +
(0.04532175+0j) [X0 Z1 X2] +
(0.04532175+0j) [X0 Z1 X2 Z3] +
(0.04532175+0j) [Y0 Z1 Y2] +
(0.04532175+0j) [Y0 Z1 Y2 Z3] +
(0.17120100000000002+0j) [Z0] +
(0.17120100000000002+0j) [Z0 Z1] +
(0.165868+0j) [Z0 Z1 Z2] +
(0.165868+0j) [Z0 Z1 Z2 Z3] +
(0.12054625+0j) [Z0 Z2] +
(0.12054625+0j) [Z0 Z2 Z3] +
(0.16862325+0j) [Z1] +
(-0.22279649999999998+0j) [Z1 Z2 Z3] +
(0.17434925+0j) [Z1 Z3] +
(-0.22279649999999998+0j) [Z2]

このような形式のファイルからオブザーバブルを生成するには、以下のように関数を通してオブザーバブルを生成することができます。

#include <cppsim/observable.hpp>
#include <string>

int main() {
    unsigned int n = 5;
    std::string filename = "H2.txt";
    Observable* observable = observable::create_observable_from_openfermion_file(filename);
    delete observable;
    return 0;
}
オブザーバブルの評価

状態に対してオブザーバブルの期待値を評価できます。

#include <cppsim/observable.hpp>
#include <cppsim/state.hpp>
#include <string>

int main() {
    unsigned int n = 5;
    double coef = 2.0;
    std::string Pauli_string = "X 0 X 1 Y 2 Z 4";
    Observable observable(n);
    observable.add_operator(coef, Pauli_string.c_str());

    QuantumState state(n);
    observable.get_expectation_value(&state);
    return 0;
}
オブザーバブルの回転

オブザーバブル \(H\) の回転 \(e^{i\theta H}\) をTrotter展開によって行います。num_repeats はデフォルト値では以下のコードのようになっていますが、ユーザがオプションで指定することが可能です。

#include <cppsim/circuit.hpp>
#include <cppsim/state.hpp>
#include <cppsim/observable.hpp>

int main() {
    UINT n;
    UINT num_repeats;
    double theta = 0.1;
    Observable* observable = observable::create_observable_from_openfermion_file("../test/cppsim/H2.txt");

    n = observable->get_qubit_count();
    QuantumState state(n);
    state.set_computational_basis(0);

    QuantumCircuit circuit(n);
    num_repeats = (UINT)std::ceil(theta * (double)n* 100.);
    circuit.add_observable_rotation_gate(*observable, theta, num_repeats);
    circuit.update_quantum_state(&state);

    auto result = observable->get_expectation_value(&state);
    std::cout << result << std::endl;
    delete observable;
    return 0;
}

変分量子回路

量子回路を ParametricQuantumCircuit クラスとして定義すると、通所の QuantumCircuit クラスの関数に加え、変分法を用いて量子回路を最適化するのに便利ないくつかの関数を利用することができます。

変分量子回路の利用例

一つの回転角を持つ量子ゲート(X-rot, Y-rot, Z-rot, multi_qubit_pauli_rotation)はパラメトリックな量子ゲートとして量子回路に追加することができます。パラメトリックなゲートとして追加された量子ゲートについては、量子回路の構成後にパラメトリックなゲート数を取り出したり、後から回転角を変更することができます。

#include <cppsim/state.hpp>
#include <vqcsim/parametric_circuit.hpp>
#include <cppsim/utility.hpp>

int main(){
    const UINT n = 3;
    const UINT depth = 10;

    // create n-qubit parametric circuit
    ParametricQuantumCircuit* circuit = new ParametricQuantumCircuit(n);
    Random random;
    for (UINT d = 0; d < depth; ++d) {
        // add parametric X,Y,Z gate with random initial rotation angle
        for (UINT i = 0; i < n; ++i) {
            circuit->add_parametric_RX_gate(i, random.uniform());
            circuit->add_parametric_RY_gate(i, random.uniform());
            circuit->add_parametric_RZ_gate(i, random.uniform());
        }
        // add neighboring two-qubit ZZ rotation
        for (UINT i = d % 2; i + 1 < n; i+=2) {
            circuit->add_parametric_multi_Pauli_rotation_gate({ i,i + 1 }, { 3,3 }, random.uniform());
        }
    }

    // get parameter count
    UINT param_count = circuit->get_parameter_count();

    // get current parameter, and set shifted parameter
    for (UINT p = 0; p < param_count; ++p) {
        double current_angle = circuit->get_parameter(p);
        circuit->set_parameter(p, current_angle + random.uniform());
    }

    // create quantum state and update
    QuantumState state(n);
    circuit->update_quantum_state(&state);

    // output state and circuit info
    std::cout << state << std::endl;
    std::cout << circuit << std::endl;

    // release quantum circuit
    delete circuit;
}

Python API リファレンス

qulacs

cppsim python interface

class qulacs_core.CausalConeSimulator

ベースクラス: pybind11_builtins.pybind11_object

build(self: qulacs_core.CausalConeSimulator) None

Build

get_circuit_list(self: qulacs_core.CausalConeSimulator) List[List[qulacs_core.ParametricQuantumCircuit]]

Return circuit_list

get_coef_list(self: qulacs_core.CausalConeSimulator) List[complex]

Return coef_list

get_expectation_value(self: qulacs_core.CausalConeSimulator) complex

Return expectation_value

get_pauli_operator_list(self: qulacs_core.CausalConeSimulator) List[List[qulacs_core.PauliOperator]]

Return pauli_operator_list

class qulacs_core.ClsNoisyEvolution

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsNoisyEvolution_fast

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsOneControlOneTargetGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsOneQubitGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsOneQubitRotationGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsPauliGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsPauliRotationGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsReversibleBooleanGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsStateReflectionGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.ClsTwoQubitGate

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.DensityMatrix

ベースクラス: qulacs_core.QuantumStateBase

add_state(self: qulacs_core.DensityMatrix, state: qulacs_core.QuantumStateBase) None

Add state vector to this state

allocate_buffer(self: qulacs_core.DensityMatrix) qulacs_core.DensityMatrix

Allocate buffer with the same size

copy(self: qulacs_core.DensityMatrix) qulacs_core.DensityMatrix

Create copied insntace

get_classical_value(self: qulacs_core.DensityMatrix, index: int) int

Get classical value

get_device_name(self: qulacs_core.DensityMatrix) str

Get allocated device name

get_entropy(self: qulacs_core.DensityMatrix) float

Get entropy

get_marginal_probability(self: qulacs_core.DensityMatrix, measured_values: List[int]) float

Get merginal probability for measured values

get_matrix(self: qulacs_core.DensityMatrix) numpy.ndarray[numpy.complex128[m, n]]

Get density matrix

get_qubit_count(self: qulacs_core.DensityMatrix) int

Get qubit count

get_squared_norm(self: qulacs_core.DensityMatrix) float

Get squared norm

get_zero_probability(self: qulacs_core.DensityMatrix, index: int) float

Get probability with which we obtain 0 when we measure a qubit

load(*args, **kwargs)

Overloaded function.

  1. load(self: qulacs_core.DensityMatrix, state: qulacs_core.QuantumStateBase) -> None

Load quantum state vector or density matrix

  1. load(self: qulacs_core.DensityMatrix, state: List[complex]) -> None

  2. load(self: qulacs_core.DensityMatrix, state: numpy.ndarray[numpy.complex128[m, n]]) -> None

multiply_coef(self: qulacs_core.DensityMatrix, coef: complex) None

Multiply coefficient to this state

normalize(self: qulacs_core.DensityMatrix, squared_norm: float) None

Normalize quantum state

sampling(*args, **kwargs)

Overloaded function.

  1. sampling(self: qulacs_core.DensityMatrix, sampling_count: int) -> List[int]

Sampling measurement results

  1. sampling(self: qulacs_core.DensityMatrix, sampling_count: int, random_seed: int) -> List[int]

set_Haar_random_state(*args, **kwargs)

Overloaded function.

  1. set_Haar_random_state(self: qulacs_core.DensityMatrix) -> None

Set Haar random state

  1. set_Haar_random_state(self: qulacs_core.DensityMatrix, seed: int) -> None

set_classical_value(self: qulacs_core.DensityMatrix, index: int, value: int) None

Set classical value

set_computational_basis(self: qulacs_core.DensityMatrix, comp_basis: int) None

Set state to computational basis

set_zero_state(self: qulacs_core.DensityMatrix) None

Set state to |0>

to_string(self: qulacs_core.DensityMatrix) str

to string

class qulacs_core.GeneralQuantumOperator

ベースクラス: pybind11_builtins.pybind11_object

add_operator(*args, **kwargs)

Overloaded function.

  1. add_operator(self: qulacs_core.GeneralQuantumOperator, pauli_operator: qulacs_core.PauliOperator) -> None

Add Pauli operator

  1. add_operator(self: qulacs_core.GeneralQuantumOperator, coef: complex, pauli_string: str) -> None

add_operator_copy(self: qulacs_core.GeneralQuantumOperator, pauli_operator: qulacs_core.PauliOperator) None

Add Pauli operator

add_operator_move(self: qulacs_core.GeneralQuantumOperator, pauli_operator: qulacs_core.PauliOperator) None

Add Pauli operator

apply_to_state(*args, **kwargs)

Overloaded function.

  1. apply_to_state(self: qulacs_core.GeneralQuantumOperator, work_state: QuantumStateBase, state_to_be_multiplied: QuantumStateBase, dst_state: QuantumStateBase) -> None

Apply observable to state_to_be_multiplied. The result is stored into dst_state.

  1. apply_to_state(self: qulacs_core.GeneralQuantumOperator, state_to_be_multiplied: QuantumStateBase, dst_state: QuantumStateBase) -> None

copy(self: qulacs_core.GeneralQuantumOperator) qulacs_core.GeneralQuantumOperator

Create copied instance of General Quantum operator class

get_expectation_value(self: qulacs_core.GeneralQuantumOperator, state: QuantumStateBase) complex

Get expectation value

get_expectation_value_single_thread(self: qulacs_core.GeneralQuantumOperator, state: QuantumStateBase) complex

Get expectation value

get_qubit_count(self: qulacs_core.GeneralQuantumOperator) int

Get qubit count

get_state_dim(self: qulacs_core.GeneralQuantumOperator) int

Get state dimension

get_term(self: qulacs_core.GeneralQuantumOperator, index: int) qulacs_core.PauliOperator

Get Pauli term

get_term_count(self: qulacs_core.GeneralQuantumOperator) int

Get count of Pauli terms

get_transition_amplitude(self: qulacs_core.GeneralQuantumOperator, state_bra: QuantumStateBase, state_ket: QuantumStateBase) complex

Get transition amplitude

is_hermitian(self: qulacs_core.GeneralQuantumOperator) bool

Get is Herimitian

class qulacs_core.GradCalculator

ベースクラス: pybind11_builtins.pybind11_object

calculate_grad(*args, **kwargs)

Overloaded function.

  1. calculate_grad(self: qulacs_core.GradCalculator, parametric_circuit: qulacs_core.ParametricQuantumCircuit, observable: qulacs_core.Observable) -> List[complex]

Calculate Grad

  1. calculate_grad(self: qulacs_core.GradCalculator, parametric_circuit: qulacs_core.ParametricQuantumCircuit, observable: qulacs_core.Observable, angles_of_gates: List[float]) -> List[complex]

class qulacs_core.NoiseSimulator

ベースクラス: pybind11_builtins.pybind11_object

execute(self: qulacs_core.NoiseSimulator, arg0: int) List[int]

Sampling & Return result [array]

execute_and_get_result(self: qulacs_core.NoiseSimulator, arg0: int) qulacs_core.SimulationResult

Simulate & Return ressult [array of (state, frequency)]

class qulacs_core.Observable

ベースクラス: qulacs_core.GeneralQuantumOperator

add_operator(*args, **kwargs)

Overloaded function.

  1. add_operator(self: qulacs_core.Observable, pauli_operator: qulacs_core.PauliOperator) -> None

Add Pauli operator

  1. add_operator(self: qulacs_core.Observable, coef: complex, string: str) -> None

add_operator_copy(self: qulacs_core.Observable, pauli_operator: qulacs_core.PauliOperator) None

Add Pauli operator

add_operator_move(self: qulacs_core.Observable, pauli_operator: qulacs_core.PauliOperator) None

Add Pauli operator

add_random_operator(*args, **kwargs)

Overloaded function.

  1. add_random_operator(self: qulacs_core.Observable, operator_count: int) -> None

Add random pauli operator

  1. add_random_operator(self: qulacs_core.Observable, operator_count: int, seed: int) -> None

apply_to_state(self: qulacs_core.Observable, work_state: QuantumStateBase, state_to_be_multiplied: QuantumStateBase, dst_state: QuantumStateBase) None

Apply observable to state_to_be_multiplied. The result is stored into dst_state.

get_expectation_value(self: qulacs_core.Observable, state: QuantumStateBase) float

Get expectation value

get_expectation_value_single_thread(self: qulacs_core.Observable, state: QuantumStateBase) float

Get expectation value

get_qubit_count(self: qulacs_core.Observable) int

Get qubit count

get_state_dim(self: qulacs_core.Observable) int

Get state dimension

get_term(self: qulacs_core.Observable, index: int) qulacs_core.PauliOperator

Get Pauli term

get_term_count(self: qulacs_core.Observable) int

Get count of Pauli terms

get_transition_amplitude(self: qulacs_core.Observable, state_bra: QuantumStateBase, state_ket: QuantumStateBase) complex

Get transition amplitude

solve_ground_state_eigenvalue_by_arnoldi_method(self: qulacs_core.Observable, state: QuantumStateBase, iter_count: int, mu: complex = 0.0) complex

Compute ground state eigenvalue by arnoldi method

solve_ground_state_eigenvalue_by_lanczos_method(self: qulacs_core.Observable, state: QuantumStateBase, iter_count: int, mu: complex = 0.0) complex

Compute ground state eigenvalue by lanczos method

solve_ground_state_eigenvalue_by_power_method(self: qulacs_core.Observable, state: QuantumStateBase, iter_count: int, mu: complex = 0.0) complex

Compute ground state eigenvalue by power method

class qulacs_core.ParametricQuantumCircuit

ベースクラス: qulacs_core.QuantumCircuit

add_gate(*args, **kwargs)

Overloaded function.

  1. add_gate(self: qulacs_core.ParametricQuantumCircuit, gate: qulacs_core.QuantumGateBase) -> None

Add gate

  1. add_gate(self: qulacs_core.ParametricQuantumCircuit, gate: qulacs_core.QuantumGateBase, position: int) -> None

add_parametric_RX_gate(self: qulacs_core.ParametricQuantumCircuit, index: int, angle: float) None

Add parametric Pauli-X rotation gate

add_parametric_RY_gate(self: qulacs_core.ParametricQuantumCircuit, index: int, angle: float) None

Add parametric Pauli-Y rotation gate

add_parametric_RZ_gate(self: qulacs_core.ParametricQuantumCircuit, index: int, angle: float) None

Add parametric Pauli-Z rotation gate

add_parametric_gate(*args, **kwargs)

Overloaded function.

  1. add_parametric_gate(self: qulacs_core.ParametricQuantumCircuit, gate: qulacs_core.QuantumGate_SingleParameter) -> None

Add parametric gate

  1. add_parametric_gate(self: qulacs_core.ParametricQuantumCircuit, gate: qulacs_core.QuantumGate_SingleParameter, position: int) -> None

add_parametric_multi_Pauli_rotation_gate(self: qulacs_core.ParametricQuantumCircuit, index_list: List[int], pauli_ids: List[int], angle: float) None

Add parametric multi-qubit Pauli rotation gate

backprop(self: qulacs_core.ParametricQuantumCircuit, obs: qulacs_core.GeneralQuantumOperator) List[float]

Do backprop

backprop_inner_product(self: qulacs_core.ParametricQuantumCircuit, state: qulacs_core.QuantumState) List[float]

Do backprop with innder product

copy(self: qulacs_core.ParametricQuantumCircuit) qulacs_core.ParametricQuantumCircuit

Create copied instance

get_parameter(self: qulacs_core.ParametricQuantumCircuit, index: int) float

Get parameter

get_parameter_count(self: qulacs_core.ParametricQuantumCircuit) int

Get parameter count

get_parametric_gate_position(self: qulacs_core.ParametricQuantumCircuit, index: int) int

Get parametric gate position

merge_circuit(self: qulacs_core.ParametricQuantumCircuit, circuit: qulacs_core.ParametricQuantumCircuit) None

Merge another ParametricQuantumCircuit

remove_gate(self: qulacs_core.ParametricQuantumCircuit, position: int) None

Remove gate

set_parameter(self: qulacs_core.ParametricQuantumCircuit, index: int, parameter: float) None

Set parameter

class qulacs_core.PauliOperator

ベースクラス: pybind11_builtins.pybind11_object

add_single_Pauli(self: qulacs_core.PauliOperator, index: int, pauli_type: int) None

Add Pauli operator to this term

change_coef(self: qulacs_core.PauliOperator, new_coef: complex) None

Change coefficient

copy(self: qulacs_core.PauliOperator) qulacs_core.PauliOperator

Create copied instance of Pauli operator class

get_coef(self: qulacs_core.PauliOperator) complex

Get coefficient of Pauli term

get_expectation_value(self: qulacs_core.PauliOperator, state: QuantumStateBase) complex

Get expectation value

get_expectation_value_single_thread(self: qulacs_core.PauliOperator, state: QuantumStateBase) complex

Get expectation value

get_index_list(self: qulacs_core.PauliOperator) List[int]

Get list of target qubit indices

get_pauli_id_list(self: qulacs_core.PauliOperator) List[int]

Get list of Pauli IDs (I,X,Y,Z) = (0,1,2,3)

get_pauli_string(self: qulacs_core.PauliOperator) str

Get pauli string

get_transition_amplitude(self: qulacs_core.PauliOperator, state_bra: QuantumStateBase, state_ket: QuantumStateBase) complex

Get transition amplitude

class qulacs_core.QuantumCircuit

ベースクラス: pybind11_builtins.pybind11_object

add_CNOT_gate(self: qulacs_core.QuantumCircuit, control: int, target: int) None

Add CNOT gate

add_CZ_gate(self: qulacs_core.QuantumCircuit, control: int, target: int) None

Add CNOT gate

add_H_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add Hadamard gate

add_P0_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add projection gate to |0> subspace

add_P1_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add projection gate to |1> subspace

add_RX_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-X rotation gate

add_RY_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Y rotation gate

add_RZ_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Z rotation gate

add_RotInvX_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-X rotation gate

add_RotInvY_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Y rotation gate

add_RotInvZ_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Z rotation gate

add_RotX_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-X rotation gate

add_RotY_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Y rotation gate

add_RotZ_gate(self: qulacs_core.QuantumCircuit, index: int, angle: float) None

Add Pauli-Z rotation gate

add_SWAP_gate(self: qulacs_core.QuantumCircuit, target1: int, target2: int) None

Add SWAP gate

add_S_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add pi/4 phase gate

add_Sdag_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add adjoint of pi/4 phsae gate

add_T_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add pi/8 phase gate

add_Tdag_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add adjoint of pi/8 phase gate

add_U1_gate(self: qulacs_core.QuantumCircuit, index: int, lambda: float) None

Add QASM U1 gate

add_U2_gate(self: qulacs_core.QuantumCircuit, index: int, phi: float, lambda: float) None

Add QASM U2 gate

add_U3_gate(self: qulacs_core.QuantumCircuit, index: int, theta: float, phi: float, lambda: float) None

Add QASM U3 gate

add_X_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add Pauli-X gate

add_Y_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add Pauli-Y gate

add_Z_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add Pauli-Z gate

add_dense_matrix_gate(*args, **kwargs)

Overloaded function.

  1. add_dense_matrix_gate(self: qulacs_core.QuantumCircuit, index: int, matrix: numpy.ndarray[numpy.complex128[m, n]]) -> None

Add dense matrix gate

  1. add_dense_matrix_gate(self: qulacs_core.QuantumCircuit, index_list: List[int], matrix: numpy.ndarray[numpy.complex128[m, n]]) -> None

add_diagonal_observable_rotation_gate(self: qulacs_core.QuantumCircuit, observable: qulacs_core.Observable, angle: float) None

Add diagonal observable rotation gate

add_gate(*args, **kwargs)

Overloaded function.

  1. add_gate(self: qulacs_core.QuantumCircuit, gate: qulacs_core.QuantumGateBase) -> None

Add gate with copy

  1. add_gate(self: qulacs_core.QuantumCircuit, gate: qulacs_core.QuantumGateBase, position: int) -> None

add_multi_Pauli_gate(*args, **kwargs)

Overloaded function.

  1. add_multi_Pauli_gate(self: qulacs_core.QuantumCircuit, index_list: List[int], pauli_ids: List[int]) -> None

Add multi-qubit Pauli gate

  1. add_multi_Pauli_gate(self: qulacs_core.QuantumCircuit, pauli: qulacs_core.PauliOperator) -> None

add_multi_Pauli_rotation_gate(*args, **kwargs)

Overloaded function.

  1. add_multi_Pauli_rotation_gate(self: qulacs_core.QuantumCircuit, index_list: List[int], pauli_ids: List[int], angle: float) -> None

Add multi-qubit Pauli rotation gate

  1. add_multi_Pauli_rotation_gate(self: qulacs_core.QuantumCircuit, pauli: qulacs_core.PauliOperator) -> None

add_noise_gate(self: qulacs_core.QuantumCircuit, gate: qulacs_core.QuantumGateBase, NoiseType: str, NoiseProbability: float) None

Add noise gate with copy

add_observable_rotation_gate(self: qulacs_core.QuantumCircuit, observable: qulacs_core.Observable, angle: float, repeat: int) None

Add observable rotation gate

add_random_unitary_gate(*args, **kwargs)

Overloaded function.

  1. add_random_unitary_gate(self: qulacs_core.QuantumCircuit, index_list: List[int]) -> None

Add random unitary gate

  1. add_random_unitary_gate(self: qulacs_core.QuantumCircuit, index_list: List[int], seed: int) -> None

add_sqrtX_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add pi/4 Pauli-X rotation gate

add_sqrtXdag_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add adjoint of pi/4 Pauli-X rotation gate

add_sqrtY_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add pi/4 Pauli-Y rotation gate

add_sqrtYdag_gate(self: qulacs_core.QuantumCircuit, index: int) None

Add adjoint of pi/4 Pauli-Y rotation gate

calculate_depth(self: qulacs_core.QuantumCircuit) int

Calculate depth of circuit

copy(self: qulacs_core.QuantumCircuit) qulacs_core.QuantumCircuit

Create copied instance

get_gate(self: qulacs_core.QuantumCircuit, position: int) qulacs_core.QuantumGateBase

Get gate instance

get_gate_count(self: qulacs_core.QuantumCircuit) int

Get gate count

get_inverse(self: qulacs_core.QuantumCircuit) qulacs_core.QuantumCircuit

get inverse circuit

get_qubit_count(self: qulacs_core.QuantumCircuit) int

Get qubit count

merge_circuit(self: qulacs_core.QuantumCircuit, circuit: qulacs_core.QuantumCircuit) None
remove_gate(self: qulacs_core.QuantumCircuit, position: int) None

Remove gate

to_string(self: qulacs_core.QuantumCircuit) str

Get string representation

update_quantum_state(*args, **kwargs)

Overloaded function.

  1. update_quantum_state(self: qulacs_core.QuantumCircuit, state: qulacs_core.QuantumStateBase) -> None

Update quantum state

  1. update_quantum_state(self: qulacs_core.QuantumCircuit, state: qulacs_core.QuantumStateBase, start: int, end: int) -> None

class qulacs_core.QuantumCircuitSimulator

ベースクラス: pybind11_builtins.pybind11_object

copy_state_from_buffer(self: qulacs_core.QuantumCircuitSimulator) None

Copy buffer to state

copy_state_to_buffer(self: qulacs_core.QuantumCircuitSimulator) None

Copy state to buffer

get_expectation_value(self: qulacs_core.QuantumCircuitSimulator, observable: qulacs_core.Observable) complex

Get expectation value

get_gate_count(self: qulacs_core.QuantumCircuitSimulator) int

Get gate count

initialize_random_state(*args, **kwargs)

Overloaded function.

  1. initialize_random_state(self: qulacs_core.QuantumCircuitSimulator) -> None

Initialize state with random pure state

  1. initialize_random_state(self: qulacs_core.QuantumCircuitSimulator, seed: int) -> None

initialize_state(self: qulacs_core.QuantumCircuitSimulator, arg0: int) None

Initialize state

simulate(self: qulacs_core.QuantumCircuitSimulator) None

Simulate circuit

simulate_range(self: qulacs_core.QuantumCircuitSimulator, start: int, end: int) None

Simulate circuit

swap_state_and_buffer(self: qulacs_core.QuantumCircuitSimulator) None

Swap state and buffer

class qulacs_core.QuantumGateBase

ベースクラス: pybind11_builtins.pybind11_object

copy(self: qulacs_core.QuantumGateBase) qulacs_core.QuantumGateBase

Create copied instance

get_control_index_list(self: qulacs_core.QuantumGateBase) List[int]

Get control qubit index list

get_control_index_value_list(self: qulacs_core.QuantumGateBase) List[Tuple[int, int]]

Get control qubit pair index value list

get_control_value_list(self: qulacs_core.QuantumGateBase) List[int]

Get control qubit value list

get_inverse(self: qulacs_core.QuantumGateBase) qulacs_core.QuantumGateBase

get inverse gate

get_matrix(self: qulacs_core.QuantumGateBase) numpy.ndarray[numpy.complex128[m, n]]

Get gate matrix

get_name(self: qulacs_core.QuantumGateBase) str

Get gate name

get_target_index_list(self: qulacs_core.QuantumGateBase) List[int]

Get target qubit index list

is_Clifford(self: qulacs_core.QuantumGateBase) bool

Check this gate is element of Clifford group

is_Gaussian(self: qulacs_core.QuantumGateBase) bool

Check this gate is element of Gaussian group

is_Pauli(self: qulacs_core.QuantumGateBase) bool

Check this gate is element of Pauli group

is_commute(self: qulacs_core.QuantumGateBase, gate: qulacs_core.QuantumGateBase) bool

Check this gate commutes with a given gate

is_diagonal(self: qulacs_core.QuantumGateBase) bool

Check the gate matrix is diagonal

is_parametric(self: qulacs_core.QuantumGateBase) bool

Check this gate is parametric gate

to_string(self: qulacs_core.QuantumGateBase) str

to string

update_quantum_state(self: qulacs_core.QuantumGateBase, state: qulacs_core.QuantumStateBase) None

Update quantum state

class qulacs_core.QuantumGateDiagonalMatrix

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.QuantumGateMatrix

ベースクラス: qulacs_core.QuantumGateBase

add_control_qubit(self: qulacs_core.QuantumGateMatrix, index: int, control_value: int) None

Add control qubit

multiply_scalar(self: qulacs_core.QuantumGateMatrix, value: complex) None

Multiply scalar value to gate matrix

class qulacs_core.QuantumGateSparseMatrix

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.QuantumGate_Adaptive

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.QuantumGate_CP

ベースクラス: qulacs_core.QuantumGateBase

class qulacs_core.QuantumGate_CPTP

ベースクラス: qulacs_core.QuantumGateBase

QuantumGate_Instrument

class qulacs_core.QuantumGate_Probabilistic

ベースクラス: qulacs_core.QuantumGateBase

QuantumGate_ProbabilisticInstrument

get_cumulative_distribution(self: qulacs_core.QuantumGate_Probabilistic) List[float]

get_cumulative_distribution

get_distribution(self: qulacs_core.QuantumGate_Probabilistic) List[float]

get_distribution

get_gate_list(self: qulacs_core.QuantumGate_Probabilistic) List[qulacs_core.QuantumGateBase]

get_gate_list

optimize_ProbablisticGate(self: qulacs_core.QuantumGate_Probabilistic) None

optimize_ProbablisticGate

class qulacs_core.QuantumGate_SingleParameter

ベースクラス: qulacs_core.QuantumGateBase

copy(self: qulacs_core.QuantumGate_SingleParameter) qulacs_core.QuantumGate_SingleParameter

Create copied instance

get_parameter_value(self: qulacs_core.QuantumGate_SingleParameter) float

Get parameter value

set_parameter_value(self: qulacs_core.QuantumGate_SingleParameter, value: float) None

Set parameter value

class qulacs_core.QuantumState

ベースクラス: qulacs_core.QuantumStateBase

add_state(self: qulacs_core.QuantumState, state: qulacs_core.QuantumStateBase) None

Add state vector to this state

allocate_buffer(self: qulacs_core.QuantumState) qulacs_core.QuantumState

Allocate buffer with the same size

copy(self: qulacs_core.QuantumState) qulacs_core.QuantumState

Create copied instance

get_amplitude(self: qulacs_core.QuantumState, comp_basis: int) complex

Get Amplitude of a specified computational basis

get_classical_value(self: qulacs_core.QuantumState, index: int) int

Get classical value

get_device_name(self: qulacs_core.QuantumState) str

Get allocated device name

get_entropy(self: qulacs_core.QuantumState) float

Get entropy

get_marginal_probability(self: qulacs_core.QuantumState, measured_values: List[int]) float

Get merginal probability for measured values

get_qubit_count(self: qulacs_core.QuantumState) int

Get qubit count

get_squared_norm(self: qulacs_core.QuantumState) float

Get squared norm

get_vector(self: qulacs_core.QuantumState) numpy.ndarray[numpy.complex128[m, 1]]

Get state vector

get_zero_probability(self: qulacs_core.QuantumState, index: int) float

Get probability with which we obtain 0 when we measure a qubit

load(*args, **kwargs)

Overloaded function.

  1. load(self: qulacs_core.QuantumState, state: qulacs_core.QuantumStateBase) -> None

Load quantum state vector

  1. load(self: qulacs_core.QuantumState, state: List[complex]) -> None

multiply_coef(self: qulacs_core.QuantumState, coef: complex) None

Multiply coefficient to this state

multiply_elementwise_function(self: qulacs_core.QuantumState, func: Callable[[int], complex]) None

Multiply elementwise function

normalize(self: qulacs_core.QuantumState, squared_norm: float) None

Normalize quantum state

sampling(*args, **kwargs)

Overloaded function.

  1. sampling(self: qulacs_core.QuantumState, sampling_count: int) -> List[int]

Sampling measurement results

  1. sampling(self: qulacs_core.QuantumState, sampling_count: int, random_seed: int) -> List[int]

set_Haar_random_state(*args, **kwargs)

Overloaded function.

  1. set_Haar_random_state(self: qulacs_core.QuantumState) -> None

Set Haar random state

  1. set_Haar_random_state(self: qulacs_core.QuantumState, seed: int) -> None

set_classical_value(self: qulacs_core.QuantumState, index: int, value: int) None

Set classical value

set_computational_basis(self: qulacs_core.QuantumState, comp_basis: int) None

Set state to computational basis

set_zero_state(self: qulacs_core.QuantumState) None

Set state to |0>

to_string(self: qulacs_core.QuantumState) str

to string

class qulacs_core.QuantumStateBase

ベースクラス: pybind11_builtins.pybind11_object

class qulacs_core.SimulationResult

ベースクラス: pybind11_builtins.pybind11_object

get_count(self: qulacs_core.SimulationResult) int

get state count

get_frequency(self: qulacs_core.SimulationResult, arg0: int) int

get state frequency

get_state(self: qulacs_core.SimulationResult, arg0: int) qulacs_core.QuantumState

get state

qulacs_core.StateVector(arg0: int) qulacs_core.QuantumState

StateVector

qulacs_core.to_general_quantum_operator(gate: qulacs_core.QuantumGateBase, qubits: int, tol: float) qulacs_core.GeneralQuantumOperator

qulacs.state

qulacs_core.state.drop_qubit(state: qulacs_core.QuantumState, target: List[int], projection: List[int]) qulacs_core.QuantumState

Drop qubits from state

qulacs_core.state.inner_product(state_bra: qulacs_core.QuantumState, state_ket: qulacs_core.QuantumState) complex

Get inner product

qulacs_core.state.make_mixture(prob1: complex, state1: qulacs_core.QuantumStateBase, prob2: complex, state2: qulacs_core.QuantumStateBase) qulacs_core.DensityMatrix

Create a mixed state

qulacs_core.state.make_superposition(coef1: complex, state1: qulacs_core.QuantumState, coef2: complex, state2: qulacs_core.QuantumState) qulacs_core.QuantumState

Create superposition of states

qulacs_core.state.partial_trace(*args, **kwargs)

Overloaded function.

  1. partial_trace(state: qulacs_core.QuantumState, target_traceout: List[int]) -> qulacs_core.DensityMatrix

Take partial trace

  1. partial_trace(state: qulacs_core.DensityMatrix, target_traceout: List[int]) -> qulacs_core.DensityMatrix

qulacs_core.state.permutate_qubit(*args, **kwargs)

Overloaded function.

  1. permutate_qubit(state: qulacs_core.QuantumState, qubit_order: List[int]) -> qulacs_core.QuantumState

Permutate qubits from state

  1. permutate_qubit(state: qulacs_core.DensityMatrix, qubit_order: List[int]) -> qulacs_core.DensityMatrix

qulacs_core.state.tensor_product(*args, **kwargs)

Overloaded function.

  1. tensor_product(state_left: qulacs_core.QuantumState, state_right: qulacs_core.QuantumState) -> qulacs_core.QuantumState

Get tensor product of states

  1. tensor_product(state_left: qulacs_core.DensityMatrix, state_right: qulacs_core.DensityMatrix) -> qulacs_core.DensityMatrix

qulacs.gate

qulacs_core.gate.Adaptive(*args, **kwargs)

Overloaded function.

  1. Adaptive(gate: qulacs_core.QuantumGateBase, condition: Callable[[List[int]], bool]) -> qulacs_core.QuantumGateBase

Create adaptive gate

  1. Adaptive(gate: qulacs_core.QuantumGateBase, condition: Callable[[List[int], int], bool], id: int) -> qulacs_core.QuantumGateBase

qulacs_core.gate.AmplitudeDampingNoise(index: int, prob: float) qulacs_core.QuantumGate_CPTP

Create amplitude damping noise

qulacs_core.gate.BitFlipNoise(index: int, prob: float) qulacs_core.QuantumGate_Probabilistic

Create bit-flip noise

qulacs_core.gate.CNOT(control: int, target: int) qulacs_core.ClsOneControlOneTargetGate

Create CNOT gate

qulacs_core.gate.CP(kraus_list: List[qulacs_core.QuantumGateBase], state_normalize: bool, probability_normalize: bool, assign_zero_if_not_matched: bool) qulacs_core.QuantumGateBase

Create completely-positive map

qulacs_core.gate.CPTP(kraus_list: List[qulacs_core.QuantumGateBase]) qulacs_core.QuantumGateBase

Create completely-positive trace preserving map

qulacs_core.gate.CZ(control: int, target: int) qulacs_core.ClsOneControlOneTargetGate

Create CZ gate

qulacs_core.gate.DenseMatrix(*args, **kwargs)

Overloaded function.

  1. DenseMatrix(index: int, matrix: numpy.ndarray[numpy.complex128[m, n]]) -> qulacs_core.QuantumGateMatrix

Create dense matrix gate

  1. DenseMatrix(index_list: List[int], matrix: numpy.ndarray[numpy.complex128[m, n]]) -> qulacs_core.QuantumGateMatrix

qulacs_core.gate.DephasingNoise(index: int, prob: float) qulacs_core.QuantumGate_Probabilistic

Create dephasing noise

qulacs_core.gate.DepolarizingNoise(index: int, prob: float) qulacs_core.QuantumGate_Probabilistic

Create depolarizing noise

qulacs_core.gate.DiagonalMatrix(index_list: List[int], diagonal_element: numpy.ndarray[numpy.complex128[m, 1]]) qulacs_core.QuantumGateDiagonalMatrix

Create diagonal matrix gate

qulacs_core.gate.FREDKIN(control: int, target1: int, target2: int) qulacs_core.QuantumGateMatrix

Create FREDKIN gate

qulacs_core.gate.H(index: int) qulacs_core.ClsOneQubitGate

Create Hadamard gate

qulacs_core.gate.Identity(index: int) qulacs_core.ClsOneQubitGate

Create identity gate

qulacs_core.gate.IndependentXZNoise(index: int, prob: float) qulacs_core.QuantumGate_Probabilistic

Create independent XZ noise

qulacs_core.gate.Instrument(kraus_list: List[qulacs_core.QuantumGateBase], register: int) qulacs_core.QuantumGateBase

Create instruments

qulacs_core.gate.Measurement(index: int, register: int) qulacs_core.QuantumGate_CPTP

Create measurement gate

qulacs_core.gate.NoisyEvolution(hamiltonian: qulacs_core.Observable, c_ops: List[qulacs_core.GeneralQuantumOperator], time: float, dt: float) qulacs_core.ClsNoisyEvolution

Create noisy evolution

qulacs_core.gate.NoisyEvolution_fast(hamiltonian: qulacs_core.Observable, c_ops: List[qulacs_core.GeneralQuantumOperator], time: float) qulacs_core.ClsNoisyEvolution_fast

Create noisy evolution fast version

qulacs_core.gate.P0(index: int) qulacs_core.ClsOneQubitGate

Create projection gate to |0> subspace

qulacs_core.gate.P1(index: int) qulacs_core.ClsOneQubitGate

Create projection gate to |1> subspace

qulacs_core.gate.ParametricPauliRotation(index_list: List[int], pauli_ids: List[int], angle: float) qulacs_core.QuantumGate_SingleParameter

Create parametric multi-qubit Pauli rotation gate

qulacs_core.gate.ParametricRX(index: int, angle: float) qulacs_core.QuantumGate_SingleParameter

Create parametric Pauli-X rotation gate

qulacs_core.gate.ParametricRY(index: int, angle: float) qulacs_core.QuantumGate_SingleParameter

Create parametric Pauli-Y rotation gate

qulacs_core.gate.ParametricRZ(index: int, angle: float) qulacs_core.QuantumGate_SingleParameter

Create parametric Pauli-Z rotation gate

qulacs_core.gate.Pauli(index_list: List[int], pauli_ids: List[int]) qulacs_core.ClsPauliGate

Create multi-qubit Pauli gate

qulacs_core.gate.PauliRotation(index_list: List[int], pauli_ids: List[int], angle: float) qulacs_core.ClsPauliRotationGate

Create multi-qubit Pauli rotation

qulacs_core.gate.Probabilistic(prob_list: List[float], gate_list: List[qulacs_core.QuantumGateBase]) qulacs_core.QuantumGateBase

Create probabilistic gate

qulacs_core.gate.ProbabilisticInstrument(prob_list: List[float], gate_list: List[qulacs_core.QuantumGateBase], register: int) qulacs_core.QuantumGateBase

Create probabilistic instrument gate

qulacs_core.gate.RX(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-X rotation gate

qulacs_core.gate.RY(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Y rotation gate

qulacs_core.gate.RZ(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Z rotation gate

qulacs_core.gate.RandomUnitary(*args, **kwargs)

Overloaded function.

  1. RandomUnitary(index_list: List[int]) -> qulacs_core.QuantumGateMatrix

Create random unitary gate

  1. RandomUnitary(index_list: List[int], seed: int) -> qulacs_core.QuantumGateMatrix

qulacs_core.gate.ReversibleBoolean(index_list: List[int], func: Callable[[int, int], int]) qulacs_core.ClsReversibleBooleanGate

Create reversible boolean gate

qulacs_core.gate.RotInvX(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-X rotation gate

qulacs_core.gate.RotInvY(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Y rotation gate

qulacs_core.gate.RotInvZ(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Z rotation gate

qulacs_core.gate.RotX(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-X rotation gate

qulacs_core.gate.RotY(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Y rotation gate

qulacs_core.gate.RotZ(index: int, angle: float) qulacs_core.ClsOneQubitRotationGate

Create Pauli-Z rotation gate

qulacs_core.gate.S(index: int) qulacs_core.ClsOneQubitGate

Create pi/4-phase gate

qulacs_core.gate.SWAP(target1: int, target2: int) qulacs_core.ClsTwoQubitGate

Create SWAP gate

qulacs_core.gate.Sdag(index: int) qulacs_core.ClsOneQubitGate

Create adjoint of pi/4-phase gate

qulacs_core.gate.SparseMatrix(index_list: List[int], matrix: scipy.sparse.csc_matrix[numpy.complex128]) qulacs_core.QuantumGateSparseMatrix

Create sparse matrix gate

qulacs_core.gate.StateReflection(state: qulacs_core.QuantumState) qulacs_core.ClsStateReflectionGate

Create state reflection gate

qulacs_core.gate.T(index: int) qulacs_core.ClsOneQubitGate

Create pi/8-phase gate

qulacs_core.gate.TOFFOLI(control1: int, control2: int, target: int) qulacs_core.QuantumGateMatrix

Create TOFFOLI gate

qulacs_core.gate.Tdag(index: int) qulacs_core.ClsOneQubitGate

Create adjoint of pi/8-phase gate

qulacs_core.gate.TwoQubitDepolarizingNoise(index1: int, index2: int, prob: float) qulacs_core.QuantumGate_Probabilistic

Create two-qubit depolarizing noise

qulacs_core.gate.U1(index: int, lambda: float) qulacs_core.QuantumGateMatrix

Create QASM U1 gate

qulacs_core.gate.U2(index: int, phi: float, lambda: float) qulacs_core.QuantumGateMatrix

Create QASM U2 gate

qulacs_core.gate.U3(index: int, theta: float, phi: float, lambda: float) qulacs_core.QuantumGateMatrix

Create QASM U3 gate

qulacs_core.gate.X(index: int) qulacs_core.ClsOneQubitGate

Create Pauli-X gate

qulacs_core.gate.Y(index: int) qulacs_core.ClsOneQubitGate

Create Pauli-Y gate

qulacs_core.gate.Z(index: int) qulacs_core.ClsOneQubitGate

Create Pauli-Z gate

qulacs_core.gate.add(*args, **kwargs)

Overloaded function.

  1. add(gate1: qulacs_core.QuantumGateBase, gate2: qulacs_core.QuantumGateBase) -> qulacs_core.QuantumGateMatrix

Add quantum gate matrices

  1. add(gate_list: List[qulacs_core.QuantumGateBase]) -> qulacs_core.QuantumGateMatrix

Add quantum gate matrices

qulacs_core.gate.merge(*args, **kwargs)

Overloaded function.

  1. merge(gate1: qulacs_core.QuantumGateBase, gate2: qulacs_core.QuantumGateBase) -> qulacs_core.QuantumGateMatrix

Merge two quantum gate or gate list

  1. merge(gate_list: List[qulacs_core.QuantumGateBase]) -> qulacs_core.QuantumGateMatrix

qulacs_core.gate.sqrtX(index: int) qulacs_core.ClsOneQubitGate

Create pi/4 Pauli-X rotation gate

qulacs_core.gate.sqrtXdag(index: int) qulacs_core.ClsOneQubitGate

Create adjoint of pi/4 Pauli-X rotation gate

qulacs_core.gate.sqrtY(index: int) qulacs_core.ClsOneQubitGate

Create pi/4 Pauli-Y rotation gate

qulacs_core.gate.sqrtYdag(index: int) qulacs_core.ClsOneQubitGate

Create adjoint of pi/4 Pauli-Y rotation gate

qulacs_core.gate.to_matrix_gate(gate: qulacs_core.QuantumGateBase) qulacs_core.QuantumGateMatrix

Convert named gate to matrix gate

qulacs.observable

qulacs_core.observable.create_observable_from_openfermion_file(file_path: str) qulacs_core.Observable

Create GeneralQuantumOperator from openfermion file

qulacs_core.observable.create_observable_from_openfermion_text(text: str) qulacs_core.Observable

Create GeneralQuantumOperator from openfermion text

qulacs_core.observable.create_split_observable(arg0: str) Tuple[qulacs_core.Observable, qulacs_core.Observable]

qulacs.quantum_operator

qulacs_core.quantum_operator.create_quantum_operator_from_openfermion_file(arg0: str) qulacs_core.GeneralQuantumOperator
qulacs_core.quantum_operator.create_quantum_operator_from_openfermion_text(arg0: str) qulacs_core.GeneralQuantumOperator
qulacs_core.quantum_operator.create_split_quantum_operator(arg0: str) Tuple[qulacs_core.GeneralQuantumOperator, qulacs_core.GeneralQuantumOperator]

qulacs.circuit

class qulacs_core.circuit.QuantumCircuitOptimizer

ベースクラス: pybind11_builtins.pybind11_object

merge_all(self: qulacs_core.circuit.QuantumCircuitOptimizer, circuit: qulacs_core.QuantumCircuit) qulacs_core.QuantumGateMatrix
optimize(self: qulacs_core.circuit.QuantumCircuitOptimizer, circuit: qulacs_core.QuantumCircuit, block_size: int) None

Optimize quantum circuit

optimize_light(self: qulacs_core.circuit.QuantumCircuitOptimizer, circuit: qulacs_core.QuantumCircuit) None

Optimize quantum circuit with light method

C++ APIリファレンス

Class Hierarchy

File Hierarchy

Full API

Namespaces
Namespace gate

Contents

Functions
Classes and Structs
Struct HermitianQuantumOperator
Inheritance Relationships
Base Type
Struct Documentation
struct HermitianQuantumOperator : public GeneralQuantumOperator

オブザーバブルの情報を保持するクラス。 PauliOperatorをリストとして持ち, 種々の操作を行う。解放時には保持しているPauliOperatorを全て解放する。

Public Functions

virtual void add_operator(const PauliOperator *mpt) override

PauliOperatorを内部で保持するリストの末尾に追加する。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator_move(PauliOperator *mpt) override

PauliOperatorを内部で保持するリストの末尾に追加する。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator_copy(const PauliOperator *mpt) override

PauliOperatorを内部で保持するリストの末尾に追加する。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator(CPPCTYPE coef, std::string pauli_string)

パウリ演算子の文字列と係数の組をオブザーバブルに追加する。

パラメータ
  • coef -- [in] pauli_stringで作られるPauliOperatorの係数

  • pauli_string -- [in] パウリ演算子と掛かるindexの組からなる文字列。(example: "X 1 Y 2 Z 5")

virtual CPPCTYPE get_expectation_value(const QuantumStateBase *state) const override

HermitianQuantumOperatorのある量子状態に対応するエネルギー(期待値)を計算して返す

パラメータ

state -- [in] 期待値をとるときの量子状態

戻り値

入力で与えた量子状態に対応するHermitianQuantumOperatorの期待値

CPPCTYPE solve_ground_state_eigenvalue_by_lanczos_method(QuantumStateBase *init_state, const UINT iter_count, const CPPCTYPE mu = 0.0) const

GeneralQuantumOperator の基底状態の固有値を lanczos method により求める (A - I) の絶対値最大固有値を求めることで基底状態の固有値を求める.

パラメータ
  • init_state -- [in] 固有値を求めるための量子状態

  • iter_count -- [in] 計算の繰り返し回数

  • mu -- [in] 固有値をシフトするための係数

戻り値

GeneralQuantumOperator の基底状態の固有値

inline virtual HermitianQuantumOperator *copy() const

自身のディープコピーを生成する

戻り値

自身のディープコピー

virtual std::string to_string() const override

文字列に変換する。

Struct NoiseSimulator::Result
Nested Relationships

This struct is a nested type of Class NoiseSimulator.

Struct Documentation
struct NoiseSimulator::Result

複数回の実行結果をまとめた構造体

Public Functions

Result(const std::vector<std::pair<QuantumState*, UINT>> &result_)
~Result()
std::vector<ITYPE> sampling() const

Public Members

std::vector<std::pair<QuantumState*, UINT>> result
Struct NoiseSimulator::SamplingRequest
Nested Relationships

This struct is a nested type of Class NoiseSimulator.

Struct Documentation
struct NoiseSimulator::SamplingRequest

サンプリングのリクエストに関する構造体

Public Functions

inline SamplingRequest(std::vector<UINT> init_gate_pos, UINT init_num_of_sampling)

Public Members

std::vector<UINT> gate_pos

1つのゲート内で複数のゲートのうちどれかが選ばれる時、どのゲートを選んでサンプリングすべきかを示す値のvector。

UINT num_of_sampling

サンプリング回数。

Struct PauliOperator
Struct Documentation
struct PauliOperator

複数qubitに作用するパウリ演算子の情報を保持するクラス。 SinglePauliOperatorをリストとして持ち, 種々の操作を行う。

Public Functions

inline std::vector<UINT> get_index_list() const

自身の保持するパウリ演算子が作用する添字のリストを返す

それぞれの添字に作用する演算子は PauliOperator::get_pauli_id_listで得られる添字のリストの対応する場所から得られる。

戻り値

自身の保持するパウリ演算子が作用する添字のリスト。

inline UINT get_qubit_count() const

自身の保持するパウリ演算子が添え字のうち、最大の添え字を返す

戻り値

自身の保持するパウリ演算子が作用する添字のうち最大の整数

inline std::vector<UINT> get_pauli_id_list() const

自身が保持するパウリ演算子を返す。

それぞれが作用するqubitは PauliOperator::get_index_listで得られる添字のリストの対応する場所から得られる。

戻り値

自身の保持するパウリ演算子のリスト。(I,X,Y,Z)が(0,1,2,3)に対応する。

inline explicit PauliOperator(CPPCTYPE coef = 1.)

コンストラクタ

係数をとって空のインスタンスを返す。

パラメータ

coef -- [in] 係数。デフォルトは1.0

戻り値

係数がcoefの空のインスタンス

explicit PauliOperator(std::string strings, CPPCTYPE coef = 1.)

コンストラクタ

パウリ演算子とその添字からなる文字列と、その係数から複数qubitに掛かるパウリ演算子を作成する

パラメータ
  • strings -- [in]

    Pauli演算子とその掛かるindex. "X 1 Y 2 Z

    5"のようにスペース区切りの文字列

  • coef -- [in] 演算子の係数

戻り値

入力のパウリ演算子と係数をもつPauliOpetatorのインスタンス

PauliOperator(const std::vector<UINT> &target_qubit_index_list, std::string Pauli_operator_type_list, CPPCTYPE coef = 1.)

コンストラクタ

パウリ演算子の文字列と添字のリスト、係数からPauliOperatorのインスタンスを生成する。 このとき入力として与える演算子と添字のリストは、i番目の演算子にi番目の添字が対応する。

パラメータ
  • target_qubit_index_list -- [in] Pauli_operator_type_listで与えるパウリ演算子が掛かるqubitを指定する添字のリスト。

  • Pauli_operator_type_list -- [in] パウリ演算子の文字列。(example: "XXYZ")

  • coef -- [in] 係数

戻り値

入力として与えたパウリ演算子のリストと添字のリスト、係数から生成されるPauliOperatorのインスタンス

explicit PauliOperator(const std::vector<UINT> &pauli_list, CPPCTYPE coef = 1.)

コンストラクタ

配列の添字に作用するパウリ演算子と係数からインスタンスを生成する。

パラメータ
  • pauli_list -- [in] 配列の添字に対応するqubitに作用するパウリ演算子のリスト

  • coef -- [in] 係数

戻り値

pauli_listの添字に対応するqubitに作用するパウリ演算子と係数をもつインスタンス

PauliOperator(const std::vector<UINT> &target_qubit_index_list, const std::vector<UINT> &target_qubit_pauli_list, CPPCTYPE coef = 1.)

コンストラクタ

パウリ演算子のリストと添字のリスト、係数からPauliOperatorのインスタンスを生成する。 このとき入力として与える演算子と添字のリストは、リストの同じ添字の場所にあるものが対応する。

パラメータ
  • target_qubit_index_list -- [in] Pauli_operator_type_listで与えるパウリ演算子が掛かるqubitを指定する添字のリスト

  • target_qubit_pauli_list -- [in] パウリ演算子の符号なし整数リスト。(I,X,Y,Z)が(0,1,2,3)に対応する。

  • coef -- [in] 係数

戻り値

入力として与えたパウリ演算子のリストと添字のリスト、係数から生成されるPauliOperatorのインスタンス

PauliOperator(const boost::dynamic_bitset<> &x, const boost::dynamic_bitset<> &z, CPPCTYPE coef = 1.)
inline virtual CPPCTYPE get_coef() const

自身の係数を返す

戻り値

自身の係数

inline virtual boost::dynamic_bitset get_x_bits() const

自身のxビットを返す

戻り値

自身のxビット

inline virtual boost::dynamic_bitset get_z_bits() const

自身のzビットを返す

戻り値

自身のzビット

inline virtual ~PauliOperator()
virtual void add_single_Pauli(UINT qubit_index, UINT pauli_type)

指定した添字のqubitに作用するSinglePauliOperatorを自身が保持するリストの末尾に追加する。

パラメータ
  • qubit_index -- [in] 作用するqubitの添字

  • pauli_type -- [in] パウリ演算子。(I,X,Y,Z)が(0,1,2,3)に対応する。

virtual CPPCTYPE get_expectation_value(const QuantumStateBase *state) const

量子状態に対応するパウリ演算子の期待値を計算する

パラメータ

state -- [in] 期待値をとるときの量子状態

戻り値

stateに対応する期待値

virtual CPPCTYPE get_expectation_value_single_thread(const QuantumStateBase *state) const

added by myself 量子状態に対応するパウリ演算子の期待値を計算する get_expectation_value の 1 スレッドバージョン

パラメータ

state -- [in] 期待値をとるときの量子状態

戻り値

stateに対応する期待値

virtual CPPCTYPE get_transition_amplitude(const QuantumStateBase *state_bra, const QuantumStateBase *state_ket) const

量子状態に対応するパウリ演算子の遷移振幅を計算する

パラメータ
  • state_bra -- [in] 遷移先の量子状態

  • state_ket -- [in] 遷移元の量子状態

戻り値

state_bra, state_ketに対応する遷移振幅

virtual PauliOperator *copy() const

自身のディープコピーを生成する

戻り値

自身のディープコピー

virtual void change_coef(CPPCTYPE new_coef)
virtual std::string get_pauli_string() const

パウリ演算子に対応する文字列を返す

PauliOperator operator*(const PauliOperator &target) const
PauliOperator operator*(CPPCTYPE target) const
PauliOperator &operator*=(const PauliOperator &target)
PauliOperator &operator*=(CPPCTYPE target)
Struct SiglePauliOperator
Struct Documentation
struct SiglePauliOperator

単一qubitに作用するパウリ演算子の情報を保持するクラス。 作用するqubitの添字と自身のパウリ演算子の情報をもつ。

Class AdamOptimizer
Inheritance Relationships
Base Type
Class Documentation
class AdamOptimizer : public GradientBasedOptimizer

Public Functions

inline AdamOptimizer(UINT trainable_parameter_count, double learning_rate = 0.001, double beta1 = 0.9, double beta2 = 0.999, double epsilon = 1e-8)
inline virtual ~AdamOptimizer()
inline virtual void apply_gradient(std::vector<double> *parameter, const std::vector<double> &gradient) override
Class BooleanFormula
Class Documentation
class BooleanFormula

Public Functions

inline virtual double evaluate(std::vector<UINT> binary_string)
inline virtual UINT get_variable_count() const
Class BooleanOptimizationProblem
Class Documentation
class BooleanOptimizationProblem

Public Functions

inline BooleanOptimizationProblem(BooleanFormula *boolean_formula)
inline virtual double compute_loss(const std::vector<UINT> &binary_string) const
inline virtual double compute_loss(const std::vector<double> answer_distribution) const
Class CausalConeSimulator
Class Documentation
class CausalConeSimulator

Public Functions

inline CausalConeSimulator(const ParametricQuantumCircuit &_init_circuit, const Observable &_init_observable)
inline ~CausalConeSimulator()
inline void build()
inline CPPCTYPE get_expectation_value()
inline std::vector<std::vector<ParametricQuantumCircuit*>> get_circuit_list()
inline std::vector<std::vector<PauliOperator>> get_pauli_operator_list()
inline std::vector<CPPCTYPE> get_coef_list()

Public Members

ParametricQuantumCircuit *init_circuit
Observable *init_observable
std::vector<std::vector<ParametricQuantumCircuit*>> circuit_list
std::vector<std::vector<PauliOperator>> pauli_operator_list
std::vector<CPPCTYPE> coef_list
bool build_run = false
Class ClassificationProblem
Class Documentation
class ClassificationProblem

Public Functions

inline ClassificationProblem(std::vector<std::vector<double>> input_data, std::vector<UINT> label_data)
inline virtual UINT get_input_dim() const
inline virtual std::vector<double> get_input_data(UINT sample_id) const
inline virtual UINT get_category_count() const
inline virtual UINT get_output_data(UINT sample_id) const
inline virtual double compute_loss(UINT sample_id, std::vector<double> probability_distribution) const
Class ClsNoisyEvolution
Inheritance Relationships
Base Type
Class Documentation
class ClsNoisyEvolution : public QuantumGateBase

Public Functions

ClsNoisyEvolution(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time, double dt = 1e-6)
~ClsNoisyEvolution()
inline virtual void set_matrix(ComplexMatrix&) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual void set_seed(int seed) override

乱数シードをセットする

パラメータ

seed -- シード値

inline virtual ClsNoisyEvolution *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual GeneralQuantumOperator *get_effective_hamiltonian() const

NoisyEvolution が使用する有効ハミルトニアンを得る

inline virtual void set_find_collapse_max_steps(int n)

collapse 時間を探すときに許す最大ループ数をセットする

パラメータ

n -- ステップ数

virtual void update_quantum_state(QuantumStateBase *state)

量子状態を更新する

パラメータ

state -- 更新する量子状態

Class ClsNoisyEvolution_auto
Inheritance Relationships
Base Type
Class Documentation
class ClsNoisyEvolution_auto : public QuantumGateBase

Public Functions

inline ClsNoisyEvolution_auto()
inline ClsNoisyEvolution_auto(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time)
inline ~ClsNoisyEvolution_auto()
inline virtual void set_matrix(ComplexMatrix&) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual void set_seed(int seed) override
inline virtual void update_quantum_state(QuantumStateBase *state)

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual QuantumGateBase *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

Class ClsNoisyEvolution_fast
Inheritance Relationships
Base Type
Class Documentation
class ClsNoisyEvolution_fast : public QuantumGateBase

Public Functions

ClsNoisyEvolution_fast(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time)
inline ~ClsNoisyEvolution_fast()
inline virtual void set_matrix(ComplexMatrix&) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual void set_seed(int seed) override

乱数シードをセットする

パラメータ

seed -- シード値

inline virtual ClsNoisyEvolution_fast *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual GeneralQuantumOperator *get_effective_hamiltonian() const

NoisyEvolution が使用する有効ハミルトニアンを得る

inline virtual void set_find_collapse_max_steps(int n)

collapse 時間を探すときに許す最大ループ数をセットする

パラメータ

n -- ステップ数

inline virtual void change_time(double time)
virtual void update_quantum_state(QuantumStateBase *state)

量子状態を更新する

パラメータ

state -- 更新する量子状態

Class ClsOneControlOneTargetGate
Inheritance Relationships
Base Type
Class Documentation
class ClsOneControlOneTargetGate : public QuantumGateBase

1量子ビットを対象とし1量子ビットにコントロールされる回転角固定のゲートのクラス

Public Functions

inline explicit ClsOneControlOneTargetGate()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsOneControlOneTargetGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline void CNOTGateinit(UINT control_qubit_index, UINT target_qubit_index)
inline void CZGateinit(UINT control_qubit_index, UINT target_qubit_index)
inline virtual ClsOneControlOneTargetGate *get_inverse(void) const override

Protected Types

using UpdateFunc = void (*)(UINT, UINT, CTYPE*, ITYPE)
using UpdateFuncGpu = void (*)(UINT, UINT, void*, ITYPE, void*, UINT)

Protected Attributes

UpdateFunc _update_func
UpdateFunc _update_func_dm
UpdateFuncGpu _update_func_gpu
ComplexMatrix _matrix_element
Class ClsOneQubitGate
Inheritance Relationships
Base Type
Class Documentation
class ClsOneQubitGate : public QuantumGateBase

Public Functions

inline explicit ClsOneQubitGate()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsOneQubitGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline void IGateinit(UINT target_qubit_index)
inline void XGateinit(UINT target_qubit_index)
inline void YGateinit(UINT target_qubit_index)
inline void ZGateinit(UINT target_qubit_index)
inline void HGateinit(UINT target_qubit_index)
inline void SGateinit(UINT target_qubit_index)
inline void SdagGateinit(UINT target_qubit_index)
inline void TGateinit(UINT target_qubit_index)
inline void TdagGateinit(UINT target_qubit_index)
inline void sqrtXGateinit(UINT target_qubit_index)
inline void sqrtXdagGateinit(UINT target_qubit_index)
inline void sqrtYGateinit(UINT target_qubit_index)
inline void sqrtYdagGateinit(UINT target_qubit_index)
inline void P0Gateinit(UINT target_qubit_index)
inline void P1Gateinit(UINT target_qubit_index)
virtual ClsOneQubitGate *get_inverse(void) const

Protected Types

using UpdateFunc = void (*)(UINT, CTYPE*, ITYPE)
using UpdateFuncGpu = void (*)(UINT, void*, ITYPE, void*, UINT)

Protected Attributes

UpdateFunc _update_func
UpdateFunc _update_func_dm
UpdateFuncGpu _update_func_gpu
ComplexMatrix _matrix_element
Class ClsOneQubitRotationGate
Inheritance Relationships
Base Type
Class Documentation
class ClsOneQubitRotationGate : public QuantumGateBase

1量子ビットを対象とする回転ゲートのクラス

Public Functions

inline explicit ClsOneQubitRotationGate()
inline explicit ClsOneQubitRotationGate(double angle)
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsOneQubitRotationGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline void RXGateinit(UINT target_qubit_index, double angle)
inline void RYGateinit(UINT target_qubit_index, double angle)
inline void RZGateinit(UINT target_qubit_index, double angle)
virtual ClsOneQubitRotationGate *get_inverse(void) const

Protected Types

using UpdateFunc = void (*)(UINT, double, CTYPE*, ITYPE)
using UpdateFuncGpu = void (*)(UINT, double, void*, ITYPE, void*, UINT)

Protected Attributes

UpdateFunc _update_func
UpdateFunc _update_func_dm
UpdateFuncGpu _update_func_gpu
ComplexMatrix _matrix_element
double _angle
Class ClsParametricPauliRotationGate
Inheritance Relationships
Base Type
Class Documentation
class ClsParametricPauliRotationGate : public QuantumGate_SingleParameter

Public Functions

inline ClsParametricPauliRotationGate(double angle, PauliOperator *pauli)
inline virtual ~ClsParametricPauliRotationGate()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsParametricPauliRotationGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual PauliOperator *get_pauli() const
inline virtual ClsParametricPauliRotationGate *get_inverse() const override

Protected Attributes

PauliOperator *_pauli
Class ClsParametricRXGate
Inheritance Relationships
Base Type
Class Documentation
class ClsParametricRXGate : public QuantumGate_SingleParameterOneQubitRotation

Public Functions

inline ClsParametricRXGate(UINT target_qubit_index, double angle)
inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual ClsParametricRXGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual ClsParametricRXGate *get_inverse() const override
Class ClsParametricRYGate
Inheritance Relationships
Base Type
Class Documentation
class ClsParametricRYGate : public QuantumGate_SingleParameterOneQubitRotation

Public Functions

inline ClsParametricRYGate(UINT target_qubit_index, double angle)
inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual ClsParametricRYGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual ClsParametricRYGate *get_inverse() const override
Class ClsParametricRZGate
Inheritance Relationships
Base Type
Class Documentation
class ClsParametricRZGate : public QuantumGate_SingleParameterOneQubitRotation

Public Functions

inline ClsParametricRZGate(UINT target_qubit_index, double angle)
inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual ClsParametricRZGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual ClsParametricRZGate *get_inverse() const override
Class ClsPauliGate
Inheritance Relationships
Base Type
Class Documentation
class ClsPauliGate : public QuantumGateBase

複数の量子ビットに作用するPauli演算子を作用させるゲート

Public Functions

inline explicit ClsPauliGate(PauliOperator *pauli)

コンストラクタ

使用したパウリ演算子はクラスにて解放される

パラメータ

pauli -- 作用させるパウリ演算子

inline virtual ~ClsPauliGate()

デストラクタ

inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsPauliGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

Protected Attributes

PauliOperator *_pauli
Class ClsPauliRotationGate
Inheritance Relationships
Base Type
Class Documentation
class ClsPauliRotationGate : public QuantumGateBase

複数の量子ビットに作用するPauli演算子で回転するゲート

Public Functions

inline ClsPauliRotationGate(double angle, PauliOperator *pauli)

コンストラクタ

使用したパウリ演算子はクラスにて解放される

パラメータ
  • angle -- 回転角

  • pauli -- 作用させるパウリ演算子

inline virtual ~ClsPauliRotationGate()

デストラクタ

inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsPauliRotationGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual ClsPauliRotationGate *get_inverse(void) const override

Protected Attributes

double _angle
PauliOperator *_pauli
Class ClsReversibleBooleanGate
Inheritance Relationships
Base Type
Class Documentation
class ClsReversibleBooleanGate : public QuantumGateBase

可逆古典回路のを表すクラス

Public Functions

inline ClsReversibleBooleanGate(std::vector<UINT> target_qubit_index_list, std::function<ITYPE(ITYPE, ITYPE)> _function_ptr)
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsReversibleBooleanGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

Class ClsStateReflectionGate
Inheritance Relationships
Base Type
Class Documentation
class ClsStateReflectionGate : public QuantumGateBase

量子状態を、別の量子状態に対して反射するゲートのクラス

Public Functions

inline explicit ClsStateReflectionGate(const QuantumState *_reflection_state)
inline virtual ~ClsStateReflectionGate()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsStateReflectionGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix&) const override

自身のゲート行列をセットする ことになっているが、実際はnot implemented

パラメータ

matrix -- 行列をセットする変数の参照

Class ClsTwoQubitGate
Inheritance Relationships
Base Type
Class Documentation
class ClsTwoQubitGate : public QuantumGateBase

2量子ビットを対象とする回転角固定のゲートのクラス

Public Functions

inline explicit ClsTwoQubitGate()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual ClsTwoQubitGate *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline void SWAPGateinit(UINT target_qubit_index1, UINT target_qubit_index2)
inline virtual ClsTwoQubitGate *get_inverse(void) const override

Protected Types

using UpdateFunc = void (*)(UINT, UINT, CTYPE*, ITYPE)
using UpdateFuncGpu = void (*)(UINT, UINT, void*, ITYPE, void*, UINT)

Protected Attributes

UpdateFunc _update_func
UpdateFunc _update_func_dm
UpdateFuncGpu _update_func_gpu
ComplexMatrix _matrix_element
Class ControlQubitInfo
Inheritance Relationships
Base Type
Class Documentation
class ControlQubitInfo : public QubitInfo

コントロール量子ビットの情報を保持するクラス

Public Functions

inline UINT control_value() const

コントロール値を取得する

戻り値

コントロール値

inline ControlQubitInfo(void)

コンストラクタ

初期化に必要、万が一使われたとき落ちるためにinvalid_qubitにしてある

inline explicit ControlQubitInfo(UINT index_)

コンストラクタ

パラメータ

index_ -- この量子ビットの添え字

inline ControlQubitInfo(UINT index_, UINT control_value_)

コンストラクタ

パラメータ
  • index_ -- この量子ビットの添え字

  • control_value_ -- この量子ビットのコントロール値

virtual bool is_commute_with(const TargetQubitInfo &info) const

ターゲット量子ビットの情報infoと可換かどうかを調べる

パラメータ

info -- 可換かどうかを調べる量子ビットの情報

戻り値

true 可換である

戻り値

false 可換ではない

virtual bool is_commute_with(const ControlQubitInfo &info) const

コントロール量子ビットの情報infoと可換かどうかを調べる

パラメータ

info -- 可換かどうかを調べる量子ビットの情報

戻り値

true 可換である

戻り値

false 可換ではない

Class DensityMatrixCpu
Inheritance Relationships
Base Type
Class Documentation
class DensityMatrixCpu : public QuantumStateBase

Public Functions

inline explicit DensityMatrixCpu(UINT qubit_count_)

コンストラクタ

パラメータ

qubit_count_ -- 量子ビット数

inline virtual ~DensityMatrixCpu()

デストラクタ

inline virtual void set_zero_state() override

量子状態を計算基底の0状態に初期化する

inline virtual void set_zero_norm_state() override

ノルム0の状態 (すべての要素が0の行列にする)

inline virtual void set_computational_basis(ITYPE comp_basis) override

量子状態をcomp_basisの基底状態に初期化する

パラメータ

comp_basis -- 初期化する基底を表す整数

inline virtual void set_Haar_random_state() override

量子状態をHaar randomにサンプリングされた量子状態に初期化する

inline virtual void set_Haar_random_state(UINT seed) override

量子状態をシードを用いてHaar randomにサンプリングされた量子状態に初期化する

inline virtual double get_zero_probability(UINT target_qubit_index) const override

target_qubit_indexの添え字の量子ビットを測定した時、0が観測される確率を計算する。

量子状態は変更しない。

パラメータ

target_qubit_index --

戻り値

double

inline virtual double get_marginal_probability(std::vector<UINT> measured_values) const override

複数の量子ビットを測定した時の周辺確率を計算する

パラメータ

measured_values -- 量子ビット数と同じ長さの0,1,2の配列。0,1はその値が観測され、2は測定をしないことを表す。

戻り値

計算された周辺確率

inline virtual double get_entropy() const override

計算基底で測定した時得られる確率分布のエントロピーを計算する。

戻り値

エントロピー

inline virtual double get_squared_norm() const override

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

inline virtual double get_squared_norm_single_thread() const override

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

inline virtual void normalize(double squared_norm) override

量子状態を正規化する

パラメータ

norm -- 自身のノルム

inline virtual void normalize_single_thread(double squared_norm) override

量子状態を正規化する

パラメータ

norm -- 自身のノルム

inline virtual DensityMatrixCpu *allocate_buffer() const override

バッファとして同じサイズの量子状態を作成する。

戻り値

生成された量子状態

inline virtual DensityMatrixCpu *copy() const override

自身の状態のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void load(const QuantumStateBase *_state)

stateの量子状態を自身へコピーする。

inline virtual void load(const std::vector<CPPCTYPE> &_state)

stateの量子状態を自身へコピーする。

inline virtual void load(const Eigen::VectorXcd &_state)
inline virtual void load(const ComplexMatrix &_state)
inline virtual void load(const CPPCTYPE *_state)

stateの量子状態を自身へコピーする。

inline virtual const std::string get_device_name() const override

量子状態が配置されているメモリを保持するデバイス名を取得する。

inline virtual void *data() const override

量子状態のポインタをvoid*型として返す

inline virtual CPPCTYPE *data_cpp() const override

量子状態をC++のstd::complex<double>の配列として取得する

戻り値

複素ベクトルのポインタ

inline virtual CTYPE *data_c() const override

量子状態をcsimのComplex型の配列として取得する

戻り値

複素ベクトルのポインタ

inline virtual CTYPE *duplicate_data_c() const override

量子状態をcsimのComplex型の配列として新たに確保する。

戻り値

複素ベクトルのポインタ

inline virtual CPPCTYPE *duplicate_data_cpp() const override

量子状態をC++のstd::complex<double>の配列として新たに確保する

戻り値

複素ベクトルのポインタ

inline virtual void add_state(const QuantumStateBase *state) override

量子状態を足しこむ

inline virtual void add_state_with_coef(CPPCTYPE coef, const QuantumStateBase *state) override

量子状態を足しこむ

inline virtual void add_state_with_coef_single_thread(CPPCTYPE coef, const QuantumStateBase *state) override

量子状態を足しこむ TODO: implement this in single_thread

inline virtual void multiply_coef(CPPCTYPE coef) override

複素数をかける

inline virtual void multiply_elementwise_function(const std::function<CPPCTYPE(ITYPE)>&) override
inline virtual std::vector<ITYPE> sampling(UINT sampling_count) override

量子状態を測定した際の計算基底のサンプリングを行う

パラメータ

sampling_count -- [in] サンプリングを行う回数

戻り値

サンプルされた値のリスト

inline virtual std::vector<ITYPE> sampling(UINT sampling_count, UINT random_seed) override
inline virtual std::string to_string() const

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

Class DiagonalizationEnergyMinimizationSolver
Class Documentation
class DiagonalizationEnergyMinimizationSolver

Public Functions

inline DiagonalizationEnergyMinimizationSolver()
inline virtual ~DiagonalizationEnergyMinimizationSolver()
inline virtual void solve(EnergyMinimizationProblem *instance)
inline virtual double get_loss()

Public Members

bool verbose
Class DuplicatedQubitIndexException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class DuplicatedQubitIndexException : public logic_error

対象ビットのインデックスが重複している例外

Public Functions

inline DuplicatedQubitIndexException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class EnergyMinimizationProblem
Class Documentation
class EnergyMinimizationProblem

Public Functions

inline EnergyMinimizationProblem(Observable *observable)
inline virtual ~EnergyMinimizationProblem()
inline virtual UINT get_term_count() const
inline virtual const PauliOperator *get_Pauli_operator(UINT index) const
inline virtual ITYPE get_state_dim() const
inline virtual UINT get_qubit_count() const
inline virtual double compute_loss(const QuantumStateBase *state) const
Class GateIndexOutOfRangeException
Inheritance Relationships
Base Type
  • public out_of_range

Class Documentation
class GateIndexOutOfRangeException : public out_of_range

QuantumCircuit内のGateのインデックスが範囲外という例外

Public Functions

inline GateIndexOutOfRangeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class GeneralQuantumOperator
Inheritance Relationships
Derived Type
Class Documentation
class GeneralQuantumOperator

Subclassed by HermitianQuantumOperator

Public Functions

explicit GeneralQuantumOperator(const UINT qubit_count)

コンストラクタ。

空のGeneralQuantumOperatorを作成する。

パラメータ

qubit_count -- [in] qubit数

戻り値

Observableのインスタンス

GeneralQuantumOperator(const GeneralQuantumOperator &obj)

コピーコンストラクタ。

与えられたGeneralQuantumOperatorのコピーを作成する。

パラメータ

obj -- [in] コピー元のインスタンス

戻り値

コピーされたObservableのインスタンス

virtual ~GeneralQuantumOperator()

デストラクタ。このとき、GeneralQuantumOperatorが保持しているPauliOperatorは解放される。

inline virtual bool is_hermitian() const

オペレータがエルミートかどうかを判定する。

エルミートでないと判定されても、実際にはエルミートであることもある。 エルミートと判定された場合は必ずエルミートである。

virtual void add_operator(const PauliOperator *mpt)

PauliOperatorを内部で保持するリストの末尾に追加する。 従来通り、引数として与えられたPauliOperatorのcopyを生成し保持する。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator_move(PauliOperator *mpt)

PauliOperatorを内部で保持するリストの末尾に追加する。 引数で与えられたPauliOperatorの所有権はGeneralQuantumOperator側に譲渡(move)される。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator_copy(const PauliOperator *mpt)

PauliOperatorを内部で保持するリストの末尾に追加する。 引数で与えられたPauliOperatorはGeneralQuantumOperatorに複製(copy)される。

パラメータ

mpt -- [in] 追加するPauliOperatorのインスタンス

virtual void add_operator(const CPPCTYPE coef, std::string pauli_string)

パウリ演算子の文字列と係数の組をGeneralQuantumOperatorに追加する。

パラメータ
  • coef -- [in] pauli_stringで作られるPauliOperatorの係数

  • pauli_string -- [in] パウリ演算子と掛かるindexの組からなる文字列。(example: "X 1 Y 2 Z 5")

virtual void add_operator(const std::vector<UINT> &target_qubit_index_list, const std::vector<UINT> &target_qubit_pauli_list, CPPCTYPE coef)
inline virtual UINT get_qubit_count() const

GeneralQuantumOperatorが掛かるqubit数を返す。

戻り値

GeneralQuantumOperatorのqubit数

inline virtual ITYPE get_state_dim() const

GeneralQuantumOperatorの行列表現の次元を返す。

戻り値

GeneralQuantumOperatorの次元

inline virtual UINT get_term_count() const

GeneralQuantumOperatorが保持するPauliOperatorの数を返す

戻り値

GeneralQuantumOperatorが保持するPauliOperatorの数

inline virtual const PauliOperator *get_term(UINT index) const

GeneralQuantumOperatorの指定した添字に対応するPauliOperatorを返す

パラメータ

index -- [in] GeneralQuantumOperatorが保持するPauliOperatorのリストの添字

戻り値

指定したindexにあるPauliOperator

inline virtual std::vector<PauliOperator*> get_terms() const

GeneralQuantumOperatorが保持するPauliOperatorのリストを返す

戻り値

GeneralQuantumOperatorが持つPauliOperatorのリスト

virtual GeneralQuantumOperator *get_dagger() const

エルミート共役を返す

戻り値

GeneralQuantumOperator

virtual std::string to_string() const

文字列に変換する。

virtual CPPCTYPE get_expectation_value(const QuantumStateBase *state) const

GeneralQuantumOperatorのある量子状態に対応するエネルギー(期待値)を計算して返す

パラメータ

state -- [in] 期待値をとるときの量子状態

戻り値

入力で与えた量子状態に対応するGeneralQuantumOperatorの期待値

virtual CPPCTYPE get_expectation_value_single_thread(const QuantumStateBase *state) const
virtual CPPCTYPE get_transition_amplitude(const QuantumStateBase *state_bra, const QuantumStateBase *state_ket) const

GeneralQuantumOperatorによってある状態が別の状態に移る遷移振幅を計算して返す

パラメータ
  • state_bra -- [in] 遷移先の量子状態

  • state_ket -- [in] 遷移前の量子状態

戻り値

入力で与えた量子状態に対応するGeneralQuantumOperatorの遷移振幅

void add_random_operator(const UINT operator_count)

ランダムなパウリ演算子をもつ observable を生成する

パラメータ
  • observable -- [in] パウリ演算子を追加する observable

  • operator_count -- [in] observable に追加するパウリ演算子数

  • seed -- [in] 乱数のシード値

戻り値

ランダムなパウリ演算子を operator_count 個もつ observable

void add_random_operator(const UINT operator_count, UINT seed)
virtual CPPCTYPE solve_ground_state_eigenvalue_by_arnoldi_method(QuantumStateBase *state, const UINT iter_count, const CPPCTYPE mu = 0.0) const

GeneralQuantumOperator の基底状態の固有値を arnordi method により求める. (A - I) の絶対値最大固有値を求めることで基底状態の固有値を求める.

パラメータ
  • state -- [in] 固有値を求めるための量子状態

  • iter_count -- [in] 計算の繰り返し回数

  • mu -- [in] 固有値をシフトするための係数

戻り値

GeneralQuantumOperator の基底状態の固有値

virtual CPPCTYPE solve_ground_state_eigenvalue_by_power_method(QuantumStateBase *state, const UINT iter_count, const CPPCTYPE mu = 0.0) const

GeneralQuantumOperator の基底状態の固有値を power method により求める (A - I) の絶対値最大固有値を求めることで基底状態の固有値を求める.

パラメータ
  • state -- [in] 固有値を求めるための量子状態

  • iter_count -- [in] 計算の繰り返し回数

  • mu -- [in] 固有値をシフトするための係数

戻り値

GeneralQuantumOperator の基底状態の固有値

void apply_to_state(QuantumStateBase *work_state, const QuantumStateBase &state_to_be_multiplied, QuantumStateBase *dst_state) const

state_to_be_multiplied に GeneralQuantumOperator を作用させる. 結果は dst_state に格納される.dst_state はすべての要素を0に初期化してから計算するため, 任意の状態を渡してよい.

パラメータ
  • work_state -- [in] 作業用の状態

  • state_to_be_multiplied -- [in] 作用を受ける状態

  • dst_state -- [in] 結果を格納する状態

void apply_to_state(QuantumStateBase *state, QuantumStateBase *dst_state) const

state_to_be_multiplied に GeneralQuantumOperator を作用させる. 結果は dst_state に格納される.dst_state はすべての要素を0に初期化してから計算するため, 任意の状態を渡してよい.

パラメータ
  • state_to_be_multiplied -- [in] 作用を受ける状態

  • dst_state -- [in] 結果を格納する状態

void apply_to_state_single_thread(QuantumStateBase *state, QuantumStateBase *dst_state) const

state_to_be_multiplied に GeneralQuantumOperator を作用させる. 結果は dst_state に格納される.dst_state はすべての要素を0に初期化してから計算するため, 任意の状態を渡してよい.

パラメータ
  • state_to_be_multiplied -- [in] 作用を受ける状態

  • dst_state -- [in] 結果を格納する状態

virtual GeneralQuantumOperator *copy() const
GeneralQuantumOperator operator+(const GeneralQuantumOperator &target) const
GeneralQuantumOperator operator+(const PauliOperator &target) const
GeneralQuantumOperator &operator+=(const GeneralQuantumOperator &target)
GeneralQuantumOperator &operator+=(const PauliOperator &target)
GeneralQuantumOperator operator-(const GeneralQuantumOperator &target) const
GeneralQuantumOperator operator-(const PauliOperator &target) const
GeneralQuantumOperator &operator-=(const GeneralQuantumOperator &target)
GeneralQuantumOperator &operator-=(const PauliOperator &target)
GeneralQuantumOperator operator*(const GeneralQuantumOperator &target) const
GeneralQuantumOperator operator*(const PauliOperator &target) const
GeneralQuantumOperator operator*(CPPCTYPE target) const
GeneralQuantumOperator &operator*=(const GeneralQuantumOperator &target)
GeneralQuantumOperator &operator*=(const PauliOperator &target)
GeneralQuantumOperator &operator*=(CPPCTYPE target)

Protected Functions

void _apply_pauli_to_state(std::vector<UINT> pauli_id_list, std::vector<UINT> target_index_list, QuantumStateBase *state) const

state にパウリ演算子を作用させる

パラメータ
  • pauli_id_list -- [in] パウリ演算子の ID

  • target_index_list -- [in] パウリ演算子が作用する量子ビットの番号

  • state -- [in] 作用を受ける状態

void _apply_pauli_to_state_single_thread(std::vector<UINT> pauli_id_list, std::vector<UINT> target_index_list, QuantumStateBase *state) const

state にパウリ演算子を作用させる

パラメータ
  • pauli_id_list -- [in] パウリ演算子の ID

  • target_index_list -- [in] パウリ演算子が作用する量子ビットの番号

  • state -- [in] 作用を受ける状態

CPPCTYPE calculate_default_mu() const

solve_ground_state_eigenvalue_by_power_method の mu のデフォルト値として,各 operator の係数の絶対値の和を計算する.

Class GradCalculator
Class Documentation
class GradCalculator

Public Functions

std::vector<std::complex<double>> calculate_grad(ParametricQuantumCircuit &x, Observable &obs, std::vector<double> theta)
std::vector<std::complex<double>> calculate_grad(ParametricQuantumCircuit &x, Observable &obs)
Class GradientBasedOptimizer
Inheritance Relationships
Base Type
Derived Types
Class Documentation
class GradientBasedOptimizer : public Optimizer

Subclassed by AdamOptimizer, GradientDecentOptimizer

Public Functions

inline GradientBasedOptimizer(UINT trainable_parameter_count)
inline virtual ~GradientBasedOptimizer()
virtual void apply_gradient(std::vector<double> *parameter, const std::vector<double> &gradient) = 0
Class GradientByHalfPi
Inheritance Relationships
Base Type
Class Documentation
class GradientByHalfPi : public QuantumCircuitGradientDifferentiation

Public Functions

virtual double compute_gradient(ParametricQuantumCircuitSimulator *sim, const EnergyMinimizationProblem *instance, const std::vector<double> &parameter, std::vector<double> *gradient) override
Class GradientDecentOptimizer
Inheritance Relationships
Base Type
Class Documentation
class GradientDecentOptimizer : public GradientBasedOptimizer

Public Functions

inline GradientDecentOptimizer(UINT trainable_parameter_count, double learning_rate = 0.01)
inline virtual ~GradientDecentOptimizer()
inline virtual void apply_gradient(std::vector<double> *parameter, const std::vector<double> &gradient) override
Class GradientFreeOptimizer
Inheritance Relationships
Base Type
Class Documentation
class GradientFreeOptimizer : public Optimizer

Public Functions

inline GradientFreeOptimizer(UINT trainable_parameter_count)
inline virtual ~GradientFreeOptimizer()
virtual void update_parameter(std::vector<double> *next_parameter, double previous_loss) = 0
Class InvalidControlQubitException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidControlQubitException : public logic_error

制御ビットのインデックスが不適切な例外

Public Functions

inline InvalidControlQubitException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidMatrixGateSizeException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidMatrixGateSizeException : public logic_error

MatrixGateのサイズが対象の量子ビット数に合わない例外

Public Functions

inline InvalidMatrixGateSizeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidNoiseTypeIdentifierException
Inheritance Relationships
Base Type
  • public domain_error

Class Documentation
class InvalidNoiseTypeIdentifierException : public domain_error

ノイズの種類の名前が不適切という例外

Public Functions

inline InvalidNoiseTypeIdentifierException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidObservableException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidObservableException : public logic_error

Observableがdiagonalでないなど条件を満たさない例外

Public Functions

inline InvalidObservableException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidOpenfermionFormatException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidOpenfermionFormatException : public logic_error

openfermionのファイルフォーマットが不適切であるという例外

Public Functions

inline InvalidOpenfermionFormatException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidPauliIdentifierException
Inheritance Relationships
Base Type
  • public domain_error

Class Documentation
class InvalidPauliIdentifierException : public domain_error

パウリ演算子のIDや名前が不適切という例外

Public Functions

inline InvalidPauliIdentifierException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidProbabilityDistributionException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidProbabilityDistributionException : public logic_error

確率分布が不適切という例外

Public Functions

inline InvalidProbabilityDistributionException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidQuantumOperatorException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidQuantumOperatorException : public logic_error

GeneralQuantumOperatorにPauliOperatorが1つも含まれていない例外

Public Functions

inline InvalidQuantumOperatorException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidQubitCountException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidQubitCountException : public logic_error

一致すべき演算対象の量子ビット数が不一致である例外

Public Functions

inline InvalidQubitCountException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class InvalidStateVectorSizeException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class InvalidStateVectorSizeException : public logic_error

std::vectorの状態のstateが量子ビット数に合わない例外

Public Functions

inline InvalidStateVectorSizeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class IOException
Inheritance Relationships
Base Type
  • public runtime_error

Class Documentation
class IOException : public runtime_error

ファイルを開くのに失敗した例外

Public Functions

inline IOException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class KAK_data
Class Documentation
class KAK_data

Public Members

QuantumGateMatrix *single_qubit_operations_before[2]
double interaction_coefficients[3]
QuantumGateMatrix *single_qubit_operations_after[2]
Class MatrixIndexOutOfRangeException
Inheritance Relationships
Base Type
  • public out_of_range

Class Documentation
class MatrixIndexOutOfRangeException : public out_of_range

行列中の対象の要素のインデックスが範囲外という例外

Public Functions

inline MatrixIndexOutOfRangeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class NoiseSimulator
Nested Relationships
Nested Types
Class Documentation
class NoiseSimulator

回路にDepolarizingNoiseを加えてサンプリングするクラス

Public Functions

explicit NoiseSimulator(const QuantumCircuit *init_circuit, const QuantumState *init_state = NULL)

コンストラクタ。

NoiseSimulatorを作成する。

パラメータ
  • init_circuit -- [in] シミュレータに使用する量子回路。

  • init_state -- [in] 最初の状態。指定されなかった場合は|00...0>で初期化される。

戻り値

NoiseSimulatorのインスタンス

virtual ~NoiseSimulator()

デストラクタ。このとき、NoiseSimulatorが保持しているcircuitとinitial_stateは解放される。

virtual std::vector<ITYPE> execute(const UINT sample_count)

サンプリングを行い、結果を配列で返す。

パラメータ

sample_count -- [in] 行うsamplingの回数

virtual Result *execute_and_get_result(const UINT execution_count)

実際にサンプリングまではせずにノイズがランダムにかかった量子状態の列を返す。

パラメータ

execution_count -- [in] 実行回数

戻り値

量子状態の列。Resultクラスに入れられる。

struct Result

複数回の実行結果をまとめた構造体

Public Functions

Result(const std::vector<std::pair<QuantumState*, UINT>> &result_)
~Result()
std::vector<ITYPE> sampling() const

Public Members

std::vector<std::pair<QuantumState*, UINT>> result
Class NonHermitianException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class NonHermitianException : public logic_error

hermitianにしか使えない演算にhermitianでないOperatorやObservableを渡した例外

Public Functions

inline NonHermitianException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class NotImplementedException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class NotImplementedException : public logic_error

未実装なものに対する例外

Public Functions

inline NotImplementedException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class OperatorIndexOutOfRangeException
Inheritance Relationships
Base Type
  • public out_of_range

Class Documentation
class OperatorIndexOutOfRangeException : public out_of_range

GeneralQuantumOperator中のPauliOperatorのインデックスが範囲外という例外

Public Functions

inline OperatorIndexOutOfRangeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class Optimizer
Inheritance Relationships
Derived Types
Class Documentation
class Optimizer

Subclassed by GradientBasedOptimizer, GradientFreeOptimizer

Protected Functions

inline Optimizer(UINT trainable_parameter_count)
inline virtual ~Optimizer()

Protected Attributes

UINT _trainable_parameter_count
Class ParameterIndexOutOfRangeException
Inheritance Relationships
Base Type
  • public out_of_range

Class Documentation
class ParameterIndexOutOfRangeException : public out_of_range

ParametricCircuitのパラメータのインデックスが範囲外という例外

Public Functions

inline ParameterIndexOutOfRangeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class ParametricCircuitBuilder
Inheritance Relationships
Base Type
Class Documentation
class ParametricCircuitBuilder : public QuantumCircuitBuilder
Class ParametricQuantumCircuit
Inheritance Relationships
Base Type
Class Documentation
class ParametricQuantumCircuit : public QuantumCircuit

Public Functions

ParametricQuantumCircuit(UINT qubit_count)
ParametricQuantumCircuit *copy() const
virtual void add_parametric_gate(QuantumGate_SingleParameter *gate)
virtual void add_parametric_gate(QuantumGate_SingleParameter *gate, UINT index)
virtual void add_parametric_gate_copy(QuantumGate_SingleParameter *gate)
virtual void add_parametric_gate_copy(QuantumGate_SingleParameter *gate, UINT index)
virtual UINT get_parameter_count() const
virtual double get_parameter(UINT index) const
virtual void set_parameter(UINT index, double value)
virtual UINT get_parametric_gate_position(UINT index) const
virtual void add_gate(QuantumGateBase *gate) override

量子ゲートを回路の末尾に追加する

量子ゲートを回路に追加する。 追加した量子ゲートは量子回路の解放時に開放される。

パラメータ

gate -- [in] 追加する量子ゲート

virtual void add_gate(QuantumGateBase *gate, UINT index) override

量子ゲートを回路の指定位置に追加する。

量子ゲートを回路の指定した位置に追加する。 追加した量子ゲートは量子回路の解放時に開放される。

パラメータ
  • gate -- [in] 追加する量子ゲート

  • index -- [in] 追加する位置

virtual void add_gate_copy(const QuantumGateBase *gate) override

量子ゲートを回路の末尾に追加する

与えられた量子ゲートのコピーを回路に追加する。 add_gateに比べコピーが発生する分低速な一方、引数で与えたゲートを再利用できる。

パラメータ

gate -- [in] 追加する量子ゲート

virtual void add_gate_copy(const QuantumGateBase *gate, UINT index) override

量子ゲートを回路の指定位置に追加する。

与えらた量子ゲートを回路の指定した位置に追加する。

パラメータ
  • gate -- [in] 追加する量子ゲート

  • index -- [in] 追加する位置

virtual void remove_gate(UINT index) override

量子回路からゲートを削除する。

削除した量子ゲートは解放される。

パラメータ

index -- [in] 削除するゲートの位置

virtual void merge_circuit(const ParametricQuantumCircuit *circuit)

量子回路をマージする。

引数で与えた量子回路のゲートを後ろに追加していく。 マージされた側の量子回路に変更を加えてもマージした側の量子回路には変更は加わらないことに注意する。 パラメータゲートに対応するため、ParametricQuantumCircuit にも merge_circuit() を追加する circuit1.add_circuit(circuit2) circuit2.add_gate(gate) # これをしても、circuit1にgateは追加されない

パラメータ

circuit -- [in] マージする量子回路

virtual std::string to_string() const

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

virtual void add_parametric_RX_gate(UINT target_index, double initial_angle)
virtual void add_parametric_RY_gate(UINT target_index, double initial_angle)
virtual void add_parametric_RZ_gate(UINT target_index, double initial_angle)
virtual void add_parametric_multi_Pauli_rotation_gate(std::vector<UINT> target, std::vector<UINT> pauli_id, double initial_angle)
virtual std::vector<double> backprop(GeneralQuantumOperator *obs)
virtual std::vector<double> backprop_inner_product(QuantumState *bistate)

Friends

friend std::ostream &operator<<(std::ostream &os, const ParametricQuantumCircuit&)
friend std::ostream &operator<<(std::ostream &os, const ParametricQuantumCircuit *circuit)
Class ParametricQuantumCircuitSimulator
Inheritance Relationships
Base Type
Class Documentation
class ParametricQuantumCircuitSimulator : public QuantumCircuitSimulator

Public Functions

ParametricQuantumCircuitSimulator(ParametricQuantumCircuit *circuit, QuantumStateBase *state = NULL)
double get_parameter(UINT index) const
void add_parameter_value(UINT index, double value)
void set_parameter_value(UINT index, double value)
UINT get_parametric_gate_count()
UINT get_parametric_gate_position(UINT index)
Class QuantumCircuit
Inheritance Relationships
Derived Type
Class Documentation
class QuantumCircuit

量子回路のクラス

量子回路を管理するクラス。QuantumGateクラスをリストとして持ち、種々の操作を行う。 管理する量子ゲートは量子回路の解放時にすべて解放される。

Subclassed by ParametricQuantumCircuit

Public Functions

explicit QuantumCircuit(UINT qubit_count)

空の量子回路を作成する

パラメータ

qubit_count -- [in] 量子ビットの数

戻り値

生成された量子回路のインスタンス

QuantumCircuit *copy() const

量子回路のディープコピーを生成する

戻り値

量子回路のディープコピー

virtual ~QuantumCircuit()

デストラクタ

virtual void add_gate(QuantumGateBase *gate)

量子ゲートを回路の末尾に追加する

量子ゲートを回路に追加する。 追加した量子ゲートは量子回路の解放時に開放される。

パラメータ

gate -- [in] 追加する量子ゲート

virtual void add_gate(QuantumGateBase *gate, UINT index)

量子ゲートを回路の指定位置に追加する。

量子ゲートを回路の指定した位置に追加する。 追加した量子ゲートは量子回路の解放時に開放される。

パラメータ
  • gate -- [in] 追加する量子ゲート

  • index -- [in] 追加する位置

virtual void add_gate_copy(const QuantumGateBase *gate)

量子ゲートを回路の末尾に追加する

与えられた量子ゲートのコピーを回路に追加する。 add_gateに比べコピーが発生する分低速な一方、引数で与えたゲートを再利用できる。

パラメータ

gate -- [in] 追加する量子ゲート

virtual void add_gate_copy(const QuantumGateBase *gate, UINT index)

量子ゲートを回路の指定位置に追加する。

与えらた量子ゲートを回路の指定した位置に追加する。

パラメータ
  • gate -- [in] 追加する量子ゲート

  • index -- [in] 追加する位置

virtual void add_noise_gate(QuantumGateBase *gate, std::string noise_type, double noise_prob)

ノイズ付き量子ゲートを回路の末尾に追加する

ノイズ付き量子ゲートを回路に追加する。 追加したノイズ付き量子ゲートは量子回路の解放時に開放される。

パラメータ
  • gate -- [in] 追加するノイズ付き量子ゲート

  • noise_type -- [in] 追加するノイズの種類

  • noise_prob -- [in] ノイズが発生する確率

void add_noise_gate_copy(QuantumGateBase *gate, std::string noise_type, double noise_prob)

ノイズ付き量子ゲートのコピーを回路の末尾に追加する

ノイズ付き量子ゲートのコピーを回路に追加する。 add_noise_gateに比べコピーが発生する分低速な一方、引数で与えたゲートを再利用できる。

パラメータ
  • gate -- [in] 追加するノイズ付き量子ゲート

  • noise_type -- [in] 追加するノイズの種類

  • noise_prob -- [in] ノイズが発生する確率

virtual void remove_gate(UINT index)

量子回路からゲートを削除する。

削除した量子ゲートは解放される。

パラメータ

index -- [in] 削除するゲートの位置

inline virtual void merge_circuit(const QuantumCircuit *circuit)

量子回路をマージする。

引数で与えた量子回路のゲートを後ろに追加していく。 マージされた側の量子回路に変更を加えてもマージした側の量子回路には変更は加わらないことに注意する。 circuit1.add_circuit(circuit2) circuit2.add_gate(gate) # これをしても、circuit1にgateは追加されない

パラメータ

circuit -- [in] マージする量子回路

void update_quantum_state(QuantumStateBase *state)

量子状態を更新する

順番にすべての量子ゲートを作用する。量子状態の初期化などは行わない。

パラメータ

state -- [inout] 作用する量子状態

void update_quantum_state(QuantumStateBase *state, UINT start_index, UINT end_index)

量子回路の指定範囲のみを用いて量子状態をを更新する

添え字がstart_indexからend_index-1までの量子ゲートを順番に量子ゲートを作用する。量子状態の初期化などは行わない。

パラメータ
  • state -- [inout] 作用する量子状態

  • start_index -- [in] 開始位置

  • end_index -- [in] 修了位置

bool is_Clifford() const

量子回路がCliffordかどうかを判定する。

全ての量子ゲートがCliffordである場合にtrueと判定される。 Non-Cliffordゲートが複数あり積がCliffordとなっている場合もfalseとして判定される点に注意。

戻り値
  • true -- Clifford

  • false -- Non-Clifford

bool is_Gaussian() const

量子回路がFermionic Gaussianかどうかを判定する。

全ての量子ゲートがFermionic Gaussianである場合にtrueと判定される。 Non-Gaussianゲートが複数あり、結果としてGaussianとなっている場合もNon-Gaussianとして判定される点に注意。

戻り値
  • true -- Fermionic Gaussian

  • false -- Non-fermionic Gaussian

UINT calculate_depth() const

量子回路のdepthを計算する。

ここでいうdepthとは、可能な限り量子ゲートを並列実行した時に掛かるステップ数を指す。

戻り値

量子回路のdepth

virtual std::string to_string() const

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

virtual void add_X_gate(UINT target_index)

\(X\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_Y_gate(UINT target_index)

\(Y\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_Z_gate(UINT target_index)

\(Z\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_H_gate(UINT target_index)

Hadamard gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_S_gate(UINT target_index)

\(S\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_Sdag_gate(UINT target_index)

\(S^{\dagger}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_T_gate(UINT target_index)

\(T\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_Tdag_gate(UINT target_index)

\(T^{\dagger}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_sqrtX_gate(UINT target_index)

\(\sqrt{X}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_sqrtXdag_gate(UINT target_index)

\(\sqrt{X}^{\dagger}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_sqrtY_gate(UINT target_index)

\(\sqrt{Y}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_sqrtYdag_gate(UINT target_index)

\(\sqrt{Y}^{\dagger}\) gateを追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_P0_gate(UINT target_index)

0状態への射影演算を追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_P1_gate(UINT target_index)

1状態への射影演算を追加する。

パラメータ

target_index -- [in] 作用する量子ビットの添え字

virtual void add_CNOT_gate(UINT control_index, UINT target_index)

CNOT gateを追加する。

パラメータ
  • control_index -- [in] 作用するcontrol qubitの添え字

  • target_index -- [in] 作用するtarget qubitの添え字

virtual void add_CZ_gate(UINT control_index, UINT target_index)

Control-Z gateを追加する。

パラメータ
  • control_index -- [in] 作用するcontrol qubitの添え字

  • target_index -- [in] 作用するtarget qubitの添え字

virtual void add_SWAP_gate(UINT target_index1, UINT target_index2)

SWAP gateを追加する。

パラメータ
  • target_index1 -- [in] 作用するtarget qubitの添え字

  • target_index2 -- [in] 作用するもう一方のtarget qubitの添え字

virtual void add_RX_gate(UINT target_index, double angle)

X-rotation gateを追加する。

ゲートの表記は \( R_X(\theta) = \exp(i\theta X) \)になっている。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RY_gate(UINT target_index, double angle)

Y-rotation gateを追加する。

ゲートの表記は \( R_Y(\theta) = \exp(i\theta Y) \)になっている。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RZ_gate(UINT target_index, double angle)

Z-rotation gateを追加する。

ゲートの表記は \( R_Z(\theta) = \exp(i\theta Z) \)になっている。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotInvX_gate(UINT target_index, double angle)

X-rotation gateを追加する。

ゲートの表記は \( R_X(\theta) = \exp(i\theta X) \)になっている。 一般的な表記に対して逆向き,qulacsのRXと同じ向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotInvY_gate(UINT target_index, double angle)

Y-rotation gateを追加する。

ゲートの表記は \( R_Y(\theta) = \exp(i\theta Y) \)になっている。 一般的な表記に対して逆向き,qulacsのRYと同じ向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotInvZ_gate(UINT target_index, double angle)

Z-rotation gateを追加する。

ゲートの表記は \( R_Z(\theta) = \exp(i\theta Z) \)になっている。 一般的な表記に対して逆向き,qulacsのRZと同じ向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotX_gate(UINT target_index, double angle)

X-rotation gateを追加する。

ゲートの表記は \( R_X(\theta) = \exp(-i\theta X) \)になっている。 一般的な表記と同じ向き,qulacsのRXに対して逆向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotY_gate(UINT target_index, double angle)

Y-rotation gateを追加する。

ゲートの表記は \( R_Y(\theta) = \exp(-i\theta Y) \)になっている。 一般的な表記と同じ向き,qulacsのRYに対して逆向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_RotZ_gate(UINT target_index, double angle)

Z-rotation gateを追加する。

ゲートの表記は \( R_Z(\theta) = \exp(-i\theta Z) \)になっている。 一般的な表記と同じ向き,qulacsのRZに対して逆向きである。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • angle -- [in] 回転角 \(\theta\)

virtual void add_U1_gate(UINT target_index, double phi)

OpenQASMのu1 gateを追加する。

ゲートの表記はIBMQのページを参照。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • phi -- [in] 回転角 \(\phi\)

virtual void add_U2_gate(UINT target_index, double phi, double psi)

OpenQASMのu2 gateを追加する。

ゲートの表記はIBMQのページを参照。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • phi -- [in] 回転角 \(\phi\)

  • psi -- [in] 回転角 \(\psi\)

virtual void add_U3_gate(UINT target_index, double phi, double psi, double lambda)

OpenQASMのu3 gateを追加する。

ゲートの表記はIBMQのページを参照。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • phi -- [in] 回転角 \(\phi\)

  • psi -- [in] 回転角 \(\psi\)

  • lambda -- [in] 回転角 \(\lambda\)

virtual void add_multi_Pauli_gate(std::vector<UINT> target_index_list, std::vector<UINT> pauli_id_list)

n-qubitパウリゲートを追加する。

n-qubitパウリゲートを作用する。 パウリ演算子は \((I,X,Y,Z) \mapsto (0,1,2,3)\)と対応している。 例えば、 \(X_3 Y_2 Z_4\)であれば、target_index_list = {3,2,4}, pauli_id_list = {1,2,3}である。 1-qubitパウリゲートとn-qubitパウリゲートの計算コストはほぼ同じため、パウリゲートのテンソル積を作用する場合はパウリゲートとして作用した方が処理が高速になる。

パラメータ
  • target_index_list -- [in] 作用するtarget qubitの添え字のリスト

  • pauli_id_list -- [in] target_index_listに対応したパウリ演算子のid

virtual void add_multi_Pauli_gate(const PauliOperator &pauli_operator)

n-qubitパウリゲートを追加する。

n-qubitパウリゲートを作用する。

パラメータ

pauli_operator -- [in] 追加するパウリ演算子

virtual void add_multi_Pauli_rotation_gate(std::vector<UINT> target_index_list, std::vector<UINT> pauli_id_list, double angle)

n-qubitパウリ回転ゲートを追加する。

n-qubitパウリ回転ゲートを作用する。 パウリ演算子は{I,X,Y,Z} = {0,1,2,3}と対応している。 例えば、 \(\exp(i\theta X_3 Y_2 Z_4)\)であれば、target_index_list = {3,2,4}, pauli_id_list = {1,2,3}, angle = \(\theta\)とする。 1-qubitパウリゲートとn-qubitパウリゲートの計算コストはほぼ同じため、パウリゲートのテンソル積を作用する場合はパウリゲートとして作用した方が処理が高速になる。

パラメータ
  • target_index_list -- [in] 作用するtarget qubitの添え字のリスト

  • pauli_id_list -- [in] target_index_listに対応したパウリ演算子のid

  • angle -- [in] 回転角

virtual void add_multi_Pauli_rotation_gate(const PauliOperator &pauli_operator)

n-qubitパウリ回転ゲートを追加する。 n-qubitパウリ回転ゲートを作用する。 回転角はPauliOperatorの係数を用いる。

パラメータ

pauli_operator -- [in] 追加するパウリ演算子

virtual void add_diagonal_observable_rotation_gate(const Observable &observable, double angle)

n-qubitオブザーバブル回転ゲートを追加する。(対角のみ)

n-qubitオブザーバブル回転ゲートを作用する。ここで用いるオブザーバブルは、対角である必要がある。

パラメータ
  • observable -- [in] 追加するオブザーバブル

  • angle -- [in] 回転角

virtual void add_observable_rotation_gate(const Observable &observable, double angle, UINT num_repeats = 0)

n-qubitオブザーバブル回転ゲートを追加する。

Suzuki-Trotter展開によりn-qubitオブザーバブル回転ゲートを作用する。ここで用いるオブザーバブルは、対角でなくてもよい。

パラメータ
  • observable -- [in] 追加するオブザーバブル

  • angle -- [in] 回転角 \( \theta \)

  • num_repeats -- [in] Trotter展開をする際の分割数 \(N\)。指定しない場合は、関数内部で \( \#qubit \cdot \theta / N = 0.01\) となるように設定される。

virtual void add_dense_matrix_gate(UINT target_index, const ComplexMatrix &matrix)

1-qubitのdenseな行列のゲートを追加する。

denseな行列はユニタリである必要はなく、射影演算子やクラウス演算子でも良い。

パラメータ
  • target_index -- [in] 作用するtarget qubitの添え字

  • matrix -- [in] 作用する2*2の行列

virtual void add_dense_matrix_gate(std::vector<UINT> target_index_list, const ComplexMatrix &matrix)

multi qubitのdenseな行列のゲートを追加する。

denseな行列はユニタリである必要はなく、射影演算子やクラウス演算子でも良い。 matrixの次元はtarget_index_listのサイズを \(m\)としたとき \(2^m\)でなければいけない。

パラメータ
  • target_index_list -- [in] 作用するtarget qubitの添え字のリスト

  • matrix -- [in] 作用する行列

virtual void add_random_unitary_gate(std::vector<UINT> target_index_list)

multi qubitのランダムユニタリゲートを追加する。

パラメータ
  • target_index_list -- [in] 作用するtarget qubitの添え字のリスト

  • seed -- [in] 乱数のseed値

virtual void add_random_unitary_gate(std::vector<UINT> target_index_list, UINT seed)
virtual QuantumCircuit *get_inverse(void)

Public Members

const UINT &qubit_count

量子ビットの数

const std::vector<QuantumGateBase*> &gate_list

量子ゲートのリスト

Protected Functions

QuantumCircuit(const QuantumCircuit &obj)
QuantumCircuit &operator=(const QuantumCircuit&) = delete

Protected Attributes

std::vector<QuantumGateBase*> _gate_list
UINT _qubit_count

Friends

friend std::ostream &operator<<(std::ostream &os, const QuantumCircuit&)

量子回路のデバッグ情報を出力する。

戻り値

受け取ったストリーム

friend std::ostream &operator<<(std::ostream &os, const QuantumCircuit *gate)

量子回路のデバッグ情報を出力する。

戻り値

受け取ったストリーム

Class QuantumCircuitBuilder
Inheritance Relationships
Derived Type
Class Documentation
class QuantumCircuitBuilder

与えられた量子ビットの数に応じて量子回路を生成するアンザッツのクラス

Subclassed by ParametricCircuitBuilder

Public Functions

virtual QuantumCircuit *create_circuit(UINT qubit_count) const = 0

量子回路を生成する

パラメータ

qubit_count -- [in] 量子ビット数

戻り値

生成された量子回路

Class QuantumCircuitEnergyMinimizationSolver
Class Documentation
class QuantumCircuitEnergyMinimizationSolver

Public Functions

inline QuantumCircuitEnergyMinimizationSolver(const std::function<ParametricQuantumCircuit*(UINT, UINT)> *circuit_generator, UINT param_count = 0)
inline virtual ~QuantumCircuitEnergyMinimizationSolver()
inline virtual void solve(EnergyMinimizationProblem *instance, UINT max_iteration = 100, std::string optimizer_name = "GD", std::string differentiation_method = "HalfPi")
inline virtual double get_loss()
inline virtual std::vector<double> get_parameter()
inline ParametricQuantumCircuitSimulator *get_quantum_circuit_simulator()

Public Members

bool verbose
Class QuantumCircuitGradientDifferentiation
Inheritance Relationships
Derived Type
Class Documentation
class QuantumCircuitGradientDifferentiation

Subclassed by GradientByHalfPi

Public Functions

virtual double compute_gradient(ParametricQuantumCircuitSimulator *sim, const EnergyMinimizationProblem *instance, const std::vector<double> &parameter, std::vector<double> *gradient) = 0
Class QuantumCircuitOptimizer
Class Documentation
class QuantumCircuitOptimizer

量子回路の圧縮を行うクラス

量子回路の圧縮を行う。 与えらえた量子回路を適切なサイズまで圧縮したり、まとめたゲートに変換するなどの処理を行う。

Public Functions

inline QuantumCircuitOptimizer()

コンストラクタ

inline virtual ~QuantumCircuitOptimizer()

デストラクタ

void optimize(QuantumCircuit *circuit, UINT max_block_size = 2)

与えられた量子回路のゲートを指定されたブロックまで纏める。

与えられた量子回路において、若い添え字から任意の二つのゲートを選び、二つが他のゲートに影響を与えず合成可能なら合成を行う。 これを合成可能なペアがなくなるまで繰り返す。 二つのゲートが合成可能であるとは、二つのゲートそれぞれについて隣接するゲートとの交換を繰り返し、二つのゲートが隣接した位置まで移動できることを指す。

パラメータ
  • circuit -- [in] 量子回路のインスタンス

  • max_block_size -- [in] 合成後に許されるブロックの最大サイズ

void optimize_light(QuantumCircuit *circuit)

与えられた量子回路のゲートを指定されたブロックまで纏める。

与えられた量子回路において、若い添え字から任意の二つのゲートを選び、二つが他のゲートに影響を与えず合成可能なら合成を行う。 これを合成可能なペアがなくなるまで繰り返す。 二つのゲートが合成可能であるとは、二つのゲートそれぞれについて隣接するゲートとの交換を繰り返し、二つのゲートが隣接した位置まで移動できることを指す。

パラメータ

circuit -- [in] 量子回路のインスタンス

QuantumGateMatrix *merge_all(const QuantumCircuit *circuit)

量子回路を纏めて一つの巨大な量子ゲートにする

パラメータ

circuit -- [in] 量子回路のインスタンス

戻り値

変換された量子ゲート

Class QuantumCircuitSimulator
Inheritance Relationships
Derived Type
Class Documentation
class QuantumCircuitSimulator

量子回路をシミュレートするためのクラス

Subclassed by ParametricQuantumCircuitSimulator

Public Functions

explicit QuantumCircuitSimulator(QuantumCircuit *circuit, QuantumStateBase *initial_state = NULL)

コンストラクタ

パラメータ
  • circuit -- シミュレートする量子回路

  • initial_state -- 初期量子状態。デフォルト値はNULLで、NULLの場合は0状態に初期化される。

~QuantumCircuitSimulator()

デストラクタ

void initialize_state(ITYPE computationl_basis = 0)

量子状態を計算基底に初期化する

パラメータ

computationl_basis -- 初期化する計算基底を二進数にした値

void initialize_random_state()

ランダムな量子状態に初期化する。

パラメータ

seed -- 乱数のシード値

void initialize_random_state(UINT seed)
void simulate()

量子回路全体シミュレートする。

void simulate_range(UINT start, UINT end)

量子回路をstartからendまでの区間シミュレートする

パラメータ
  • start -- シミュレートを開始する添え字

  • end -- シミュレートを終了する添え字

CPPCTYPE get_expectation_value(const Observable *observable)

現在の量子状態の受け取ったオブザーバブルの期待値を計算する。

パラメータ

observable -- オブザーバブル

戻り値

期待値

UINT get_gate_count()

量子回路中のゲートの数を取得する

戻り値

ゲートの数

void copy_state_to_buffer()

量子状態をバッファへコピーする

void copy_state_from_buffer()

バッファの量子状態を現在の量子状態へコピーする

void swap_state_and_buffer()

現在の量子状態をバッファと交換する

inline const QuantumStateBase *get_state_ptr() const

現在の量子状態のポインタを取得する

戻り値

量子状態のポインタ

Class QuantumGate_Adaptive
Inheritance Relationships
Base Type
Class Documentation
class QuantumGate_Adaptive : public QuantumGateBase

Adaptiveな操作

Public Functions

inline explicit QuantumGate_Adaptive(QuantumGateBase *gate, std::function<bool(const std::vector<UINT>&)> func_without_id)
inline explicit QuantumGate_Adaptive(QuantumGateBase *gate, std::function<bool(const std::vector<UINT>&, UINT)> func_with_id, UINT id)
inline virtual ~QuantumGate_Adaptive()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual QuantumGate_Adaptive *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

Protected Attributes

QuantumGateBase *_gate
std::function<bool(const std::vector<UINT>&)> _func_without_id
std::function<bool(const std::vector<UINT>&, UINT)> _func_with_id
const int _id
Class QuantumGate_CP
Inheritance Relationships
Base Type
Class Documentation
class QuantumGate_CP : public QuantumGateBase

Kraus表現のCP-map

Public Functions

inline explicit QuantumGate_CP(std::vector<QuantumGateBase*> gate_list, bool state_normalize, bool probability_normalize, bool assign_zero_if_not_matched)
inline virtual ~QuantumGate_CP()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual QuantumGate_CP *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

Protected Attributes

Random random
std::vector<QuantumGateBase*> _gate_list
const bool _state_normalize
const bool _probability_normalize
const bool _assign_zero_if_not_matched
Class QuantumGate_CPTP
Inheritance Relationships
Base Type
Class Documentation
class QuantumGate_CPTP : public QuantumGateBase

Kraus表現のCPTP-map

Public Functions

inline explicit QuantumGate_CPTP(std::vector<QuantumGateBase*> gate_list)
inline explicit QuantumGate_CPTP(std::vector<QuantumGateBase*> gate_list, UINT classical_register_address)
inline virtual ~QuantumGate_CPTP()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual QuantumGate_CPTP *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

Protected Attributes

Random random
std::vector<QuantumGateBase*> _gate_list
bool is_instrument
UINT _classical_register_address
Class QuantumGate_Probabilistic
Inheritance Relationships
Base Type
Class Documentation
class QuantumGate_Probabilistic : public QuantumGateBase

ここら辺のtarget listの仕様について ゲートをマージしたときのtargetやcontrolの挙動は get_new_qubit_list 関数で決められている Identity のゲート + 含まれるすべてのゲート のゲート集合を元に、 get_new_qubit_list で決める ただし、和が1のProbabilistic においてのみ、 Identityなしで求めている 確率的なユニタリ操作

Public Functions

inline explicit QuantumGate_Probabilistic(const std::vector<double> &distribution, const std::vector<QuantumGateBase*> &gate_list)

コンストラクタ

パラメータ
  • distribution -- ゲートが現れる確率

  • gate_list -- ゲートのリスト

inline explicit QuantumGate_Probabilistic(const std::vector<double> &distribution, const std::vector<QuantumGateBase*> &gate_list, UINT classical_register_address)
inline virtual ~QuantumGate_Probabilistic()
inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

inline virtual QuantumGate_Probabilistic *copy() const override

自身のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

inline virtual void set_seed(int seed) override
inline virtual std::vector<double> get_cumulative_distribution()
inline virtual std::vector<double> get_distribution()
inline virtual std::vector<QuantumGateBase*> get_gate_list()
inline virtual void optimize_ProbablisticGate()
inline virtual bool is_noise()

Protected Attributes

Random random
std::vector<double> _distribution
std::vector<double> _cumulative_distribution
std::vector<QuantumGateBase*> _gate_list
bool is_instrument
UINT _classical_register_address
Class QuantumGate_SingleParameter
Inheritance Relationships
Base Type
Derived Types
Class Documentation
class QuantumGate_SingleParameter : public QuantumGateBase

Subclassed by ClsParametricPauliRotationGate, QuantumGate_SingleParameterOneQubitRotation

Public Functions

inline QuantumGate_SingleParameter(double angle)
inline virtual void set_parameter_value(double value)
inline virtual double get_parameter_value() const
virtual QuantumGate_SingleParameter *copy() const override = 0

自身のディープコピーを生成する

戻り値

自身のディープコピー

Protected Attributes

double _angle
UINT _parameter_type
Class QuantumGate_SingleParameterOneQubitRotation
Inheritance Relationships
Base Type
Derived Types
Class Documentation
class QuantumGate_SingleParameterOneQubitRotation : public QuantumGate_SingleParameter

Subclassed by ClsParametricRXGate, ClsParametricRYGate, ClsParametricRZGate

Public Functions

inline virtual void update_quantum_state(QuantumStateBase *state) override

量子状態を更新する

パラメータ

state -- 更新する量子状態

Protected Types

using UpdateFunc = void (*)(UINT, double, CTYPE*, ITYPE)
using UpdateFuncGpu = void (*)(UINT, double, void*, ITYPE, void*, UINT)

Protected Functions

inline QuantumGate_SingleParameterOneQubitRotation(double angle)

Protected Attributes

UpdateFunc _update_func = nullptr
UpdateFunc _update_func_dm = nullptr
UpdateFuncGpu _update_func_gpu = nullptr
Class QuantumGateBase
Inheritance Relationships
Derived Types
Class Documentation
class QuantumGateBase

量子ゲートの基底クラス

Subclassed by ClsNoisyEvolution, ClsNoisyEvolution_auto, ClsNoisyEvolution_fast, ClsOneControlOneTargetGate, ClsOneQubitGate, ClsOneQubitRotationGate, ClsPauliGate, ClsPauliRotationGate, ClsReversibleBooleanGate, ClsStateReflectionGate, ClsTwoQubitGate, QuantumGate_Adaptive, QuantumGate_CP, QuantumGate_CPTP, QuantumGate_Probabilistic, QuantumGate_SingleParameter, QuantumGateDiagonalMatrix, QuantumGateMatrix, QuantumGateSparseMatrix

Public Functions

inline virtual ~QuantumGateBase()

デストラクタ

inline std::vector<UINT> get_target_index_list() const

ターゲット量子ビットの添え字のリストを取得する

戻り値

量子ビットの添え字のリスト

inline std::vector<UINT> get_control_index_list() const

コントロール量子ビットの添え字のリストを取得する

戻り値

量子ビットの添え字のリスト

inline std::vector<UINT> get_control_value_list() const
inline std::vector<std::pair<UINT, UINT>> get_control_index_value_list() const
virtual void update_quantum_state(QuantumStateBase *state) = 0

量子状態を更新する

パラメータ

state -- 更新する量子状態

virtual QuantumGateBase *copy() const = 0

自身のディープコピーを生成する

戻り値

自身のディープコピー

virtual void set_matrix(ComplexMatrix &matrix) const = 0

自身のゲート行列をセットする

パラメータ

matrix -- 行列をセットする変数の参照

bool is_commute(const QuantumGateBase *gate) const

与えれたゲートgateと自身が可換かを判定する

非可換であると判定されても、実際には可換であることもある。 可換と判定された場合は必ず可換である。

パラメータ

gate -- 可換か比較するゲート

戻り値

true 可換である

戻り値

false 非可換である

bool is_Pauli() const

ゲートがパウリゲートかどうかを判定する

戻り値

true パウリゲートである

戻り値

false パウリゲートではない

bool is_Clifford() const

ゲートがクリフォードゲートかどうかを判定する

戻り値

true クリフォードゲートである

戻り値

false クリフォードゲートではない

bool is_Gaussian() const

ゲートがFermionic Gaussianかどうかを判定する

戻り値

true Fermionic Gaussianである

戻り値

false Fermionic Gaussianではない

bool is_parametric() const

ゲートがparametricかどうかを判定する

戻り値

true parametricである

戻り値

false parametricではない

bool is_diagonal() const

ゲート行列が対角行列かどうかを判定する

戻り値

true 対角行列である

戻り値

false 対角行列ではない

UINT get_property_value() const

ゲートのプロパティ値を取得する

ゲートのプロパティ値はゲートがパウリかどうかなどのゲート全体の性質の情報を持つ

戻り値

プロパティ値

bool commute_Pauli_at(UINT qubit_index, UINT pauli_type) const

ゲートがある添え字の量子ビットにおいて、与えられたパウリ演算子と可換かどうかを判定する。

パラメータ
  • qubit_index -- 量子ビットの添え字

  • pauli_type -- 比較するパウリ演算子。(I,X,Y,Z)が(0,1,2,3)に対応する。

戻り値

true 可換である

戻り値

false 可換ではない

virtual std::string get_name() const

量子ゲートの名前を出力する。

戻り値

ゲート名

virtual std::string to_string() const

量子ゲートのデバッグ情報の文字列を生成する

戻り値

生成した文字列

inline virtual bool is_noise()
inline virtual void set_seed(int)
inline void set_target_index_list(const std::vector<UINT> &target_index_list)
inline void set_control_index_list(const std::vector<UINT> &control_index_list)
virtual QuantumGateBase *get_inverse(void) const

Public Members

std::vector<TargetQubitInfo> &target_qubit_list

ターゲット量子ビットのリスト

std::vector<ControlQubitInfo> &control_qubit_list

コントロール量子ビットのリスト

Protected Functions

inline QuantumGateBase()
inline QuantumGateBase(const QuantumGateBase &obj)
QuantumGateBase &operator=(const QuantumGateBase &rhs) = delete

Protected Attributes

std::vector<TargetQubitInfo> _target_qubit_list
std::vector<ControlQubitInfo> _control_qubit_list
UINT _gate_property = 0

property of whole gate (e.g. Clifford or Pauli)

std::string _name = "Generic gate"

Friends

friend std::ostream &operator<<(std::ostream &os, const QuantumGateBase&)

量子回路のデバッグ情報を出力する。

戻り値

受け取ったストリーム

friend std::ostream &operator<<(std::ostream &os, const QuantumGateBase *gate)

量子回路のデバッグ情報を出力する。

戻り値

受け取ったストリーム

Class QuantumGateDiagonalMatrix
Inheritance Relationships
Base Type
Class Documentation
class QuantumGateDiagonalMatrix : public QuantumGateBase

行列要素で自身が作用する内容を保持するクラス 対角行列を持つ。

Public Functions

QuantumGateDiagonalMatrix(const std::vector<UINT> &target_qubit_index_list, const ComplexVector &matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateDiagonalMatrix(const std::vector<UINT> &target_qubit_index_list, ComplexVector *matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateDiagonalMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, const ComplexVector &matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

QuantumGateDiagonalMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, ComplexVector *matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

inline virtual ~QuantumGateDiagonalMatrix()

デストラクタ

virtual void add_control_qubit(UINT qubit_index, UINT control_value)

コントロールの量子ビットを追加する

qubit_indexはゲートのターゲットやコントロールの値に含まれてはいけない。

パラメータ
  • qubit_index -- [in] コントロールの量子ビットの添え字

  • control_value -- [in] 基底のqubit_indexcontrol_valueである場合にのみゲートが作用する。

inline virtual void multiply_scalar(CPPCTYPE value)

ゲート行列にスカラー値をかける

パラメータ

value -- [in] かける値

inline virtual void set_gate_property(UINT gate_property_)

ゲートのプロパティを設定する

パラメータ

gate_property_ -- [in] ゲートのプロパティ値

virtual void update_quantum_state(QuantumStateBase *state) override

量子状態に作用する

パラメータ

state -- [inout] 更新する量子状態

inline virtual QuantumGateDiagonalMatrix *copy() const override

自身のコピーを作成する

戻り値

コピーされたゲートのインスタンス

inline virtual QuantumGateDiagonalMatrix *get_inverse(void) const override
inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身の行列要素をセットする

パラメータ

matrix -- [out] 行列要素をセットする行列の参照

virtual std::string to_string() const override

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

Friends

friend std::ostream &operator<<(std::ostream &os, const QuantumGateDiagonalMatrix &gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

friend std::ostream &operator<<(std::ostream &os, QuantumGateDiagonalMatrix *gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

Class QuantumGateMatrix
Inheritance Relationships
Base Type
Class Documentation
class QuantumGateMatrix : public QuantumGateBase

行列要素で自身が作用する内容を保持するクラス

Public Functions

QuantumGateMatrix(const std::vector<UINT> &target_qubit_index_list, const ComplexMatrix &matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateMatrix(const std::vector<UINT> &target_qubit_index_list, ComplexMatrix *matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, const ComplexMatrix &matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

QuantumGateMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, ComplexMatrix *matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

inline virtual ~QuantumGateMatrix()

デストラクタ

virtual void add_control_qubit(UINT qubit_index, UINT control_value)

コントロールの量子ビットを追加する

qubit_indexはゲートのターゲットやコントロールの値に含まれてはいけない。

パラメータ
  • qubit_index -- [in] コントロールの量子ビットの添え字

  • control_value -- [in] 基底のqubit_indexcontrol_valueである場合にのみゲートが作用する。

inline virtual void multiply_scalar(CPPCTYPE value)

ゲート行列にスカラー値をかける

パラメータ

value -- [in] かける値

inline virtual void set_gate_property(UINT gate_property_)

ゲートのプロパティを設定する

パラメータ

gate_property_ -- [in] ゲートのプロパティ値

virtual void update_quantum_state(QuantumStateBase *state) override

量子状態に作用する

パラメータ

state -- [inout] 更新する量子状態

inline virtual QuantumGateMatrix *copy() const override

自身のコピーを作成する

戻り値

コピーされたゲートのインスタンス

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身の行列要素をセットする

パラメータ

matrix -- [out] 行列要素をセットする行列の参照

virtual std::string to_string() const override

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

virtual QuantumGateMatrix *get_inverse(void) const

Friends

friend std::ostream &operator<<(std::ostream &os, const QuantumGateMatrix &gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

friend std::ostream &operator<<(std::ostream &os, QuantumGateMatrix *gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

Class QuantumGateSparseMatrix
Inheritance Relationships
Base Type
Class Documentation
class QuantumGateSparseMatrix : public QuantumGateBase

行列要素で自身が作用する内容を保持するクラス 疎行列を持つ。

Public Functions

QuantumGateSparseMatrix(const std::vector<UINT> &target_qubit_index_list, const SparseComplexMatrix &matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateSparseMatrix(const std::vector<UINT> &target_qubit_index_list, SparseComplexMatrix *matrix_element, const std::vector<UINT> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの添え字のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットのリスト control_valueはすべて1になる。

QuantumGateSparseMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, const SparseComplexMatrix &matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はコピーされるため、matrixは再利用できるが低速である

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

QuantumGateSparseMatrix(const std::vector<TargetQubitInfo> &target_qubit_index_list, SparseComplexMatrix *matrix_element, const std::vector<ControlQubitInfo> &control_qubit_index_list = {})

コンストラクタ

行列要素はswapされるため、matrixは再利用できないが高速である。

パラメータ
  • target_qubit_index_list -- ターゲットとなる量子ビットの情報のリスト

  • matrix_element -- 行列要素

  • control_qubit_index_list -- コントロールとなる量子ビットの情報のリスト

inline virtual ~QuantumGateSparseMatrix()

デストラクタ

virtual void add_control_qubit(UINT qubit_index, UINT control_value)

コントロールの量子ビットを追加する

qubit_indexはゲートのターゲットやコントロールの値に含まれてはいけない。

パラメータ
  • qubit_index -- [in] コントロールの量子ビットの添え字

  • control_value -- [in] 基底のqubit_indexcontrol_valueである場合にのみゲートが作用する。

inline virtual void multiply_scalar(CPPCTYPE value)

ゲート行列にスカラー値をかける

パラメータ

value -- [in] かける値

inline virtual void set_gate_property(UINT gate_property_)

ゲートのプロパティを設定する

パラメータ

gate_property_ -- [in] ゲートのプロパティ値

virtual void update_quantum_state(QuantumStateBase *state) override

量子状態に作用する

パラメータ

state -- [inout] 更新する量子状態

inline virtual QuantumGateSparseMatrix *copy() const override

自身のコピーを作成する

戻り値

コピーされたゲートのインスタンス

inline virtual void set_matrix(ComplexMatrix &matrix) const override

自身の行列要素をセットする

パラメータ

matrix -- [out] 行列要素をセットする行列の参照

virtual std::string to_string() const override

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

Friends

friend std::ostream &operator<<(std::ostream &os, const QuantumGateSparseMatrix &gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

friend std::ostream &operator<<(std::ostream &os, QuantumGateSparseMatrix *gate)

ゲートの情報を文字列で出力する

パラメータ
  • os -- 出力するストリーム

  • gate -- 情報の出力を行うゲート

戻り値

受け取ったストリーム

Class QuantumStateBase
Inheritance Relationships
Derived Types
Class Documentation
class QuantumStateBase

量子状態の基底クラス

Subclassed by DensityMatrixCpu, QuantumStateCpu

Public Functions

inline QuantumStateBase(UINT qubit_count_, bool is_state_vector)

コンストラクタ

パラメータ

qubit_count_ -- 量子ビット数

inline QuantumStateBase(UINT qubit_count_, bool is_state_vector, UINT device_number_)
inline virtual ~QuantumStateBase()

デストラクタ

inline virtual bool is_state_vector() const

量子状態が状態ベクトルか密度行列かを判定する

virtual void set_zero_state() = 0

量子状態を計算基底の0状態に初期化する

virtual void set_zero_norm_state() = 0

ノルム0の状態 (要素がすべて0のベクトル) にする

virtual void set_computational_basis(ITYPE comp_basis) = 0

量子状態をcomp_basisの基底状態に初期化する

パラメータ

comp_basis -- 初期化する基底を表す整数

virtual void set_Haar_random_state() = 0

量子状態をHaar randomにサンプリングされた量子状態に初期化する

virtual void set_Haar_random_state(UINT seed) = 0

量子状態をシードを用いてHaar randomにサンプリングされた量子状態に初期化する

virtual double get_zero_probability(UINT target_qubit_index) const = 0

target_qubit_indexの添え字の量子ビットを測定した時、0が観測される確率を計算する。

量子状態は変更しない。

パラメータ

target_qubit_index --

戻り値

double

virtual double get_marginal_probability(std::vector<UINT> measured_values) const = 0

複数の量子ビットを測定した時の周辺確率を計算する

パラメータ

measured_values -- 量子ビット数と同じ長さの0,1,2の配列。0,1はその値が観測され、2は測定をしないことを表す。

戻り値

計算された周辺確率

virtual double get_entropy() const = 0

計算基底で測定した時得られる確率分布のエントロピーを計算する。

戻り値

エントロピー

virtual double get_squared_norm() const = 0

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

virtual double get_squared_norm_single_thread() const = 0

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

virtual void normalize(double squared_norm) = 0

量子状態を正規化する

パラメータ

norm -- 自身のノルム

virtual void normalize_single_thread(double squared_norm) = 0

量子状態を正規化する

パラメータ

norm -- 自身のノルム

virtual QuantumStateBase *allocate_buffer() const = 0

バッファとして同じサイズの量子状態を作成する。

戻り値

生成された量子状態

virtual QuantumStateBase *copy() const = 0

自身の状態のディープコピーを生成する

戻り値

自身のディープコピー

virtual void load(const QuantumStateBase *state) = 0

stateの量子状態を自身へコピーする。

virtual void load(const std::vector<CPPCTYPE> &state) = 0

stateの量子状態を自身へコピーする。

virtual void load(const CPPCTYPE *state) = 0

stateの量子状態を自身へコピーする。

virtual const std::string get_device_name() const = 0

量子状態が配置されているメモリを保持するデバイス名を取得する。

virtual void *data() const = 0
virtual CPPCTYPE *data_cpp() const = 0

量子状態をC++のstd::complex<double>の配列として取得する

戻り値

複素ベクトルのポインタ

virtual CTYPE *data_c() const = 0

量子状態をcsimのComplex型の配列として取得する

戻り値

複素ベクトルのポインタ

virtual CPPCTYPE *duplicate_data_cpp() const = 0

量子状態をC++のstd::complex<double>の配列として新たに確保する

戻り値

複素ベクトルのポインタ

virtual CTYPE *duplicate_data_c() const = 0

量子状態をcsimのComplex型の配列として新たに確保する。

戻り値

複素ベクトルのポインタ

virtual void add_state(const QuantumStateBase *state) = 0

量子状態を足しこむ

virtual void add_state_with_coef(CPPCTYPE coef, const QuantumStateBase *state) = 0

量子状態を係数付きで足しこむ

virtual void add_state_with_coef_single_thread(CPPCTYPE coef, const QuantumStateBase *state) = 0

量子状態を係数付きで足しこむ

virtual void multiply_coef(CPPCTYPE coef) = 0

複素数をかける

virtual void multiply_elementwise_function(const std::function<CPPCTYPE(ITYPE)> &func) = 0
inline virtual UINT get_classical_value(UINT index)

指定した添え字の古典レジスタの値を取得する。

パラメータ

index -- セットするレジスタの添え字

戻り値

古典レジスタの値

inline virtual void set_classical_value(UINT index, UINT val)

指定した添え字の古典レジスタに値をセットする

パラメータ
  • index -- セットするレジスタの添え字

  • val -- セットする値

inline virtual const std::vector<UINT> get_classical_register() const

古典レジスタのベクトルを返す

戻り値

古典レジスタ

virtual std::vector<ITYPE> sampling(UINT sampling_count) = 0

量子状態を測定した際の計算基底のサンプリングを行う

パラメータ
  • sampling_count -- [in] サンプリングを行う回数

  • random_seed -- [in] サンプリングで乱数を振るシード値

戻り値

サンプルされた値のリスト

virtual std::vector<ITYPE> sampling(UINT sampling_count, UINT random_seed) = 0
inline virtual std::string to_string() const

量子回路のデバッグ情報の文字列を生成する

戻り値

生成した文字列

inline virtual void *get_cuda_stream() const

Public Members

const UINT &qubit_count

量子ビット数

const ITYPE &dim

量子状態の次元

const std::vector<UINT> &classical_register

古典ビットのレジスタ

const UINT &device_number

Protected Attributes

ITYPE _dim
UINT _qubit_count
bool _is_state_vector
std::vector<UINT> _classical_register
UINT _device_number
void *_cuda_stream

Friends

inline friend std::ostream &operator<<(std::ostream &os, const QuantumStateBase &state)

量子状態のデバッグ情報を出力する。

戻り値

受け取ったストリーム

inline friend std::ostream &operator<<(std::ostream &os, const QuantumStateBase *state)

量子状態のデバッグ情報を出力する。

戻り値

受け取ったストリーム

Class QuantumStateCpu
Inheritance Relationships
Base Type
Class Documentation
class QuantumStateCpu : public QuantumStateBase

Public Functions

inline explicit QuantumStateCpu(UINT qubit_count_)

コンストラクタ

パラメータ

qubit_count_ -- 量子ビット数

inline virtual ~QuantumStateCpu()

デストラクタ

inline virtual void set_zero_state() override

量子状態を計算基底の0状態に初期化する

inline virtual void set_zero_norm_state() override

量子状態をノルム0の状態にする

inline virtual void set_computational_basis(ITYPE comp_basis) override

量子状態をcomp_basisの基底状態に初期化する

パラメータ

comp_basis -- 初期化する基底を表す整数

inline virtual void set_Haar_random_state() override

量子状態をHaar randomにサンプリングされた量子状態に初期化する

inline virtual void set_Haar_random_state(UINT seed) override

量子状態をシードを用いてHaar randomにサンプリングされた量子状態に初期化する

inline virtual double get_zero_probability(UINT target_qubit_index) const override

target_qubit_indexの添え字の量子ビットを測定した時、0が観測される確率を計算する。

量子状態は変更しない。

パラメータ

target_qubit_index --

戻り値

double

inline virtual double get_marginal_probability(std::vector<UINT> measured_values) const override

複数の量子ビットを測定した時の周辺確率を計算する

パラメータ

measured_values -- 量子ビット数と同じ長さの0,1,2の配列。0,1はその値が観測され、2は測定をしないことを表す。

戻り値

計算された周辺確率

inline virtual double get_entropy() const override

計算基底で測定した時得られる確率分布のエントロピーを計算する。

戻り値

エントロピー

inline virtual double get_squared_norm() const override

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

inline virtual double get_squared_norm_single_thread() const override

量子状態のノルムを計算する

量子状態のノルムは非ユニタリなゲートを作用した時に小さくなる。

戻り値

ノルム

inline virtual void normalize(double squared_norm) override

量子状態を正規化する

パラメータ

norm -- 自身のノルム

inline virtual void normalize_single_thread(double squared_norm) override

量子状態を正規化する

パラメータ

norm -- 自身のノルム

inline virtual QuantumStateCpu *allocate_buffer() const override

バッファとして同じサイズの量子状態を作成する。

戻り値

生成された量子状態

inline virtual QuantumStateCpu *copy() const override

自身の状態のディープコピーを生成する

戻り値

自身のディープコピー

inline virtual void load(const QuantumStateBase *_state) override

stateの量子状態を自身へコピーする。

inline virtual void load(const std::vector<CPPCTYPE> &_state) override

stateの量子状態を自身へコピーする。

inline virtual void load(const CPPCTYPE *_state) override

stateの量子状態を自身へコピーする。

inline virtual const std::string get_device_name() const override

量子状態が配置されているメモリを保持するデバイス名を取得する。

inline virtual void *data() const override

量子状態のポインタをvoid*型として返す

inline virtual CPPCTYPE *data_cpp() const override

量子状態をC++のstd::complex<double>の配列として取得する

戻り値

複素ベクトルのポインタ

inline virtual CTYPE *data_c() const override

量子状態をcsimのComplex型の配列として取得する

戻り値

複素ベクトルのポインタ

inline virtual CTYPE *duplicate_data_c() const override

量子状態をcsimのComplex型の配列として新たに確保する。

戻り値

複素ベクトルのポインタ

inline virtual CPPCTYPE *duplicate_data_cpp() const override

量子状態をC++のstd::complex<double>の配列として新たに確保する

戻り値

複素ベクトルのポインタ

inline virtual void add_state(const QuantumStateBase *state) override

量子状態を足しこむ

inline virtual void add_state_with_coef(CPPCTYPE coef, const QuantumStateBase *state) override

量子状態を足しこむ

inline virtual void add_state_with_coef_single_thread(CPPCTYPE coef, const QuantumStateBase *state) override

量子状態を足しこむ

inline virtual void multiply_coef(CPPCTYPE coef) override

複素数をかける

inline virtual void multiply_elementwise_function(const std::function<CPPCTYPE(ITYPE)> &func) override
inline virtual std::vector<ITYPE> sampling(UINT sampling_count) override

量子状態を測定した際の計算基底のサンプリングを行う

パラメータ

sampling_count -- [in] サンプリングを行う回数

戻り値

サンプルされた値のリスト

inline virtual std::vector<ITYPE> sampling(UINT sampling_count, UINT random_seed) override
Class QuantumStateProcessorException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class QuantumStateProcessorException : public logic_error

QuantumStateCpuとQuantumStateGpuを同じ演算中で用いている例外

Public Functions

inline QuantumStateProcessorException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class QubitIndexOutOfRangeException
Inheritance Relationships
Base Type
  • public out_of_range

Class Documentation
class QubitIndexOutOfRangeException : public out_of_range

対象の量子ビットのインデックスが範囲外という例外

Public Functions

inline QubitIndexOutOfRangeException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class QubitInfo
Inheritance Relationships
Derived Types
Class Documentation
class QubitInfo

量子ゲートが対象とする量子ビットの情報を保持するクラス

Subclassed by ControlQubitInfo, TargetQubitInfo

Public Functions

inline UINT index() const

量子ビットの添え字を返す

戻り値

この量子ビットの添え字

inline void set_index(int idx)
inline explicit QubitInfo(UINT index_)

コンストラクタ

パラメータ

index_ -- 量子ビットの添え字

Protected Attributes

UINT _index

量子ビットの添え字

Class Random
Class Documentation
class Random

乱数を管理するクラス

Public Functions

inline Random()

コンストラクタ

inline void set_seed(uint64_t seed)

シードを設定する

パラメータ

seed -- シード値

inline double uniform()

\([0,1)\)の一様分布から乱数を生成する

戻り値

生成された乱数

inline double normal()

期待値0、分散1の正規分から乱数を生成する

戻り値

double 生成された乱数

inline unsigned long long int64()

64bit整数の乱数を生成する

戻り値

生成された乱数

inline unsigned long int32()

32bit整数の乱数を生成する

戻り値

生成された乱数

Class RegressionProblem
Class Documentation
class RegressionProblem

Public Functions

inline RegressionProblem(std::vector<std::vector<double>> input_data, std::vector<std::vector<double>> output_data)
inline virtual UINT get_input_dim() const
inline virtual std::vector<double> get_input_data(UINT sample_id) const
inline virtual UINT get_output_dim() const
inline virtual std::vector<double> get_output_data(UINT sample_id)
inline virtual double compute_loss(UINT sample_id, std::vector<double> prediction)

Protected Attributes

std::function<double(std::vector<double>, std::vector<double>)> _loss_function = loss_function::L2_distance<double>
std::vector<std::vector<double>> _input_data
std::vector<std::vector<double>> _output_data
Class SinglePauliOperator
Class Documentation
class SinglePauliOperator

Public Functions

inline SinglePauliOperator(UINT index_, UINT pauli_id_)

コンストラクタ

添字とパウリ演算子からインスタンスを生成する。

パラメータ
  • index_ -- [in] 作用するqubitの添字

  • pauli_id_ -- [in] パウリ演算子を表す整数。(I,X,Y,Z)が(0,1,2,3)に対応する。

戻り値

新しいインスタンス

inline UINT index() const

自身が作用する添字を返す

戻り値

自身が作用する添字

inline UINT pauli_id() const

自身を表すパウリ演算子を返す

戻り値

自身のもつパウリ演算子を表す整数。(I,X,Y,Z)が(0,1,2,3)に対応する。

Protected Attributes

UINT _index
UINT _pauli_id
Class TargetQubitInfo
Inheritance Relationships
Base Type
Class Documentation
class TargetQubitInfo : public QubitInfo

ターゲット量子ビットの情報を保持するクラス

Public Functions

inline TargetQubitInfo(void)

コンストラクタ 初期化に必要、 万が一使われたとき落ちるように、invalid_qubitにしてある

inline explicit TargetQubitInfo(UINT index_)

コンストラクタ

パラメータ

index_ -- この量子ビットの添え字

inline TargetQubitInfo(UINT index_, UINT commutation_property_)

コンストラクタ

パラメータ
  • index_ -- この量子ビットの添え字

  • commutation_property_ -- この量子ビットのパウリとの交換関係

inline bool is_commute_X() const

Xパウリと可換かを調べる

戻り値

true 可換である

戻り値

false 非可換である

inline bool is_commute_Y() const

Yパウリと可換かを調べる

戻り値

true 可換である

戻り値

false 非可換である

inline bool is_commute_Z() const

Zパウリと可換かを調べる

戻り値

true 可換である

戻り値

false 非可換である

virtual bool is_commute_with(const TargetQubitInfo &info) const

ターゲット量子ビットの情報infoと可換かどうかを調べる

パラメータ

info -- 可換かどうかを調べる量子ビットの情報

戻り値

true 可換である

戻り値

false 可換ではない

virtual bool is_commute_with(const ControlQubitInfo &info) const

コントロール量子ビットの情報infoと可換かどうかを調べる

パラメータ

info -- 可換かどうかを調べる量子ビットの情報

戻り値

true 可換である

戻り値

false 可換ではない

inline virtual UINT get_merged_property(UINT property) const

与えられたpropertyの値のパウリとの交換関係と自身をマージした時、得られるパウリ演算子との可換関係のプロパティ値を返す。

パラメータ

property -- マージするプロパティ値

戻り値

マージされたプロパティ値

inline virtual UINT get_merged_property(const TargetQubitInfo &target) const

与えられたtargetの量子ビットの情報のパウリとの交換関係と自身をマージした時、得られるパウリ演算子との可換関係のプロパティ値を返す。

パラメータ

target -- マージする量子ビット情報

戻り値

マージされたプロパティ値

inline virtual UINT get_merged_property(const ControlQubitInfo &control) const

与えられたcontrolの量子ビットの情報のパウリとの交換関係と自身をマージした時、得られるパウリ演算子との可換関係のプロパティ値を返す。

パラメータ

control -- マージする量子ビット情報

戻り値

マージされたプロパティ値

Class Timer
Class Documentation
class Timer

時間計測用のユーティリティクラス

一時停止を行うことで、必要な箇所だけの積算時間を計測する。

Public Functions

inline Timer()

コンストラクタ

inline void reset()

時間計測をリセットする

蓄積された時間を0にし、測定の起点となる時間を0にする。

inline double elapsed()

現在の経過時間を取得する

経過時間を取得する。単位は秒で返される。一時停止を用いて時間を積算している場合は、積算している時間も併せた値が帰る。

戻り値

経過時間 単位は秒

inline void temporal_stop()

タイマーを一時停止する

タイマーを一時停止し、現在までの経過時間を蓄積中の時間に加える。

inline void temporal_resume()

タイマーを再開する

タイマーを再開し、新たな時間計測のための起点を設定する。

Class UndefinedUpdateFuncException
Inheritance Relationships
Base Type
  • public logic_error

Class Documentation
class UndefinedUpdateFuncException : public logic_error

ParametricGateのupdate_funcが定義されていないという例外

Public Functions

inline UndefinedUpdateFuncException(const std::string &message)

コンストラクタ

パラメータ

message -- エラーメッセージ

Class UnionFind
Class Documentation
class UnionFind

Public Functions

inline explicit UnionFind(int N)
inline int root(int A)
inline bool same(int A, int B)
inline int size(int A)
inline bool connect(int A, int B)
Functions
Function bidiagonalize_real_matrix_pair_with_symmetric_products
Function Documentation
std::tuple<Eigen::Matrix4cd, Eigen::Matrix4cd> bidiagonalize_real_matrix_pair_with_symmetric_products(Eigen::Matrix4d matA, Eigen::Matrix4d matB)
Function bidiagonalize_unitary_with_special_orthogonals
Function Documentation
std::tuple<Eigen::Matrix4cd, Eigen::Matrix4cd, Eigen::Matrix4cd> bidiagonalize_unitary_with_special_orthogonals(Eigen::Matrix4cd mat)
Function check_is_unique_index_list
Function Documentation
bool check_is_unique_index_list(const std::vector<UINT> &index_list)

配列の中に重複する添え字があるかをチェックする。

パラメータ

index_list -- [in] チェックする配列

戻り値

重複がある場合にtrue、ない場合にfalse

Function check_Pauli_operator
Function Documentation
bool check_Pauli_operator(const GeneralQuantumOperator *quantum_operator, const PauliOperator *pauli_operator)
Function chfmt
Function Documentation
void chfmt(std::string &ops)

引数にとった文字列を、PauliOperatorで渡すことができる形に整形します。この関数は第一引数に与えた文字列に破壊的な変更を加えます。

パラメータ

ops -- [in] 演算子と添字が隣り合った文字列。(example: "X12 Y13 Z5" に対して, "X 12 Y 13 Z 5"のように変更を加えます。)

Function convert_observable_to_matrix
Function Documentation
ComplexMatrix convert_observable_to_matrix(const HermitianQuantumOperator &observable)

observable を対応する行列に変換する

パラメータ

observable -- [in] 行列に変換する observable

戻り値

observable に対応する行列

Function count_population_cpp
Function Documentation
static inline UINT count_population_cpp(ITYPE x)

1になっているビットの数を数える

パラメータ

x -- [in] 1になっているビットの数を数える整数

戻り値

1になっているビットの数

Function CSD
Function Documentation
std::vector<QuantumGateBase*> CSD(QuantumGateBase *target_gate)
Function CSD_internal
Function Documentation
void CSD_internal(ComplexMatrix mat, std::vector<UINT> now_control_qubits, std::vector<UINT> all_control_qubits, int ban, std::vector<QuantumGateBase*> &CSD_gate_list)
Function gate::Adaptive(QuantumGateBase *, std::function<bool(const std::vector<UINT>&)>)
Function Documentation
QuantumGateBase *gate::Adaptive(QuantumGateBase *gate, std::function<bool(const std::vector<UINT>&)> func)

適応操作のゲートを作成する

functrueを返すときのみgateを作用する量子ゲートを作成する。

パラメータ
  • gate -- ゲート

  • func -- std::vector<unsigned int>="">&を受け取り、boolを返す関数

戻り値

Adaptive gate

Function gate::Adaptive(QuantumGateBase *, std::function<bool(const std::vector<UINT>&, UINT)>, UINT)
Function Documentation
QuantumGateBase *gate::Adaptive(QuantumGateBase *gate, std::function<bool(const std::vector<UINT>&, UINT)> func, UINT id)

適応操作のゲートを作成する

functrueを返すときのみgateを作用する量子ゲートを作成する。

パラメータ
  • gate -- ゲート

  • func -- std::vector<unsigned int>="">&,UINTを受け取り、boolを返す関数

  • id -- funcに引数として与えるUINTの値

戻り値

Adaptive gate

Function gate::add(const QuantumGateBase *, const QuantumGateBase *)
Function Documentation
QuantumGateMatrix *gate::add(const QuantumGateBase *gate1, const QuantumGateBase *gate2)

二つのゲートのゲート行列を足して新たなゲートを作成する。

TODO: control-qubitがあるときの挙動が未定義

パラメータ
  • gate1 -- 先に状態に作用するゲート

  • gate2 -- 後に状態に作用するゲート

戻り値

二つのゲートを足したゲート

Function gate::add(std::vector<QuantumGateBase *>)
Function Documentation
QuantumGateMatrix *gate::add(std::vector<QuantumGateBase*> gate_list)

複数のゲートを足して新たなゲートを作成する。

TODO: control-qubitがあるときの挙動が未定義

パラメータ

gate_list -- 足すゲート列

戻り値

足したゲート

Function gate::AmplitudeDampingNoise
Function Documentation
QuantumGate_CPTP *gate::AmplitudeDampingNoise(UINT target_index, double prob)

Amplitude damping noiseを発生させるゲート

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::BitFlipNoise
Function Documentation
QuantumGate_Probabilistic *gate::BitFlipNoise(UINT target_index, double prob)

bit-flipノイズを発生させるゲート

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::CNOT
Function Documentation
ClsOneControlOneTargetGate *gate::CNOT(UINT control_qubit_index, UINT target_qubit_index)

CNOTゲートを作成する

パラメータ
  • control_qubit_index -- [in] コントロールとなる量子ビットの添え字

  • target_qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::CP
Function Documentation
QuantumGateBase *gate::CP(std::vector<QuantumGateBase*> gate_list, bool state_normalize, bool probability_normalize, bool assign_zero_if_not_matched)

CP-mapを作成する

\(p_i = {\rm Tr}[K_i \rho K_i^{\dagger}]\)を計算し、 \(\{p_i\}\)の確率分布でクラウス演算子を採用する。

パラメータ
  • gate_list -- クラウス演算を行うゲートのリスト

  • state_normlize -- trueだったら状態を規格化する

  • probability_normalize -- trueだったら確率分布を規格化する

  • assign_zero_if_not_matched -- どのKraus演算子にもマッチしなかったら0を代入する

戻り値

CP-map

Function gate::CPTP
Function Documentation
QuantumGateBase *gate::CPTP(std::vector<QuantumGateBase*> gate_list)

CPTP-mapを作成する

\(p_i = {\rm Tr}[K_i \rho K_i^{\dagger}]\)を計算し、 \(\{p_i\}\)の確率分布でクラウス演算子を採用して、 \(\sqrt{p_i}^{-1}\)で正規化する。

パラメータ

gate_list -- クラウス演算を行うゲートのリスト

戻り値

CPTP-map

Function gate::create_parametric_quantum_gate_from_string
Function Documentation
QuantumGateBase *gate::create_parametric_quantum_gate_from_string(std::string gate_string)
Function gate::create_quantum_gate_from_string
Function Documentation
QuantumGateBase *gate::create_quantum_gate_from_string(std::string gate_string)

量子ゲートを文字列から生成する。

ゲートを生成するための文字列は以下の通り Identity : I <index> X : X <index> Y : Y <index> Z : Z <index> H : H <index> S : S <index> Sdag : Sdag <index> T : T <index> Tdag : Tdag <index> CNOT,CX : CNOT <control> <target>, or CX <control> <target> CZ : CZ <control> <target> SWAP : SWAP <target1> <target2> U1 : U1 <index> <angle1> U2 : U2 <index> <angle1> <angle2> U3 : U3 <index> <angle1> <angle2> <angle3> RX : RX <index> <angle1> RY : RY <index> <angle1> RZ : RZ <index> <angle1> DifRot X : RDX <index> DifRot Y : RDY <index> DifRot Z : RDZ <index> MultiRot : RM <paulistr> <index1> <index2> ... <theta> (for どれにも合致しない場合はNULLを返す example: "RM XYZ 2 3 1 0.123") DifMultiRot : RDM <paulistr> <index1> <index2> ... (for example: "RDM XYZ 2 3 1") general U : U <index_count> <index1> <index2> ... <element1_real> <element1_imag> <element2_real> ...

パラメータ

gate_string -- [in] ゲートを生成する文字列

戻り値

作成されたゲートのインスタンス

Function gate::CZ
Function Documentation
ClsOneControlOneTargetGate *gate::CZ(UINT control_qubit_index, UINT target_qubit_index)

CZゲートを作成する

パラメータ
  • control_qubit_index -- [in] コントロールとなる量子ビットの添え字

  • target_qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::DenseMatrix(UINT, ComplexMatrix)
Function Documentation
QuantumGateMatrix *gate::DenseMatrix(UINT target_qubit_index, ComplexMatrix matrix)

\(n\)-qubit 行列を用いて1-qubitゲートを生成する。

パラメータ
  • target_qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • matrix -- [in] 作用するゲートの \(2\times 2\)の複素行列

戻り値

作成されたゲートのインスタンス

Function gate::DenseMatrix(std::vector<UINT>, ComplexMatrix)
Function Documentation
QuantumGateMatrix *gate::DenseMatrix(std::vector<UINT> target_qubit_index_list, ComplexMatrix matrix)

\(n\)-qubit 行列を用いてn-qubitゲートを生成する。

target_qubit_index_listの要素数を \(m\)としたとき、matrix\(2^m \times 2^m \)の複素行列でなくてはいけない。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字

  • matrix -- [in] 作用するゲートの複素行列。

戻り値

作成されたゲートのインスタンス

Function gate::DephasingNoise
Function Documentation
QuantumGate_Probabilistic *gate::DephasingNoise(UINT target_index, double prob)

phase-flipノイズを発生させるゲート

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::DepolarizingNoise
Function Documentation
QuantumGate_Probabilistic *gate::DepolarizingNoise(UINT target_index, double prob)

Depolarizin noiseを発生させるゲート

X,Y,Zがそれぞれprob/3の確率で生じる。

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::DiagonalMatrix
Function Documentation
QuantumGateDiagonalMatrix *gate::DiagonalMatrix(std::vector<UINT> target_qubit_index_list, ComplexVector diagonal_element)

\(n\)-qubit 対角な行列を用いてn-qubitゲートを生成する。

target_qubit_index_listの要素数を \(m\)としたとき、matrix\(2^m \times 2^m \)の複素行列でなくてはいけない。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字

  • matrix -- [in] 作用するゲートの複素行列の対角成分。

戻り値

作成されたゲートのインスタンス

Function gate::get_adjoint_gate
Function Documentation
QuantumGateMatrix *gate::get_adjoint_gate(const QuantumGateBase *gate)
Function gate::get_conjugate_gate
Function Documentation
QuantumGateMatrix *gate::get_conjugate_gate(const QuantumGateBase *gate)
Function gate::get_extended_matrix
Function Documentation
void gate::get_extended_matrix(const QuantumGateBase *gate, const std::vector<TargetQubitInfo> &new_target_list, const std::vector<ControlQubitInfo> &new_control_list, ComplexMatrix &matrix)
Function gate::get_new_qubit_list
Function Documentation
void gate::get_new_qubit_list(const QuantumGateBase *gate_first, const QuantumGateBase *gate_second, std::vector<TargetQubitInfo> &new_target_list, std::vector<ControlQubitInfo> &new_control_list)
Function gate::get_transpose_gate
Function Documentation
QuantumGateMatrix *gate::get_transpose_gate(const QuantumGateBase *gate)
Function gate::H
Function Documentation
ClsOneQubitGate *gate::H(UINT qubit_index)

Hadamardゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::Identity
Function Documentation
ClsOneQubitGate *gate::Identity(UINT qubit_index)

Identityゲートを作成する。

作用しても状態は変わらないが、ノイズなどが付与された際の挙動が異なる。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::IndependentXZNoise
Function Documentation
QuantumGate_Probabilistic *gate::IndependentXZNoise(UINT target_index, double prob)

bit-flipとphase-flipを同じ確率でノイズを発生させるゲート

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::Instrument
Function Documentation
QuantumGateBase *gate::Instrument(std::vector<QuantumGateBase*> gate_list, UINT classical_register_address)

Instrumentを作成する

InstrumentではCPTP-mapを作用させ、かつ作用されたクラウス演算子の添え字をclassical_register_addressに書き込む。

パラメータ
  • gate_list -- クラウス演算を行うゲートのリスト

  • classical_register_address -- 添え字を書きこむclassical registerの添え字

戻り値

Instrument

Function gate::Measurement
Function Documentation
QuantumGate_Instrument *gate::Measurement(UINT target_index, UINT classical_register_address)

測定を行う

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • classical_register_address -- [in] 測定値を格納する古典レジスタの場所

戻り値

作成されたゲートのインスタンス

Function gate::merge(const QuantumGateBase *, const QuantumGateBase *)
Function Documentation
QuantumGateMatrix *gate::merge(const QuantumGateBase *gate_applied_first, const QuantumGateBase *gate_applied_later)

二つのゲートが連続して作用する新たなゲートを作成する。

パラメータ
  • gate_applied_first -- 先に状態に作用するゲート

  • gate_applied_later -- 後に状態に作用するゲート

戻り値

二つのゲートを合成したゲート

Function gate::merge(std::vector<QuantumGateBase *>)
Function Documentation
QuantumGateMatrix *gate::merge(std::vector<QuantumGateBase*> gate_list)

複数のゲートが連続して作用する新たなゲートを作成する。

パラメータ

gate_list -- 作用するゲート列。先頭要素から順番に状態に作用する。

戻り値

合成したゲート

Function gate::NoisyEvolution
Function Documentation
ClsNoisyEvolution *gate::NoisyEvolution(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time, double dt = 1e-6)

Noisy Evolution TODO: do this comment

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • classical_register_address -- [in] 測定値を格納する古典レジスタの場所

戻り値

作成されたゲートのインスタンス

Function gate::NoisyEvolution_auto
Function Documentation
ClsNoisyEvolution_auto *gate::NoisyEvolution_auto(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time)

Noisy Evolution TODO: do this comment

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • classical_register_address -- [in] 測定値を格納する古典レジスタの場所

戻り値

作成されたゲートのインスタンス

Function gate::NoisyEvolution_fast
Function Documentation
ClsNoisyEvolution_fast *gate::NoisyEvolution_fast(Observable *hamiltonian, std::vector<GeneralQuantumOperator*> c_ops, double time)

Noisy Evolution TODO: do this comment

パラメータ
  • target_index -- [in] ターゲットとなる量子ビットの添え字

  • classical_register_address -- [in] 測定値を格納する古典レジスタの場所

戻り値

作成されたゲートのインスタンス

Function gate::P0
Function Documentation
ClsOneQubitGate *gate::P0(UINT qubit_index)

qubit_indexを0へ射影するゲートを作成する

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::P1
Function Documentation
ClsOneQubitGate *gate::P1(UINT qubit_index)

qubit_indexを1へ射影するゲートを作成する

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::ParametricPauliRotation
Function Documentation
QuantumGate_SingleParameter *gate::ParametricPauliRotation(std::vector<UINT> target, std::vector<UINT> pauli_id, double initial_angle = 0.)
Function gate::ParametricRX
Function Documentation
QuantumGate_SingleParameter *gate::ParametricRX(UINT qubit_index, double initial_angle = 0.)
Function gate::ParametricRY
Function Documentation
QuantumGate_SingleParameter *gate::ParametricRY(UINT qubit_index, double initial_angle = 0.)
Function gate::ParametricRZ
Function Documentation
QuantumGate_SingleParameter *gate::ParametricRZ(UINT qubit_index, double initial_angle = 0.)
Function gate::Pauli
Function Documentation
ClsPauliGate *gate::Pauli(std::vector<UINT> target_qubit_index_list, std::vector<UINT> pauli_id_list)

\(n\)-qubit パウリ演算子のゲートを作成する

例えば \(Y_1 X_3\)であれば、target_qubit_index_list = {1,3}, pauli_id_list = {2,1};である。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字のリスト

  • pauli_id_list -- [in] その量子ビットに作用するパウリ演算子。 \({I,X,Y,Z}\)\({0,1,2,3}\)に対応する。

戻り値

作成されたゲートのインスタンス

Function gate::PauliRotation
Function Documentation
ClsPauliRotationGate *gate::PauliRotation(std::vector<UINT> target_qubit_index_list, std::vector<UINT> pauli_id_list, double angle)

\(n\)-qubit パウリ演算子の回転ゲートを作成する

例えば \(Y_1 X_3\)であれば、target_qubit_index_list = {1,3}, pauli_id_list = {2,1};である。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字のリスト

  • pauli_id_list -- [in] その量子ビットに作用するパウリ演算子。 \({I,X,Y,Z}\)\({0,1,2,3}\)に対応する。

  • angle -- [in] 回転角

戻り値

作成されたゲートのインスタンス

Function gate::Probabilistic
Function Documentation
QuantumGateBase *gate::Probabilistic(std::vector<double> distribution, std::vector<QuantumGateBase*> gate_list)

確率的に作用する量子ゲートを作成する。

確率分布の総和が1でない場合、残った確率が採用されたときには何も作用しない。

パラメータ
  • distribution -- 確率分布

  • gate_list -- 作用する量子ゲート

戻り値

確率的に作用するゲート

Function gate::ProbabilisticInstrument
Function Documentation
QuantumGateBase *gate::ProbabilisticInstrument(std::vector<double> distribution, std::vector<QuantumGateBase*> gate_list, UINT classical_register_address)

密度行列にも確率的に作用する量子ゲートを作成する。

確率分布の総和が1でない場合、残った確率が採用されたときには何も作用しない。

パラメータ
  • distribution -- 確率分布

  • gate_list -- 作用する量子ゲート

  • classical_register_address -- 作用したゲートの添え字を保存するアドレス

戻り値

確率的に作用するゲート

Function gate::RandomUnitary(std::vector<UINT>)
Function Documentation
QuantumGateMatrix *gate::RandomUnitary(std::vector<UINT> target_qubit_index_list)

\(n\)-qubit のランダムユニタリゲートを作成する。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字

  • seed -- [in] 乱数のシード値

戻り値

作成されたゲートのインスタンス

Function gate::RandomUnitary(std::vector<UINT>, UINT)
Function Documentation
QuantumGateMatrix *gate::RandomUnitary(std::vector<UINT> target_qubit_index_list, UINT seed)
Function gate::ReversibleBoolean
Function Documentation
ClsReversibleBooleanGate *gate::ReversibleBoolean(std::vector<UINT> target_qubit_index_list, std::function<ITYPE(ITYPE, ITYPE)>)

\(n\)-qubit の可逆古典回路を作用する。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字

  • function_ptr -- [in] 可逆古典回路の動作をする関数

戻り値

作成されたゲートのインスタンス

Function gate::RotInvX
Function Documentation
ClsOneQubitRotationGate *gate::RotInvX(UINT qubit_index, double angle)
Function gate::RotInvY
Function Documentation
ClsOneQubitRotationGate *gate::RotInvY(UINT qubit_index, double angle)
Function gate::RotInvZ
Function Documentation
ClsOneQubitRotationGate *gate::RotInvZ(UINT qubit_index, double angle)
Function gate::RotX
Function Documentation
ClsOneQubitRotationGate *gate::RotX(UINT qubit_index, double angle)
Function gate::RotY
Function Documentation
ClsOneQubitRotationGate *gate::RotY(UINT qubit_index, double angle)
Function gate::RotZ
Function Documentation
ClsOneQubitRotationGate *gate::RotZ(UINT qubit_index, double angle)
Function gate::RX
Function Documentation
ClsOneQubitRotationGate *gate::RX(UINT qubit_index, double angle)

\(X\)回転ゲートを作成する。

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • angle -- [in] 回転角

戻り値

作成されたゲートのインスタンス

Function gate::RY
Function Documentation
ClsOneQubitRotationGate *gate::RY(UINT qubit_index, double angle)

\(Y\)回転ゲートを作成する。

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • angle -- [in] 回転角

戻り値

作成されたゲートのインスタンス

Function gate::RZ
Function Documentation
ClsOneQubitRotationGate *gate::RZ(UINT qubit_index, double angle)

\(Z\)回転ゲートを作成する。

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • angle -- [in] 回転角

戻り値

作成されたゲートのインスタンス

Function gate::S
Function Documentation
ClsOneQubitGate *gate::S(UINT qubit_index)

\(S\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::Sdag
Function Documentation
ClsOneQubitGate *gate::Sdag(UINT qubit_index)

\(S^{\dagger}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::SparseMatrix
Function Documentation
QuantumGateSparseMatrix *gate::SparseMatrix(std::vector<UINT> target_qubit_index_list, SparseComplexMatrix matrix)

\(n\)-qubit スパースな行列を用いてn-qubitゲートを生成する。

target_qubit_index_listの要素数を \(m\)としたとき、matrix\(2^m \times 2^m \)の複素行列でなくてはいけない。

パラメータ
  • target_qubit_index_list -- [in] ターゲットとなる量子ビットの添え字

  • matrix -- [in] 作用するゲートの複素行列。

戻り値

作成されたゲートのインスタンス

Function gate::sqrtX
Function Documentation
ClsOneQubitGate *gate::sqrtX(UINT qubit_index)

\(\sqrt{X}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::sqrtXdag
Function Documentation
ClsOneQubitGate *gate::sqrtXdag(UINT qubit_index)

\(\sqrt{X}^{\dagger}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::sqrtY
Function Documentation
ClsOneQubitGate *gate::sqrtY(UINT qubit_index)

\(\sqrt{Y}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::sqrtYdag
Function Documentation
ClsOneQubitGate *gate::sqrtYdag(UINT qubit_index)

\(\sqrt{Y}^{\dagger}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::StateReflection
Function Documentation
ClsStateReflectionGate *gate::StateReflection(const QuantumState *reflection_state)

量子状態に対して量子状態を反射する。

パラメータ

reflection_state -- [in] 反射に用いられる量子状態

戻り値

作成されたゲートのインスタンス

Function gate::SWAP
Function Documentation
ClsTwoQubitGate *gate::SWAP(UINT qubit_index1, UINT qubit_index2)

SWAPゲートを作成する

パラメータ
  • qubit_index1 -- [in] ターゲットとなる量子ビットの添え字

  • qubit_index2 -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::T
Function Documentation
ClsOneQubitGate *gate::T(UINT qubit_index)

\(T\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::Tdag
Function Documentation
ClsOneQubitGate *gate::Tdag(UINT qubit_index)

\(T^{\dagger}\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::to_matrix_gate
Function Documentation
QuantumGateMatrix *gate::to_matrix_gate(const QuantumGateBase *gate)

QuantumGateBaseの任意のサブクラスを、QuantumGateMatrixのクラスの変換する。

\(n\)-qubitゲートで \(n\)が非常に大きいとき、 \(d^2\)の大量のメモリを使用する点に注意。

パラメータ

gate -- 変換するゲート

戻り値

変換されたQuantumGateMatrixクラスのインスタンス

Function gate::TwoQubitDepolarizingNoise
Function Documentation
QuantumGate_Probabilistic *gate::TwoQubitDepolarizingNoise(UINT target_index1, UINT target_index2, double prob)

Two-qubit depolarizin noiseを発生させるゲート

IIを除くtwo qubit Pauli operationがそれぞれprob/15の確率で生じる。

パラメータ
  • target_index1 -- [in] ターゲットとなる量子ビットの添え字

  • target_index2 -- [in] ターゲットとなる量子ビットの添え字

  • prob -- [in] エラーが生じる確率

戻り値

作成されたゲートのインスタンス

Function gate::U1
Function Documentation
QuantumGateMatrix *gate::U1(UINT qubit_index, double lambda)

OpenQASMのU1ゲートを作成する。

具体的なゲートについてはOpenQASMのマニュアルを参照

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • lambda -- [in] 回転角の第一引数

戻り値

作成されたゲートのインスタンス

Function gate::U2
Function Documentation
QuantumGateMatrix *gate::U2(UINT qubit_index, double phi, double lambda)

OpenQASMのU2ゲートを作成する。

具体的なゲートについてはOpenQASMのマニュアルを参照

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • lambda -- [in] 回転角の第一引数

  • phi -- [in] 回転角の第二引数

戻り値

作成されたゲートのインスタンス

Function gate::U3
Function Documentation
QuantumGateMatrix *gate::U3(UINT qubit_index, double theta, double phi, double lambda)

OpenQASMのU3ゲートを作成する。

具体的なゲートについてはOpenQASMのマニュアルを参照

パラメータ
  • qubit_index -- [in] ターゲットとなる量子ビットの添え字

  • lambda -- [in] 回転角の第一引数

  • phi -- [in] 回転角の第二引数

  • theta -- [in] 回転角の第三引数

戻り値

作成されたゲートのインスタンス

Function gate::X
Function Documentation
ClsOneQubitGate *gate::X(UINT qubit_index)

\(X\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::Y
Function Documentation
ClsOneQubitGate *gate::Y(UINT qubit_index)

\(Y\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function gate::Z
Function Documentation
ClsOneQubitGate *gate::Z(UINT qubit_index)

\(Z\)ゲートを作成する。

パラメータ

qubit_index -- [in] ターゲットとなる量子ビットの添え字

戻り値

作成されたゲートのインスタンス

Function get_Pauli_matrix
Function Documentation
void get_Pauli_matrix(ComplexMatrix &matrix, const std::vector<UINT> &pauli_id_list)

pauli_id_listからパウリ行列をmatrix生成する。

パラメータ
  • matrix -- [out] 作成する行列を格納する行列の参照

  • pauli_id_list -- [in] 生成するパウリ演算子のIDのリスト。 \({I,X,Y,Z}\)\({0,1,2,3}\)に対応する。

Function Igate_idling
Function Documentation
static void Igate_idling(UINT, CTYPE*, ITYPE)

1量子ビットを対象とする回転角固定のゲートのクラス

Function Igate_idling_gpu
Function Documentation
static void Igate_idling_gpu(UINT, void*, ITYPE, void*, UINT)
Function KAK_decomposition
Function Documentation
KAK_data KAK_decomposition(QuantumGateBase *target_gate, std::vector<UINT> target_bits)
Function KAK_decomposition_internal
Function Documentation
KAK_data KAK_decomposition_internal(QuantumGateBase *target_gate)
Function loss_function::cross_entropy
Function Documentation
double loss_function::cross_entropy(const std::vector<double> &prediction, const std::vector<double> &correct_label)
Template Function loss_function::L2_distance
Function Documentation
template<typename T>
double loss_function::L2_distance(const std::vector<T> &s1, const std::vector<T> &s2)
Function loss_function::softmax_cross_entropy
Function Documentation
double loss_function::softmax_cross_entropy(const std::vector<double> &prediction, const std::vector<double> &correct_label)
Function loss_function::softmax_cross_entropy_category
Function Documentation
double loss_function::softmax_cross_entropy_category(std::vector<double> prediction, UINT correct_label)
Function observable::create_observable_from_openfermion_file
Function Documentation
HermitianQuantumOperator *observable::create_observable_from_openfermion_file(std::string file_path)

OpenFermionから出力されたオブザーバブルのテキストファイルを読み込んでHermitianQuantumOperatorを生成します。オブザーバブルのqubit数はファイル読み込み時に、オブザーバブルの構成に必要なqubit数となります。

パラメータ

file_path -- [in] OpenFermion形式のオブザーバブルのファイルパス

戻り値

Observableのインスタンス

Function observable::create_observable_from_openfermion_text
Function Documentation
HermitianQuantumOperator *observable::create_observable_from_openfermion_text(const std::string &text)

OpenFermionの出力テキストを読み込んでObservableを生成します。オブザーバブルのqubit数はファイル読み込み時に、オブザーバブルの構成に必要なqubit数となります。

パラメータ

text -- [in] OpenFermion形式のテキスト

戻り値

Observableのインスタンス

Function observable::create_split_observable
Function Documentation
std::pair<HermitianQuantumOperator*, HermitianQuantumOperator*> observable::create_split_observable(std::string file_path)

OpenFermion形式のファイルを読んで、対角なObservableと非対角なObservableを返す。オブザーバブルのqubit数はファイル読み込み時に、オブザーバブルの構成に必要なqubit数となります。

パラメータ

file_path -- [in] OpenFermion形式のオブザーバブルのファイルパス

Function parse_openfermion_line
Function Documentation
std::tuple<double, double, std::string> parse_openfermion_line(std::string line)
Function quantum_operator::create_general_quantum_operator_from_openfermion_file
Function Documentation
GeneralQuantumOperator *quantum_operator::create_general_quantum_operator_from_openfermion_file(std::string file_path)

OpenFermionから出力されたGeneralQuantumOperatorのテキストファイルを読み込んでGeneralQuantumOperatorを生成します。GeneralQuantumOperatorのqubit数はファイル読み込み時に、GeneralQuantumOperatorの構成に必要なqubit数となります。

パラメータ

filename -- [in] OpenFermion形式のGeneralQuantumOperatorのファイル名

戻り値

Observableのインスタンス

Function quantum_operator::create_general_quantum_operator_from_openfermion_text
Function Documentation
GeneralQuantumOperator *quantum_operator::create_general_quantum_operator_from_openfermion_text(std::string text)

OpenFermionの出力テキストを読み込んでGeneralQuantumOperatorを生成します。GeneralQuantumOperatorのqubit数はファイル読み込み時に、GeneralQuantumOperatorの構成に必要なqubit数となります。

パラメータ

filename -- [in] OpenFermion形式のテキスト

戻り値

General_Quantum_Operatorのインスタンス

Function quantum_operator::create_split_general_quantum_operator
Function Documentation
std::pair<GeneralQuantumOperator*, GeneralQuantumOperator*> quantum_operator::create_split_general_quantum_operator(std::string file_path)

OpenFermion形式のファイルを読んで、対角なGeneralQuantumOperatorと非対角なGeneralQuantumOperatorを返す。GeneralQuantumOperatorのqubit数はファイル読み込み時に、GeneralQuantumOperatorの構成に必要なqubit数となります。

パラメータ

filename -- [in] OpenFermion形式のGeneralQuantumOperatorのファイル名

Function rtrim
Function Documentation
std::string &rtrim(std::string &str)

与えられた文字列の末尾の空白文字を削除します。

パラメータ

str -- [in] 文字列

戻り値

末尾の空白文字を削除された文字列

Function so4_to_magic_su2s
Function Documentation
std::pair<Eigen::Matrix<CPPCTYPE, 2, 2>, Eigen::Matrix<CPPCTYPE, 2, 2>> so4_to_magic_su2s(Eigen::Matrix4cd mat)
Function split
Function Documentation
std::vector<std::string> split(const std::string &s, const std::string &delim)

第一引数の文字列を第二引数の文字列で区切ったリストを返します。この関数は第一引数に対して非破壊です。

パラメータ
  • s -- [in] 分割したい文字列。

  • delim -- [in] 区切り文字列。

戻り値

第一引数に含まれる区切り文字列で区切った文字列。(example: split("aabcaaca", "bc") -> {"aa", "aa", "a"}

Function state::drop_qubit
Function Documentation
QuantumState *state::drop_qubit(const QuantumState *state, std::vector<UINT> target, std::vector<UINT> projection)
Function state::inner_product
Function Documentation
CPPCTYPE state::inner_product(const QuantumState *state_bra, const QuantumState *state_ket)

量子状態間の内積を計算する

パラメータ
  • state_bra -- [in] 内積のブラ側の量子状態

  • state_ket -- [in] 内積のケット側の量子状態

戻り値

内積の値

Function state::make_mixture
Function Documentation
DensityMatrixCpu *state::make_mixture(CPPCTYPE prob1, const QuantumStateBase *state1, CPPCTYPE prob2, const QuantumStateBase *state2)
Function state::make_superposition
Function Documentation
QuantumState *state::make_superposition(CPPCTYPE coef1, const QuantumState *state1, CPPCTYPE coef2, const QuantumState *state2)
Function state::partial_trace(const QuantumStateCpu *, std::vector<UINT>)
Function Documentation
DensityMatrixCpu *state::partial_trace(const QuantumStateCpu *state, std::vector<UINT> target)
Function state::partial_trace(const DensityMatrixCpu *, std::vector<UINT>)
Function Documentation
DensityMatrixCpu *state::partial_trace(const DensityMatrixCpu *state, std::vector<UINT> target_traceout)
Function state::permutate_qubit(const QuantumState *, std::vector<UINT>)
Function Documentation
QuantumState *state::permutate_qubit(const QuantumState *state, std::vector<UINT> qubit_order)
Function state::permutate_qubit(const DensityMatrixCpu *, std::vector<UINT>)
Function Documentation
DensityMatrixCpu *state::permutate_qubit(const DensityMatrixCpu *state, std::vector<UINT> qubit_order)
Function state::tensor_product(const QuantumState *, const QuantumState *)
Function Documentation
QuantumState *state::tensor_product(const QuantumState *state_left, const QuantumState *state_right)
Function state::tensor_product(const DensityMatrixCpu *, const DensityMatrixCpu *)
Function Documentation
DensityMatrixCpu *state::tensor_product(const DensityMatrixCpu *state_bra, const DensityMatrixCpu *state_ket)
Function to_general_quantum_operator
Function Documentation
GeneralQuantumOperator *to_general_quantum_operator(const QuantumGateBase *gate, UINT GQO_qubits, double tol = 1e-6)
Variables
Variable invalid_qubit
Variable Documentation
const UINT invalid_qubit = 9999
Variable KAK_GAMMA
Variable Documentation
Eigen::Matrix4cd KAK_GAMMA = (Eigen::Matrix4cd() << 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1).finished() * 0.25
Variable KAK_MAGIC
Variable Documentation
Eigen::Matrix4cd KAK_MAGIC = (Eigen::Matrix4cd() << 1, 0, 0, 1i, 0, 1i, 1, 0, 0, 1i, -1, 0, 1, 0, 0, -1i).finished() * sqrt(0.5)
Variable KAK_MAGIC_DAG
Variable Documentation
Eigen::Matrix4cd KAK_MAGIC_DAG = (Eigen::Matrix4cd() << 1, 0, 0, 1, 0, -1i, -1i, 0, 0, 1, -1, 0, -1i, 0, 0, 1i).finished() * sqrt(0.5)
Defines
Define _USE_MATH_DEFINES
Define Documentation
_USE_MATH_DEFINES
Define DllExport
Define Documentation
DllExport
Define FLAG_CLIFFORD
Define Documentation
FLAG_CLIFFORD

Flgas for gate property: gate is Clifford.

Define FLAG_GAUSSIAN
Define Documentation
FLAG_GAUSSIAN

Flgas for gate property: gate is Gaussian.

Define FLAG_PARAMETRIC
Define Documentation
FLAG_PARAMETRIC

Flgas for gate property: gate is parametrized.

Define FLAG_PAULI
Define Documentation
FLAG_PAULI

Flgas for gate property: gate is Pauli.

Regulation for argument/qubit/index ordering Read this before treating kronecker product

&#8212; arguments &#8212; Arguments of create_gate_*** function must be ordered as [control qubit (list), target qubit (list), rotation angle, state, dimension]

E.g. arguments of controlled gate must be ordered as [control qubit, target qubit]. CNOT_gate(0,1) = gate_from_string("CNOT 0 1") = control-0 X-1 gate

When we perform gate->add_control(i, value), the operation is performed on the index where its i-th bit is value, i.e. if (index&(1ULL<<i) != 0)

&#8212; state &#8212; In C/C++, it is useful to order the computational basis so that the RIGHTmost bit is the lowest bit. e.g. state = [ state[0b00], state[0b01], state[0b10], state[0b11] ]

In quantum circuit, we call the TOP-line qubit as the FIRST qubit.

In the braket representation, we consider the RIGHTmost bit in ket represents the FIRST (or TOP-line) qubit in the quantum circuit. state[0b01] = <01|state|01> = the probability with which the TOP-qubit is one, and the second-top qubit is zero.

&#8212; gate &#8212; To be consistent with the above index ordering, the order of tensor product is *** REVERSED ***.

X_0 has matrix representation : X_0 = I \otimes X = np.kron(I,X) = [0,1,0,0] |00> state[00] [1,0,0,0] |01> state[01] [0,0,0,1] |10> state[10] [0,0,1,0] |11> state[11]

CNOT(0,1) = control-0 target-NOT-1 has matrix representation [1,0,0,0] |00> [0,0,0,1] |01> [0,0,1,0] |10> [0,1,0,0] |11>

X_0 Y_1 Z_2 = np.kron(Z_2, np.kron(Y1, X0))

Define FLAG_X_COMMUTE
Define Documentation
FLAG_X_COMMUTE

Flags for bit property: diagonal in X-basis.

Define FLAG_Y_COMMUTE
Define Documentation
FLAG_Y_COMMUTE

Flags for bit property: diagonal in Y-basis.

Define FLAG_Z_COMMUTE
Define Documentation
FLAG_Z_COMMUTE

Flags for bit property: diagonal in Z-basis.

Typedefs
Typedef ComplexMatrix
Typedef Documentation
using ComplexMatrix = Eigen::Matrix<CPPCTYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
Typedef ComplexVector
Typedef Documentation
using ComplexVector = Eigen::VectorXcd
Typedef CPPCTYPE
Typedef Documentation
using CPPCTYPE = std::complex<double>
Typedef DensityMatrix
Typedef Documentation
using DensityMatrix = DensityMatrixCpu
Typedef Observable
Typedef Documentation
using Observable = HermitianQuantumOperator
Typedef Observable
Typedef Documentation
using Observable = HermitianQuantumOperator
Typedef Observable
Typedef Documentation
using Observable = HermitianQuantumOperator
Typedef QuantumGate_Instrument
Typedef Documentation
using QuantumGate_Instrument = QuantumGate_CPTP
Typedef QuantumGate_OneControlOneTarget
Typedef Documentation
using QuantumGate_OneControlOneTarget = ClsOneControlOneTargetGate
Typedef QuantumGate_OneQubit
Typedef Documentation
using QuantumGate_OneQubit = ClsOneQubitGate
Typedef QuantumGate_OneQubitRotation
Typedef Documentation
using QuantumGate_OneQubitRotation = ClsOneQubitRotationGate
Typedef QuantumGate_ProbabilisticInstrument
Typedef Documentation
using QuantumGate_ProbabilisticInstrument = QuantumGate_Probabilistic

This type alias is kept for backward compatibility. Do not edit this!

Typedef QuantumGate_TwoQubit
Typedef Documentation
using QuantumGate_TwoQubit = ClsTwoQubitGate
Typedef QuantumState
Typedef Documentation
using QuantumState = QuantumStateCpu
Typedef SparseComplexMatrix
Typedef Documentation
using SparseComplexMatrix = Eigen::SparseMatrix<CPPCTYPE>