【欠陥あり】イジングモデルで作るQRコード【強引】
はじめに
1年ほど前にQRコードについてのポッドキャストを聴き、それ以降の人生ではたびたびQRコードについて考えることがありました。そして、学部時代に学び最近になってもう一度出てきたイジングモデルをぼーっと眺めていた時に、「イジングモデルを使ってQRコード作れるんじゃね?」と思ったので作ってみました。
物理とPython、そしてQRコードを浅く知っているZenn初投稿者なので、改善点があれば優しく教えてください🥳
結論
結果としてはうまく読み込めるQRコードを生成することができなかった。
イジングモデルについて理解したこと⚡
概要
統計物理学において磁性体などを記述するために用いられる格子模型。格子点上に配置されたスピンが相互作用することで全体としてどのような振る舞いを見せるかを解析するモデル。系全体が低エネルギー状態に向かうようになっている。
基本的な要素:
- スピン: 各格子点には、上向き(+1)または下向き(-1)のいずれかの状態をとるスピンが存在。
- 相互作用: 隣り合うスピン同士は相互作用し、同じ方向を向いているとエネルギーが低くなり、逆向きだとエネルギーが高くなる。
- 温度: 系の温度は、スピンの向きがランダムに反転する度合いを表す。温度が高いほど、スピンの向きはランダムになり、低いほど、スピンはエネルギーの低い状態、つまり同じ方向を向きやすくなる。
エネルギーの計算方法
-
: システム全体のエネルギーE -
: 隣接スピン間の相互作用の強さを表す結合定数J -
,s_i : i番目とj番目のサイトのスピン(+1または-1の値をとる)s_j -
: 外部磁場の強さh -
: 最近接サイトのペアについての和\sum_{\langle i,j \rangle} -
: すべてのサイトについての和\sum_i
メトロポリス法
イジングモデルの振る舞いを解析する手法の一つに、メトロポリス法を用いたモンテカルロシミュレーションがある。
メトロポリス法のアルゴリズム:
- ランダムに格子点を選び、そのスピンを反転させる。
- スピン反転前後のエネルギー差
を計算する。\Delta E -
ならば、スピン反転を受け入れる。\Delta E < 0 -
ならば、確率\Delta E > 0 でスピン反転を受け入れる。(e^{-\frac{\Delta E}{k_B T}} はボルツマン定数、k_B は温度)T - 上記の手順を繰り返し行うことで、系の平衡状態をシミュレートする。
メトロポリス法を用いることで、様々な温度や外部磁場におけるイジングモデルの性質を調べることができる。
今回のコードでは外部磁場については考えてはいません(面倒臭かった)
QRコードについて理解したこと👁️🗨️
QRコードのモデルとバージョン:
- モデル: QRコードには、モデル1とモデル2の2つのモデルがある。モデル1は初期のバージョンで、モデル2はエラー訂正能力やデータ容量が向上したバージョン。
- バージョン: QRコードのバージョンは、データ容量とコードのサイズを表す指標。バージョン1は21x21セル、バージョン40は177x177セルまで、バージョンが上がるにつれてセル数が増加し、より多くのデータを格納できる。
QRコード必要4要素:
- 位置検出パターン❤️: QRコードの3つの角に配置され、QRコードの位置と向きを認識するために使用。白セルと黒セルの比率が1:1:3:1:1の正方形。
- アライメントパターン🌲: モデル2のQRコードでは必須。位置検出パターン以外の場所に配置され、QRコードの歪みを補正するために使用。右下から斜めに7マス目を中心に白セルと黒セルの比率が1:1:1の正方形。
- タイミングパターン🌀: 位置検出パターンを結ぶように配置され、QRコードのサイズを認識するために使用。位置検出パターンの内側を繋ぐように白黒を交互に配置。
- クワイエットゾーン: 2次元コードの周りの空白。4セル必要。
実装
コードの読みやすさとかは考えられていないので少し冗長かも。
1. 初期化🏖️: Model,Versionを入力しなければただのイジングモデルとして使えるようにする。Modelが入力されたらinitiate()を実行。QRコードとして必須な部分はset()で管理され、反転されないようにする。
class Ising:
def __init__(self, L, T, Model=0, Version=None):
self.L = L
if Version:
self.L = 17 + 4 * Version
self.T = T
self.spins = np.random.choice([-1, 1], size=(self.L, self.L))
self.essence = set()
self.model = Model
self.version = Version
if Model:
self.initiate()
def initiate(self):
for i in range(3):
self.make_eye(i)
for i in range(2):
self.make_timingpatern(i)
for i in range(3):
self.make_separater(i)
if self.model == 2:
self.make_alignment()
- 位置検出パターンの作成❤️: 3つの位置検出パターンをそれぞれ配置する。パターンの見た目が👀ぽかったので関数名はeyeにした。
def make_eye(self, n):
if n == 0:
x, y = 0, 0
elif n == 1:
x, y = 0, self.L - 7
elif n == 2:
x, y = self.L - 7, 0
for i in range(x, x + 7):
for j in range(y, y + 7):
self.essence.add((i, j))
self.spins[i, j] = -1
for i in range(x + 1, x + 6):
for j in range(y + 1, y + 6):
self.spins[i, j] = 1
for i in range(x + 2, x + 5):
for j in range(y + 2, y + 5):
self.spins[i, j] = -1
- アライメントパターン🌲: そのまま
def make_alignment(self):
x, y = self.L - 9, self.L - 9
for i in range(5):
for j in range(5):
self.essence.add((x + i, y + j))
self.spins[x + i, y + j] = -1
for i in range(3):
for j in range(3):
self.spins[x + i + 1, y + j + 1] = 1
self.spins[x + 2, y + 2] = -1
- タイミングパターン🌀: そのまま
def make_timingpatern(self, n):
if n == 0:
x, y = 7, 6
for i in range(x, x + self.L - 14):
self.essence.add((i, y))
if i % 2 == 0:
self.spins[i, y] = -1
else:
self.spins[i, y] = 1
elif n == 1:
x, y = 6, 7
for i in range(y, y + self.L - 14):
self.essence.add((x, i))
if i % 2 == 0:
self.spins[x, i] = -1
else:
self.spins[x, i] = 1
- 電子を1つ選択し、反転させる💞: ランダムに格子点を1つ選択する。その際選択した格子点がQRコードのエッセンスであった場合反転操作はせずにそのままにする。
def choice(self):
i, j = np.random.randint(self.L, size=2)
if (i, j) in self.essence:
return
now_energy = self.calc_energy(i, j)
self.spins[i, j] *= -1
new_energy = self.calc_energy(i, j)
dE = new_energy - now_energy
if dE < 0:
return
if np.random.rand() < np.exp(-dE / self.T):
return
self.spins[i, j] *= -1
def calc_energy(self, i, j):
energy = 0
for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
energy -= (
self.spins[i, j] * self.spins[(i + di) % self.L, (j + dj) % self.L]
)
return energy
生成されたQRコード🏭
実際に出力された画像は上に示したQRコードの4つのエッセンスを保ちながら生成されていることがわかる。(読み込めないけど)
モデル2,バージョン3(読み込めないやつ)
温度をいい感じにすると臨界状態を揺らぎ続けるのでいつかいい感じのQRコードが生成されるのですかne?🍿
もちろん温度を下げると巨大なクラスターが生成され、秩序的❓️なQRコードが生成されるのがわかる。🙉
おわりに
今回のコードだとうまくイジングモデルからQRコードを生成することができなかったので、QRコード、Pythonに詳しいお兄様お姉様方がいらっしゃいましいたら、こうした方がいいよなど指摘していただけると喜びます😌
参考にしたサイト
Discussion