0
# Proposal Moves
1
2
emcee provides a comprehensive collection of proposal move algorithms for generating new walker positions during MCMC sampling. These moves can be used individually or combined in weighted ensembles to optimize sampling performance for different types of problems.
3
4
## Capabilities
5
6
### Base Move Classes
7
8
Abstract base classes that define the move interface and common functionality.
9
10
```python { .api }
11
class Move:
12
"""Abstract base class for all moves."""
13
14
def tune(self, state, accepted):
15
"""
16
Tune move parameters based on acceptance history.
17
18
Args:
19
state: Current ensemble state
20
accepted: Boolean array indicating accepted proposals
21
"""
22
23
def update(self, old_state, new_state, accepted, subset=None):
24
"""
25
Update walker states with accepted proposals.
26
27
Args:
28
old_state: Current ensemble state
29
new_state: Proposed ensemble state
30
accepted: Boolean array indicating accepted proposals
31
subset: Subset of walkers to update
32
33
Returns:
34
State: Updated ensemble state
35
"""
36
37
class RedBlueMove(Move):
38
"""Base class for red-blue ensemble moves."""
39
40
def get_proposal(self, s, c, random):
41
"""
42
Generate proposals for red-blue moves.
43
44
Args:
45
s: Active walker positions
46
c: Complementary walker positions
47
random: Random number generator
48
49
Returns:
50
tuple: (proposed_positions, log_proposal_factors)
51
"""
52
53
class MHMove(Move):
54
"""Base class for Metropolis-Hastings style moves."""
55
56
def propose(self, model, state):
57
"""
58
Generate proposal state.
59
60
Args:
61
model: Model object containing log probability function
62
state: Current ensemble state
63
64
Returns:
65
State: Proposed ensemble state
66
"""
67
```
68
69
### Stretch Move
70
71
The default Goodman & Weare stretch move, highly effective for most problems.
72
73
```python { .api }
74
class StretchMove(RedBlueMove):
75
def __init__(self, a: float = 2.0):
76
"""
77
Initialize stretch move.
78
79
Args:
80
a: Stretch scale parameter (default: 2.0)
81
"""
82
```
83
84
### Walk Move
85
86
Simple random walk move for local exploration.
87
88
```python { .api }
89
class WalkMove(RedBlueMove):
90
def __init__(self, s: float = None):
91
"""
92
Initialize walk move.
93
94
Args:
95
s: Step size parameter
96
"""
97
```
98
99
### Differential Evolution Moves
100
101
Moves based on differential evolution algorithms for efficient exploration.
102
103
```python { .api }
104
class DEMove(RedBlueMove):
105
def __init__(self, sigma: float = 1e-5, gamma0: float = None):
106
"""
107
Initialize differential evolution move.
108
109
Args:
110
sigma: Scaling parameter for random perturbation
111
gamma0: Base scaling factor (default: 2.38 / sqrt(2 * ndim))
112
"""
113
114
class DESnookerMove(RedBlueMove):
115
def __init__(self, sigma: float = 1e-5, gammas: list = None):
116
"""
117
Initialize differential evolution snooker move.
118
119
Args:
120
sigma: Scaling parameter
121
gammas: List of scaling factors for different move types
122
"""
123
```
124
125
### Kernel Density Estimation Move
126
127
Advanced move using kernel density estimation for proposal generation.
128
129
```python { .api }
130
class KDEMove(RedBlueMove):
131
def __init__(self, bw_method=None):
132
"""
133
Initialize KDE move.
134
135
Args:
136
bw_method: Bandwidth selection method for KDE
137
"""
138
```
139
140
### Gaussian Move
141
142
Metropolis-Hastings move with Gaussian proposals.
143
144
```python { .api }
145
class GaussianMove(MHMove):
146
def __init__(self, cov, mode: str = "vector", factor=None):
147
"""
148
Initialize Gaussian move.
149
150
Args:
151
cov: Covariance matrix or proposal scale
152
mode: Proposal mode ("vector", "random", "sequential")
153
factor: Scaling factor for covariance
154
"""
155
```
156
157
### Generic Metropolis-Hastings Move
158
159
Generic MH move for custom proposal functions.
160
161
```python { .api }
162
class MHMove(Move):
163
def __init__(self, proposal_function):
164
"""
165
Initialize generic MH move.
166
167
Args:
168
proposal_function: Function generating proposals
169
"""
170
```
171
172
## Usage Examples
173
174
### Using Single Moves
175
176
```python
177
import emcee
178
from emcee import moves
179
import numpy as np
180
181
def log_prob(theta):
182
return -0.5 * np.sum(theta**2)
183
184
# Use stretch move (default)
185
sampler = emcee.EnsembleSampler(32, 2, log_prob)
186
187
# Use specific move
188
stretch_move = moves.StretchMove(a=2.5)
189
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=stretch_move)
190
191
# Use DE move
192
de_move = moves.DEMove(sigma=1e-4)
193
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=de_move)
194
```
195
196
### Combining Multiple Moves
197
198
```python
199
# List of moves (equal weight)
200
move_list = [
201
moves.StretchMove(),
202
moves.DEMove(),
203
moves.WalkMove()
204
]
205
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=move_list)
206
207
# Weighted moves
208
weighted_moves = [
209
(moves.StretchMove(), 0.6),
210
(moves.DEMove(), 0.3),
211
(moves.WalkMove(), 0.1)
212
]
213
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=weighted_moves)
214
```
215
216
### Gaussian Move with Covariance
217
218
```python
219
# Define covariance matrix
220
cov = np.array([[1.0, 0.5], [0.5, 2.0]])
221
gaussian_move = moves.GaussianMove(cov)
222
223
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=gaussian_move)
224
```
225
226
### KDE Move for Complex Distributions
227
228
```python
229
# KDE move adapts to the shape of the distribution
230
kde_move = moves.KDEMove()
231
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=kde_move)
232
233
# Can specify bandwidth method
234
kde_move = moves.KDEMove(bw_method='scott')
235
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=kde_move)
236
```
237
238
### Custom Move Tuning
239
240
```python
241
# Move that adapts during sampling
242
class AdaptiveMove(moves.Move):
243
def __init__(self, initial_scale=1.0):
244
self.scale = initial_scale
245
self.n_accepted = 0
246
self.n_total = 0
247
248
def tune(self, state, accepted):
249
self.n_accepted += np.sum(accepted)
250
self.n_total += len(accepted)
251
252
# Adjust scale based on acceptance rate
253
acceptance_rate = self.n_accepted / self.n_total
254
if acceptance_rate > 0.5:
255
self.scale *= 1.1
256
elif acceptance_rate < 0.2:
257
self.scale *= 0.9
258
259
# Use with tuning enabled
260
custom_move = AdaptiveMove()
261
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=custom_move)
262
sampler.run_mcmc(pos, 1000, tune=True)
263
```
264
265
### Move Selection Strategy
266
267
```python
268
# Different strategies for different problem types
269
270
# For well-behaved, unimodal distributions
271
standard_moves = moves.StretchMove(a=2.0)
272
273
# For multimodal distributions
274
multimodal_moves = [
275
(moves.StretchMove(), 0.4),
276
(moves.DEMove(), 0.4),
277
(moves.KDEMove(), 0.2)
278
]
279
280
# For highly correlated parameters
281
correlated_moves = [
282
(moves.StretchMove(), 0.5),
283
(moves.DEMove(), 0.3),
284
(moves.GaussianMove(cov_matrix), 0.2)
285
]
286
287
# For local exploration
288
local_moves = moves.WalkMove(s=0.1)
289
```