By default, RocketPy's Monte Carlo simulations sample parameters independently. To model correlations between parameters (e.g., correlated wind speeds on the X and Y axes), you must implement a CustomSampler and use a shared generator object.
The Core Pattern:
- Create a common generator class: This class generates multivariate samples (e.g., using
np.random.multivariate_normal) and stores them in a list. - Implement multiple
CustomSampler subclasses: Each subclass represents one parameter. Instead of generating new random numbers, these samplers call the shared generator to retrieve specific indices/axes from the pre-generated sample list. - Inject samplers into Stochastic objects: Pass the custom sampler instances into the relevant arguments of stochastic classes (like
StochasticEnvironment).
from rocketpy import Environment, StochasticEnvironment
from datetime import datetime, timedelta
import numpy as np
# 1. Define a shared generator to handle correlations
class BivariateGaussianGenerator:
def __init__(self, mean, cov, seed=None):
self.mean = mean
self.cov = cov
self.samples_list = []
self.samples_generated = 0
self.used_samples_x = 0
self.used_samples_y = 0
self.generate_samples(1000)
def generate_samples(self, n_samples=1):
samples = np.random.multivariate_normal(self.mean, self.cov, n_samples)
self.samples_generated += n_samples
self.samples_list += list(samples)
def get_samples(self, n_samples, axis):
# Logic to slice the pre-generated samples based on axis 'x' or 'y'
# ... (implementation details)
return samples_list
# 2. Create specific samplers that use the generator
class WindXSampler(CustomSampler):
def __init__(self, generator):
self.generator = generator
def sample(self, n_samples=1):
return self.generator.get_samples(n_samples, "x")
class WindYSampler(CustomSampler):
def __init__(self, generator):
self.generator = generator
def sample(self, n_samples=1):
return self.generator.get_samples(n_samples, "y")
# 3. Initialize and use in a StochasticEnvironment
mean = [1, 2]
cov_mat = [[0.2, 0.171], [0.171, 0.3]]
gen = BivariateGaussianGenerator(mean, cov_mat)
stochastic_env = StochasticEnvironment(
environment=spaceport_env,
wind_velocity_x_factor=WindXSampler(gen),
wind_velocity_y_factor=WindYSampler(gen)
)