@@ -297,7 +297,22 @@ def competence(var):
297
297
298
298
299
299
class BinaryGibbsMetropolis (ArrayStep ):
300
- """A Metropolis-within-Gibbs step method optimized for binary variables"""
300
+ """A Metropolis-within-Gibbs step method optimized for binary variables
301
+
302
+ Parameters
303
+ ----------
304
+ vars : list
305
+ List of variables for sampler
306
+ order : list or 'random'
307
+ List of integers indicating the Gibbs update order
308
+ e.g., [0, 2, 1, ...]. Default is random
309
+ transit_p : float
310
+ The diagonal of the transition kernel. A value > .5 gives anticorrelated proposals,
311
+ which resulting in more efficient antithetical sampling.
312
+ model : PyMC Model
313
+ Optional model for sampling step. Defaults to None (taken from context).
314
+
315
+ """
301
316
name = 'binary_gibbs_metropolis'
302
317
303
318
def __init__ (self , vars , order = 'random' , transit_p = .8 , model = None ):
@@ -333,12 +348,14 @@ def astep(self, q0, logp):
333
348
logp_curr = logp (q )
334
349
335
350
for idx in order :
336
- state = [q [idx ], True - q [idx ]]
337
- curr_val , q [idx ] = q [idx ], state [int (nr .rand () < self .transit_p )]
338
- logp_prop = logp (q )
339
- q [idx ], accepted = metrop_select (logp_prop - logp_curr , q [idx ], curr_val )
340
- if accepted :
341
- logp_curr = logp_prop
351
+ # No need to do metropolis update if the same value is proposed,
352
+ # as you will get the same value regardless of accepted or reject
353
+ if nr .rand () < self .transit_p :
354
+ curr_val , q [idx ] = q [idx ], True - q [idx ]
355
+ logp_prop = logp (q )
356
+ q [idx ], accepted = metrop_select (logp_prop - logp_curr , q [idx ], curr_val )
357
+ if accepted :
358
+ logp_curr = logp_prop
342
359
343
360
return q
344
361
0 commit comments