LYNCSブログ

慶應義塾大学公認学生団体 宇宙科学総合研究会(LYNCS)のブログです。

量子情報科学序論 IBM Qを動かして学ぶ量子コンピュータ

【前置き】この記事は『量子コンピュータ Advent Calendar 2017』の12月16日分です. 11月の三田祭(慶應義塾大学の文化祭)にてLYNCSが配布した部誌『Escape Velocity』の記事を一部改訂(最新のニュースを反映)したものになっております.

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

概要

量子計算機アルゴリズムの基礎を学びます. 直感的理解のため, 読者が実際にIBMの保持する量子計算機クラウド上で実行できるように導入します. 最後に少し最近のニュースに触れています.

はじめに

みなさん初めまして. LYNCS理学研究本部所属のTsujishin(@shin_tsujido)と申します. 本年度, LYNCS理学研究本部では量子情報科学輪講を行いました. 量子情報科学は年々規模が拡大しており, 各国各企業の研究の一部は実装の段階に移行しつつあります. 一方,量子情報科学が世間から十分に理解を得られているとは言い難いです(『量子コンピュータ』の定義の議論含め). よって本誌では学部1年レベルの線形代数以外に前提知識を必要とせず, 分野に関しての一歩目となるような序論を展開します. また, 読者が量子コンピュータ(IBMQ)の操作を一通りできるような導入を行います.

量子情報科学とは

量子情報科学とは, 量子力学を物理的基盤(ハードウェア構成要素が従うことわり)としている情報科学(コンピュータ科学を含む)のことです. 具体的には, 量子コンピュータ(計算機)や量子通信, 量子暗号などに関する学問です. 80年代にベニオフやファインマン, ドイチュの構想から始まった分野ですが, 人類の不断の努力によって実用段階になりつつあります. 多くの量子情報科学におけるアルゴリズムは後述する重ね合わせや量子もつれなどの性質を用いることでより効率的な計算やより安全な通信を実現しています. 1

量子コンピュータ

ガ○ダム00やマブ○ヴオルタなどのSFでもよく目にする量子コンピュータ. それは果たしてどのようなコンピュータなのでしょうか. 理想的な計算機(コンピュータ)のモデルとしてよく語られるものにチューリングマシンがありますが, 量子コンピュータのモデルの一つである量子チューリングマシンは, 計算可能性(どんな問題を解くことができるか)は等価になっています. チューリングマシンで解くことができない問題は量子チューリングマシンでも解くことはできません. しかし, 解くことができる計算において, 計算量(計算の手順数)では, 量子チューリングマシンチューリングマシン以下になること, すなわちより効率よく計算できる可能性があることが示されています. また, 量子チューリングマシンチューリングマシンのエミュレート(動作の真似をすること)ができます.

量子ゲート(回路)方式計算機と呼ばれる方式は量子コンピュータで最も歴史的に研究されてきました. 量子ゲート方式は既存のコンピュータの汎用性を引き継ぎ, さらに計算を効率化することを目標としています. また, 断熱計算機や量子シミュレータなどと呼ばれる計算機がよく量子ゲート方式計算機への比較の対象として取り上げられてきました. 断熱計算機には量子アニーリング方式と呼ばれるタイプのコンピュータがあります. 量子アニーリング方式計算機は, カナダのD-Wave社が実用化し話題を呼びました. 他にもコヒーレントイジングマシン(開発者の方は量子ニューラルネットワークと呼称されています)と呼ばれる光を用いた計算機が比較対象にされることもあります. 量子アニーリング方式やコヒーレントイジングマシンは最適化問題(サラリーマン巡回問題やグループ分けの問題など. グラフ理論などに関連する問題)を解くことに特化しています. コヒーレントイジングマシンは分かりやすく基本的な仕組みが説明されている記事があるのでリンクを貼っておきます.

codezine.jp

また, クラウドで実際に動かすこともできます.

QNNcloud

これらさまざまな非ノイマン型計算機(特殊な計算機)のうちいくつかは, 量子力学的性質を用いることで様々な問題の計算量(計算複雑性)を減らすことを試みています. 計算量とは, 問題を解くのに当たって必要な計算の回数なので, これを減らすことによってより短い時間で計算できるようになります. 現在, 量子コンピュータ開発は規模を拡大しつつあります. アメリカ国防省は毎年約220億円投資しており, EUは2019年からの10年で1300億円, 日本も来年度予算で32億円投資予定です. 2 世界中の研究室で量子コンピュータなどの非ノイマン型計算機の開発は続いており, 以下のように様々な物質の性質を用いた非ノイマン型計算機が研究されています.

(A)ゲート方式

  1. 超電導(トランズモンなど) IBM, Googleなど
  2. 光子 東大古澤研
  3. シリコン核スピン 慶應伊藤研

(B)量子アニーリング

*超電導 D-Wave, 東工大西森研, USC

(C)コヒーレントイジングマシン

*光(パルス) NTT, NII, Stanford

量子力学的性質

物理を古典力学から量子力学に拡張したら、計算は拡張されたんだ。それは、これまで数学的に決まっていると思っていた計算が、実は古典物理をもとに作られた計算だったからだ。そのことに我々は気づいていなかった. - David Deutsch(1953〜)3

量子力学を用いると何が今までのコンピュータ(量子情報科学者は敬意を込めて古典コンピュータと呼称する)や通信と違うのでしょうか. そもそも量子力学とは, 電子や光子(フォトン)などミクロな領域から始まった物理学です(マクロな物体における量子力学の話は長くなるので今回は割愛します).量子力学においてはマクロな世界観を持った我々の感覚とは異なる現象が多々起こります.

例えば, 量子力学では, 観測という概念が非常に重要です. 古典力学(非量子力学)では, 初期値(例えば物体の位置や速度, 加速度)がわかればその後の運動は基本的に予測できます(外部からの影響がない限り). しかしながら量子力学では, 観測するまでその後の推移は確定できません.

