Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  1. # Modified from original implementation by Dominik Wabersich (2013)
  2.  
  3. import numpy as np
  4. import numpy.random as nr
  5.  
  6. from .arraystep import ArrayStep, Competence
  7. from ..model import modelcontext
  8. from ..theanof import inputvars
  9. from ..vartypes import continuous_types
  10.  
  11. __all__ = ['Slice']
  12.  
  13.  
  14. class Slice(ArrayStep):
  15. """
  16. Univariate slice sampler step method
  17.  
  18. Parameters
  19. ----------
  20. vars : list
  21. List of variables for sampler.
  22. w : float
  23. Initial width of slice (Defaults to 1).
  24. tune : bool
  25. Flag for tuning (Defaults to True).
  26. model : PyMC Model
  27. Optional model for sampling step. Defaults to None (taken from context).
  28.  
  29. """
  30. name = 'slice'
  31. default_blocked = False
  32.  
  33. def __init__(self, vars=None, w=1., tune=True, model=None, **kwargs):
  34. self.model = modelcontext(model)
  35. self.w = w
  36. self.tune = tune
  37. # self.w_sum = 0 #probably we don't need it now
  38. self.n_tunes = 0.
  39.  
  40. if vars is None:
  41. vars = self.model.cont_vars
  42. vars = inputvars(vars)
  43.  
  44. super(Slice, self).__init__(vars, [self.model.fastlogp], **kwargs)
  45.  
  46. def astep(self, q0, logp):
  47. self.w = np.resize(self.w, len(q0)) # this is a repmat
  48. q = np.copy(q0) # TODO: find out if we need this
  49. ql = np.copy(q0) # l for left boundary
  50. qr = np.copy(q0) # r for right boudary
  51. for i in range(len(q0)):
  52. y = logp(q) - nr.standard_exponential() #uniformly sample from 0 to p(q), but in log space
  53. ql[i] = q[i] - nr.uniform(0,self.w[i])
  54. qr[i] = q[i] + self.w[i]
  55. # Stepping out procedure
  56. while(y<=logp(ql)): #changed lt to leq for locally uniform posteriors
  57. ql[i] -= self.w[i]
  58. while(y<=logp(qr)):
  59. qr[i] += self.w[i]
  60.  
  61.  
  62. q[i] = nr.uniform(ql[i], qr[i])
  63. while logp(q) < y: # Changed leq to lt, to accomodate for locally flat posteriors
  64. # Sample uniformly from slice
  65. if q[i] > q0[i]:
  66. qr[i] = q[i]
  67. elif q[i] < q0[i]:
  68. ql[i] = q[i]
  69. q[i] = nr.uniform(ql[i], qr[i])
  70.  
  71. if self.tune: # I was under impression from MacKays lectures that slice width can be tuned without
  72. # breaking markovianness. Can we do it regardless of self.tune?(@madanh)
  73. self.w[i] = self.w[i]*(self.n_tunes/(self.n_tunes+1))+\
  74. (qr[i]-ql[i])/(self.n_tunes+1) # same as before
  75. #unobvious and important: return qr and ql to the same point
  76. qr[i]=q[i]
  77. ql[i]=q[i]
  78. if self.tune:
  79. self.n_tunes+=1
  80. return q
  81.  
  82. @staticmethod
  83. def competence(var):
  84. if var.dtype in continuous_types:
  85. if not var.shape:
  86. return Competence.PREFERRED
  87. return Competence.COMPATIBLE
  88. return Competence.INCOMPATIBLE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement