Source code for nbodykit.source.catalog.uniform

from nbodykit.base.catalog import CatalogSource, column
from nbodykit import CurrentMPIComm
from nbodykit.mpirng import MPIRandomState
import numpy

[docs]class RandomCatalog(CatalogSource): """ A CatalogSource that can have columns added via a collective random number generator. The random number generator stored as :attr:`rng` behaves as :class:`numpy.random.RandomState` but generates random numbers only on the local rank in a manner independent of the number of ranks. Parameters ---------- csize : int the desired collective size of the Source seed : int, optional the global seed for the random number generator comm : MPI communicator the MPI communicator; set automatically if None """ def __repr__(self): args = (self.size, self.attrs['seed']) return "RandomCatalog(size=%d, seed=%s)" % args @CurrentMPIComm.enable def __init__(self, csize, seed=None, comm=None): self.comm = comm # set the seed randomly if it is None if seed is None: if self.comm.rank == 0: seed = numpy.random.randint(0, 4294967295) seed = self.comm.bcast(seed) self.attrs['seed'] = seed # generate the seeds from the global seed if csize == 0: raise ValueError("no random particles generated!") start = comm.rank * csize // comm.size end = (comm.rank + 1) * csize // comm.size self._size = end - start self._rng = MPIRandomState(comm, seed=seed, size=self._size) # init the base class CatalogSource.__init__(self, comm=comm) @property def rng(self): """ A :class:`MPIRandomState` that behaves as :class:`numpy.random.RandomState` but generates random numbers in a manner independent of the number of ranks. """ return self._rng
[docs]class UniformCatalog(RandomCatalog): """ A CatalogSource that has uniformly-distributed ``Position`` and ``Velocity`` columns. The random numbers generated do not depend on the number of available ranks. Parameters ---------- nbar : float the desired number density of particles in the box BoxSize : float, 3-vector the size of the box seed : int, optional the random seed comm : the MPI communicator """ def __repr__(self): args = (self.size, self.attrs['seed']) return "UniformCatalog(size=%d, seed=%s)" % args @CurrentMPIComm.enable def __init__(self, nbar, BoxSize, seed=None, dtype='f8', comm=None): self.comm = comm _BoxSize = numpy.empty(3, dtype='f8') _BoxSize[:] = BoxSize self.attrs['BoxSize'] = _BoxSize rng = numpy.random.RandomState(seed) N = rng.poisson(nbar * numpy.prod(self.attrs['BoxSize'])) if N == 0: raise ValueError("no uniform particles generated, try increasing `nbar` parameter") RandomCatalog.__init__(self, N, seed=seed, comm=comm) self._pos = (self.rng.uniform(itemshape=(3,)) * self.attrs['BoxSize']).astype(dtype) self._vel = (self.rng.uniform(itemshape=(3,)) * self.attrs['BoxSize'] * 0.01).astype(dtype)
[docs] @column def Position(self): """ The position of particles, uniformly distributed in :attr:`BoxSize` """ return self.make_column(self._pos)
[docs] @column def Velocity(self): """ The velocity of particles, uniformly distributed in ``0.01 x BoxSize`` """ return self.make_column(self._vel)