teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

6

アルゴリズムにミスがあったので更新しました

2018/10/24 13:57

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
File without changes
body CHANGED
@@ -2,8 +2,10 @@
2
2
  コードにもコメント文で書いていますが、以下に具体的に書きたいと思います。
3
3
  メトロポリス法という物理学の中の統計力学におけるシミュレーションをを行う際の計算方法です。
4
4
 
5
- **初期状態の形成**
5
+ **20181024 追記メトロポリスアルゴリズムにミスがあったため、全面的に書きなおしました。**
6
6
 
7
+ **初期状態の形成**
8
+
7
9
  (1)Nx*Nyの行列を生成し、各成分を(i,j)であらわす。
8
10
 
9
11
  (2)行列の各要素は0~2*np.piの乱数を取るものとする。この値をS[i,j]とする。
@@ -14,37 +16,22 @@
14
16
  ~~周期的境界条件~~
15
17
  例えばNx=8,Ny=8の場合、S[0,1]=S[8,1]、S[1,0]=S[1,8]というように、行列の各端で値を折り返します。
16
18
 
17
- **メトロポリスアルゴリズム(10/24追記:(6)以下で一部間違っています。下に正しいものを載せました。)**
18
19
 
19
20
  (4)行列Sのある要素S(i,j)をランダムに抽出し、その要素だけを0~2πの乱数で変動させる。
20
21
 
21
22
  (5)変動させたS(i,j)をSal(i,j)として、以下の計算を行い、Eal(i,j)を計算する。
22
- Eal(i,j)=cos(Sal(i,j)-S(i+1,j))-cos(Sal(i,j)-S(i-1,j))-cos(Sal(i,j)-S(i,j+1))-cos(Sal(i,j)-S(i,j-1))
23
23
 
24
- つまり、変動させた(i,j)以外の要素はそのままにして、手順(3)で行ったものと同じ計算をするということです。
24
+ つまり、変動させた(i,j)以外の要素はそのままにして、手順(3)で行ったものと同じ計算をするということです。この時、行列Sの要素S[i,j]の変動に伴い、行列Eの要素E[i,j],E[i+1,j],E[i-1,j],E[i,j+1],E[1,j-1]も変動することに注意してください。
25
25
 
