[이과 대학생 지원] 울프프의 손놀림으로 갑질 풀기.
개요 
이 글의 목적은'Collective Monte Carlo Updating for Spin Systems', 1989 알고리즘을 수치로 팝업 모델을 풀기 위한 것이다.
"갑자기 복잡한 알고리즘으로 팝업 모델 해결하니까 좀..."이런 사람, 과거의 보도
[이과대학생 응원] 단선점프를 통해서 스트레스 풀기. 
[이과 대학생 지원] 스웨덴슨왕의 손놀림으로 갑질 풀기. 
괴롭힘 모델에 대한 이해가 깊어지면 이 기사를 읽어주시기 바랍니다.
계산법 
STEP 0
 
초기 상태의 수치 조절 설정을 적당히 준비하십시오. (예를 들어 무작위입니다.)
 
 
STEP 1
 
좌표 $(i, j)$의 수치 조절을 무작위로 선택합니다.
STEP 2
 
STEP1에서 선택한 값을 포켓, cluster로 등록합니다.
 
 
이전 STEP에 등록된 cluster가 있다면 이것을 비워 두세요.
STEP 3
 
포켓에서 하나의 회전구에 착안한 다음에 인접한 회전구neighbor에 대해 다음과 같은 순환을 한다.
STEP 3-1
 
아래의 모든 조건을 충족시킬 때neighbor의 자전거를pocket과cluster에 등록합니다.
(1) 인접 회전 방향이 동일
(2) 옆에 있는 회전구가 cluster에 등록되지 않았습니다.
(3)$0 
 
STEP 4
 
Pocket에서 STEP3에서 선택한 회전을 제거합니다.
 
 
STEP 5
 
포켓이 비어 있을 때까지 STEP2~STEP4를 반복합니다.
 
 
STEP 6
 
위의 STEP을 통해 cluster에 등록된 회전 점프를 합니다.
 
 
파이썬 스크립트 
다음은 파이썬의 구현 스크립트입니다.#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
import random
class IsingWolff:
    def __init__(self):
        # set the number of spins in x-direrection, y-direction
        self.IXMAX = 200
        self.JYMAX = 200
        # set J_ij (= J, uniform)
        self.J = 1.0
        # set initial condition (-1 or 1, random)
        self.S = (np.random.rand(self.IXMAX, self.JYMAX)<0.5) * (-2) + 1
        # set 1/(k_B T)
        self.ONEOKBT = 1.0
        # set the number of iteration 
        self.ITER = 10000
        # set (i, j) neighbor
        self.NEIGHBOR = {}
        for i in range(self.IXMAX):
            for j in range(self.JYMAX):
                self.NEIGHBOR[(i, j)] = [((i+1)%self.IXMAX, j), ((i-1)%self.IXMAX, j), (i, (j+1)%self.JYMAX), (i, (j-1)%self.JYMAX)]
    def Compute_Probability(self):
        # calcurate probability of flip
        return 1.0 - np.exp(-2.0*self.J*self.ONEOKBT)
    def Cluster_Flip(self, p):
        # set random coordinate (i, j)
        coord = (np.random.randint(self.IXMAX), np.random.randint(self.JYMAX))
        # set pocket
        pocket = [coord]
        # set cluster
        cluster = [coord]
        # search pocket while pocket is not empty
        while pocket != []:
            # choose random tuple from pocket
            l = random.choice(pocket)
            # for loop for neightborhood
            for m in self.NEIGHBOR[l]:
                # if spins are parallel & (i, j) is not in cluster and r < p, add to pocket & cluster
                if self.S[m[0]][m[1]] == self.S[l[0]][l[1]]:
                    if m not in cluster:
                        if np.random.rand() < p:
                            pocket.append(m)
                            cluster.append(m)
            # remove choosen (i, j) from pocket list
            pocket.remove(l)
        # flip spin including cluster
        for l in cluster:
            self.S[l[0]][l[1]] *= -1
    def Plot_Spin(self, n):
        # remove previous figure
        plt.clf()
        # plot color map
        plt.imshow(self.S, cmap='PuOr', vmin=-1, vmax=1, animated=True)
        # add colorbar
        plt.colorbar(ticks=[-1, 1], orientation='vertical')
        # set pause interval time
        plt.pause(1.0e-6)
        # save figure as png format
        plt.savefig('fig'+str(n)+'.png')
    def run(self):
        # set cluster flip probability
        p = self.Compute_Probability()
        # main loop start
        for n in range(self.ITER):
            # plot
            if n % 1 == 0:
                self.Plot_Spin(n)
            # flip cluster
            self.Cluster_Flip(p)
