nano_exit

基礎的なことこそ、簡単な例が必要だと思うのです。

ブール領域を用いたエンタングルメントの説明。

ブール領域  \mathbb{B}:=\{0, 1\} の直積の部分集合として、以下のものを考える。

\mathcal{C} := \{ (0, 0), (1, 1) \} \subset \mathbb{B} \times \mathbb{B}

これは、次の様に書くことが出来ない。

\mathcal{C} \neq \{ (b, b') | b \in \mathbb{B}, b' \in \mathbb{B} \} = \mathbb{B} \times \mathbb{B}
これを、ここでは「分離不可能」と言うことにする。

一方で、次のようなものは分離可能である。

\mathcal{C}_1 := \{ (0, 0) \}
\\
\mathcal{C}_2 := \{ (1, 1) \}
\\
\mathcal{C}_3 := \{ (0, 1) \}
\\
\mathcal{C}_4 := \{ (1, 0) \}
\\
\mathcal{C}_5 := \{ ( 0, 0 ), ( 0, 1 ), ( 1, 0 ), ( 1, 1 ) \} = \mathbb{B} \times \mathbb{B}

よって、部分集合を取れば何でもよい訳ではなく、 \mathcal{C} は特殊な状態であることが分かる。

参考文献:圏論量子力学入門

追記(2021/03/28)
上の定義で言うと、分離不可能な部分集合は結構ある。

\mathcal{C}^c := \{ (0, 1), (1,0) \}
\\
\mathcal{C}_1^c := \{ (0, 1), (1,0), (1, 1) \}
\\
\mathcal{C}_2^c := \{ (0, 0), (0, 1), (1, 0) \}
\\
\mathcal{C}_3^c := \{ (0, 0), (1, 0), (1, 1) \}
\\
\mathcal{C}_4^c := \{ (0, 0), (0, 1), (1, 1) \}
水素分子的に言えば、 \mathcal{C}はイオン状態で、 \mathcal{C}^cは原子状態に対応させることが出来る。
なので、もつれている部分集合の中でも、性質の良いものだけを抜き出して何か数学的な構造が出来ると面白そう。
こうしてみると、量子論だけでなく、もっと普遍的にエンタングルメントが存在して何かしらの機能を果たしているような気もする。

上極限集合と下極限集合。

個人的には、数列を作った方が分かり易い。

  •  \limsup


\displaystyle
\lim_{m \to \infty} S_m \equiv \limsup_{n \to \infty} A_n = \bigcap^\infty_{k=1} \bigcup^\infty_{n=k} A_n
\\
\displaystyle
S_m \equiv \bigcap^{m}_{k=1} \bigcup^\infty_{n=k} A_n
\\
\displaystyle
S_1 = \bigcup^\infty_{n=1} A_n
\\
\displaystyle
S_{l+1} = S_l \cap \left( \bigcup^\infty_{n=l+1} A_n \right) \subset S_l
よって、数列 \{S_m\}は単調減少数列である。
また、 \bigcup^\infty_{n=l+1} A_n \supset A_{\infty}より、 \lim_{m \to \infty} S_m \supset A_{\infty}

  •  \liminf


\displaystyle
\lim_{m \to \infty} I_m \equiv  \liminf_{n \to \infty} A_n = \bigcup^\infty_{k=1} \bigcap^\infty_{n=k} A_n
\\
\displaystyle
I_m \equiv \bigcup^{m}_{k=1} \bigcap^\infty_{n=k} A_n
\\
\displaystyle
I_1 = \bigcap^\infty_{n=1} A_n
\\
\displaystyle
I_{l+1} = I_l \cup \left( \bigcup^\infty_{n=2} A_n \right) \supset I_l
よって、数列 \{I_m\}は単調増加数列である。
また、 \bigcap^\infty_{n=l+1} A_n \subset A_{\infty}より、 \lim_{m \to \infty} I_m \subset A_{\infty}


したがって、 \liminf_{n \to \infty} A_n \subset \limsup_{n \to \infty} A_n が自然に言える。


実際に計算するときにも、数列を考えた方が扱い易いと思う。

例: A_n = [ 1/n, 1 ]


\displaystyle
\forall k \ge 1, \bigcup^\infty_{n=k}  [ 1/n, 1 ] = ( 0, 1]
\\
\therefore
\displaystyle
\forall m \ge1, S_m = ( 0, 1]
\\
 \limsup_{n \to \infty} A_n = \lim_{m \to \infty} S_m= ( 0, 1 ]


\displaystyle
I_1 = \bigcap^\infty_{n=1}  [ 1/n, 1 ] = [1]
\\
\displaystyle
I_2 = I_1 \cup \left( \bigcap^\infty_{n=2}  [ 1/n, 1 ] \right) = [ 1 ] \cup [1/2, 1] = [1/2, 1]
\\
\displaystyle
\therefore
I_m =  [1/m, 1]
\\
 \liminf_{n \to \infty} A_n = \lim_{m \to \infty} I_m= ( 0, 1 ]


参考サイト:
極限集合[数学についてのwebノート]
極限集合の解釈(イプシロンデルタ風に) - 岡竜之介のブログ

時間反転演算子のエルミート共役について。

時間反転演算子 \Thetaは反ユニタリー演算子である。
反ユニタリー演算子は、ユニタリー演算子 Uと反線形演算子 Kの積で表される。
教科書によって、「時間反転演算子のエルミート共役は取ってはいけない」と書いてあったり、普通にエルミート共役 \Theta^\daggerが定義されていたりする。
ここでは、 \Theta^\daggerを何故考えてはいけないかを考察する。

エルミート共役をわざわざ取りたいのは、以下のような関係を利用したいからである。

\displaystyle
\langle \psi | O | \phi \rangle
  = \langle \psi | O \phi \rangle
  = \langle O^{\dagger} \psi | \phi \rangle

内積は、適当に基底を選べば具体的に計算できる。

\displaystyle
\langle \psi | \phi \rangle
  = \sum_a \langle \psi | a \rangle \langle a | \phi \rangle
  = \sum_a \int \psi^*(a) \phi(a)

見た目的には、 \psi \phiは対等な関係のように見える。
しかし、数学的には、ケットベクトルはブラベクトルを入力して内積を返す線形汎関数で定義されている。
多分 F_{\psi} \equiv \langle \psi |と書き換えると分かり易いかも。

\displaystyle
F_{\psi}[ | \phi \rangle ] \equiv \langle \psi | \phi \rangle \in \mathbb{C}

ここで、 \phiが線形結合で表されているとすると、

\displaystyle
F_{\psi}[ c_1 | \phi_1 \rangle + c_2 | \phi_2 \rangle ]
\\
\displaystyle
\quad
  = c_1 F_{\psi}[ | \phi_1 \rangle ]
  + c_2 F_{\psi}[ | \phi_2 \rangle ]
\\
\displaystyle
\quad
  = c_1 \langle \psi | \phi_1 \rangle
  + c_2 \langle \psi | \phi_2 \rangle
線形汎関数の感じが伝わると思う。

ここで、反ユニタリー演算子 \phiに掛けると、

\displaystyle
F_{ \psi }[ UK ( c_1 | \phi_1 \rangle + c_2 | \phi_2 \rangle ) ]
\\
\quad
\displaystyle
  =F_{ \psi }[ U ( c^*_1 | \phi_1 \rangle + c^*_2 | \phi_2 \rangle ) ]
\\
\displaystyle
\quad
  = c^{*}_1 \langle \psi | U | \phi_1 \rangle
  + c^{*}_2 \langle \psi | U | \phi_2 \rangle
上では \phi_{1,2}が基底ベクトルと仮定した( K| \phi_{1,2} \rangle = | \phi_{1,2} \rangle )。
基底ベクトルでなくても、ユニタリー変換でいつでも基底の線形結合で書けるので、一般性は失われていない。

それで、今度はブラベクトルに作用させたときに上記と同じものを与えるにはどうしたら良いを考える。

\displaystyle
F_{ (UK)^\dagger \psi }[ c_1 | \phi_1 \rangle + c_2 | \phi_2 \rangle ]
\\
\displaystyle
\quad
  = c_1 F_{ (UK)^\dagger \psi}[ | \phi_1 \rangle ]
  + c_2 F_{ (UK)^\dagger \psi}[ | \phi_2 \rangle ]
だがしかし、どう足掻いても \psi (UK)^\daggerを作用させるだけでは c^{*}_{1,2}は作れない。

実際には、「全体の複素共役を取る」などをすると対応出来るは出来るのだが、それは元々の線形汎関数の能力を超えているので、上手く定義出来ないのである。
なので、 \langle \psi | \Theta | \phi \rangleは常に \phiに掛けるようにして、 \psiには掛けないからエルミート共役 \Theta^\daggerはわざわざ定義しない、という形を取るのである。

参考文献:J. J. サクライ「現代の量子力学・下」

pandasに一からデータを入れる(自分用メモ)。

pandasの使い方をググると、多くの場合にはsampleのcsvファイルを用意してそれを読み込ませてから使うという流れのものが多い印象がある。
読み込ませるファイルの区切りは基本的にカンマかタブであることを前提として作られている。
しかし、数値計算を扱っているコミュニティーとしては普通は(複数の)空白で数値を区切る。そして、普通に空白を区切りとして指定しpandasに読み込ませると、NaNだらけになってパッと使えない。
そのため、通常の用途ではnumpy.loadtxtで数値計算結果ファイルを読み込ませた方が楽である。
だが一方で、pandasのDataFrameのフィルタリングは非常に便利で、恩恵も多い。そのため、何らかの方法で用意したリストからDataFrameを構築し、体裁を整える or 解析することをやりたい。

例えば、次のような計算結果ファイル(sample.dat)があるとする。

Energy  Intensity  Quantity
0.0  0.0  0.0
0.5  0.25  1.0
1.0  0.75  3.0
...

これを例えば横軸をEnergy、縦軸をIntensityにしてプロットしたいときには、numpy.loadtxtで読み込ませた配列を転置して使う。

import numpy as np
from matplotlib import pyplot as plt

data_T = np.loadtxt( 'sample.dat', skiprows=1 ).T  # Transpose
plt.plot( data_T[0], data_T[1] )
plt.show()

転置することで、行の指定によってEnergyかIntensityかを選ぶことができる。

一方、pandas.DataFrameに流し込む際には、表の構造を保ちたいので、転置無しでnumpy.loadtxtを使う。

import pandas as pd

data = np.loadtxt( 'sample.dat' )  # No Transpose
df = pd.DataFrame( data, columns=('Energy', 'Intensity', 'Quantity') )
# df.values is same as data

columnsやindexを変更するには、要素ではなくリストまるごとで指定する必要がある。

df.columns = ('E', 'I', 'Q')

中身の修正には、DataFrame.valuesからではなく、DataFrame.locやDataFrame.atと言った要素指定メソッドを介して行う。

df.loc[ :, 'I' ] *= 10

データの追加には、いろいろ方法があるが、好きな位置に挿入できるinsertが個人的には分かり易い。

def func( e_ ):
   ...

df.insert( len(df.columns), 'Q2', func( df.loc[ :, 'E' ].values ) )

Energyに依存する適当な関数funcを用意して、Q2として最終列に挿入した。
ただし、insertは元のdfを変更してしまう(破壊的な手続き)であるため、メソッドチェーンに組み込むことができない場合がある。その時は、他のメソッドを使った方が無難であろう。

気に入らない行が列がある場合には、DataFrame.dropで落とせる。

df = df.drop( index =[...], columns=[...] )


本命のフィルタリングについては、DataFrame.queryを用いることで実行可能である。

e0 = 10
max_intensity = 1
print( df.query('E > @e0 and I < @max_intensity') )
# Not like df.query('"E" > @e0 and "I" < @max_intensity') 

文字列で条件を入れることに注意。また列名が文字列でも「文字列の中で文字列」にする必要はない。変数は@を付ける。
注意として、列名に空白やピリオドが含まれているとコケる。一応、DataFrame.queryを使わなくても以下のような形で複数条件によるフィルタリングが可能ではある。

print( df.[ (df['E'] > e0 ) & (df['I'] < max_intensity) ] )

最後にソートについて。

df.sort_values( by='Q2', ascending=True )

"ascending=True"で昇順になる。

参考サイト
pandas.DataFrameの構造とその作成方法 | note.nkmk.me
pandas.DataFrameに列や行を追加(assign, appendなど) | note.nkmk.me
pandas.DataFrameの行・列を指定して削除するdrop | note.nkmk.me
pandas.DataFrameの行を条件で抽出するquery | note.nkmk.me
データ分析で頻出のPandas基本操作 - Qiita
pandasでcsv/tsvファイル読み込み(read_csv, read_table) | note.nkmk.me

pythonでの==とisの違い。

次のコードを見て頂きたい。

x = 0; y = 0

if (x, y) is (0, 0):
    print( True )
else:
    print( False )

if (x, y) == (0, 0):
    print( True )
else:
    print( False )

ニュアンスはどちらも同じようなことをしたい訳だが、"is"では"False"が、"=="では"True"が出力される。

以下のサイトに説明を発見。
== と is の違い | Python-izm

"is"だと、値が同じかどうかではなく、「同一のオブジェクトかどうか」で判断されるため、弾かれたということであった。

もしかしたら、過去のプログラムにこの手のバグがある気がしてめっちゃ怖くなった。。。

pythonでawkを呼んでファイルを編集する。

pythonを使って、awkでinput fileを編集しながらプログラムを回したい。

参考サイト様:
テキスト処理にたまに便利なAWK入門 - Qiita
awkで処理結果を元になったファイルに上書きする | 俺的備忘録 〜なんかいろいろ〜
フォーマット文字列内での波括弧のエスケープ - Qiita

from subprocess import call

input_file = 'input_file'
n_line = 999
replace_string = '"{:}"'.fomrat( 'string' )

cmd = "awk -i inplace '{{ if (NR == {:}) print {:} ; else print $0 }}' {:}".format( n_line, replace_string, input_file )
call( cmd, shell = True )

call( 'path to external program', shell = True )

上で書いたawkに流し込まれるコマンドは、

awk -i inplace '{ if (NR=999) print "string" ; else print $0 }' input_file

となる。

ポイントは以下の通り。

  • awkのコマンドでクオーテションが必要なので、文字列表現としてダブルクオーテーションを用いている。
  • 「-i inplace」で読み込んだファイルを上書きすることができる。
  • pythonで中括弧を書くには、二個重ねて書く。
  • NRはawkがファイルを読んでいる最中に更新される行番号変数。上のコマンドでは、NRがn_lineと同じときに行の内容をreplace_stringに置き換えるようにしている。つまりn_line行目を変更する。
  • awkで文字列を書き込むには、ダブルクオーテーションが必要なので、「'"string"'」という形で文字列変数を宣言しておく。つまり、「"..."」を含めて文字列にしておく。
  • 「$0」は一行分の行の内容全部である。したがって、興味のない部分はそのまま書き出しておけば良い。

グラフ理論の個人用メモ(その2)

  • bipartite grapheのcycleは全て偶数長。
  • edge数の制限

vertex数 nのsimple graphにおいて、connected graphが k個含まれているとき、edge数 mは次の不等式を満たす。

\displaystyle
n-k \le m \le\frac{1}{2}(n-k)(n-k+1)
これは、cycleが無いときに最もedge数が少なく、complete graphのときに最もedge数が多いことが背景にある。

  • conneceted graphの条件。

vertex数 nのsimple graphにedge数が m \ge \frac{1}{2}(n-1)(n-2) + 1個あれば、connected graphである。

  • disconnecting set

edge setの部分集合で、それをgraphから消去すると、disconnected graphになるようなもの。非連結化集合。

  • cutset

disconnecting setのうち、真部分集合がdisconnecting setではないもの。

  • bridge

元が1個からなるcutset。

  • edge connectivity

最小なcutsetの大きさ。辺連結度。

  • separating set

vertex setの部分集合で、その部分集合およびvertexにincidnetしているedgeを消去すると、disconnected graphになるようなもの。分離集合。

  • cut vertex

元が1個からなるseparating setに含まれているvertex。

  • girth

最短なcycleの長さ。内周。

  • distance

最短のpathの長さ。距離。

vertex数2kのsimple graphで、三角形が無いとすると、edge数は k^2以下。

  • 独立

edge setにcycleが含まれていないとき、edge setは独立であるという。

  • handshakingg lemma

任意のgraphにおけて、全てのvertexのdegreeの和は偶数になる。握手補題

全てのvertexのdegreeが2以上のとき、cycleが存在する。

  • 定理6.2

connected diagramがEulerian graphである必要十分条件は、全てのvertexのdegreeが偶数であることである。

  • 系6.3

connected diagramがEulerian graphである必要十分条件は、edge setが互いに素なcycleに分割できることである。

  • 系6.4

connected diagramがsemi-Eulerian graphである必要十分条件は、奇数次のvertexを2個だけ含んでいることである。

次の規則に従いながら、任意のinitial vertexから自由にedgeを辿る。
1. 辿ったedgeは削除する。それによりisolated vertexが生じたら、それも削除する。
2. どの段階でも、他に辿るedgeが無い限り、bridgeは渡らない。

  • Oreの定理

 n \ge 3のsimple graphにおいて、adjacentでない任意の二つのvetexを v, wとするとき、 deg( v ) + deg( w ) \ge nであれば、Hamiltonian graphとなる。

 n \ge 3のsimple graphにおいて、任意のvertex  vに対して \forall v \, deg(v) \ge n/2であれば、Hamiltonian graphとなる。

参考文献:グラフ理論入門