量子力学の最も重要な現象(概念)として, 重ね合わせと量子もつれという現象があります. 量子コンピュータでは, これらの現象を用いて量子ビットと呼ばれる情報単位を生成し, 計算を行っています.

量子ビット

古典コンピュータでは, 情報の最小単位としてビット(bit)を用います. ビットは、0もしくは1の2通りの情報を表現することができます. これをn個用意することによって, 2nの状態を表現することができます. 量子情報科学分野では, 古典ビットと呼称します. 古典ビットは, 物理的には主に電圧の高下などを用います. また, 古典ビットはコピーすることができます.

それに対し, 量子コンピュータ量子ビット(Qubit)と呼ばれる情報の単位を用います. この量子ビットは, 古典計算機のビットのように, 二つの情報を表現することができます. この時, 量子ビットでは, 二つの直行するベクトル(二次元複素ベクトル空間での正規直交基底)を用いて情報を表現します.4 また, 量子分野ではよく, ベクトルをブラッケット記法という記法で表現します. ブラケット記法では, 任意のベクトルは,$\ket{}$(ケットと読みます)のような記号に入れて表現します.
例えば, 古典ビットにおける0と1に相当する単純な状態は,

$$ \ket{0} ≡ \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) \ket{1} ≡ \left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) $$

のように表現されます. ケットの中に入る数字もしくはアルファベットは, 特に意味はなく, ラベルづけ(ベクトルに名前をつける)として機能します. つまり,

$$ \ket{*°Д°} ≡ \left( \begin{array}{r} 12345 \\ 54321 \\ \end{array} \right) $$

のようにケットの中には好きなものを入れてベクトルを置くことができます. なお量子力学では, 主に$ψ$(プサイ)や$φ$(ファイ)を用います. なお, 複数の量子の状態を表す時, $\ket{}$の中に複数の状態を入れることもできます. 例えば, $\ket{0}$の量子ビットが二つあった時, $\ket{00}$のように表現することができます.

この量子ビットをより視覚的に捉えるツールとして, ブロッホ球という概念があります. 球の表面は中心からの距離がどこでも等しいので, 2次元複素ベクトル空間内のあらゆる単位ベクトルを表現可能です. ブロッホ球はベクトルのZ軸で$\ket{0}$と$\ket{1}$を観測できる確率を表し、XY平面の角度で位相を表します。北極が$\ket{0}$, 南極が$\ket{1}$に相当します. 例えば,

$$\ket{ψ}=\cos\frac{θ}{2}\ket{0}+exp(iφ)\sin\frac{θ}{2}\ket{1}$$

は以下のようになります.

f:id:lyncs:20171217235309j:plain
ブロッホ

量子ビットは, 物理的には光子や電子のエネルギー, 原子のスピンなどで実現されます.

重ね合わせ

古典ビットにはない性質として, 量子ビットは古典ビットと違い, 0と1が共存した状態を生成することが可能になっています. この共存した状態とは, 2次元複素ベクトル空間内のあらゆる単位ベクトル(大きさ1のベクトル)を表現可能です.

$$ \ket{ψ} =a\ket{0}+b\ket{1} = \left( \begin{array}{r} a \\ b \\ \end{array} \right) $$

この式が意味するのは, 確率$|a|^2$で状態$\ket{0}$, 確率$|b|^2$で状態$\ket{1}$が観測できるという状態です. 例えば,

$$ \ket{ψ} =\frac{\ket{0}+\ket{1}}{\sqrt{2}} = \frac{1}{\sqrt{2}}{\left( \begin{array}{r} 1 \\ 1 \\ \end{array} \right)} $$

では,それぞれ $\left( \frac{1}{\sqrt{2}} \right) ^2=\frac{1}{2}$の確率で状態$\ket{0}$, $\ket{1}$を観測できます.

このような現象を活用することで, 複数のデータ(状態)に対して同時に操作を行うことができ, 古典コンピュータへのアドバンテージになっています. 物理的にどのようなことであるのかなどより深く知りたい方は, "シュレーディンガーの猫"などに関して調べてみてください.

量子もつれ

もう一つ古典ビットと明確に違う性質として, 量子もつれがあります. これは, 複数の量子ビットにおいて発生することのある特殊な相関です. まずは簡単のため, 二つの量子における量子もつれを考えましょう. 1つ目の量子をA, 2つ目の量子をBとします. ここで2量子のもつれかつ重ね合わせの4つの状態(Bell pair)を例に出してみましょう.

$$ |\Phi^+\rangle ≡ \frac{1}{\sqrt{2}} (|0\rangle_A \otimes |0\rangle_B + |1\rangle_A \otimes |1\rangle_B) $$ $$ |\Phi^-\rangle ≡ \frac{1}{\sqrt{2}} (|0\rangle_A \otimes |0\rangle_B - |1\rangle_A \otimes |1\rangle_B) $$ $$ |\Psi^+\rangle ≡ \frac{1}{\sqrt{2}} (|0\rangle_A \otimes |1\rangle_B + |1\rangle_A \otimes |0\rangle_B)\ $$ $$ |\Psi^-\rangle ≡ \frac{1}{\sqrt{2}} (|0\rangle_A \otimes |1\rangle_B - |1\rangle_A \otimes |0\rangle_B)\ $$

例えば$|\Phi^+\rangle$では,確率$\left( \frac{1}{\sqrt{2}} \right) ^2=\frac{1}{2}$で A,B共に$\ket{0}$, 確率$\left( \frac{1}{\sqrt{2}} \right) ^2=\frac{1}{2}$でA,B共に$\ket{1}$という意味です. $|\Phi^+\rangle$では, バラバラに観測しても片方のみが0, もう片方が1,という結果は得られません. 片方の量子ビットを観測した時点で両方の状態は確定するということを意味します.

