def test_parallel_apply(): array = numpy.linspace(-1, 1, 100) with pytest.raises(TypeError): parallel_apply(f, array, wrong_argument=None) with pytest.raises(ValueError): parallel_apply(f, array, parallel='wrong_argument') for par in [False, True, -1, 2]: farray = parallel_apply(f, array, parallel=par) assert_allclose([f(x) for x in array], farray)
def compute_samples(f, x, samples, **kwargs): r""" Apply f(x,theta) to x array and theta in samples. Parameters ---------- f: function list of functions :math:`f(x;\theta)` with dependent variable :math:`x`, parameterised by :math:`\theta`. x: 1D array-like x values to evaluate :math:`f(x;\theta)` at. samples: 2D array-like list of theta samples to evaluate :math:`f(x;\theta)` at. `shape = (nfunc, nsamples, npars)` parallel, tqdm_kwargs: optional see docstring for :func:`fgivenx.parallel.parallel_apply` cache: str, optional File root for saving previous calculations for re-use default None Returns ------- 2D numpy.array: samples at each x. `shape=(len(x),len(samples),)` """ parallel = kwargs.pop('parallel', False) cache = kwargs.pop('cache', '') tqdm_kwargs = kwargs.pop('tqdm_kwargs', {}) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) if cache: cache = Cache(cache + '_fsamples') try: return cache.check(x, samples) except CacheException as e: print(e) fsamples = [] for fi, s in zip(f, samples): if len(s) > 0: fsamps = parallel_apply(fi, s, precurry=(x, ), parallel=parallel, tqdm_kwargs=tqdm_kwargs) fsamps = numpy.array(fsamps).transpose().copy() fsamples.append(fsamps) fsamples = numpy.concatenate(fsamples, axis=1) if cache: cache.save(x, samples, fsamples) return fsamples
def compute_dkl(fsamps, prior_fsamps, **kwargs): """ Compute the Kullback Leibler divergence for function samples for posterior and prior pre-calculated at a range of x values. Parameters ---------- fsamps: 2D numpy.array Posterior function samples, as computed by :func:`fgivenx.compute_samples` prior_fsamps: 2D numpy.array Prior function samples, as computed by :func:`fgivenx.compute_samples` parallel, tqdm_kwargs: optional see docstring for :func:`fgivenx.parallel.parallel_apply`. cache: str, optional File root for saving previous calculations for re-use. Returns ------- 1D numpy.array: Kullback-Leibler divergences at each value of x. `shape=(len(fsamps))` """ parallel = kwargs.pop('parallel', False) cache = kwargs.pop('cache', '') tqdm_kwargs = kwargs.pop('tqdm_kwargs', {}) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) if cache: cache = Cache(cache + '_dkl') try: return cache.check(fsamps, prior_fsamps) except CacheException as e: print(e) zip_fsamps = list(zip(fsamps, prior_fsamps)) dkls = parallel_apply(DKL, zip_fsamps, parallel=parallel, tqdm_kwargs=tqdm_kwargs) dkls = numpy.array(dkls) if cache: cache.save(fsamps, prior_fsamps, dkls) return dkls
def compute_pmf(fsamps, y, **kwargs): """ Compute the pmf defined by fsamps at each x for each y. Parameters ---------- fsamps: 2D array-like array of function samples, as returned by :func:`fgivenx.compute_samples` y: 1D array-like y values to evaluate the PMF at parallel, tqdm_kwargs: optional see docstring for :func:`fgivenx.parallel.parallel_apply`. Returns ------- 2D numpy.array probability mass function at each x for each y `shape=(len(fsamps),len(y)` """ parallel = kwargs.pop('parallel', False) cache = kwargs.pop('cache', '') tqdm_kwargs = kwargs.pop('tqdm_kwargs', {}) if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) if cache: cache = Cache(cache + '_masses') try: return cache.check(fsamps, y) except CacheException as e: print(e) masses = parallel_apply(PMF, fsamps, postcurry=(y, ), parallel=parallel, tqdm_kwargs=tqdm_kwargs) masses = numpy.array(masses).transpose().copy() if cache: cache.save(fsamps, y, masses) return masses