mlmc.quantity

Subpackage provides methods to represent and handle a quantity of interest.

Submodules

mlmc.quantity.quantity module

mlmc.quantity.quantity.make_root_quantity(storage, q_specs)[source]

Create a root quantity that has QuantityStorage as the input quantity. QuantityStorage is the only class that directly accesses the stored data. The returned QuantityStorage uses a QType built from provided QuantitySpec objects.

Parameters:
  • storage (SampleStorage) – SampleStorage instance that provides stored samples

  • q_specs (List[QuantitySpec]) – list of QuantitySpec describing the simulation result format

Returns:

QuantityStorage that wraps the provided SampleStorage with a matching QType

class mlmc.quantity.quantity.Quantity(quantity_type, operation, input_quantities=[])[source]

Bases: object

Represents a quantity (a measurable value or expression) constructed from a QType, an operation (callable) and zero-or-more input quantities. Quantities are lazy: their actual data are returned by calling samples(chunk_spec).

  • qtype: structure description (QType)

  • _operation: callable that takes sample-chunks from input_quantities and returns result chunks

  • _input_quantities: dependencies (other Quantity instances)

get_quantity_storage()[source]

Find the first QuantityStorage among inputs (if any) and return it.

Returns:

QuantityStorage instance or None if not found

set_selection_id()[source]

Determine the selection id for this Quantity. If inputs have a selection id (created by select), inherit it; if multiple different selection ids are present among inputs, raise an exception.

Returns:

selection id or None

selection_id()[source]

Return this Quantity’s selection id. If not set, use id(self._storage) to identify the underlying storage instance.

Returns:

selection identifier (int or None)

size()[source]

Return the number of scalar components described by the QType.

Return type:

int

Returns:

int

get_cache_key(chunk_spec)[source]
Create a cache key used by memoization for samples. We include:
  • level id

  • chunk id

  • chunk size (derived from slice)

  • id(self) to distinguish different quantity instances

Parameters:

chunk_spec – ChunkSpec

Returns:

tuple key

samples(chunk_spec)[source]

Evaluate and return the data chunk for this quantity at the specified chunk_spec. Calls samples(chunk_spec) recursively on inputs and passes the results to _operation.

Parameters:

chunk_spec – ChunkSpec object with level_id, chunk_id, and optional slice

Returns:

np.ndarray (M, chunk_size, 2) or None

select(*args)[source]

Apply boolean selection masks to this Quantity’s samples.

Parameters:

args – One or more Quantity instances with BoolType that act as masks.

Returns:

Quantity representing the selected samples (mask applied on sample axis)

static create_quantity(quantities, operation)[source]

Create a new Quantity or QuantityConst. If any input is non-constant, return a Quantity that will evaluate lazily. If all are constant, return QuantityConst.

Parameters:
  • quantities – list-like of Quantity / QuantityConst

  • operation – callable to combine inputs

Returns:

Quantity or QuantityConst

static add_op(x, y)[source]
static sub_op(x, y)[source]
static mult_op(x, y)[source]
static truediv_op(x, y)[source]
static mod_op(x, y)[source]
static pick_samples(chunk, subsample_params)[source]

Subsample a chunk using Method S (hypergeometric sampling) so that across chunks we end up with k samples from n total.

Parameters:
  • chunk – ndarray of shape (M, N, 2) where N is number of samples in this chunk

  • subsample_params – object with attributes k (remaining desired) and n (remaining available)

Returns:

selected sub-chunk array with shape (M, m, 2), where m is chosen by hypergeometric draw

subsample(sample_vec)[source]

Build a Quantity that implements subsampling across levels to obtain a specified number of samples per level (sample_vec).

Returns a Quantity whose operation will pick samples according to subsample params stored per-level. Uses QuantityConst with a level-aware _adjust_value to pass different parameters to each level chunk.

Parameters:

sample_vec – list-like of desired numbers of samples per level

Returns:

Quantity producing subsampled chunks

static wrap(value)[source]

Convert a primitive (int, float, bool), a numpy/list array, or an existing Quantity into a Quantity.

Parameters:

value – scalar, bool, list/ndarray, or Quantity

Returns:

Quantity or QuantityConst wrapping the value

static QArray(quantities)[source]

Build a Quantity representing an array-of-quantities aggregated into a single QType.

static QDict(key_quantity)[source]

Build a Quantity representing a dictionary of quantities. :type key_quantity: :param key_quantity: iterable of (key, Quantity)

static QTimeSeries(time_quantity)[source]

Build a Quantity representing a time series constructed from (time, Quantity) pairs.

static QField(key_quantity)[source]

Build a Quantity representing a field (mapping of locations to quantities).

class mlmc.quantity.quantity.QuantityConst(quantity_type, value)[source]

Bases: Quantity

Represents a constant quantity whose value is stored directly in the instance. The samples() method returns the constant value broadcasted to the requested chunk shape.

selection_id()[source]

Constants have no selection id (they are independent of storage).

samples(chunk_spec)[source]

Return the constant value, optionally adjusted for the given level via _adjust_value.

Parameters:

chunk_spec – ChunkSpec with level_id

Returns:

ndarray representing the constant for this chunk

class mlmc.quantity.quantity.QuantityMean(quantity_type, l_means, l_vars, n_samples, n_rm_samples)[source]

Bases: object

Container for aggregated mean/variance results computed by mlmc.quantity.quantity_estimate.estimate_mean.

  • qtype: QType of the quantity

  • _l_means: per-level mean contributions (L x M flattened)

  • _l_vars: per-level variance contributions (L x M flattened)

  • _n_samples: number of samples used per level

  • _n_rm_samples: number of removed samples per level

property mean

Reshaped overall mean according to QType.

property var

Reshaped overall variance according to QType.

property l_means

Level means reshaped according to QType for each level.

property l_vars

Level variances reshaped according to QType for each level.

property n_samples
property n_rm_samples
class mlmc.quantity.quantity.QuantityStorage(storage, qtype)[source]

Bases: Quantity

Special Quantity that provides direct access to SampleStorage. It implements the bridge between storage and the Quantity abstraction.

level_ids()[source]

Return list of available level ids from the SampleStorage. :return: List[int]

selection_id()[source]

Identity of this QuantityStorage (unique by object id). :return: int

get_quantity_storage()[source]

For QuantityStorage the storage is itself. :return: self

chunks(level_id=None)[source]

Proxy to SampleStorage.chunks which yields ChunkSpec instances describing available chunks. :type level_id: :param level_id: optional level id to restrict chunks :return: generator of ChunkSpec

samples(chunk_spec)[source]

Retrieve stored sample pairs for the requested level/chunk.

Parameters:

chunk_spec – ChunkSpec describing (level, chunk slice)

Returns:

ndarray shaped [M, chunk_size, 2] where M is number of result quantities

n_collected()[source]

Return number of collected results per level from the underlying SampleStorage. :return: list of ints

mlmc.quantity.quantity_estimate module

mlmc.quantity.quantity_estimate.mask_nan_samples(chunk)[source]

Remove (mask out) samples containing NaN values in either the fine or coarse part of the result.

Parameters:

chunk – np.ndarray of shape [M, chunk_size, 2] M - quantity size (number of scalar components), chunk_size - number of samples in the chunk, 2 - fine and coarse parts of the result.

Returns:

(filtered_chunk, n_masked) filtered_chunk: np.ndarray with invalid samples removed, n_masked: int, number of masked (removed) samples.

mlmc.quantity.quantity_estimate.cache_clear()[source]

Clear cached Quantity sample evaluations.

Used before running MLMC estimations to ensure fresh data is fetched from storage.

mlmc.quantity.quantity_estimate.estimate_mean(quantity, form='diff', operation_func=None, **kwargs)[source]

Estimate the MLMC mean (and variance) of a Quantity using multilevel sampling.

The function computes per-level means and variances from simulation results. Supports large datasets via chunked processing and handles NaN-masked samples.

Parameters:
  • quantity – Quantity instance to estimate.

  • form – str, type of estimation: - “diff”: estimate based on differences (fine - coarse) → standard MLMC approach. - “fine”: estimate using fine-level data only. - “coarse”: estimate using coarse-level data only.

  • operation_func – Optional transformation applied to chunk data before accumulation (e.g., for moment or kurtosis computation).

  • kwargs – Additional keyword arguments passed to operation_func.