このように, 多量子系において, 複数の量子の状態が不可分になっている状態を量子もつれと呼称します. 物理的にどのようなことであるのかなどより深く知りたい方は, "EPRパラドックス", "CHSH不等式"などに関して調べてみてください.

ゲート方式量子コンピュータ

量子ゲート(回路)方式計算機では, 量子回路を用いて量子ビットを操作します. これは, 既存の計算機における電子回路の論理回路の拡張になっています. 量子回路は量子ゲート(素子)から構成されており, を量子ビットに対して掛けることを「量子素子を適用する」と呼称します. 量子ゲートは, 図のように, 線の上にボックスを乗せて表記します. この時線一本が1量子ビットを表しています.

f:id:lyncs:20171215224125p:plain

この節では, IBM量子計算機に実装されている量子ゲートを説明します. 量子回路は, 量子ビットから量子ビットへの変換を行い, ユニタリー行列として与えられます.

f:id:lyncs:20171215224243p:plain
量子操作はユニタリーである

任意のユニタリー行列Uは,

$$U^{*}U=UU^{*}=I$$

となっています. ここで, $U^*$は, 行列$U$の転置(後述)かつ複素共役(実部はそのまま虚部の符号を反転すること)な行列, $I$は単位行列となっています. 転置とは, m行n列の任意の行列Aの$(i,j)$成分と$(j,i)$成分を入れ替えたn行m列の行列$A^{\mathrm{T}}$を表します.

また, 単位行列とは, 対角成分に$0$が並び, それ以外に$1$が並んだ行列のことです. つまり, 行列要素$a_ij$に関して,

$$ a_ij= \begin{cases} 1 & (i=j) \\ 0 & (i\neq j) \end{cases} $$

という式が成り立つ行列を表します.

恒等演算子

恒等演算子は以下のような行列で, どのような量子ビットに対して適用しても量子ビットの状態は変化しません. つまり, 入力と出力が等しいゲートということになります. よくIやIdと表記します.

$$ I ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) $$

f:id:lyncs:20171215224429p:plain
適用後も量子ビットは変化しない

パウリXYZゲート

パウリX

$$ X ≡ \left( \begin{array}{rr} 0 & 1 \\ 1 & 0 \\ \end{array} \right) $$

パウリXゲートは, ビット反転演算子とも呼ばれます. これは, パウリXゲートを量子ビットに適応すると, 以下のように$\ket{0}$は$\ket{1}$に, $\ket{1}$が$\ket{0}$に変換できるためです. これは古典におけるNOTゲートに相当します. また, ブロッホ球上では, $x$軸の周りに角度$π$回転させる操作と捉えることができます.

$$ X\ket{0}= \left( \begin{array}{rr} 0 & 1 \\ 1 & 0 \\ \end{array} \right) \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) =\left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) =\ket{1} $$ $$ X\ket{1}= \left( \begin{array}{rr} 0 & 1 \\ 1 & 0 \\ \end{array} \right) \left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) = \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right)=\ket{0} $$

量子回路上では以下のように表現します.

f:id:lyncs:20171215230404p:plain

パウリY

$$ Y ≡ \left( \begin{array}{rr} 0 & -i \\ i & 0 \\ \end{array} \right) $$

パウリYゲートは, 位相・ビット反転演算子とも呼びます. ブロッホ球上では, $y$軸の周りに角度$π$回転させる操作と捉えることができます.

$$ Y\ket{0}=\left( \begin{array}{rr} 0 & -i \\ i & 0 \\ \end{array} \right) \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) =\left( \begin{array}{r} 0 \\ i \\ \end{array} \right) =i\ket{1} $$ $$ Y\ket{1}=\left( \begin{array}{rr} 0 & -i \\ i & 0 \\ \end{array} \right) \left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) =\left( \begin{array}{r} -i \\ 0 \\ \end{array} \right) =-i\ket{0} $$

量子回路上では以下のように表現します.

f:id:lyncs:20171215230436p:plain

パウリZ

$$ Z ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & -1 \\ \end{array} \right) $$

パウリZゲートは, 位相反転演算子とも呼びます.ブロッホ球上では, $z$軸周りに角度$π$回転することを意味します. $\ket{0}$に対しては何も変化させず,$\ket{1}$に対しては, 状態に対しては位相のみ反転を行います.

$$ Z\ket{0}=\left( \begin{array}{rr} 1 & 0 \\ 0 & -1 \\ \end{array} \right) \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) =\left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) =\ket{0} $$ $$ Z\ket{1}=\left( \begin{array}{rr} 1 & 0 \\ 0 & -1 \\ \end{array} \right) \left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) ] [ =\left( \begin{array}{r} 0 \\ -1 \\ \end{array} \right) =-\left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) =-\ket{1} $$

量子回路上では以下のように表現します.

f:id:lyncs:20171215230520p:plain

アダマールゲート

$$ H ≡ \frac{1}{\sqrt{2}}\left( \begin{array}{rr} 1 & 1 \\ 1 & -1 \\ \end{array} \right) $$

アダマールゲートは, 量子ビットを重ね合わせ状態にすることができるゲートです. アダマール変換とも呼称します. アダマールゲートは, フランス人Hadamardに因んで名付けられました. フランス語で頭文字のHと最後のDは発音しないので, ハダマードではなくアダマールと呼びます.

$$ H\ket{0}=\frac{1}{\sqrt{2}}\left( \begin{array}{rr} 1 & 1 \\ 1 & -1 \\ \end{array} \right) \left( \begin{array}{r} 1 \\ 0 \\ \end{array} \right) =\frac{1}{\sqrt{2}} \left( \begin{array}{r} 1 \\ 1 \\ \end{array} \right) $$ $$ H\ket{1}=\frac{1}{\sqrt{2}}\left( \begin{array}{rr} 1 & 1 \\ 1 & -1 \\ \end{array} \right) \left( \begin{array}{r} 0 \\ 1 \\ \end{array} \right) =\frac{1}{\sqrt{2}} \left( \begin{array}{r} 1 \\ -1 \\ \end{array} \right) $$

