Source code for easyvvuq.sampling.sampler_of_samplers

from .base import BaseSamplingElement
import logging
import itertools
import functools

__copyright__ = """

    Copyright 2018 Robin A. Richardson, David W. Wright

    This file is part of EasyVVUQ

    EasyVVUQ is free software: you can redistribute it and/or modify
    it under the terms of the Lesser GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    EasyVVUQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

"""
__license__ = "LGPL"

logger = logging.getLogger(__name__)


[docs]class MultiSampler(BaseSamplingElement, sampler_name="multisampler"): def __init__(self, *samplers, count=0): """ Expects one or more samplers """ if len(samplers) < 1: raise RuntimeError("You need to supply at least one sampler to the MultiSampler") self.samplers = samplers # Multisampler is finite only if all samplers in it are finite for sampler in self.samplers: if sampler.is_finite() is False: msg = "Multisampler must be composed of finite samplers" logger.critical(msg) raise RuntimeError(msg) # Combine all the iterables/generators into one self.multi_iterator = itertools.product(*self.samplers) self.count = 0 for i in range(count): try: self.__next__() except StopIteration: logger.warning("Multisampler constructed, but has no samples left to draw.")
[docs] def is_finite(self): return True
[docs] def n_samples(self): """Returns the number of samples in this sampler. Returns ------- a product of the sizes of samplers passed to MultiSampler """ return functools.reduce( lambda x, y: x * y, [sampler.n_samples() for sampler in self.samplers], 1)
def __next__(self): # Will raise StopIteration when there are none left multisampler_run = self.multi_iterator.__next__() run_dict = {} for contribution in multisampler_run: run_dict = {**run_dict, **contribution} self.count += 1 return run_dict