From 0b2ce3c50899f1c58e9f9386db39a87f9b46e5eb Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 22:29:27 -0400 Subject: [PATCH 1/8] Update documentation --- pymc3/sampling.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 5806a42ee5..599391f4f0 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -52,7 +52,8 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): One or more step functions that have been assigned to some subset of the model's parameters. Defaults to None (no assigned variables). selected_steps: dictionary of step methods and variables - The step methods and the variables that have were assigned to them. + Variables with selected step methods. Keys are the step methods, and + values are the variables that have been assigned to them. step_kwargs : dict Parameters for the samplers. Keys are the lower case names of the step method, values a dict of arguments. @@ -100,7 +101,7 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, ---------- model : Model object A fully-specified model object - step : step function or vector of step functions + step : step function or list of step functions One or more step functions that have been assigned to some subset of the model's parameters. Defaults to None (no assigned variables). methods : vector of step method classes @@ -119,9 +120,9 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, assigned_vars = set() if step is not None: - try: + try: # If `step` is a list, concatenate steps += list(step) - except TypeError: + except TypeError: # If `step` is a single step method, append steps.append(step) for step in steps: try: @@ -135,7 +136,7 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, selected_steps = defaultdict(list) for var in model.free_RVs: if var not in assigned_vars: - # determine if a gradient can be computed + # Determine if a gradient can be computed has_gradient = var.dtype not in discrete_types if has_gradient: try: @@ -144,7 +145,7 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, NotImplementedError, tg.NullTypeGradError): has_gradient = False - # select the best method + # Select the method with maximum competence selected = max(methods, key=lambda method, var=var, has_gradient=has_gradient: method._competence(var, has_gradient)) From 4cb8de7931fe7f7930cb54b8e0cdc113bc56b89f Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 22:29:53 -0400 Subject: [PATCH 2/8] Add newline for readability --- pymc3/sampling.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 599391f4f0..d8525bff18 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -124,6 +124,7 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, steps += list(step) except TypeError: # If `step` is a single step method, append steps.append(step) + for step in steps: try: assigned_vars = assigned_vars.union(set(step.vars)) From 0ec28b9254c78d88af9fc604173227dc389b5802 Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 23:00:12 -0400 Subject: [PATCH 3/8] Do without assigned_vars --- pymc3/sampling.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index d8525bff18..78a892481a 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -117,25 +117,27 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, List of step methods associated with the model's variables. """ steps = [] - assigned_vars = set() + selected_steps = defaultdict(list) if step is not None: try: # If `step` is a list, concatenate steps += list(step) - except TypeError: # If `step` is a single step method, append + except TypeError: # If `step` is not iterable, append steps.append(step) for step in steps: try: - assigned_vars = assigned_vars.union(set(step.vars)) + selected_steps[step] += step.vars except AttributeError: for method in step.methods: - assigned_vars = assigned_vars.union(set(method.vars)) + selected_steps[step] += method.vars # Use competence classmethods to select step methods for remaining # variables - selected_steps = defaultdict(list) for var in model.free_RVs: + # Flatten assigned variables into a set + assigned_vars = set(var for lst in selected_steps.values() + for var in lst) if var not in assigned_vars: # Determine if a gradient can be computed has_gradient = var.dtype not in discrete_types From 22ab0a108aedec1a61d26cea79f1e356ec54833b Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 23:21:14 -0400 Subject: [PATCH 4/8] Update docstring --- pymc3/sampling.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 78a892481a..9eb2d776f6 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -48,7 +48,7 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): ---------- model : Model object A fully-specified model object - step : step function or vector of step functions + step : step function or list of step functions One or more step functions that have been assigned to some subset of the model's parameters. Defaults to None (no assigned variables). selected_steps: dictionary of step methods and variables @@ -72,8 +72,7 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): continue args = step_kwargs.get(step_class.name, {}) used_keys.add(step_class.name) - step = step_class(vars=vars, **args) - steps.append(step) + steps.append(step_class) unused_args = set(step_kwargs).difference(used_keys) if unused_args: From 7995fe786fdfcc3eb63eb2089783b0c831c5a20a Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 23:29:04 -0400 Subject: [PATCH 5/8] Clearer variable names --- pymc3/sampling.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 9eb2d776f6..0b4573662c 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -66,15 +66,15 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): if step_kwargs is None: step_kwargs = {} - used_keys = set() - for step_class, vars in selected_steps.items(): - if len(vars) == 0: + used_args = set() + for step, var_list in selected_steps.items(): + if len(var_list) == 0: continue - args = step_kwargs.get(step_class.name, {}) - used_keys.add(step_class.name) - steps.append(step_class) + args = step_kwargs.get(step.name, {}) + used_args.add(step.name) + steps.append(step) - unused_args = set(step_kwargs).difference(used_keys) + unused_args = set(step_kwargs).difference(used_args) if unused_args: raise ValueError('Unused step method arguments: %s' % unused_args) From 976627a4df63f7d956ea1e60ede9b68b7ce9193c Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 16 Sep 2018 23:29:17 -0400 Subject: [PATCH 6/8] Friendlier error message --- pymc3/sampling.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 0b4573662c..06c77215d8 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -76,7 +76,8 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): unused_args = set(step_kwargs).difference(used_args) if unused_args: - raise ValueError('Unused step method arguments: %s' % unused_args) + raise ValueError('Unused arguments for step method(s): %s' + % [s.title() for s in unused_args]) if len(steps) == 1: steps = steps[0] From 99b63c9258363eb915ced4c32a1f1239a4a90a15 Mon Sep 17 00:00:00 2001 From: George Ho Date: Mon, 17 Sep 2018 08:48:32 -0400 Subject: [PATCH 7/8] Add names to compound and elliptical slice --- pymc3/step_methods/compound.py | 1 + pymc3/step_methods/elliptical_slice.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pymc3/step_methods/compound.py b/pymc3/step_methods/compound.py index 8deb0555fd..ac2ca9a777 100644 --- a/pymc3/step_methods/compound.py +++ b/pymc3/step_methods/compound.py @@ -9,6 +9,7 @@ class CompoundStep(object): """Step method composed of a list of several other step methods applied in sequence.""" + name = 'compound' def __init__(self, methods): self.methods = list(methods) diff --git a/pymc3/step_methods/elliptical_slice.py b/pymc3/step_methods/elliptical_slice.py index 5936c554c0..ed58035df8 100644 --- a/pymc3/step_methods/elliptical_slice.py +++ b/pymc3/step_methods/elliptical_slice.py @@ -66,7 +66,7 @@ class EllipticalSlice(ArrayStep): Artificial Intelligence and Statistics (AISTATS), JMLR W&CP 9:541-548, 2010. """ - + name = 'elliptical_slice' default_blocked = True def __init__(self, vars=None, prior_cov=None, prior_chol=None, model=None, From 61f8204859dc2fa2c9d43e88d75bf7ef980100d2 Mon Sep 17 00:00:00 2001 From: George Ho Date: Sun, 23 Sep 2018 10:50:54 -0400 Subject: [PATCH 8/8] MAINT: remove title, use iterable in docs --- pymc3/sampling.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymc3/sampling.py b/pymc3/sampling.py index 06c77215d8..5988beb564 100644 --- a/pymc3/sampling.py +++ b/pymc3/sampling.py @@ -48,7 +48,7 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): ---------- model : Model object A fully-specified model object - step : step function or list of step functions + step : step function or iterable of step functions One or more step functions that have been assigned to some subset of the model's parameters. Defaults to None (no assigned variables). selected_steps: dictionary of step methods and variables @@ -77,7 +77,7 @@ def instantiate_steppers(model, steps, selected_steps, step_kwargs=None): unused_args = set(step_kwargs).difference(used_args) if unused_args: raise ValueError('Unused arguments for step method(s): %s' - % [s.title() for s in unused_args]) + % [s for s in unused_args]) if len(steps) == 1: steps = steps[0] @@ -101,7 +101,7 @@ def assign_step_methods(model, step=None, methods=STEP_METHODS, ---------- model : Model object A fully-specified model object - step : step function or list of step functions + step : step function or iterable of step functions One or more step functions that have been assigned to some subset of the model's parameters. Defaults to None (no assigned variables). methods : vector of step method classes