ここで

$$ \frac{1}{\sqrt{2}} \left( \begin{array}{r} 1 \\ 1 \\ \end{array} \right)=\frac{\ket{0}+\ket{1}}{\sqrt{2}} $$

であり, これは量子ビットを観測するとそれぞれ$\left( \frac{1}{\sqrt{2}} \right) ^2=\frac{1}{2}$の確率で状態$\ket{0}$, $\ket{1}$という結果を得ることができる重ね合わせの状態です.

量子回路上では以下のように表現します. f:id:lyncs:20171215230556p:plain

位相シフトゲート

$$ S ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & i \\ \end{array} \right)  S^\dagger ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & -i \\ \end{array} \right) $$ $$ T ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & exp(i\frac{\pi}{4}) \\ \end{array} \right)  T^\dagger ≡ \left( \begin{array}{rr} 1 & 0 \\ 0 & exp(-i\frac{\pi}{4}) \\ \end{array} \right) $$

位相シフト演算は, 任意の重ね合わせ状態に対して適用すると, $\ket{0}$には何も操作を行わず, $\ket{1}$にのみ位相の操作を行います. 将来的には位相の角度を指定して様々な位相シフトゲートを作ることができることが望まれていますが, 今回操作する予定のIBM Qでは二つの角に対応した$S,T$とその反転の$S^\dagger, T^\dagger$が実装されています.

$$ S\ket{x}= \left( \begin{array}{rr} 1 & 0 \\ 0 & i \\ \end{array} \right) \left( \begin{array}{r} a\\ b\\ \end{array} \right) =a\ket{0}+ib\ket{1} $$ $$ T\ket{x}= \left( \begin{array}{rr} 1 & 0 \\ 0 & exp(i\frac{\pi}{4}) \\ \end{array} \right) \left( \begin{array}{r} a\\ b\\ \end{array} \right) =a\ket{0}+exp(i\frac{\pi}{4})b\ket{1} $$

位相シフト演算$S^\dagger$と$T^\dagger$は, 元の$S$,$T$シフト演算の逆向きの回転になっています. よって, $SS^\dagger=I$, $TT^\dagger=I$となっています.

f:id:lyncs:20171215232636p:plain

CNOTゲート

$$ CNOT^{(c,t)}≡ \left( \begin{array}{rrrr} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ \end{array} \right) $$

CNOT(controll-NOT)ゲートは, 2つの量子をもつれさせるゲートです. 今までのゲートが単一量子ビット演算子(素子)だったのに対し, CNOTゲートは2量子ビットを必要とします. 基本的にはビット反転演算子Xを実行することができるゲートですが, この時別の量子ビットによって制御されていることが特徴です. NOT演算子(Xゲート)を制御することから, 制御NOTゲートとも呼ばれます.

CNOTゲートの実行には, 制御(controll)量子ビット$\ket{c}$と標的(target)量子ビット$\ket{t}$の二つが必要です. そして, 制御量子ビットが$\ket{0}$ならば何もせず, $\ket{1}$ならばXゲート(ビット反転)を実行します.

$$ CNOT\ket{00}=\ket{00}  CNOT\ket{01}=\ket{01} $$ $$ CNOT\ket{10}=\ket{11}  CNOT\ket{11}=\ket{10} $$

量子回路上では以下のように表現します. 十字になっているのが標的量子ビットで, 小さな塗りつぶされた丸が制御量子ビットです.

f:id:lyncs:20171215230710p:plain

ここで, 先ほどの量子もつれの説明ででてきたBell pairの一つ,$\ket{Φ^+}$を生成してみましょう. Bell pairは,アダマールゲートとCNOTゲートを使えばすぐに生成できます.

f:id:lyncs:20171215230638p:plain

この時,二つの量子ビットはどのような行列の式で表現できるのでしょうか. 答えは, 一つの量子ビットは当然アダマールを適用するとして, もう一つの何もしない量子ビットに対しては,「何もしない」量子ゲートを適用したことにすればいいのです.「何もしない」量子ゲートは, 最初に説明したゲート, 恒等演算子(Id)のことでした. それを元に最初の段階の操作を式にすると以下のようになります.

ここで, 二つの量子に別の量子ゲートを適用した場合, 操作をテンソル積を用いることでひとつの式にまとめることができます.(このためにわざわざ「何もしない」操作の式を立てたのです.)このまとめたテンソル積を, クロネッカー積と呼称します.

$$H\otimes I$$ $$=\frac{1}{\sqrt{2}}\left( \begin{array}{rr} 1 & 1 \\ 1 & -1 \\ \end{array} \right)\otimes\left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) $$ $$=\frac{1}{\sqrt{2}}\left( \begin{array}{rr} 1\left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) & 1\left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) \\ 1\left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) & -1\left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right) \\ \end{array} \right) $$ $$ =\frac{1}{\sqrt{2}}\left( \begin{array}{rrrr} 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 \\ 1 & 0 & -1& 0 \\ 0 & 1 & 0 & -1 \\ \end{array} \right) $$

ここまでくれば, あとはCNOTを適用するだけです.

観測

今まで説明してきたように, 量子ビットは重ね合わせやもつれの状態にすることが可能ですが, 量子ビットを観測すると状態が確定し, 重ね合わせや量子もつれは壊れてしまい, 古典ビットになります. 観測は以下のようなアイコンで表現します.

f:id:lyncs:20171215230736p:plain

この図では, 第四量子ビットを測定し, 値(古典ビット)が得られるということを示しています.

IBM Qの使い方

IBMクラウド上に誰でも無料で動かせる量子コンピュータを「IBM Quantum Experience」として公開しています. この量子コンピュータの本体はIBMのニューヨークの研究施設にあり, 利用者が命令を送るたびに実際に超電導回路で量子ビットを生成, 操作してくれます.

