算術演算
足し算回路
任意の数を足す
これまでは、+1 や -1 のように定数を足す回路を見てきました。 これだけではほとんど何もできずつまらないので、任意の数を足し合わせる回路を考えてみましょう。
足し算というと \(a + b = c\) という式をすぐに思い付きますが、これは可逆な回路として実装できません。 なぜかと言うと、 \(a\) と \(b\) から \(c\) を求めることはできても、逆に \(c\) から \(a\) と \(b\) を一意に求めることができないからです。 つまり足し算 \(a + b = c\) に逆演算が存在しないことになり、よって可逆な回路としては実装できない (= 重ね合わせをそのまま出力できない) ことになります。
そのかわりに、\(a \mathrel{+}= b\) という回路を実装します。 これはプログラミングによく出てくる演算子で、\(a\) に \(a + b\) の結果を代入することを意味します。 もし \(a\) を元の値に戻したくなった場合、\(a \mathrel{-}= b\) (\(a\) に \(a - b\) の結果を代入) という逆演算が存在するので、逆回路も問題なく実装できそうです。
足し算回路
以下が \(a \mathrel{+}= b\) を実装した量子回路です。 \(a\) に 1 と 5 を重ね合わせた値をセットし、\(b\) には 3 をセットします。 \(a \mathrel{+}= b\) を実行すると \(a\) には 4 と 8 を重ね合わせた値が残ります。 \(b\) は変化しません。
インクリメントやデクリメント回路と大きく違う点は、b をセットするブロック (\(b = 3\)) が存在することです。 \(a\) の値は 7 量子ビットの下位 4 ビット、\(b\) の値は上位 3 ビットを使って表されていることに注意してください。 ここで \(b\) の値は 3 (二進数で 011) にセットされており、また計算中は \(b\) の値はずっと変わらず 011 のままなので、\(b = 3\) のブロック以降の円表示では、上位 3 ビットが必ず 011 となります。
このため、計算結果の見方には注意が必要です。 計算結果の \(a\) の値は 4 と 8 (二進数で 0100 と 1000) の重ね合わせになっているはずですが、円表示で見ると 52 と 56 (二進数で 0110100 と 0111000) になっています。 これは計算結果に \(b\) の値 3 (二進数で 011) もあわせて表示されているためで、これが上位 3 ビットなので二進数では 0110000 (十進数で 48) が足し合わされています。 そこで \(a\) の値だけを読み取るには上位 3 ビットの 011 を無視するか、十進数で 48 を引いてやる必要があります。
a += b 回路の仕組み
この回路はやや複雑に見えますが、よく見るとインクリメント回路の各ステップに
- \(b\) のビット 0 が 1 なら、\(a\) を 1 インクリメントする (= ビット 0 をインクリメントする)
- \(b\) のビット 1 が 1 なら、\(a\) のビット 1 をインクリメントする
- \(b\) のビット 2 が 1 なら、\(a\) のビット 2 をインクリメントする
これは、ビットごとに 2 進数の足し算を行っていることになり、結果として \(a \mathrel{+}= b\) が計算できます。
重ね合わせに重ね合わせを足す
先ほどの例では \(b\) に 3 をセットしていましたが、これを重ね合わせにするとどうなるでしょうか? たとえば \(a\) を 1 と 5 の重ね合わせ、\(b\) を 2 と 6 の組合わせにして足すと、和はどんな重ね合わせになるでしょう?
1 と 5 の重ね合わせ + 2 と 6 の重ね合わせ = ???
上の回路の実行結果を見ると、35 (二進数で 0100011)、39 (二進数で 0100111)、103 (二進数で 1100111)、107 (二進数で 1101011) の重ね合わせが出力されています。 ここで \(b\) の値は 2 と 6 の重ね合わせ (それぞれ二進数で 010 と 110) なので、これら上位 3 ビットを無視すると、 出力結果は 0011, 0111, 0111, 1011 であり、ダブった値 0111 を除くと 3 通りになります。 これは十進数で 3 (= 1 + 2), 7 (= 1 + 6 または 5 + 2), 11 (= 5 + 6) となり、重ね合わせの和がすべての通りについて出ていることが分かります。