if __name__ == '__main__':
    a = IsingWolff()
    a.run()
스크립트 세부 정보
 
__init__
 self.IXMAX, self.JYMAX에서 각각 달러×, y달러 방향의 회전 횟수를 지정하였다.self.J는 상호작용 계수이고, self.ONEOKBT는 $1/k이다.BT달러의 크기self.ITER가 몬테카로의 실험 횟수를 결정한다.self.NEIGHBOR $(i, j)달러의 자전거와 인접한 자전거 $(i+1, j), (i-1, j), (i, j+1), (i, j-1)$는 사전 형식으로 로그인합니다.
Compute_Probability
 
$p$확률을 계산하는 중입니다.
Cluster_Flip
 
위 알고리즘을 실행하는 STEP1~STEP6
Plot_Spin
 
이 함수matplotlib를 사용하여 self.S($\pm1의 자선 배열)를 2차원 컬러 렌즈로 그립니다.또한 그림 결과를 jpeg 파일로 저장합니다.
run
 
이 함수는 Wolff 메서드의 수치 반전self.ITER 횟수만 반복합니다.
결실 self.IXMAX = 200
self.JYMAX = 200
self.J = 1.0
self.ONEOKBT = 1.0
self.ITER = 10000       
위의 매개변수로 계산된 결과를 비디오로 표시합니다.
울프프의 수법으로 괴롭힘 모드를 풀면 영상은 이쪽pic.twitter.com/6rVJQuLj08-안에 있는 사람은 댄스문(@tweet nakashoo)September 12, 2019
$k_BT=1달러를 계산했을 때 회전구가 예쁘게 맞춰진 결과를 볼 수 있었다p>
결어 
이 방법은 Swendsen-Wang의 방법과 마찬가지로 단자선 트리거보다 더 강한 방법이다.그러나 울프프의 알고리즘은 스웨덴슨왕의 알고리즘을 더 큰 클러스터에서 스핀스체인지가 발생할 확률을 높인 개량판이다.계속 활용하세요.p>
Reference
                            
                            이 문제에 관하여([이과 대학생 지원] 울프프의 손놀림으로 갑질 풀기.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
                                
                                https://qiita.com/github-nakasho/items/aa1d039dbd7779beb665
                            
                            
                            
                                텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                            
                            
                                
                                
                                 우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                            
                            
                        
                    
                
                
                
            
STEP 0
초기 상태의 수치 조절 설정을 적당히 준비하십시오. (예를 들어 무작위입니다.)
 
 STEP 1
좌표 $(i, j)$의 수치 조절을 무작위로 선택합니다.
STEP 2
STEP1에서 선택한 값을 포켓, cluster로 등록합니다.
 
 이전 STEP에 등록된 cluster가 있다면 이것을 비워 두세요.
STEP 3
포켓에서 하나의 회전구에 착안한 다음에 인접한 회전구neighbor에 대해 다음과 같은 순환을 한다.
STEP 3-1
아래의 모든 조건을 충족시킬 때neighbor의 자전거를pocket과cluster에 등록합니다.
(1) 인접 회전 방향이 동일
(2) 옆에 있는 회전구가 cluster에 등록되지 않았습니다.
(3)$0
 
 STEP 4
Pocket에서 STEP3에서 선택한 회전을 제거합니다.
 
 STEP 5
포켓이 비어 있을 때까지 STEP2~STEP4를 반복합니다.
 
 STEP 6
위의 STEP을 통해 cluster에 등록된 회전 점프를 합니다.
 
 파이썬 스크립트 
다음은 파이썬의 구현 스크립트입니다.#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
import random
class IsingWolff:
    def __init__(self):
        # set the number of spins in x-direrection, y-direction
        self.IXMAX = 200
        self.JYMAX = 200
        # set J_ij (= J, uniform)
        self.J = 1.0
        # set initial condition (-1 or 1, random)
        self.S = (np.random.rand(self.IXMAX, self.JYMAX)<0.5) * (-2) + 1
        # set 1/(k_B T)
        self.ONEOKBT = 1.0
        # set the number of iteration 
        self.ITER = 10000
        # set (i, j) neighbor
        self.NEIGHBOR = {}
        for i in range(self.IXMAX):
            for j in range(self.JYMAX):
                self.NEIGHBOR[(i, j)] = [((i+1)%self.IXMAX, j), ((i-1)%self.IXMAX, j), (i, (j+1)%self.JYMAX), (i, (j-1)%self.JYMAX)]
    def Compute_Probability(self):
        # calcurate probability of flip
        return 1.0 - np.exp(-2.0*self.J*self.ONEOKBT)
    def Cluster_Flip(self, p):
        # set random coordinate (i, j)
        coord = (np.random.randint(self.IXMAX), np.random.randint(self.JYMAX))
        # set pocket
        pocket = [coord]
        # set cluster
        cluster = [coord]
        # search pocket while pocket is not empty
        while pocket != []:
            # choose random tuple from pocket
            l = random.choice(pocket)
            # for loop for neightborhood
            for m in self.NEIGHBOR[l]:
                # if spins are parallel & (i, j) is not in cluster and r < p, add to pocket & cluster
                if self.S[m[0]][m[1]] == self.S[l[0]][l[1]]:
                    if m not in cluster:
                        if np.random.rand() < p:
                            pocket.append(m)
                            cluster.append(m)
            # remove choosen (i, j) from pocket list
            pocket.remove(l)
        # flip spin including cluster
        for l in cluster:
            self.S[l[0]][l[1]] *= -1
    def Plot_Spin(self, n):
        # remove previous figure
        plt.clf()
        # plot color map
        plt.imshow(self.S, cmap='PuOr', vmin=-1, vmax=1, animated=True)
        # add colorbar
        plt.colorbar(ticks=[-1, 1], orientation='vertical')
        # set pause interval time
        plt.pause(1.0e-6)
        # save figure as png format
        plt.savefig('fig'+str(n)+'.png')
    def run(self):
        # set cluster flip probability
        p = self.Compute_Probability()
        # main loop start
        for n in range(self.ITER):
            # plot
            if n % 1 == 0:
                self.Plot_Spin(n)
            # flip cluster
            self.Cluster_Flip(p)
if __name__ == '__main__':
    a = IsingWolff()
    a.run()
스크립트 세부 정보
 
__init__
 self.IXMAX, self.JYMAX에서 각각 달러×, y달러 방향의 회전 횟수를 지정하였다.self.J는 상호작용 계수이고, self.ONEOKBT는 $1/k이다.BT달러의 크기self.ITER가 몬테카로의 실험 횟수를 결정한다.self.NEIGHBOR $(i, j)달러의 자전거와 인접한 자전거 $(i+1, j), (i-1, j), (i, j+1), (i, j-1)$는 사전 형식으로 로그인합니다.
Compute_Probability
 
$p$확률을 계산하는 중입니다.
Cluster_Flip
 
위 알고리즘을 실행하는 STEP1~STEP6
Plot_Spin
 
이 함수matplotlib를 사용하여 self.S($\pm1의 자선 배열)를 2차원 컬러 렌즈로 그립니다.또한 그림 결과를 jpeg 파일로 저장합니다.
run
 
이 함수는 Wolff 메서드의 수치 반전self.ITER 횟수만 반복합니다.
결실 self.IXMAX = 200
self.JYMAX = 200
self.J = 1.0
self.ONEOKBT = 1.0
self.ITER = 10000       
위의 매개변수로 계산된 결과를 비디오로 표시합니다.
울프프의 수법으로 괴롭힘 모드를 풀면 영상은 이쪽pic.twitter.com/6rVJQuLj08-안에 있는 사람은 댄스문(@tweet nakashoo)September 12, 2019
#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
import random
class IsingWolff:
    def __init__(self):
        # set the number of spins in x-direrection, y-direction
        self.IXMAX = 200
        self.JYMAX = 200
        # set J_ij (= J, uniform)
        self.J = 1.0
        # set initial condition (-1 or 1, random)
        self.S = (np.random.rand(self.IXMAX, self.JYMAX)<0.5) * (-2) + 1
        # set 1/(k_B T)
        self.ONEOKBT = 1.0
        # set the number of iteration 
        self.ITER = 10000
        # set (i, j) neighbor
        self.NEIGHBOR = {}
        for i in range(self.IXMAX):
            for j in range(self.JYMAX):
                self.NEIGHBOR[(i, j)] = [((i+1)%self.IXMAX, j), ((i-1)%self.IXMAX, j), (i, (j+1)%self.JYMAX), (i, (j-1)%self.JYMAX)]
    def Compute_Probability(self):
        # calcurate probability of flip
        return 1.0 - np.exp(-2.0*self.J*self.ONEOKBT)
    def Cluster_Flip(self, p):
        # set random coordinate (i, j)
        coord = (np.random.randint(self.IXMAX), np.random.randint(self.JYMAX))
        # set pocket
        pocket = [coord]
        # set cluster
        cluster = [coord]
        # search pocket while pocket is not empty
        while pocket != []:
            # choose random tuple from pocket
            l = random.choice(pocket)
            # for loop for neightborhood
            for m in self.NEIGHBOR[l]:
                # if spins are parallel & (i, j) is not in cluster and r < p, add to pocket & cluster
                if self.S[m[0]][m[1]] == self.S[l[0]][l[1]]:
                    if m not in cluster:
                        if np.random.rand() < p:
                            pocket.append(m)
                            cluster.append(m)
            # remove choosen (i, j) from pocket list
            pocket.remove(l)
        # flip spin including cluster
        for l in cluster:
            self.S[l[0]][l[1]] *= -1
    def Plot_Spin(self, n):
        # remove previous figure
        plt.clf()
        # plot color map
        plt.imshow(self.S, cmap='PuOr', vmin=-1, vmax=1, animated=True)
        # add colorbar
        plt.colorbar(ticks=[-1, 1], orientation='vertical')
        # set pause interval time
        plt.pause(1.0e-6)
        # save figure as png format
        plt.savefig('fig'+str(n)+'.png')
    def run(self):
        # set cluster flip probability
        p = self.Compute_Probability()
        # main loop start
        for n in range(self.ITER):
            # plot
            if n % 1 == 0:
                self.Plot_Spin(n)
            # flip cluster
            self.Cluster_Flip(p)
if __name__ == '__main__':
    a = IsingWolff()
    a.run()
self.IXMAX = 200
self.JYMAX = 200
self.J = 1.0
self.ONEOKBT = 1.0
self.ITER = 10000       
울프프의 수법으로 괴롭힘 모드를 풀면 영상은 이쪽pic.twitter.com/6rVJQuLj08-안에 있는 사람은 댄스문(@tweet nakashoo)September 12, 2019
$k_BT=1달러를 계산했을 때 회전구가 예쁘게 맞춰진 결과를 볼 수 있었다p>
결어 
이 방법은 Swendsen-Wang의 방법과 마찬가지로 단자선 트리거보다 더 강한 방법이다.그러나 울프프의 알고리즘은 스웨덴슨왕의 알고리즘을 더 큰 클러스터에서 스핀스체인지가 발생할 확률을 높인 개량판이다.계속 활용하세요.p>
Reference
이 문제에 관하여([이과 대학생 지원] 울프프의 손놀림으로 갑질 풀기.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/github-nakasho/items/aa1d039dbd7779beb665텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)