f:id:lyncs:20171215230813j:plain
IBMQ

現在すぐに誰でも動かせる量子コンピュータは, IBM qx2, qx4, qx5の3種類です. これらが扱うことのできる量子ビットは,それぞれ5,5,17量子ビットです. qx5のみBeta版で,webサイト上のGUI(グラフィカルユーザインターフェース)に対応していないので今回は説明を省きます. qx2,qx4に関してはGUIが実装されており, 量子回路のグラフィックをいじることで量子コンピュータに行って欲しい命令を伝えることができます.

f:id:lyncs:20171217004528p:plain
利用可能な量子コンピュータ

ただし, 量子コンピュータ量子もつれを生成するのには少し制限があります. 例えば, IBM qx4の設定を見ると以下のような図が表示されています.

f:id:lyncs:20171215230905p:plain

この図は, トポロジーと呼ばれるもので, 量子もつれ(CNOTゲート)に関する制限が書かれています. 読み方としては, 丸に囲まれたQ0からQ4が使用可能な量子ビットを表しています. 先ほど述べたようにqx4は5量子ビット使用可能なので, Q0,1,2,3,4の5つが表示されています. 各矢印は, 量子もつれ状態を生成可能(CNOTゲートを使用可能)であることを示しています. 矢印の方向は,コントロール量子ビット→ターゲット量子ビットになっています. なので, 例えばQ2の量子ビットは, CNOTゲートを用いるとき, Q3をコントロール量子ビットとしてターゲット量子ビットになることができ, また自身をコントロール量子ビットとしてQ0,1,4をターゲット量子ビットとすることができます.

IBMQはZ測定のみに対応していますが,ブロッホ球の回転操作を行うことによってX測定,Y測定に近い測定を行うことができます.これは,以下のような量子回路で実行できます. ただし,それぞれの操作によるノイズの発生があるので, より厳密な議論では注意が必要です.

f:id:lyncs:20171215232703p:plain

IBM Qを動かしてみる

実際にIBM qx4で動かしてみましょう. 現在の量子コンピュータでは計算を行うごとにノイズが発生しますが, それがどれだけ計算に影響を与えているか知ることができます. ノイズは, 量子ビットが物理的に存在するにあたって完全に閉じた系にすることが難しいことに起因しています. (量子コンピュータ外部からの振動や電磁波, 観測機器の故障や精度限界など様々な要因が考えられます.)

IBM Qの操作

IBM Qは, 量子回路の読み方がわかれば, 極めて簡単に量子ビットを操作することができるようなGUIが実装されています. ここまでの説明で量子回路の基礎は抑えたので, 早速動かしてみましょう.

まず, https://www.research.ibm.com/ibm-q/をwebブラウザで開いてください. すると以下のような画面が出てきます. f:id:lyncs:20171217004901p:plain

開けたら, 右側のExperimentに入り,"Start experimenting with a quantum computer"をクリックして開いてください. 次に, ページの右上にある"Sign In"をクリックしてください.メールアドレスを登録するか,IBM Id, Linkedin, Github, Google, Twitterなどのアカウントでログインができます.

Sign inするとCommunityのForumが表示されるので, 右上のメニューの"composer"を選択してください. 先ほど少し紹介したトポロジーが表示されるので下に行くと, 楽譜のようなものがあります. これが量子回路になっており, 右側に見える量子ゲートをマウスでドラッグ&ドロップすることで行いたい操作を設定できます. なお, 楽譜に似ているのでこの量子回路を"Composer"と称することがあります.

f:id:lyncs:20171215225941p:plain

実行したい回路の作成が終わったら, 回路の右上のRunかSimulateをクリックしましょう.

Runを押すと実際の量子コンピュータを動かすことができ, Simulateをクリックすると, 古典コンピュータで量子コンピュータをシミュレートしたものを動かすことができます. 古典コンピュータによるシミュレータは, 実際の量子コンピュータと違ってノイズがほぼ全くない理想的な状態の計算を行うことができます(このことをフィデリティがほぼ1である、と呼称します). なお,現状の技術では量子ビット数が非常に少ないので古典コンピュータによるシミュレートが可能ですが, 今後量子ビット数が増えるにつれ, 古典コンピュータによるシミュレートが不可能になる(処理が追いつかなくなる)ことが明確に予測されています.

"Run"すると, 数時間から数日ほどしてから計算結果(量子の観測結果)がメールで届きます. ただし, すでに同じ回路を実行した人がいた場合, 過去の観測データを待たずに見ることもできます.また, 右上の”save”から自分の作った量子回路を保存することができます.

最近のニュース

IBMは, 2017年11月, 20量子ビット量子コンピュータの作成に成功したと発表しました. (12/15に利用開始)また、それを活用した50量子ビットのチップのプロトタイプも完成しているようです. 20量子ビットのものは, IBMQネットワークのメンバー(慶應義塾など)や一部企業はクラウド利用可能です. 20量子ビットのものはトポロジーが公開されていますが, 双方向のトポロジーになっており, 大変利便性が向上していると言えるでしょう.

最後に

最後まで読んで頂き, ありがとうございました. ご意見, ご指摘などございましたらお気軽にツイッター(@shin_tsujido)までご連絡下さい.

|つじしん〉 (@shin_tsujido) | Twitter

今回は誌面の都合もあり, 量子回路を用いたアルゴリズムなどを紹介することはできませんでしたが, 次回以降アップデートしていきたいと思っております. 【12/23追記】 トポロジーのことをトモグラフィーと誤記していたため修正。 【12/25追記】 アダマールゲート、位相シフトゲートの式に符号の欠落が見られたため修正

