class Gabor(FrozenObject): """Describes a random generator for Gabor filters.""" theta = DistributionParam("theta") freq = DistributionParam("freq") phase = DistributionParam("phase") sigma_x = DistributionParam("sigma_x") sigma_y = DistributionParam("sigma_y") def __init__( self, theta=Uniform(-np.pi, np.pi), freq=Uniform(0.2, 2), phase=Uniform(-np.pi, np.pi), sigma_x=Choice([0.45]), sigma_y=Choice([0.45]), ): super().__init__() self.theta = theta self.freq = freq self.phase = phase self.sigma_x = sigma_x self.sigma_y = sigma_y def generate(self, n, shape, rng=np.random, norm=1.0): assert isinstance(shape, tuple) and len(shape) == 2 thetas = self.theta.sample(n, rng=rng)[:, None, None] freqs = self.freq.sample(n, rng=rng)[:, None, None] phases = self.phase.sample(n, rng=rng)[:, None, None] sigma_xs = self.sigma_x.sample(n, rng=rng)[:, None, None] sigma_ys = self.sigma_y.sample(n, rng=rng)[:, None, None] x, y = np.linspace(-1, 1, shape[1]), np.linspace(-1, 1, shape[0]) X, Y = np.meshgrid(x, y) c, s = np.cos(thetas), np.sin(thetas) X1 = X * c + Y * s Y1 = -X * s + Y * c gabors = np.exp(-0.5 * ((X1 / sigma_xs)**2 + (Y1 / sigma_ys)**2)) gabors *= np.cos((2 * np.pi) * freqs * X1 + phases) if norm is not None: gabors *= norm / np.sqrt( (gabors**2).sum(axis=(1, 2), keepdims=True)).clip( 1e-5, np.inf) return gabors
class FilteredNoise(Process): """Filtered white noise process. This process takes white noise and filters it using the provided synapse. Parameters ---------- synapse : Synapse, optional (Default: ``Lowpass(tau=0.005)``) The synapse to use to filter the noise. dist : Distribution, optional (Default: ``Gaussian(mean=0, std=1)``) The distribution used to generate the white noise. scale : bool, optional (Default: True) Whether to scale the white noise for integration, making the output signal invariant to ``dt``. synapse_kwargs : dict, optional (Default: None) Arguments to pass to ``synapse.make_step``. seed : int, optional (Default: None) Random number seed. Ensures noise will be the same each run. """ synapse = SynapseParam('synapse') dist = DistributionParam('dist') scale = BoolParam('scale') synapse_kwargs = DictParam('synapse_kwargs') def __init__(self, synapse=Lowpass(tau=0.005), dist=Gaussian(mean=0, std=1), scale=True, synapse_kwargs=None, **kwargs): super(FilteredNoise, self).__init__(default_size_in=0, **kwargs) self.synapse = synapse self.synapse_kwargs = {} if synapse_kwargs is None else synapse_kwargs self.dist = dist self.scale = scale def __repr__(self): return "%s(synapse=%r, dist=%r, scale=%r)" % ( type(self).__name__, self.synapse, self.dist, self.scale) def make_step(self, shape_in, shape_out, dt, rng): assert shape_in == (0, ) assert len(shape_out) == 1 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) filter_step = self.synapse.make_step(shape_out, shape_out, dt, None, **self.synapse_kwargs) def step_filterednoise(t): x = dist.sample(n=1, d=shape_out[0], rng=rng)[0] if scale: x *= alpha return filter_step(t, x) return step_filterednoise
class FilteredNoise(Process): """Filtered white noise process. This process takes white noise and filters it using the provided synapse. Parameters ---------- synapse : Synapse, optional The synapse to use to filter the noise. Default: Lowpass(tau=0.005) synapse_kwargs : dict, optional Arguments to pass to `synapse.make_step`. dist : Distribution, optional The distribution used to generate the white noise. Default: Gaussian(mean=0, std=1) scale : bool, optional Whether to scale the white noise for integration, making the output signal invariant to `dt`. Defaults to True. seed : int, optional Random number seed. Ensures noise will be the same each run. """ synapse = LinearFilterParam('synapse') dist = DistributionParam('dist') scale = BoolParam('scale') def __init__(self, synapse=Lowpass(tau=0.005), synapse_kwargs={}, dist=Gaussian(mean=0, std=1), scale=True, seed=None): super(FilteredNoise, self).__init__(seed=seed) self.synapse = synapse self.synapse_kwargs = synapse_kwargs self.dist = dist self.scale = scale def __repr__(self): return "%s(synapse=%r, dist=%r, scale=%r)" % ( self.__class__.__name__, self.synapse, self.dist, self.scale) def make_step(self, size_in, size_out, dt, rng): assert size_in == 0 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) output = np.zeros(size_out) filter_step = self.synapse.make_step(dt, output, **self.synapse_kwargs) def step_filterednoise(t): x = dist.sample(n=1, d=size_out, rng=rng)[0] if scale: x *= alpha filter_step(x) return output return step_filterednoise
class FilteredNoise(Process): """Filtered white noise process. This process takes white noise and filters it using the provided synapse. Parameters ---------- synapse : Synapse, optional The synapse to use to filter the noise. dist : Distribution, optional The distribution used to generate the white noise. scale : bool, optional Whether to scale the white noise for integration, making the output signal invariant to ``dt``. seed : int, optional Random number seed. Ensures noise will be the same each run. """ synapse = SynapseParam("synapse") dist = DistributionParam("dist") scale = BoolParam("scale") def __init__( self, synapse=Lowpass(tau=0.005), dist=Gaussian(mean=0, std=1), scale=True, **kwargs, ): super().__init__(default_size_in=0, **kwargs) self.synapse = synapse self.dist = dist self.scale = scale def make_state(self, shape_in, shape_out, dt, dtype=None): return self.synapse.make_state(shape_out, shape_out, dt, dtype=dtype) def make_step(self, shape_in, shape_out, dt, rng, state): assert shape_in == (0, ) assert len(shape_out) == 1 dist = self.dist scale = self.scale alpha = 1.0 / np.sqrt(dt) filter_step = self.synapse.make_step(shape_out, shape_out, dt, rng, state) def step_filterednoise(t): x = dist.sample(n=1, d=shape_out[0], rng=rng)[0] if scale: x *= alpha return filter_step(t, x) return step_filterednoise
class FilteredNoise(Process): """Filtered white noise process. This process takes white noise and filters it using the provided synapse. Parameters ---------- synapse : Synapse, optional The synapse to use to filter the noise. Default: Lowpass(tau=0.005) synapse_kwargs : dict, optional Arguments to pass to `synapse.make_step`. dist : Distribution, optional The distribution used to generate the white noise. Default: Gaussian(mean=0, std=1) scale : bool, optional Whether to scale the white noise for integration, making the output signal invariant to `dt`. Defaults to True. """ synapse = LinearFilterParam() dist = DistributionParam() scale = BoolParam() def __init__(self, synapse=None, synapse_kwargs={}, dist=None, scale=True): super(FilteredNoise, self).__init__() self.synapse = Lowpass(tau=0.005) if synapse is None else synapse self.synapse_kwargs = synapse_kwargs self.dist = Gaussian(mean=0, std=1) if dist is None else dist self.scale = scale def make_step(self, size_in, size_out, dt, rng): assert size_in == 0 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) output = np.zeros(size_out) filter_step = self.synapse.make_step(dt, output, **self.synapse_kwargs) # separate RNG for simulation for step order independence sim_rng = np.random.RandomState(rng.randint(npext.maxint)) def step(t): x = dist.sample(n=1, d=size_out, rng=sim_rng)[0] if scale: x *= alpha filter_step(x) return output return step
class WhiteNoise(Process): """Full-spectrum white noise process. Parameters ---------- dist : Distribution, optional (Default: ``Gaussian(mean=0, std=1)``) The distribution from which to draw samples. scale : bool, optional (Default: True) Whether to scale the white noise for integration. Integrating white noise requires using a time constant of ``sqrt(dt)`` instead of ``dt`` on the noise term [1]_, to ensure the magnitude of the integrated noise does not change with ``dt``. seed : int, optional (Default: None) Random number seed. Ensures noise will be the same each run. References ---------- .. [1] Gillespie, D.T. (1996) Exact numerical simulation of the Ornstein- Uhlenbeck process and its integral. Phys. Rev. E 54, pp. 2084-91. """ dist = DistributionParam('dist') scale = BoolParam('scale') def __init__(self, dist=Gaussian(mean=0, std=1), scale=True, **kwargs): super(WhiteNoise, self).__init__(default_size_in=0, **kwargs) self.dist = dist self.scale = scale def __repr__(self): return "%s(%r, scale=%r)" % (type(self).__name__, self.dist, self.scale) def make_step(self, shape_in, shape_out, dt, rng): assert shape_in == (0, ) assert len(shape_out) == 1 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) # ^ need sqrt(dt) when integrating, so divide by sqrt(dt) here, # since dt / sqrt(dt) = sqrt(dt). def step_whitenoise(t): x = dist.sample(n=1, d=shape_out[0], rng=rng)[0] return alpha * x if scale else x return step_whitenoise
class WhiteNoise(Process): """Full-spectrum white noise process. Parameters ---------- dist : Distribution, optional The distribution to draw samples from. Default: Gaussian(mean=0, std=1) scale : bool, optional Whether to scale the white noise for integration. Integrating white noise requires using a time constant of `sqrt(dt)` instead of `dt` on the noise term [1]_, to ensure the magnitude of the integrated noise does not change with `dt`. Defaults to True. seed : int, optional Random number seed. Ensures noise will be the same each run. References ---------- .. [1] Gillespie, D.T. (1996) Exact numerical simulation of the Ornstein- Uhlenbeck process and its integral. Phys. Rev. E 54, pp. 2084-91. """ dist = DistributionParam() scale = BoolParam() def __init__(self, dist=Gaussian(mean=0, std=1), scale=True, seed=None): super(WhiteNoise, self).__init__(seed=seed) self.dist = dist self.scale = scale def __repr__(self): return "%s(%r, scale=%r)" % ( self.__class__.__name__, self.dist, self.scale) def make_step(self, size_in, size_out, dt, rng): assert size_in == 0 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) # ^ need sqrt(dt) when integrating, so divide by sqrt(dt) here, # since dt / sqrt(dt) = sqrt(dt). sim_rng = self.get_sim_rng(rng) def step(t): x = dist.sample(n=1, d=size_out, rng=sim_rng)[0] return alpha * x if scale else x return step
class WhiteNoise(Process): """Full-spectrum white noise process. Parameters ---------- dist : Distribution, optional The distribution to draw samples from. Default: Gaussian(mean=0, std=1) scale : bool, optional Whether to scale the white noise for integration. Integrating white noise requires using a time constant of `sqrt(dt)` instead of `dt` on the noise term [1]_, to ensure the magnitude of the integrated noise does not change with `dt`. Defaults to True. References ---------- .. [1] Gillespie, D.T. (1996) Exact numerical simulation of the Ornstein- Uhlenbeck process and its integral. Phys. Rev. E 54, pp. 2084-91. """ dist = DistributionParam() scale = BoolParam() def __init__(self, dist=None, scale=True): super(WhiteNoise, self).__init__() self.dist = Gaussian(mean=0, std=1) if dist is None else dist self.scale = scale def make_step(self, size_in, size_out, dt, rng): assert size_in == 0 dist = self.dist scale = self.scale alpha = 1. / np.sqrt(dt) # ^ need sqrt(dt) when integrating, so divide by sqrt(dt) here, # since dt / sqrt(dt) = sqrt(dt). # separate RNG for simulation for step order independence sim_rng = np.random.RandomState(rng.randint(npext.maxint)) def step(t): x = dist.sample(n=1, d=size_out, rng=sim_rng)[0] return alpha * x if scale else x return step