0
# Core Nested Samplers
1
2
The main nested sampling implementations in UltraNest for Bayesian parameter estimation and model comparison. These classes provide the primary interface for conducting nested sampling analysis.
3
4
## Capabilities
5
6
### ReactiveNestedSampler
7
8
Advanced nested sampler with reactive exploration that adapts to the problem structure. This is the recommended sampler for most applications as it automatically adjusts sampling parameters based on the likelihood landscape.
9
10
```python { .api }
11
class ReactiveNestedSampler:
12
def __init__(
13
self,
14
param_names: list,
15
loglike: callable,
16
transform: callable = None,
17
derived_param_names: list = [],
18
wrapped_params: list = None,
19
resume: str = 'subfolder',
20
run_num: int = None,
21
log_dir: str = None,
22
num_test_samples: int = 2,
23
draw_multiple: bool = True,
24
num_bootstraps: int = 30,
25
vectorized: bool = False,
26
ndraw_min: int = 128,
27
ndraw_max: int = 65536,
28
storage_backend: str = 'hdf5',
29
warmstart_max_tau: float = -1
30
):
31
"""
32
Initialize a ReactiveNestedSampler.
33
34
Parameters:
35
- param_names (list): Names of parameters being sampled
36
- loglike (callable): Log-likelihood function accepting parameter array
37
- transform (callable, optional): Transform from unit cube [0,1]^n to parameter space
38
- derived_param_names (list): Names of derived parameters computed from main parameters
39
- wrapped_params (list, optional): Indices of circular/periodic parameters
40
- resume (str): Resume strategy ('resume', 'overwrite', 'subfolder', 'resume-similar')
41
- run_num (int, optional): Run number for organizing multiple runs
42
- log_dir (str, optional): Directory for output files
43
- num_test_samples (int): Number of test samples for validation
44
- draw_multiple (bool): Enable adaptive multiple point drawing
45
- num_bootstraps (int): Number of bootstrap rounds for error estimation
46
- vectorized (bool): Whether likelihood function accepts multiple points
47
- ndraw_min (int): Minimum number of points to draw per iteration
48
- ndraw_max (int): Maximum number of points to draw per iteration
49
- storage_backend (str): Storage backend ('hdf5', 'tsv', 'csv')
50
- warmstart_max_tau (float): Disorder tolerance for warm restarts
51
"""
52
53
def run(self):
54
"""
55
Execute the nested sampling run.
56
57
Returns:
58
dict: Complete results including evidence, posterior samples, and diagnostics
59
"""
60
61
def run_iter(self):
62
"""
63
Iterator interface for nested sampling execution.
64
65
Yields:
66
dict: Intermediate results at each iteration
67
"""
68
69
def print_results(self, use_unicode: bool = True):
70
"""
71
Print a summary of sampling results.
72
73
Parameters:
74
- use_unicode (bool): Use Unicode characters for formatting
75
"""
76
77
def plot(self):
78
"""Create diagnostic plots for the sampling run."""
79
80
def plot_corner(self):
81
"""Create corner plot of posterior distributions."""
82
83
def plot_trace(self):
84
"""Create trace plots showing parameter evolution."""
85
86
def plot_run(self):
87
"""Create run diagnostic plots."""
88
89
def store_tree(self):
90
"""Store the sampling tree for detailed analysis."""
91
92
@property
93
def results(self):
94
"""
95
dict: Dictionary containing final sampling results including:
96
- 'logz': Log evidence estimate
97
- 'logzerr': Log evidence uncertainty
98
- 'posterior': Posterior samples and statistics
99
- 'samples': Raw samples from nested sampling
100
- 'loglikelihood': Log-likelihood values
101
- 'information': Information content (H)
102
"""
103
104
@property
105
def stepsampler(self):
106
"""Current step sampler instance used for parameter space exploration."""
107
```
108
109
#### Usage Example
110
111
```python
112
import numpy as np
113
from ultranest import ReactiveNestedSampler
114
115
# Define parameters
116
param_names = ['amplitude', 'mean', 'sigma']
117
118
# Define log-likelihood (Gaussian model)
119
def loglike(theta):
120
amplitude, mean, sigma = theta
121
# Your likelihood calculation
122
model_prediction = amplitude * np.exp(-0.5 * ((x_data - mean) / sigma)**2)
123
chi2 = np.sum((y_data - model_prediction)**2 / yerr_data**2)
124
return -0.5 * chi2
125
126
# Define prior transform
127
def prior_transform(cube):
128
params = cube.copy()
129
params[0] = cube[0] * 10 # amplitude: 0 to 10
130
params[1] = cube[1] * 20 - 10 # mean: -10 to 10
131
params[2] = cube[2] * 5 # sigma: 0 to 5
132
return params
133
134
# Create and run sampler
135
sampler = ReactiveNestedSampler(
136
param_names=param_names,
137
loglike=loglike,
138
transform=prior_transform,
139
resume='subfolder'
140
)
141
142
result = sampler.run()
143
```
144
145
### NestedSampler
146
147
Traditional nested sampler with fixed number of live points. Provides more direct control over sampling parameters but requires manual tuning for optimal performance.
148
149
```python { .api }
150
class NestedSampler:
151
def __init__(
152
self,
153
param_names: list,
154
loglike: callable,
155
transform: callable = None,
156
derived_param_names: list = [],
157
resume: str = 'subfolder',
158
run_num: int = None,
159
log_dir: str = 'logs/test',
160
num_live_points: int = 1000,
161
vectorized: bool = False,
162
wrapped_params: list = []
163
):
164
"""
165
Initialize a traditional NestedSampler.
166
167
Parameters:
168
- param_names (list): Names of parameters being sampled
169
- loglike (callable): Log-likelihood function
170
- transform (callable, optional): Prior transform function
171
- derived_param_names (list): Names of derived parameters
172
- resume (str): Resume strategy
173
- run_num (int, optional): Run identifier
174
- log_dir (str): Output directory
175
- num_live_points (int): Fixed number of live points to maintain
176
- vectorized (bool): Whether likelihood accepts multiple points
177
- wrapped_params (list): Indices of circular parameters
178
"""
179
180
def run(self):
181
"""
182
Execute nested sampling with fixed live points.
183
184
Returns:
185
dict: Sampling results
186
"""
187
188
def print_results(self):
189
"""Print summary of results."""
190
191
def plot(self):
192
"""Generate diagnostic plots."""
193
```
194
195
### File Reading and Results Access
196
197
Access stored nested sampling results from previous runs.
198
199
```python { .api }
200
def read_file(
201
log_dir: str,
202
x_dim: int,
203
num_bootstraps: int = 20,
204
random: bool = True,
205
verbose: bool = False,
206
check_insertion_order: bool = True
207
):
208
"""
209
Read UltraNest output files from a completed run.
210
211
Parameters:
212
- log_dir (str): Directory containing output files
213
- x_dim (int): Dimensionality of parameter space
214
- num_bootstraps (int): Number of bootstraps for estimating logZ
215
- random (bool): Use randomization for volume estimation
216
- verbose (bool): Show progress during reading
217
- check_insertion_order (bool): Perform MWW insertion order test for convergence assessment
218
219
Returns:
220
dict: Results dictionary with same structure as sampler.results
221
"""
222
```
223
224
### Warm Starting
225
226
Resume sampling from similar previous runs to improve efficiency.
227
228
```python { .api }
229
def warmstart_from_similar_file(**kwargs):
230
"""
231
Initialize sampling using similar previous run as starting point.
232
233
Returns:
234
Initialization data for faster convergence
235
"""
236
```
237
238
## Advanced Configuration
239
240
### Vectorized Functions
241
242
For improved performance with expensive likelihood functions:
243
244
```python
245
# Vectorized likelihood function
246
def vectorized_loglike(theta_array):
247
"""
248
Compute log-likelihood for multiple parameter sets.
249
250
Parameters:
251
- theta_array (array): Shape (n_points, n_params)
252
253
Returns:
254
array: Log-likelihood values, shape (n_points,)
255
"""
256
return np.array([loglike(theta) for theta in theta_array])
257
258
sampler = ReactiveNestedSampler(
259
param_names=param_names,
260
loglike=vectorized_loglike,
261
vectorized=True # Enable vectorized processing
262
)
263
```
264
265
### Derived Parameters
266
267
Compute additional quantities from main parameters:
268
269
```python
270
def loglike_with_derived(theta):
271
x, y = theta
272
# Compute derived parameter
273
derived = x**2 + y**2
274
# Return likelihood and derived parameters
275
return -0.5 * (x**2 + y**2), np.array([derived])
276
277
sampler = ReactiveNestedSampler(
278
param_names=['x', 'y'],
279
loglike=loglike_with_derived,
280
derived_param_names=['radius_squared']
281
)
282
```
283
284
### Wrapped Parameters
285
286
Handle circular/periodic parameters (e.g., angles):
287
288
```python
289
sampler = ReactiveNestedSampler(
290
param_names=['x', 'y', 'angle'],
291
loglike=loglike,
292
wrapped_params=[2] # Angle parameter is circular
293
)
294
```