26
- ~~(6)ここで(3)で計算したE[i,j]と(5)で計算したEal[i,j]を比較します。
26
+ 6)変動前の行列Eおよび変動後の行列Eの行列式をそれぞれE、Ealとします。
27
- ~~
28
- ~~(6-1E[i,j] > Eal[i,j] の場合、もともとの要素S[i,j]Sal[i,j]更新し、(7)以降の過程へ。
27
+ (6-1)E > Eal の場合、要素S[i,j]Sal[i,j]への更新に成功たとし、(7)以降の過程へ。
29
- ~~
30
- ~~(6-2) E[i,j] < Eal[i,j] の場合、deltaE[i,j]=Eal[i,j]-E[i,j]を計算します。そして確率exp(-deltaE[i,j]/0.001)でもともとの要素S[i,j]をSal[i,j]に更新します。
31
- ~~
32
- ~~(7)(4)~(6)を10000回繰り返すことでおおよそすべての要素S[i,j]がスピン更新を経験するようにします。
33
- ~~
34
- ~~(8)(7)の操作後の行列Sを用いて行列Eを計算する。それぞれの行列の行列式の値Ssum=np.sum(S)、Esum=np.sum(E)をもとめることができれば計算終了です。
35
- 参考程度にですが、Ssum~64、Esum~-250 (Nx=8、Ny=8)  となれば成功と言えます。~~
36
- ~~
37
- **10/24追記 (6)以下のメトロポリスアルゴリズム(文献を再度確認しなおしました。)**
38
- (6)ここで(3)で計算したE[i,j]と(5)で計算したEal[i,j]とを比較します。
39
28
 
40
- (6-1)E[i,j] > Eal[i,j] の場合、もともとの要素S[i,j]Sal[i,j]に更新し、(7)以降過程へ
29
+ (6-2) E < Eal の場合、deltaE=Eal-Eを計算します。そして確率exp(-deltaE/0.001)でもともとの要素S[i,j]Sal[i,j]への更新成功したとします。ここで(6)~(6-2)においてS[i,j]の更新に成功た場合は行列E[i,j],E[i+1,j],E[i-1,j],E[i,j+1],E[1,j-1]要素も当然変化します
41
30
 
42
- (6-2) E[i,j] < Eal[i,j] の場合、deltaE[i,j]=Eal[i,j]-E[i,j]計算します。そして確率exp(-deltaE[i,j]/0.001)でもともと要素S[i,j]をSal[i,j]に更新す。
31
+ (7)(4)~(6-2)を1回試行とて、1000回繰り返す。
43
32
 
44
- (7)(4)~(6-2)を1000回繰り返す。(こでは(8)でしているような計算は行わずSの更新だけす。)
33
+ (8)(7)の後(4)~(6-2)を10000回繰り返す。しかし、の時1回ごとにS_sum = np.sum(S)、E_sum = np.sun(E)を計算足し合わせていく。つまりi回目の更新で得られたS_sumS_sum(i)とすると、S_end(10000)=S_sum(1)+S_sum(2)+S_sum(3)...+S_sum(10000)を求めるとうことです。E_end(10000)についても同様です。
45
34
 
46
- (8)(7)の後(4)~(6-2)を10000回繰り返す。しかし、この時1回ごとにS_sum = np.sum(S)、E_sum = np.sun(E)を計算し、その和を求める。つまりi回目の更新で得られたS_sumをS_sum(i)とすると、S_end(10000)=S_sum(1)+S_sum(2)+S_sum(3)...+S_sum(10000)を求めるということです。E_end(10000)についても同様です。
47
-
48
35
  (9)(8)で求めた値を用いて、S_ave = S_end(10000)/10000,E_ave = E_end(10000)/10000 を出力できればOKです。
49
36
 
50
37
 

5

アルゴリズムにミスがあったので、訂正を行いました。

2018/10/24 13:57

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
File without changes
body CHANGED
@@ -1,5 +1,5 @@
1
1
  ### 仕様
2
- コードにもコメント文で書いていますが、以下に具体的にきたいと思います。
2
+ コードにもコメント文で書いていますが、以下に具体的にきたいと思います。
3
3
  メトロポリス法という物理学の中の統計力学におけるシミュレーションをを行う際の計算方法です。
4
4
 
5
5
  **初期状態の形成**
@@ -14,7 +14,7 @@
14
14
  ~~周期的境界条件~~
15
15
  例えばNx=8,Ny=8の場合、S[0,1]=S[8,1]、S[1,0]=S[1,8]というように、行列の各端で値を折り返します。
16
16
 
17
- **メトロポリスアルゴリズム**
17
+ **メトロポリスアルゴリズム(10/24追記:(6)以下で一部間違っています。下に正しいものを載せました。)**
18
18
 
19
19
  (4)行列Sのある要素S(i,j)をランダムに抽出し、その要素だけを0~2πの乱数で変動させる。
20
20
 
@@ -23,17 +23,35 @@
23
23
 
24
24
  つまり、変動させた(i,j)以外の要素はそのままにして、手順(3)で行ったものと同じ計算をするということです。
25
25
 
26
+ ~~(6)ここで(3)で計算したE[i,j]と(5)で計算したEal[i,j]とを比較します。
27
+ ~~
28
+ ~~(6-1)E[i,j] > Eal[i,j] の場合、もともとの要素S[i,j]をSal[i,j]に更新し、(7)以降の過程へ。
29
+ ~~
30
+ ~~(6-2) E[i,j] < Eal[i,j] の場合、deltaE[i,j]=Eal[i,j]-E[i,j]を計算します。そして確率exp(-deltaE[i,j]/0.001)でもともとの要素S[i,j]をSal[i,j]に更新します。
31
+ ~~
32
+ ~~(7)(4)~(6)を10000回繰り返すことでおおよそすべての要素S[i,j]がスピン更新を経験するようにします。
33
+ ~~
34
+ ~~(8)(7)の操作後の行列Sを用いて行列Eを計算する。それぞれの行列の行列式の値Ssum=np.sum(S)、Esum=np.sum(E)をもとめることができれば計算終了です。
35
+ 参考程度にですが、Ssum~64、Esum~-250 (Nx=8、Ny=8)  となれば成功と言えます。~~
36
+ ~~
37
+ **10/24追記 (6)以下のメトロポリスアルゴリズム(文献を再度確認しなおしました。)**
26
38
  (6)ここで(3)で計算したE[i,j]と(5)で計算したEal[i,j]とを比較します。
27
39
 
28
- (6-1E[i,j] > Eal[i,j] の場合、もともとの要素S[i,j]をSal[i,j]に更新し、(7)以降の過程へ。
40
+ (6-1)E[i,j] > Eal[i,j] の場合、もともとの要素S[i,j]をSal[i,j]に更新し、(7)以降の過程へ。
29
41
 
30
42
  (6-2) E[i,j] < Eal[i,j] の場合、deltaE[i,j]=Eal[i,j]-E[i,j]を計算します。そして確率exp(-deltaE[i,j]/0.001)でもともとの要素S[i,j]をSal[i,j]に更新します。
31
43
 
32
- (7)(4)~(6)を10000回繰り返すこおおよそすべの要素S[i,j]がスピン更新を経験するようにします。
44
+ (7)(4)~(6-2)を1000回繰り返す。(は(8)でしいるような計算は行わず、S更新だけ行います。)
33
45
 
34
- (8)(7)の操作の行列S用いて行列Eを計算それぞれ行列の行列式の値Ssum=np.sum(S)、Esum=np.sum(E)をとめることきれば計算終了です。
35
- 参考程度にですが、Ssum~64、Esum~-250 (Nx=8、Ny=8)  となれば成功と言えます。
46
+ (8)(7)の後(4)~(6-2)10000回繰り返す。しかし、こ時1回ごとにS_sum = np.sum(S)、E_sum = np.sun(E)を計算し、その和を求める。つまりi回目の更新で得られたS_sumをS_sum(i)すると、S_end(10000)=S_sum(1)+S_sum(2)+S_sum(3)...+S_sum(10000)を求めるということです。E_end(10000)についても同様です。
36
47
 
48
+ (9)(8)で求めた値を用いて、S_ave = S_end(10000)/10000,E_ave = E_end(10000)/10000 を出力できればOKです。
49
+
50
+
51
+
52
+
53
+
54
+
37
55
  ### 実際に書いてみたコード
38
56
 
39
57
  ```python

4

仕様の項目に追記を行いました

2018/10/24 08:40

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
File without changes
body CHANGED
@@ -31,9 +31,9 @@
31
31
 
32
32
  (7)(4)~(6)を10000回繰り返すことでおおよそすべての要素S[i,j]がスピン更新を経験するようにします。
33
33
 
34
- (8)(7)の操作後の行列式Send=np.sum(S)及びEend=np.sum(E)を出力できればこのシミュレーションは終了です。
34
+ (8)(7)の操作後の行列Sを用いて行列Eを計算する。それぞれの行列の行列の値Ssum=np.sum(S)、Esum=np.sum(E)をもとめることができれば計算終了です。
35
+ 参考程度にですが、Ssum~64、Esum~-250 (Nx=8、Ny=8)  となれば成功と言えます。
35
36
 
36
-
37
37
  ### 実際に書いてみたコード
38
38
 
39
39
  ```python

3

追記2を更新しました

2018/10/19 22:34

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
File without changes
body CHANGED
@@ -158,4 +158,35 @@
158
158
  if random() < np.exp(-delta / 0.001):
159
159
  TypeError: 'module' object is not callable
160
160
 
161
+ ```
162
+
163
+ ###追記2(#更新部分について、教えていただいた内容をもとに条件分岐を訂正しました)
164
+ ```python
165
+ def Metropolis(Nx=8, Ny=8, iterations=10000):
166
+ S = np.random.uniform(0, 2 * np.pi, (Nx, Ny)) # Nx * Ny の行列Sを形成。各要素は0~2πの乱数
167
+ E = update(S)
168
+
169
+ indices = np.dstack(np.mgrid[0:Nx, 0:Ny]).reshape(-1, 2)
170
+ for k in range(iterations): # モンテカルロステップ数を 10000 とする
171
+ # ランダムに要素を選択する。
172
+ index = tuple(indices[np.random.randint(len(indices))])
173
+
174
+ # 乱数を生成する。
175
+ E_tmp = E.copy()
176
+ E_tmp[index] = np.random.uniform(0, 2 * np.pi)
177
+
178
+ # 計算
179
+ E_tmp = update(E_tmp)
180
+
181
+ # 更新
182
+ if E[index] > E_tmp[index]:
183
+ E[index] = E_tmp[index]
184
+
185
+ else:
186
+ delta = E_tmp[index] - E[index]
187
+ if np.random.random() < np.exp(-delta / 0.001):
188
+ E[index] = E_tmp[index]
189
+
190
+
191
+ return S, E
161
192
  ```

2

追記を追加しました。

2018/10/19 11:27

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
File without changes
body CHANGED
@@ -116,4 +116,46 @@
116
116
  ### 参考
117
117
  以前にも以下のような質問をし、本プログラム作成の際にお世話になりました。
118
118
  https://teratail.com/questions/152409
119
- https://teratail.com/questions/152518
119
+ https://teratail.com/questions/152518
120
+
121
+ ###追記(elseの分岐以降でエラーが出ています)
122
+
123
+
124
+ ```python
125
+ def Metropolis(Nx=8, Ny=8, iterations=10000):
126
+ S = np.random.uniform(0, 2 * np.pi, (Nx, Ny)) # Nx * Ny の行列Sを形成。各要素は0~2πの乱数
127
+ E = update(S)
128
+
129
+ indices = np.dstack(np.mgrid[0:Nx, 0:Ny]).reshape(-1, 2)
130
+ for k in range(iterations): # モンテカルロステップ数を 10000 とする
131
+ # ランダムに要素を選択する。
132
+ index = tuple(indices[np.random.randint(len(indices))])
133
+
134
+ # 乱数を生成する。
135
+ E_tmp = E.copy()
136
+ E_tmp[index] = np.random.uniform(0, 2 * np.pi)
137
+
138
+ # 計算
139
+ E_tmp = update(E_tmp)
140
+
141
+ # 更新
142
+ if E[index] > E_tmp[index]:
143
+ continue
144
+ else:
145
+ delta = E_tmp[index] - E[index]
146
+ if random() < np.exp(-delta / 0.001):#変更部分です
147
+ continue
148
+
149
+ return S, E
150
+
151
+ ```
152
+
153
+ ```output
154
+ Traceback (most recent call last):
155
+ File "C:/Users/user2/Desktop/2DXYTEST/testtesttesttest13.py", line 44, in <module>
156
+ S, E = Metropolis(Nx=8, Ny=8, iterations=10000)
157
+ File "C:/Users/user2/Desktop/2DXYTEST/testtesttesttest13.py", line 37, in Metropolis
158
+ if random() < np.exp(-delta / 0.001):
159
+ TypeError: 'module' object is not callable
160
+
161
+ ```

1

質問の題にミスがあったので修正しました。

2018/10/19 10:15

投稿

astromelt0416
astromelt0416

スコア15

title CHANGED
@@ -1,1 +1,1 @@
1
- python NameErrorが解決できない
1
+ python TypeErrorが解決できない
body CHANGED
File without changes