参考文献


  1. 石坂 智, 小川 朋宏, 河内 亮周, 木村 元, 林 正人 『量子情報科学入門』(2012)

  2. ロイター『量子コンピューター、来年度予算に32億円 米国先行に危機感』 (2017)

  3. 古田 彩 https://twitter.com/ayafuruta/status/924051215314403328 (2017)

  4. 中山 茂 『クラウド量子計算入門 IBMの量子シミュレーションと量子コンピュータ』(2016)

三田祭告知・会誌の発行について

慶應義塾大学三田キャンパスのお祭り、三田祭が近づいてきました。

Twitterの方でも順次告知しておりますが、今年もLYNCSは三田祭に参加致します。 出展内容は以下の通りです。

  • 自作ドームでのプラネタリウム展示・生解説
  • 天体写真ポストカードの販売
  • 会誌「Escape Velocity」無料頒布

Escape Velocity

LYNCS初の試みとして、各部門からの寄稿をまとめた会誌を発行します。 団体全体として印刷物を公開するのは初めてであり、混乱も多々ありましたが、会員の協力で三田祭合わせでの発行が実現しました。

以下、掲載した記事の一覧です。

  1. 代表挨拶
  2. 量子情報科学序論~IBM Qを動かして学ぶ量子コンピュータ
  3. LYNCS理学研究本部 線型代数ゼミノート
  4. 2017種子島ロケットコンテスト
  5. 天文研究本部活動紹介
  6. LYNCS会員の機材紹介
  7. 星景・天体写真の撮り方
  8. 望遠鏡の紹介・扱い方
  9. LYNCS会員入会理由語り

希望される方には無料でお配りしますので、お近くの会員にお声掛けください。

皆様のご来場心よりお待ちしています。

(広報・И)

第13回能代宇宙イベント ~結果と3年間の感想~

f:id:lyncs:20170901074813j:plain 皆様お久しぶりです.代表のあっきーです.
先月8月17日~21日で第13回能代宇宙イベントのCanSat部門に出場してきました.
Twitterで実況や感想ツイートを行ってきましたが,このブログで結果をご報告させていただきます.

続きを読む

mbed / Raspberry Pi 用のBSch3V用部品データ (Win/Mac対応)

回路図エディタ「BSch3V」を使用していると、意外と最近のマイコンボードの部品データがなかったり、あったとしてもリンクが消滅しているといった事態に悩まされます。ということで作りました。

最近のマイコンボードといっても無限にありますので、とりあえず弊団体で使用しているmbedの主要なボード(LPC1768など)やRaspberry PiのGPIOピンをデータ化しています。もしご要望などありましたらコメント頂けると対応できるかもしれません。

また、Mac版のQt-BSch3V Modifiedでも利用できることを確認しております。

ダウンロード

BSch3V_mbed_raspberrypi.zip - Google ドライブ

(ryo-a)

JSONファイルを定期的に取得・保存したい (Node.js)

個人タスクで発生した備忘録です。

JSONを採取したい

東京メトロのオープンデータでは、JSON形式で運行情報などを取得できます。 実際の運行情報の事例を収集して解析の対象とするために簡単なスクリプトを書きました。

使用するもの

  • Node.js
  • date-utils
  • cheerio-httpcli
    • DOM解析するわけではないですが、単にエンコードとかの取り扱いが楽になるので。

コード

require('date-utils');
const cheerio = require('cheerio-httpcli');
const fs = require('fs');

var datetime = new Date().toFormat('YYYY-MM-DD-HH24_MI_SS');
var filename = datetime + '.json';
var savepath = './saved_json/' + filename;

cheerio.fetch('***input URL here***', 'utf-8', function (err, $, res, body) {
    //今回はダイヤ乱れなどの情報がある場合のみJSONを保存したいので
    if ($.html().search(/のため/) != -1){ 
        fs.writeFileSync(savepath, $.html(), 'utf8');
    }   
});

定期実行

言わずもがな、cronに登録します。 筆者はラズパイで走らせています。ラズパイが1台あれば気軽にcron回せるのでおすすめです。

(ryo-a)

MediaWiki「サムネイルの作成エラー: 12.5 MPよりも大きな寸法のファイル」の表示を解決する

問題

MediaWikiはアップロードされた画像に対して自動でサムネイル画像を作成し、ページ内ではそのサムネイル画像を表示しています。

しかし、一定のサイズ(ファイルサイズではなく解像度)を超えた画像がアップロードされた場合、以下のようなエラーを返します。 f:id:lyncs:20170618125307p:plain なお、このエラーが出ても画像はしっかりとアップロードされています。サムネイルが生成されないだけです。

解決策

初期値では解像度の上限は12.5MP(3500 x 3500ピクセル)となっていますので、単にこの値を引き上げてやれば大丈夫です。
LocalSettings.php$wgMaxImageArea の値を設定しましょう。 Manual:$wgMaxImageArea - MediaWiki

4.9MP(7000x7000px)の場合こんな感じです。

$wgMaxImageArea = 4.9e7;

通常、LocalSettings.phpの初期値では$wgMaxImageAreaの項目がないはずなので、上記の内容を最終行に追加してあげればOKです。

多くの人が慣れ親しんだ◯x◯ピクセルという数値ではなく、ピクセル数で数値指定する必要があるので、参考のために上記MediaWikiマニュアルにはいくつかの例が記載さています。

  • 25 million pixels or 5000×5000: 2.5e7
  • 36 million pixels or 6000×6000: 3.6e7
  • 49 million pixels or 7000×7000: 4.9e7
  • 64 million pixels or 8000×8000: 6.4e7
  • 72 million pixels or 9000×9000: 7.2e7
  • 100 million pixels or 10000×10000: 10e7

その他

設定ファイルを変更すれば既存の画像もサムネイルが作成されるので、アップロードし直す必要はありません。

(LYNCSwiki運用担当 ゆん)

Slackの古くなったファイルを自動で削除してみた

概要

Slack(無料プラン)の容量制限をオーバーしないために、特定チャンネルの、ある日数より古いファイルを削除するbotを作成した記録です。 GAS(Google Apps Script)で毎日タイマー起動するように設定し、ファイル容量を管理するコストを大幅に抑えることができます。

