Samples Scheduling

Once you have created a Sampler, you can schedule the execution of MLMC samples in different ways.

This tutorial demonstrates two approaches: 1. Scheduling with a prescribed number of samples. 2. Scheduling to reach a target variance automatically.

1. Prescribing an Exact Number of Samples

In this approach, you explicitly set how many samples should be created at each MLMC level.

Set the number of samples for each level:

n_samples = [100, 75, 50]
sampler.set_initial_n_samples(n_samples)

Schedule the prescribed samples:

sampler.schedule_samples()

Wait until all samples have finished:

running = 1
while running > 0:
    running = 0
    running += sampler.ask_sampling_pool_for_samples()

2. Prescribing a Target Variance

This approach automatically determines the number of samples needed to achieve a desired target variance.

Define the target variance and the number of moment functions used for estimation:

target_var = 1e-4
n_moments = 10

As before, initialize and run a first batch of samples (automatically ranging from 100 samples on the coarsest level to 10 on the finest level):

sampler.set_initial_n_samples()
sampler.schedule_samples()

running = 1
while running > 0:
    running = 0
    running += sampler.ask_sampling_pool_for_samples()

Creating the Quantity and Moment Functions

Next, create a mlmc.quantity.quantity.Quantity object representing the MLMC results.

root_quantity = mlmc.make_root_quantity(
    storage=sampler.sample_storage,
    q_specs=sampler.sample_storage.load_result_format()
)

The root_quantity contains both the data structure and the sampled values.

Now we create the moment functions and an mlmc.estimator.Estimate instance to perform statistical estimation.

true_domain = mlmc.Estimate.estimate_domain(root_quantity, sample_storage)
moments_fn = mlmc.Legendre(n_moments, true_domain)

estimate_obj = mlmc.Estimate(
    root_quantity,
    sample_storage=sampler.sample_storage,
    moments_fn=moments_fn
)

Estimating Variances and Computational Cost

From the finished samples, estimate the variance of moments and the average computational cost per sample for each level:

variances, n_ops = estimate_obj.estimate_diff_vars_regression(sampler.n_finished_samples)

Estimating the Required Number of Samples

Using the estimated variances and costs, determine the number of samples required to meet the target variance:

from mlmc.estimator import estimate_n_samples_for_target_variance

n_estimated = estimate_n_samples_for_target_variance(
    target_var, variances, n_ops, n_levels=sampler.n_levels
)

Iterative Sampling Process

The sampling algorithm incrementally schedules additional samples until the estimated number of required samples is reached.

while not sampler.process_adding_samples(n_estimated):
    # Recalculate estimates based on completed samples
    variances, n_ops = estimate_obj.estimate_diff_vars_regression(sampler._n_scheduled_samples)
    n_estimated = estimate_n_samples_for_target_variance(
        target_var, variances, n_ops, n_levels=sampler.n_levels
    )

Finally, wait until all samples are completed:

running = 1
while running > 0:
    running = 0
    running += sampler.ask_sampling_pool_for_samples()

Notes

  • The sampling algorithm automatically adjusts the number of samples per level based on estimated moment variances.

  • The choice of moment functions (e.g. mlmc.Legendre) influences the total number of samples needed.

  • For most cases, the default Legendre polynomials provide a good balance between accuracy and computational cost.

Summary

In this tutorial, you learned how to: - Schedule MLMC samples with a fixed number of samples per level. - Automatically adapt the number of samples to achieve a target variance. - Use moment functions and variance regression for optimal sample allocation.

Continue to the next section for Results Postprocessing.