import scipy as sp
from scipy.stats import bernoulli
from itertools import cycle


def sorn_input(nr_neurons):
    return sp.randn(nr_neurons) * 0.05


class RepeatingPatterns:
    def __init__(self, nr_patterns=3, strength=0.05, sparsity=.2):
        self.nr_patterns = nr_patterns
        self.strength = strength
        self.sparsity = sparsity
        self.patterns = None

    def _init_patterns(self, nr_neurons):
        sparseness = (bernoulli(self.sparsity)
                      .rvs((self.nr_patterns, nr_neurons)))
        self.patterns = sparseness * self.strength
        self.patterns *= sp.randn(*self.patterns.shape)
        self._generator = cycle(self.patterns)

    def __call__(self, nr_neurons):
        if self.patterns is None:
            self._init_patterns(nr_neurons)
        return next(self._generator)