対象読者

  • Slackを普段使っている方
  • JavaScriptを少し使ったことがある方

ねらい

LYNCSでは、2015年11月ごろからSlackをメインの連絡ツールとして利用しています。 Slackは企業向けのチャットサービスではありますが、無料プランでもかなり便利に使えるのが嬉しいですよね。

しかし、少人数で数ヶ月ほどの利用ならいざ知らず、人数が増え長く使い続けるとある問題にぶち当たります。 ファイルストレージの5GB容量制限です。

f:id:lyncs:20170604130347p:plain
LYNCS SlackチームのStatistics

画像は現在のLYNCSチームの統計ですが、数千のファイルが存在していることがわかります。 何も対策せずに使っていると、「5GB超えてるぞ金払えコラ(意訳)」と怒られることもしばしばでした。 しかし、Slack有料プランの価格設定は企業向けとなっており、学生団体にとってはおいそれと払える額ではありません。

従っていらないファイルを削除し、無料プランの制限内で使うしかないことになります。 でも、Slackにはファイルの一括削除機能がなく、ポチポチ手作業で消すことしかできません。 「ファイルを選ぶ→削除ボタンを押す→削除の確認ボタンを押す」を数百回も繰り返すのはさすがに耐えがたい。

f:id:lyncs:20170604130316p:plain
ファイル削除の確認メッセージ

そこで、SlackのWeb APIを利用して古いファイルを消す仕組みを作ることにしました。

実行環境

GASを知らない人のために簡単に説明すると、「GoogleのサーバーでJavaScriptを動かせる夢のようなサービス」です。 一応時間制限はあるものの、無料で24時間いつでもJavaScriptが動きます。 サーバーを持たなくても、Googleアカウントさえあれば簡単なBotが作れてしまうのです。

GASでSlack向けのBotを作った事例は既に多数あって、ライブラリも存在しています。 GASの具体的な操作などについてはあまり書かないので、以下の記事などをご覧ください。

Slack Web APIを使ってみる

Slackには、とても便利なWeb APIが存在します。 コマンド操作は敷居が高いと思うかもしれませんが、実はWeb上に素晴らしいテスト環境が用意されているので全く心配いりません。

API Methodsページに使えるメソッドの一覧があり、それぞれのページで詳細を閲覧できます。 実行するにはTokenを持っている必要があるので、発行ページで作っておきましょう。

例えば、files.listの動作を試してみます。 “Tester"と書かれたタブでオプション(token以外は空欄でも可)を入力してTest Methodをクリックすると、結果が下のテキストエリアに出てきます。

f:id:lyncs:20170604130311p:plain
APIテスター

親切にURLまで表示してくれています。 これにアクセスすれば自分のチームのファイル一覧が手に入るというわけです。 さて、リスト先頭の"image.png"を削除してみましょう。

f:id:lyncs:20170604130334p:plain
files.listの実行結果

ファイルの削除にはfiles.deleteを使います。 ファイルの"id"が必要になるので、files.listで出てきたものをコピペします。

f:id:lyncs:20170604130327p:plain
files.deleteの実行結果

"ok": trueとしか返ってきませんが、これで削除が完了しています。 とっても手軽ですね。

なお、削除に限らずSlackのデータを変更するメソッドをテストすると実際に変更されてしまうので、試す場合は十分気をつけてください!!!!!

削除を行うプログラムの流れ

APIの使い方が分かったので、一連の流れをプログラムにしていきます。 基本的には

  1. ファイル一覧を取得する(files.list)
  2. 見つけたファイルの数だけファイル削除を繰り返す(files.delete)

だけですが、いくつか問題があるので実際はもう少し複雑です。

不要なファイルを絞り込む

チームのファイルを全部消してしまっては、必要なものまで消えてしまい混乱が起こるので、不要なものだけに絞ります。

