TVDTemperingRev.py
From Werner KRAUTH
(Difference between revisions)
Revision as of 10:23, 8 September 2022 Werner (Talk | contribs) ← Previous diff |
Current revision Werner (Talk | contribs) |
||
Line 1: | Line 1: | ||
- | # | + | # |
- | # Simulated tempering for the V-shaped stationary distribution --- Metropolis | + | # Simulated tempering for the V-shaped stationary distribution --- Metropolis |
- | # algorithm | + | # algorithm |
- | # | + | # |
- | import random | + | import random |
- | import pylab | + | import pylab |
- | import numpy as np | + | import numpy as np |
- | for n in [10, 20, 40, 80, 160, 320]: | + | for n in [10, 20, 40, 80, 160, 320]: |
- | ReplicaChange = 0.1 | + | ReplicaChange = 0.1 |
- | const = 4.0 / n ** 2 | + | const = 4.0 / n ** 2 |
- | PiStat = {} | + | PiStat = {} |
- | Table = [] | + | Table = [] |
- | for x in range(1, n + 1): | + | for x in range(1, n + 1): |
- | Table.append((x, 0)) | + | Table.append((x, 0)) |
- | Table.append((x, 1)) | + | Table.append((x, 1)) |
- | # | + | # |
- | # factor of 1/2 because the total must be normalized | + | # factor of 1/2 because the total must be normalized |
- | # | + | # |
- | PiStat[(x, 0)] = 1.0 / float(n) / 2.0 | + | PiStat[(x, 0)] = 1.0 / float(n) / 2.0 |
- | PiStat[(x, 1)] = const * abs( (n + 1) / 2 - x) / 2.0 | + | PiStat[(x, 1)] = const * abs( (n + 1) / 2 - x) / 2.0 |
- | PiStat[(0, 0)] = 0.0 | + | PiStat[(0, 0)] = 0.0 |
- | PiStat[(0, 1)] = 0.0 | + | PiStat[(0, 1)] = 0.0 |
- | PiStat[(n + 1, 0)] = 0.0 | + | PiStat[(n + 1, 0)] = 0.0 |
- | PiStat[(n + 1, 1)] = 0.0 | + | PiStat[(n + 1, 1)] = 0.0 |
- | PTrans = np.eye(2 * n) | + | PTrans = np.eye(2 * n) |
- | Pi = np.zeros([2 * n]) | + | Pi = np.zeros([2 * n]) |
- | for x in range(1, n + 1): | + | for x in range(1, n + 1): |
- | for Rep in [0, 1]: | + | for Rep in [0, 1]: |
- | i = Table.index((x, Rep)) | + | i = Table.index((x, Rep)) |
- | Pi[i] = PiStat[(x, Rep)] | + | Pi[i] = PiStat[(x, Rep)] |
- | for Dir in [-1, 1]: | + | for Dir in [-1, 1]: |
- | if PiStat[(x + Dir, Rep)] > 0.0: | + | if PiStat[(x + Dir, Rep)] > 0.0: |
- | j = Table.index((x + Dir, Rep)) | + | j = Table.index((x + Dir, Rep)) |
- | PTrans[i, j] = min(1.0, PiStat[(x + Dir, Rep)] / PiStat[(x, Rep)]) / 2.0 | + | PTrans[i, j] = min(1.0, PiStat[(x + Dir, Rep)] / PiStat[(x, Rep)]) / 2.0 |
- | PTrans[i, i] -= PTrans[i, j] | + | PTrans[i, i] -= PTrans[i, j] |
- | PReplica = np.zeros((2 * n,2 * n)) | + | PReplica = np.zeros((2 * n,2 * n)) |
- | for x in range(1, n + 1): | + | for x in range(1, n + 1): |
- | i = Table.index((x,0)) | + | i = Table.index((x,0)) |
- | j = Table.index((x,1)) | + | j = Table.index((x,1)) |
- | PReplica[i, j] = ReplicaChange * min(1.0, PiStat[(x, 1)] / PiStat[(x, 0)]) | + | PReplica[i, j] = ReplicaChange * min(1.0, PiStat[(x, 1)] / PiStat[(x, 0)]) |
- | PReplica[i, i] = 1.0 - PReplica[i, j] | + | PReplica[i, i] = 1.0 - PReplica[i, j] |
- | PReplica[j, i] = ReplicaChange * min(1.0, PiStat[(x, 0)] / PiStat[(x, 1)]) | + | PReplica[j, i] = ReplicaChange * min(1.0, PiStat[(x, 0)] / PiStat[(x, 1)]) |
- | PReplica[j, j] = 1.0 - PReplica[j, i] | + | PReplica[j, j] = 1.0 - PReplica[j, i] |
- | P = PTrans @ PReplica | + | P = PTrans @ PReplica |
- | Pit = np.zeros([2 * n]) | + | Pit = np.zeros([2 * n]) |
- | Pit[0] = 1.0 | + | Pit[0] = 1.0 |
- | xvalues = [] | + | xvalues = [] |
- | yvalues = [] | + | yvalues = [] |
- | iter = 0 | + | iter = 0 |
- | while True: | + | while True: |
- | iter += 1 | + | iter += 1 |
- | Pit = Pit @ P | + | Pit = Pit @ P |
- | TVD = sum(np.absolute(Pi - Pit) / 2.0) | + | TVD = sum(np.absolute(Pi - Pit) / 2.0) |
- | xvalues.append(iter / float(n ** 2)) | + | xvalues.append(iter / float(n ** 2)) |
- | yvalues.append(TVD) | + | yvalues.append(TVD) |
- | if TVD < 0.1: break | + | if TVD < 0.1: break |
- | pylab.plot(xvalues,yvalues, label='$n =$ '+str(n)) | + | pylab.plot(xvalues,yvalues, label='$n =$ '+str(n)) |
- | pylab.legend(loc='upper right') | + | pylab.legend(loc='upper right') |
- | pylab.xlabel("$t/ n^2$ (rescaled time) ") | + | pylab.xlabel("$t/ n^2$ (rescaled time) ") |
- | pylab.ylabel("TVD") | + | pylab.ylabel("TVD") |
- | pylab.title("TVD rev tempering on the path graph of $n$ sites") | + | pylab.title("TVD rev tempering on the path graph of $n$ sites") |
- | pylab.show() | + | pylab.show() |
Current revision
# # Simulated tempering for the V-shaped stationary distribution --- Metropolis # algorithm # import random import pylab import numpy as np for n in [10, 20, 40, 80, 160, 320]: ReplicaChange = 0.1 const = 4.0 / n ** 2 PiStat = {} Table = []
for x in range(1, n + 1): Table.append((x, 0)) Table.append((x, 1)) # # factor of 1/2 because the total must be normalized # PiStat[(x, 0)] = 1.0 / float(n) / 2.0 PiStat[(x, 1)] = const * abs( (n + 1) / 2 - x) / 2.0 PiStat[(0, 0)] = 0.0 PiStat[(0, 1)] = 0.0 PiStat[(n + 1, 0)] = 0.0 PiStat[(n + 1, 1)] = 0.0 PTrans = np.eye(2 * n) Pi = np.zeros([2 * n]) for x in range(1, n + 1): for Rep in [0, 1]: i = Table.index((x, Rep)) Pi[i] = PiStat[(x, Rep)] for Dir in [-1, 1]: if PiStat[(x + Dir, Rep)] > 0.0: j = Table.index((x + Dir, Rep)) PTrans[i, j] = min(1.0, PiStat[(x + Dir, Rep)] / PiStat[(x, Rep)]) / 2.0 PTrans[i, i] -= PTrans[i, j]
PReplica = np.zeros((2 * n,2 * n)) for x in range(1, n + 1): i = Table.index((x,0)) j = Table.index((x,1)) PReplica[i, j] = ReplicaChange * min(1.0, PiStat[(x, 1)] / PiStat[(x, 0)]) PReplica[i, i] = 1.0 - PReplica[i, j] PReplica[j, i] = ReplicaChange * min(1.0, PiStat[(x, 0)] / PiStat[(x, 1)]) PReplica[j, j] = 1.0 - PReplica[j, i] P = PTrans @ PReplica Pit = np.zeros([2 * n]) Pit[0] = 1.0 xvalues = [] yvalues = [] iter = 0 while True: iter += 1 Pit = Pit @ P TVD = sum(np.absolute(Pi - Pit) / 2.0) xvalues.append(iter / float(n ** 2)) yvalues.append(TVD) if TVD < 0.1: break pylab.plot(xvalues,yvalues, label='$n =$ '+str(n)) pylab.legend(loc='upper right') pylab.xlabel("$t/ n^2$ (rescaled time) ") pylab.ylabel("TVD") pylab.title("TVD rev tempering on the path graph of $n$ sites") pylab.show()