@@ -107,13 +107,16 @@ class Sampler:
107107 Metric used for determining the next temperature (``beta``) level (default is ``metric="ess"``).
108108 Options are ``"ess"`` (Effective Sample Size) or ``"uss"`` (Unique Sample Size). The metric
109109 is used to determine the next temperature level based on the ESS or USS of the importance
110- weights. If the ESS or USS of the importance weights is below the target threshold, the temperature
111- is increased. If the ESS or USS is above the target threshold, the temperature is decreased. The
112- target threshold is set by the ``n_effective`` parameter.
113- n_prior : int
114- Number of prior samples to draw (default is ``n_prior=2*(n_effective//n_active)*n_active``). This
115- is used to initialise the particles at the beginning of the run. The prior samples are used to
116- warm-up the sampler and ensure that the particles are well distributed across the prior volume.
110+ weights. If the ESS or USS of the importance weights is below the target threshold, the
111+ temperature is increased. If the ESS or USS is above the target threshold, the temperature
112+ is decreased. The target threshold is set by the ``n_effective`` parameter.
113+
114+ Note
115+ ----
116+ The sampler uses an adaptive temperature scheduler that automatically maintains
117+ beta=0 (prior sampling) until the effective sample size reaches n_effective.
118+ This adaptive warmup ensures sufficient prior samples are accumulated before
119+ transitioning to tempered sampling, without requiring a preset iteration count.
117120 sample : ``str``
118121 Type of MCMC sampler to use (default is ``sample="tpcn"``). Options are
119122 ``"pcn"`` (t-preconditioned Crank-Nicolson) or ``"rwm"`` (Random-walk Metropolis).
@@ -164,7 +167,6 @@ def __init__(
164167 split_threshold : float = 1.0 ,
165168 n_max_clusters : Optional [int ] = None ,
166169 metric : str = "ess" ,
167- n_prior : Optional [int ] = None ,
168170 sample : str = "tpcn" ,
169171 n_steps : Optional [int ] = None ,
170172 n_max_steps : Optional [int ] = None ,
@@ -326,17 +328,6 @@ def __init__(
326328 else :
327329 self .resample = resample
328330
329- # Prior samples to draw
330- if n_prior is None :
331- self .n_prior = int (
332- 2 * np .maximum (self .n_effective // self .n_active , 1 ) * self .n_active
333- )
334- else :
335- self .n_prior = int (np .maximum (n_prior / self .n_active , 1 ) * self .n_active )
336- self .prior_samples = None
337-
338- self .n_warmup_iters = None # Set in run()
339-
340331 self .progress = None
341332 self .pbar = None
342333
@@ -434,10 +425,7 @@ def run(
434425
435426 self .n_total = int (n_total )
436427
437- # Number of warmup iterations (prior sampling at beta=0)
438- self .n_warmup_iters = self .n_prior // self .n_active
439-
440- # Run PS loop (includes warmup iterations at beta=0)
428+ # Run PS loop (adaptive warmup and annealing)
441429 while self ._not_termination ():
442430 self .sample (save_every = save_every , t0 = t0 )
443431
@@ -689,12 +677,8 @@ def _train(self):
689677 current_particles : dict
690678 Dictionary containing the updated particles.
691679 """
692- # Skip training during warmup ( beta=0) - use simple isotropic proposal
680+ # Skip training at beta=0 (mutation draws fresh prior samples)
693681 if self .beta == 0.0 :
694- self .means = np .array ([[0.5 ] * self .n_dim ])
695- self .covariances = np .array ([np .eye (self .n_dim ) * 0.1 ])
696- self .degrees_of_freedom = np .array ([self .DOF_FALLBACK ])
697- self .K = 1
698682 return
699683
700684 if self .clustering and (self .iter % self .cluster_every == 0 or self .iter == 0 ):
@@ -815,18 +799,12 @@ def _reweight(self):
815799 self .iter += 1
816800 self .pbar .update_iter ()
817801
818- # During warmup phase, keep beta=0 to accumulate prior samples
819- if self .iter <= self . n_warmup_iters :
802+ # Handle first iteration (no particles yet)
803+ if len ( self .particles . past . get ( "beta" , [])) == 0 :
820804 self .beta = 0.0
821805 self .logz = 0.0
822806 self .ess = self .n_effective
823- # Uniform weights during warmup
824- n_particles = (
825- len (self .particles .get ("logl" , flat = True ))
826- if self .iter > 1
827- else self .n_active
828- )
829- self .weights = np .ones (n_particles ) / n_particles
807+ self .weights = np .ones (self .n_active ) / self .n_active
830808 self .pbar .update_stats (
831809 dict (beta = self .beta , ESS = int (self .ess ), logZ = self .logz )
832810 )
0 commit comments