幸い、LYNCSのSlackは業務系のチャンネル(#generalなど)と雑談系のチャンネル(#randomなど)が分かれているので、雑談系にあがったファイルだけを削除すればよさそうです。 それでも、写真を貼った瞬間に消されては雑談にならないので、特定日数以前のファイルだけを対象にします。

チャンネルを指定する

特定チャンネルのファイル一覧を取り出すには、files.list"channel"を指定します。 チャンネルの指定はファイルと同様IDで行います。 チャンネルのIDなんて普通は覚えていないので、これもAPIで調べることにしますが、少し面倒です。

Slackのチャンネルには、公開(Public)のものと非公開(Private)のものがあります。 APIでは前者はchannel・後者はgroupという扱いで、メソッドを使い分けねばなりません。 そこで、チャンネルの名称からIDを得る方法はこうなります:

  1. チャンネル一覧を取得する(channels.list)
  2. 探している名称と一致するチャンネルがあるかどうか調べる
  3. 一致しなかったら、グループ一覧を取得する(groups.list)
  4. 探している名称と一致するグループがあるかどうか調べる

以下はchannelを探す関数です。 groupの方も流れは全く同じなので省略します。 UrlFetchApp.fetch()はGASの機能で、渡したURLにアクセスしてくれるものです。

結果がJSONで送られてくるので、パースしてsomeループで名称が一致するまで調べます。

/* チャンネル名を検索してIDを取得 */
function channelNameToId(name) {
  var res = UrlFetchApp.fetch('https://slack.com/api/channels.list?token=' + SLACK_ACCESS_TOKEN);
  var channelsList=JSON.parse(res.getContentText());
  var foundChannelsId = '';
  var isFound = channelsList.channels.some(function(channels){
    if (channels.name.match(name)){
      foundChannelsId = channels.id;
      return true;
    } 
  });
  return foundChannelsId;
}

経過日数を指定する

files.listts_toオプションを使うと、ある時刻までのファイルだけを取得できます。 この時刻はUNIX timeで指定しなければなりません。 そこで、経過日数からts_toに変換する関数を作りました。

JavaScriptではDate.getTime()で現在時刻をUNIX時間で取得できます。 これはミリ秒単位なので1000で割る必要があるのに注意です。 あとは、日数を秒数に換算して引き算するだけですね。

function elapsedDaysToUnixTime(days){  
  var date = new Date();
  var now = Math.floor(date.getTime()/ 1000); // unixtime[sec]
  return now - 8.64e4 * days + '' // 8.64e4[sec] = 1[day] 文字列じゃないと動かないので型変換している
}

ファイル削除プログラム

事前準備

スクリプトのプロパティ

APIのtokenは、流出するとチームに好き勝手されてしまうので扱いに注意が必要です。 外部の人に見せないものでも、コードに直接書くのは考えものです。 幸い、GASには「スクリプトのプロパティ」という任意の値を保存しておける機能があるので、そこにtokenなどを格納することにします。

取得は次のようにすれば可能です。

var SLACK_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty("TOKEN");

また、削除するファイルを探すチャンネルもOLDFILEというプロパティにカンマ区切りで入力することにします。 これで、ソースコードを公開してもどんなチャンネルがあるかバレません。

f:id:lyncs:20170604130247p:plain
スクリプトのプロパティの入力例

APIを叩く

SlackのAPIを使うには、各種メソッドを叩く仕組みが必要です。 GASにはsoundTricker/SlackAppというライブラリがあり、これをインポートするだけでAPIが使えちゃいます。 ただ、最近これを使うより自前で書いたものの方がなぜか数倍速いのに気づいてしまったので、自前実装に切り替えました。

自分の環境で動けばいいので、かなり適当に書いてます。 他の環境でライブラリをお使いの方は、適宜読み替えてください。

例:

/* ファイルのリスト */
function filesList(data){
  var params = {
    'token': SLACK_ACCESS_TOKEN,
    'channel': data.channel,
    'ts_to': data.ts_to,
    'count': data.count
  }
  var options = {
    'method': 'POST',
    'payload': params
  }
  var res = UrlFetchApp.fetch('https://slack.com/api/files.list',options);
  return JSON.parse(res.getContentText());
}

ファイルを削除するスクリプト

まずはコードを。

/* 雑談チャンネル・グループの名称を検索して古いファイルを削除 */
function oldFileExecutioner(){
  const targetChannels = PropertiesService.getScriptProperties().getProperty("OLDFILE").split(",");    
  targetChannels.forEach(deleteOldFile);
}

/* 指定チャンネル内・特定日数より以前のファイルを削除 */
function deleteOldFile(channelName) {
  const days = 21;  // 遡る日数(ユーザが指定)
  
  var channelId = channelNameToId(channelName) || groupNameToId(channelName);
  if(!channelId){
    Logger.log('Not found "' + channelName + '". Skipping.');
    return -1; //見つからなければ終了
  }
  Logger.log('Found "' + channelName + '"(' + channelId + ')');
  var options = {
    channel: channelId,
    ts_to: elapsedDaysToUnixTime(days),
    count: 1000
  }
  filesList(options).files.forEach(function(val){
    data = filesDelete(val.id);
    if (data.error) Logger.log('  Failed to delete file ' + val.name + ' Error: ' + data.error);
    else Logger.log('  Deleted file "' + val.name + '"(' + val.id + ')');
  });
}

oldFileExecutioner()でプロパティから取得したチャンネル名それぞれについて、deleteOldFile(channelName)を実行しています。

チャンネルはchannels.listgroups.listの両方から探して、どちらでもなければログにエラーメッセージを残して終了します。 見つけたらchannelts_toを指定してfiles.listを叩くのですが、実はこれだけではファイル100件までしか取得できません。 そこで、countオプションに適当に大きめの値を入れておきます。

あとは各ファイルのIDをfiles.deleteに放り込むだけです。 実在するIDを入れるので普通は成功しますが、一応エラーが出たら内容をログに記録するようにしてあります。

トリガーの設定

GASには、指定したタイミングで関数を自動実行する「トリガー」という機能があります。 LYNCSでは、oldFileExecutioner()が毎日昼頃に実行されるように設定しています。 使い方はググればたくさん記事が出てくるので省略させてください。

実行例

チームのSlackでやると危ないので、テスト用の一人Slackにいろんなファイルをアップロードした上でoldFileExecutioner()を実行してみます。

f:id:lyncs:20170604130338p:plain
テスト用にアップロードしたファイルたち

スクリプトのプロパティにはtokenと、巡回してほしいチャンネルを指定しますが、わざと存在しないチャンネル名も混ぜておきます。

プロパティ
TOKEN {チームのtoken}
OLDFILE random,ch1,ch2

oldFileExecutioner()を実行して数秒待つとログを閲覧できます。

f:id:lyncs:20170604130306p:plain
実行後のログ

無事削除してくれたようです。 ch2というチャンネルは存在しないのでエラーになっています。 Slackの方を見てみるとファイルが減っていますが、#generalに上がっていたファイルは残っています。

f:id:lyncs:20170604130342p:plain
削除の対象外のファイル

展望

アーカイブ済みのチャンネルのファイルを削除する

channels.listis_archivedという項目があるので、アーカイブ済みなら中のファイルを消す、といったこともできます。

特定タイプのファイルだけを削除する

Slackでは、作成したスニペットやポストもファイル扱いです。 これらは文章データでストレージ容量にはほとんど影響ないのですが、自動削除の対象となってしまいます。

files.listで取得するファイルオブジェクトのプロパティにfiletypeという項目がある(一覧)ので、これを見て分類すれば、ファイルの種類によって動作を変えられそうです。

また、ファイルオブジェクトのsizeを見ればサイズがわかるので、一定サイズを超えていたら削除、という方針でもいいかもしれません。

(Webシステム担当 И)