Skip to content

rxnew/qc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QC (Quantum Circuit)

This program is quantum circuit simulator.

Requirements

How to install

依存ライブラリが見つからない場合,自動でダウンロードされ,ビルドディレクトリにインストールされます.

$ cd build
$ cmake [-DCMAKE_INSTALL_PREFIX=<dir>] [-DCMAKE_BUILD_TYPE=(Debug|Release)] ..
$ make install

How to test

Google Test を使用しています.

$ cd build
$ cmake -DQC_BUILD_TESTS=ON ..
$ make
$ ctest

How to run a sample program

QC ライブラリを利用するプロジェクトのサンプルです.
すでにインストールされたライブラリを利用する場合は,INSTALL_EXTERNAL_PROJECTS_PREFIX を設定します.

$ cd sample/build
$ cmake [-DINSTALL_EXTERNAL_PROJECTS_PREFIX=<dir>] ..
$ make
$ cd ..
$ ./bin/main

How to use

UML_Class_Diagram

qc::Bit クラス

"qc/bit.hpp"

量子ビットを実装しているクラス.

派生クラスとして,qc::CBitqc::TBit がある. それぞれ,コントロールビットとターゲットビットに対応している.

auto cbit = qc::CBit(qc::BitNo(0)); // デフォルトの極性は正極
auto cbit = qc::CBit(qc::BitNo(0), qc::positive); 
auto cbit = qc::CBit(qc::BitNo(0), qc::negative);
auto tbit = qc::TBit(qc::BitNo(1);

qc::BitNo や qc::CBit, qc::TBit にはリテラルが用意されている.

using namespace qc::literals::bit_literals;
auto bit_no = 0_bit;
auto cbit = 0_cbit;
auto cbit = !0_cbit; // 負極には否定演算子を使用
auto tbit = 1_tbit;

qc::Bit クラスの主なメンバを以下にまとめる.

members description
no_ ビット番号 (private member variable)
get_no ビット番号を取得する (public member function)

qc::CBit クラスの主なメンバを以下にまとめる.

members description
polarity_ コントロールビットの極性 (private member variable)
get_polarity 極性を取得する (public member function)
invert_polarity 極性を反転する (public member function)

qc::Gate クラス

"qc/gate.hpp", "qc/gate/library.hpp"

量子ゲートを実装しているクラス.

ゲートの機能を提供する qc::GateKernel 抽象クラスをポインタで保持している. qc::GateKernel は qc::CBit と qc::TBit の集合を保持している.

qc::GateKernel の派生クラスを用いて各量子ゲート (e.g., H, X) のカーネルを実装している. 各ゲートに対応するクラスは,qc::Gate を継承している. また,qc::Gate への暗黙的な型変換が可能.

auto x = qc::X(cbit, tbit);
auto gate = static_cast<qc::Gate>(x);

以下のような例に注意する必要がある.

auto h = qc::H(tbit);
auto x = qc::X(cbit, tbit);
h = x; // error

qc::X から qc::H など,異なる種類のゲート間の型変換はできない. 同様に qc::Gate から qc::X などへの型変換もできない. 異なる種類のゲートを同列に扱う場合,各ゲートを qc::Gate オブジェクトとして扱うべきである.

auto h = static_cast<qc::Gate>(qc::H(tbit));
auto x = static_cast<qc::Gate>(qc::X(cbit, tbit));
h = x; // ok

上記の例では,qc::H (qc::X) の一時オブジェクトが生成されている. 一時オブジェクトを生成せずに,直接 qc::Gate オブジェクトを生成する場合は,qc::Gate::make() を利用する.

auto x = qc::Gate::make<X>(cbit, tbit);

ゲート名の文字列からゲートを生成する場合は,qc::make_gate() を利用する. ゲート名にはエイリアスも使用可能. また,大文字小文字を区別しない.

auto x = qc::make_gate("X", cbit, tbit);
auto x = qc::make_gate("NOT", cbit, tbit);

実装済みのゲートは以下の通り. (括弧内の斜体はエイリアス)

  • I (単位行列)
  • H (Hadamard)
  • X (パウリ行列, NOT, Toffoli, MCT, MPMCT)
  • Y (パウリ行列)
  • Z (パウリ行列)
  • V (Rx(pi/2))
  • V* (V+, VDagger, VPlus)
  • W (Rx(pi/4))
  • W* (W+, WDagger, WPlus)
  • S (Rz(pi/2), P)
  • S* (S+, SDagger, SPlus)
  • T (Rz(pi/4))
  • T* (T+, TDagger, TPlus)
  • Swap

ダガー行列 (Hermitian adjoint) は,コンストラクタの第1引数に qc::bedaggered を渡すか、 ゲート名の末尾に "*", "+", "dagger", "plus" のいずれかを付けることで生成可能.

auto v_dagger = qc::V(qc::bedaggered, cbit, tbit);
auto v_dagger = qc::make_gate("V*", cbit, tbit);

また,否定演算子を用いてダガー行列を生成することも可能.

auto v = qc::V(cbit, tbit);
auto v_dagger = !v;

Rvalue に対して否定演算子を用いた場合,この演算は新たなオブジェクトの生成を行わないため,高速に動作する.

auto v_dagger = !qc::V(cbit, tbit);

qc::X 等,一部のゲートは X == X* が成り立つ.

v == !v; // false
x == !x; // true

qc::Gate クラスの主なメンバ関数を以下にまとめる.

members description
cbits_ コントロールビットのリスト (private member variable)
tbits_ ターゲットビットのリスト (private member variable)
get_type_name ゲート名を取得する (public member function)
get_cbits コントロールビットの集合を取得する (public member function)
get_tbits ターゲットビットの集合を取得する (public member function)
set_cbits コントロールビットの集合をセットする (public member function)
set_tbits ターゲットビットの集合をセットする (public member function)
add_cbit コントロールビットを追加する (public member function)
add_tbit ターゲットビットを追加する (public member function)
has_bit ビットを含んでいるか確認する (public member function)
has_cbit コントロールビットを含んでいるか確認する (public member function)
has_tbit ターゲットビットを含んでいるか確認する (public member function)
erase_bit ビットを削除する (public member function)
collect_bits 使用しているビット番号の集合を生成する (public member function)
is_controlled 制御ゲートか確認する (public member function)
is_single_controlled 1-制御ゲートか確認する (public member function)
is_multi_controlled n-制御ゲートか確認する (public member function)
is_single_target 1-標的ゲートか確認する (public member function)
is_multi_target n-標的ゲートか確認する (public member function)
is_single_qubit_rotation 1量子ビット回転ゲートか確認する (public member function)
is_all_positive 全てのコントロールビットの極性が正か確認する (public member function)
print ストリームに出力する (public member function)

qc::Circuit クラス

"qc/circuit.hpp"

量子回路を実装しているクラス.

qc::Gate をリストで保持している.

auto circuit = qc::Circuit();
circuit.add_gate(x);

qc::Circuit クラスの主なメンバ関数を以下にまとめる.

members description
description_ 説明文 (private member variable)
gates_ ゲートのリスト (private member variable)
get_description 説明文を取得する (public member function)
set_description 説明文をセットする (public member function)
get_gates ゲートのリストを取得する (public member function)
set_gates ゲートのリストをセットする (public member function)
add_gate ゲートを末尾に追加する (public member function)
insert_gate ゲートを任意の位置に挿入する (public member function)
erase_gate 指定した位置のゲートを削除する (public member function)
remove_gate ゲートを削除する (public member function)
remove_gate_if 条件を満たすゲートを削除する (public member function)
move_gate ゲートを移動する (public member function)
swap_gate ゲートを入れ替える (public member function)
begin_gates ゲートのリストの先頭のイテレータを取得する (public member function)
end_gates ゲートのリストの末尾のイテレータを取得する (public member function)
cbegin_gates ゲートのリストの先頭のイテレータ (const) を取得する (public member function)
cend_gates ゲートのリストの末尾のイテレータ (const) を取得する (public member function)
extend 連結する (public member function)
clear ゲートを全て削除する (public member function)
empty ゲートが存在しないか確認する (public member function)
get_gate_count ゲート数を取得する (public member function)
collect_bits 使用しているビット番号の集合を生成する (public member function)
print ストリームに出力する (public member function)

qc::Group クラス

"qc/gate/group.hpp"

複数の qc::Gate をグループとして扱うためのクラス.

qc::Gate をリストで保持しており,qc::Circuit と同様のメンバを持っている. qc::Group 自体も qc::Gate を継承しており,qc::Circuit のゲートのリストの要素として扱うことが可能.

auto group = qc::Group(x);
group.add_gate(h);
circuit.add_gate(group);

直接 qc::Gate オブジェクトを生成する場合は,qc::Gate::make() または,qc::Group::make() を利用する.

auto group = qc::Group::make();
group.add_gate(h);

上記の例で,qc::Gate オブジェクトに対して add_gate() が呼べていることに注意すべきである. これは,qc::Gate が qc::Circuit と同様のメソッドを持っているためである. そのため,以下のようなコードのコンパイルは通ってしまう.

auto x = qc::X(tbit);
x.add_gate(x); // コンパイルは通る

しかし,このようなコードは実行時に (NODEBUG マクロを定義していなければ) アサーションが発生する. qc::Gate オブジェクトに対して add_gate() などのメソッドを呼ぶときには,qc::Gate::is_group() を使うべきである.

if(gate.is_group()) gate.add_gate(x);

qc::Circuit や qc::Gate が持つゲートのリストに対して,メソッドに無い操作を行いたい場合には,apply_to_gates() を利用する. function の第1引数は,ゲートのリストへの参照 (qc::Gates&) である必要がある.

auto function = [](qc::Gates& gates, auto compare) {gates.sort(compare);};
circuit.apply_to_gates(function, compare);

アルゴリズム

"qc/algorithm.hpp"

量子回路に関するアルゴリズムを実装した関数がまとめられている.

functions description
get_cbit 1-制御ゲートのコントロールビットを取得する
get_tbit 1-標的ゲートのターゲットビットを取得する
add_gate_front 回路やグループの先頭にゲートを追加する
add_gate_back 回路やグループの末尾にゲートを追加する
insert_gate_before 回路やグループの pos の直前にゲートを挿入する
insert_gate_after 回路やグループの pos の直後にゲートを挿入する
decomp_to_single_target_gates 全てのゲートを1-標的ゲートに分解する
collect_cbits コントロールビットのビット番号の集合を生成する
collect_tbits ターゲットビットのビット番号の集合を生成する
is_mct_circuit MCT (Multi-Control Toffoli) のみで構成された回路か確認する
is_esop_circuit ESOP (Exclusive Sum-of-Products) 形式に変換可能な回路か確認する
get_mct_cost MCT のコストを取得する
calculate_mct_circuit_cost MCT 回路の総コストを計算する
sort_gates_by_cbits コントロールビットで回路をソートする
sort_gates_by_tbits ターゲットビットで回路をソートする
sort_gates 回路をソートする
decomp_to_single_target_circuits 1-出力回路に分解する
has_group 回路やグループ内にグループが存在するか確認する
remove_empty_groups 回路やグループ内の空のグループを全て削除する
expand_groups 回路やグループ内のグループを展開する

入出力

"qc/io.hpp"

qc::io に IO 関連の機能がまとめられている.

auto circuit = qc::io::open(filename);
qc::io::input(circuit, filename);
qc::io::output(circuit, filename);

拡張子からファイル形式を判断する.

対応しているファイル形式は以下の通り.

  • qo
  • esop
  • blif (入力は nand2 のみ)
  • json