Returns:

QuantityMean object containing mean, variance, and sample statistics per level.

mlmc.quantity.quantity_estimate.moment(quantity, moments_fn, i=0)[source]

Construct a Quantity that represents a single statistical moment.

Parameters:
  • quantity – Base Quantity instance.

  • moments_fn – Instance of mlmc.moments.Moments defining the moment computation.

  • i – Index of the moment to compute.

Returns:

New Quantity that computes the i-th moment.

mlmc.quantity.quantity_estimate.moments(quantity, moments_fn, mom_at_bottom=True)[source]

Construct a Quantity representing all moments defined by a given Moments object.

Parameters:
  • quantity – Base Quantity.

  • moments_fn – mlmc.moments.Moments child defining moment evaluations.

  • mom_at_bottom – bool, if True, moments are added at the lowest (scalar) level of the Quantity type.

Returns:

Quantity that computes all defined moments.

mlmc.quantity.quantity_estimate.covariance(quantity, moments_fn, cov_at_bottom=True)[source]

Construct a Quantity representing covariance matrices of the given moments.

Parameters:
  • quantity – Base Quantity.

  • moments_fn – mlmc.moments.Moments child defining moment evaluations.

  • cov_at_bottom – bool, if True covariance matrices are attached at the scalar level of the Quantity type.

Returns:

Quantity that computes covariance matrices.

mlmc.quantity.quantity_estimate.kurtosis_numerator(chunk_diff, chunk_spec, l_means)[source]
Compute the numerator for the sample kurtosis:

E[(Y_l - E[Y_l])^4]

Parameters:
  • chunk_diff – np.ndarray [quantity shape, number of samples]

  • chunk_spec – quantity_spec.ChunkSpec describing current level and chunk.

  • l_means – List of per-level means used for centering.

Returns:

np.ndarray of the same shape as input.

mlmc.quantity.quantity_estimate.level_kurtosis(quantity, means_obj)[source]
Estimate the sample kurtosis for each level:

E[(Y_l - E[Y_l])^4] / (Var[Y_l])^2, where Y_l = fine_l - coarse_l

Parameters:
  • quantity – Quantity instance.

  • means_obj – QuantityMean object containing level means and variances.

Returns:

np.ndarray of kurtosis values per level.

mlmc.quantity.quantity_spec module

class mlmc.quantity.quantity_spec.QuantitySpec(name, unit, shape, times, locations)[source]

Bases: object

Specification of a physical quantity for simulation or data storage.

Parameters:
  • name (str) – Name of the quantity (e.g. ‘pressure’, ‘velocity’).

  • unit (str) – Unit of the quantity (e.g. ‘m/s’, ‘Pa’).

  • shape (Tuple[int, int]) – Tuple describing the shape of the data (e.g. (64, 64)).

  • times (List[float]) – List of time points associated with this quantity.

  • locations (Union[List[str], List[Tuple[float, float, float]]]) – List of either string-based identifiers or 3D coordinates (x, y, z) where the quantity is defined.

name: str
unit: str
shape: Tuple[int, int]
times: List[float]
locations: Union[List[str], List[Tuple[float, float, float]]]
class mlmc.quantity.quantity_spec.ChunkSpec(chunk_id=None, chunk_slice=None, level_id=None)[source]

Bases: object

Specification of a simulation or dataset chunk.

Parameters:
  • chunk_id (Optional[int]) – Integer identifier of the chunk.

  • chunk_slice (Optional[slice]) – Slice object defining the range of data indices in the chunk.

  • level_id (Optional[int]) – Identifier of the refinement or simulation level.

chunk_id: int
chunk_slice: slice
level_id: int

mlmc.quantity.quantity_types module

class mlmc.quantity.quantity_types.QType(qtype)[source]

Bases: object

Base class for quantity types.

Parameters:

qtype – inner/contained QType or Python type

size()[source]

Size of the type in flattened units.

Return type:

int

Returns:

int

base_qtype()[source]

Return the base scalar/bool type for nested types.

Returns:

QType

