こんにちは、なんか意外と教育や開発の現場で困ったことがあるらしいのですが、それに対応したソルバーや解決がないこともあります。そうした新しいツールをどんどん作っていきましょう。
今回の相談は、
Lattice Folding Simulation of Peptide by Quantum Computation, 2023
https://blueqat.com/bqresearch/7fc45c52-5b97-4386-9cde-f5d61a0b9b17
学生さんの卒論ですが、たんぱく質折りたたみ問題ですが、既存のQUBOソルバーでとくと、せっかくのHOBOと呼ばれる高次の式をわざわざQUBOの二次に変換する必要があるようです。
変換するとものすごく計算が面倒になりやらなくて良い作業がものすごい増えます。
量子コンピュータのシミュレーションでQAOAなどは時間発展演算子の変換があるので分解不要ですが、なぜか過去の呪縛に囚われてQUBO変換しないといけないという意識がある人も多いみたいで、HOBOのまま解いてみることを提案しました。
QUBOの場合は、qubo matrixを利用して、ベクトルxとmatrix Qを利用して
C=xTQxC = x^T Q xC=xTQx
で解けますが、なかなか高次元ではイメージがつかないようです。行列表記をやめて一般化をしたほうがいいと思います。
C=∑xxQC=\sum x x QC=∑xxQ
このようにテンソルネットワーク表記をすることで、拡張を簡単にできます。こうすることで、これまでQUBOとして使っていたような理論を簡単に高次に展開できます。元の式は例えば最大で5次の項がある場合、
C=∑xxxxxHC = \sum x x x x x HC=∑xxxxxH
とするだけです。HOBOは正確にはmatrixではなく、tensorなので、今後はHOBO tensorと呼びます。
HOBOにテンソルを利用する場合、今後の発展としてさまざまなことが考えられますが、まずはシンプルに実装方法を見てみます。HOBOのテンソルの作り方はプレプリントに載せました。
Tensor Network Based HOBO Solver, July 2024
https://blueqat.com/bqresearch/2e6a2fb2-3607-4bd7-8696-13f8658aec35
例)3次の場合。PyTorch
import torch
T = torch.tensor([
[[-10., 1, -4], [0, 0, -1], [0, 0, 0]],
[[0, 0, 0], [0, 7, 8], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
])
x = torch.tensor([1.,0,1], dtype=torch.float32)
cost = torch.einsum('i,j,k,ijk->', x,x,x,T)
cost.item()
テンソルを準備して、ベクトルを準備して、縮約すればOKです。
例)3次の場合。Sympy
シンボルを使いたいこともあると思います。
import sympy as sp
Define the symbolic variables
x0, x1, x2 = sp.symbols('x0 x1 x2')
Define the tensor T as a symbolic 3D array
T = sp.Array([
[[-10, 1, -4], [0, 0, -1], [0, 0, 0]],
[[0, 0, 0], [0, 7, 8], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
])
Define the symbolic vector x
x = sp.Array([x0, x1, x2])
Calculate the cost using Einstein summation
cost = sp.tensorcontraction(sp.tensorproduct(T, x, x, x), (0, 3), (1, 4), (2, 5))
cost_simplified = sp.simplify(cost)
Print the result
cost_simplified
こんな感じです。
3次までは想像できるがそれ以上が難しいという意見もありますが、4次以降も特に普通にできます。
例)4次の計算。PyTorch
import torch
3次元テンソルの定義
T = torch.tensor([
[[[-10., 0., 0.],
[ 1., 0., 0.],
[ -4., 0., 0.]],
[[ 0., 0., 0.],
[ 0., 0., 0.],
[ -1., 0., 0.]],
[[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]],
\[\[\[ 0., 0., 0.\],
\[ 0., 0., 0.\],
\[ 0., 0., 0.\]\],
\[\[ 0., 0., 0.\],
\[ 7., 0., 0.\],
\[ 8., 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., 0.\],
\[ 0., 0., 0.\],
\[ 0., 0., 0.\]\]\]\])
ベクトル x の定義
x = torch.tensor([1., 0, 1], dtype=torch.float32)
einsum 演算
cost = torch.einsum('i,j,k,l,ijkl->', x, x, x, x, T)
コストの表示
print(cost.item())
ちなみにQUBOは単純に上三角行列と対角成分を調整すれば良かったですがHOBO tensorはもっと複雑です。定式化についてもプレプリント中には作り方は書いてますが、効率的な作り方や実装の方法などは今後コミュニティで提案していかないといけないですね。
HOBO tensorについても中身はかなり無駄が多いです。各種テンソルネットワークの技術を使って効率的な計算ができるかどうかも研究対象として楽しそうですね。
今の所Torch Tytanに実装しようかなと思っています。
https://github.com/tytansdk/tytan
以上です。