replace_scalar(substitute_qtype)[source]

Find ScalarType and replace it with substitute_qtype.

Parameters:

substitute_qtype – QType that replaces ScalarType

Returns:

QType (new instance with scalar replaced)

static keep_dims(chunk)[source]

Ensure chunk has shape [M, chunk size, 2].

For scalar quantities the input block can have shape (chunk size, 2). Sometimes we need to ‘flatten’ first few dimensions to achieve desired chunk shape.

Parameters:

chunk (ndarray) – numpy array

Return type:

ndarray

Returns:

numpy array with shape [M, chunk size, 2]

Raises:

ValueError – if chunk.ndim < 2

reshape(data)[source]

Default reshape (identity).

Parameters:

data (ndarray) – numpy array

Return type:

ndarray

Returns:

numpy array

class mlmc.quantity.quantity_types.ScalarType(qtype=<class 'float'>)[source]

Bases: QType

Scalar quantity type (leaf type).

base_qtype()[source]
Returns:

base scalar QType (self or underlying BoolType base)

size()[source]
Return type:

int

Returns:

int size of the scalar (defaults to 1 or uses _qtype.size() if present)

replace_scalar(substitute_qtype)[source]

Replace ScalarType with substitute type.

Parameters:

substitute_qtype – QType that replaces ScalarType

Returns:

substitute_qtype

class mlmc.quantity.quantity_types.BoolType(qtype=<class 'float'>)[source]

Bases: ScalarType

Boolean scalar type (inherits ScalarType).

class mlmc.quantity.quantity_types.ArrayType(shape, qtype)[source]

Bases: QType

Array quantity type.

Parameters:
  • shape – int or tuple describing array shape

  • qtype (QType) – contained QType for array elements

size()[source]
Return type:

int

Returns:

total flattened size (product of shape * inner qtype size)

get_key(key)[source]

ArrayType indexing.

Parameters:

key – int, tuple of ints or slice objects

Returns:

Tuple (QuantityType, offset) where offset is 0 for this implementation

reshape(data)[source]

Reshape flattened data to array shape.

Parameters:

data (ndarray) – numpy array

Return type:

ndarray

Returns:

reshaped numpy array

class mlmc.quantity.quantity_types.TimeSeriesType(times, qtype)[source]

Bases: QType

Time-series quantity type.

Parameters:
  • times – iterable of time points

  • qtype – QType for each time slice

size()[source]
Return type:

int

Returns:

total size = number of time points * inner qtype.size()

get_key(key)[source]

Get a qtype and offset corresponding to a given time key.

Parameters:

key – time value to locate

Returns:

Tuple (q_type, offset)

static time_interpolation(quantity, value)[source]

Interpolate a time-series quantity to a single time value.

Parameters:
  • quantity – Quantity instance with qtype being a TimeSeriesType

  • value – float time value where to interpolate

Returns:

Quantity object representing interpolated value

class mlmc.quantity.quantity_types.FieldType(args)[source]

Bases: QType

Field type composed of named entries each having the same base qtype.

Parameters:

args (List[Tuple[str, QType]]) – List of (name, QType) pairs

size()[source]
Return type:

int

Returns:

total size = number of fields * inner qtype size

get_key(key)[source]

Access sub-field by name.

Parameters:

key – field name

Returns:

Tuple (q_type, offset)

class mlmc.quantity.quantity_types.DictType(args)[source]

Bases: QType

Dictionary-like type of named QTypes which may differ in size.

Parameters:

args (List[Tuple[str, QType]]) – List of (name, QType) pairs

base_qtype()[source]
Returns:

base_qtype of the first element

size()[source]
Return type:

int

Returns:

total flattened size (sum of sizes of contained qtypes)

get_qtypes()[source]
Returns:

iterable of contained qtypes

replace_scalar(substitute_qtype)[source]

Replace scalar types recursively inside dict entries.

Parameters:

substitute_qtype – QType that replaces ScalarType

Returns:

new DictType instance

get_key(key)[source]

Return the QType and starting offset for a named key.

Parameters:

key – name of entry

Returns:

Tuple (q_type, start_offset)

Module contents

Subpackage provides methods to represent and handle a quantity of interest.