Esempio n. 1
0
    def __init__(self, rate=1):
        """Create Exp(rate) distribution.

        :param rate First shape parameter of exp
        """

        assert rate > 0

        self.rate = rate
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))
    def __init__(self, shape=1, scale=1):
        """Create Ga(shape,scale) distribution.

        :param shape Shape of Ga(shape,scale)
        :param scale Scale of Ga(shape,scale)
        """
        self.shape = shape
        self.scale = scale

        self.UG = UniformDist()
        if shape >= 1: self.NG = NormalDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))
Esempio n. 3
0
    def __init__(self, rate=1):
        """Create Poi(rate) distribution.

        :param rate The rate parameter.
        """

        # save params
        assert 0 < rate
        self.rate = rate

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(0, np.inf))
    def __init__(self, mean=0, var=1):
        """Create N(mean, var) distribution.

        :param mean Center of the gaussian
        :param var Variance around the center.
        """
        self.mean = mean
        self.var = var

        # create random generators
        self.EG = ExpDist()
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))
Esempio n. 5
0
    def __init__(self, p=0.5):
        """Create Ber(p) distribution.

        :param p Probability that random var is true
        """

        # save params
        assert 0 <= p <= 1
        self.p = p

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace([0, 1]))
Esempio n. 6
0
    def __init__(self, a=1, b=3):
        """Create U(K) distribution.

        :param rate The rate parameter.
        """

        # save params
        assert b >= a
        self.a = a
        self.b = b

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(a, b + 1))
    def __init__(self, loc=1, scale=1):
        """Creates Gumbel(loc,scale) distribution.

        :param loc Location of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.loc = loc
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))
Esempio n. 8
0
    def __init__(self, v = 1, loc = 0, scale = 1):
        """Create t(v,loc,scale) distribution.

        :param v Degrees of Freedom
        """

        # save params
        self.v = v
        self.loc = loc
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))
Esempio n. 9
0
    def __init__(self, shape=1, scale=1):
        """Creates Pareto(shape,scale) distribution.

        :param shape Shape of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.shape = shape
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))
    def __init__(self, n = 1, p = 0.5):
        """Create Geom(p) distribution.

        :param n Which should be summed
        :param p Probability that random var is true
        """

        # save params
        assert 0 <= p <= 1
        assert 1 <= n
        self.p = p
        self.n = n

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(1, np.inf))
Esempio n. 11
0
class ExpDist(ProbDist):
    """Simple exponential distribution."""
    def __init__(self, rate=1):
        """Create Exp(rate) distribution.

        :param rate First shape parameter of exp
        """

        assert rate > 0

        self.rate = rate
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return 1 / self.rate

    def moment(self, k):
        """Calculates the k-th moment for that distribution.

        :param k which moment to calc
        :returns The k-th moment of the distribution"""

        return m.factorial(k) / self.rate**k

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return 1 / self.rate**2

    def c_pdf(self, x):
        """This method calculates the density Exp(x|rate).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        rate = self.rate
        return rate * np.exp(-rate * x)

    def sample(self, num_samples=1):
        """Generate random numbers from Exp(rate) by using inverse-transform method.

        :param num_samples How many random numbers should be generated.
        :returns A random number from Exp(rate).
        """

        # generate result list and uniform samples
        rate = self.rate
        U = self.UG.sample(num_samples)
        return (-1 / rate) * np.log(U)
Esempio n. 12
0
class DUniformDist(ProbDist):
    """Sample U(K) distribution."""
    def __init__(self, a=1, b=3):
        """Create U(K) distribution.

        :param rate The rate parameter.
        """

        # save params
        assert b >= a
        self.a = a
        self.b = b

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(a, b + 1))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        a = self.a
        b = self.b
        return (a + b) / 2

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        a = self.a
        b = self.b

        return ((b - a) * (b - a + 2)) / 12

    def sample(self, num_samples=1):
        """Generate random numbers from Poi(rate).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Poi(rate).
        """

        U = self.UG.sample(num_samples)
        X = np.floor()
        return

    def __density(self, x):
        """This method calculates the mass Poi(rate).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        z = np.power(self.rate, x) / m.factorial(x)
        return z * np.exp(-self.rate)
class GeometricDist(ProbDist):
    """Simple Geom(p) distribution."""

    def __init__(self, n = 1, p = 0.5):
        """Create Geom(p) distribution.

        :param n Which should be summed
        :param p Probability that random var is true
        """

        # save params
        assert 0 <= p <= 1
        assert 1 <= n
        self.p = p
        self.n = n

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(1, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return 1 / self.p

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return (1 - self.p) / self.p ** 2

    def sample(self, num_samples = 1):
        """Generate random numbers from Geom(p).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Geom(p).
        """

        U = self.UG.sample(num_samples)
        X = np.floor(np.log(U) / np.log(1 - self.p))
        return X

    def __density(self, x):
        """This method calculates the mass Geom(p).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        f = np.power(1 - self.p, x - 1) * self.p
        return f
Esempio n. 14
0
class BernDist(ProbDist):
    """Simple bernoulli distribution."""
    def __init__(self, p=0.5):
        """Create Ber(p) distribution.

        :param p Probability that random var is true
        """

        # save params
        assert 0 <= p <= 1
        self.p = p

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace([0, 1]))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.p

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.p * (1 - self.p)

    def sample(self, num_samples=1):
        """Generate random numbers from Ber(p).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Ber(p).
        """

        # create gamma distributed vars
        U = self.UG.sample(num_samples)
        for k in range(num_samples):
            U[k] = int(U[k] <= self.p)

        return U

    def __density(self, x):
        """This method calculates the mass Ber(x|p).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        assert np.all([np.logical_or(np.equal(x, 0), np.equal(x, 1))])
        return np.power(self.p, x) * np.power(1 - self.p, np.subtract(1, x))
Esempio n. 15
0
    def __init__(self, alpha, A):
        """Create DPH(alpha, A) distribution.

        :param alpha probability vector 1xm
        :param A mxm matrix such that (I - A) is invertible.
        """

        # save params
        assert np.sum(alpha) == 1
        assert np.shape(A)[0] == np.shape(A)[1] == len(alpha)
        self.alpha = np.expand_dims(alpha, 0)
        self.A = np.array(A)
        self.m = np.shape(A)[1]

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(1, np.inf))
    def __init__(self, n=20, r=150, N=300):
        """Create Hyp(n, r, N) distribution.

        :param n offset vars
        :param r binomaial offset
        :param N biggest number.
        """

        # save params
        self.r = r
        self.n = n
        self.N = N

        # generate upper and lower bound
        lb = np.maximum(0, r + n - N)
        ub = np.minimum(n, r)

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(lb, ub + 1))
Esempio n. 17
0
class ParetoDist(ProbDist):
    """Simple Pareto distribution."""
    def __init__(self, shape=1, scale=1):
        """Creates Pareto(shape,scale) distribution.

        :param shape Shape of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.shape = shape
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return 1 / (self.scale * (self.shape - 1))

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        shape = self.shape
        scale = self.scale
        return shape / (scale**2 * (shape - 1)**2 * (shape - 2))

    def sample(self, num_samples=1):
        """Generate random numbers from Pareto(shape,scale).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Pareto(shape,scale).
        """

        # shortcut
        shape = self.shape
        scale = self.scale

        # sample data
        U = self.UG.sample(num_samples)
        X = U**(-1 / shape) - 1
        return scale * X

    def c_pdf(self, x):
        """This method calculates the density Pareto(shape,scale).

        :param x Which value should be evaluated.
        :returns The probability that this element occurs.
        """

        # shortcut
        shape = self.shape
        scale = self.scale

        # update x
        return shape * scale * (1 + np.multiply(scale, x))**(-(shape + 1))
Esempio n. 18
0
class StudentsTDist(ProbDist):
    """Simple student-t distribution."""

    def __init__(self, v = 1, loc = 0, scale = 1):
        """Create t(v,loc,scale) distribution.

        :param v Degrees of Freedom
        """

        # save params
        self.v = v
        self.loc = loc
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.loc

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.scale ** 2 * (self.v / (self.v - 2))

    def sample(self, num_samples=1):
        """Generate random numbers from t(v,loc,scale).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers from t(v,loc,scale).
        """

        # shortcut
        v = self.v
        loc = self.loc
        scale = self.scale
        elements = np.empty(num_samples)

        # create samples
        for k in range(num_samples):

            # iterate till found
            found = False
            while not found:

                # generate some samples
                u1 = self.UG.sample()
                u2 = self.UG.sample()

                # set X and V
                if u1 < 0.5:
                    X = 1 / (4 * u1 - 1)
                    V = u2 / X ** 2
                else:
                    X = 4 * u1 - 3
                    V = u2

                # acceptance check
                if V < 1 - abs(X) / 2 or V < (1 + (X ** 2) / v) ** (-(v+1) / 2):
                    elements[k] = X
                    found = True

        return scale * elements + loc

    def c_pdf(self, x):
        """This method calculates the density t(v,loc,scale).

        :param x What values should be evaluated.
        :returns The probability this element occurs.
        """

        # shortcut
        v = self.v
        loc = self.loc
        scale = self.scale

        # update x
        xn = np.subtract(x, loc) / scale
        z = m.gamma((v + 1) / 2) / (np.sqrt(v * m.pi) * m.gamma(v / 2))
        X = (1 + np.square(xn) / v) ** (-(v+1) / 2)
        return (z * X) / scale
Esempio n. 19
0
class GumbelDist(ProbDist):
    """Simple Gumbel distribution."""
    def __init__(self, loc=1, scale=1):
        """Creates Gumbel(loc,scale) distribution.

        :param loc Location of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.loc = loc
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.scale * 0.577216 + self.loc

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return (self.scale**2) * (m.pi**2 / 6)

    def sample(self, num_samples=1):
        """Generate random numbers from Gumbel(loc, scale) by using acceptance rejection distributions.

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Gumbel(loc, scale).
        """

        # shortcut
        loc = self.loc
        scale = self.scale

        # sample data
        U = self.UG.sample(num_samples)
        X = -np.log(-np.log(U))
        return scale * X + loc

    def c_pdf(self, x):
        """This method calculates the density Dist(x).

        :param x Which value should be evaluated.
        :returns The probability that this element occurs.
        """

        # shortcut
        loc = self.loc
        scale = self.scale

        # update x
        xn = np.subtract(x, loc) / scale
        f = np.exp(-xn - np.exp(-xn)) / scale
        return f
class WeibullDist(ProbDist):
    """Simple Weibull distribution."""
    def __init__(self, shape=1, loc=1, scale=1):
        """Creates Weib(shape,loc,scale) distribution.

        :param shape Shape of the distribution.
        :param loc Location of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.shape = shape
        self.loc = loc
        self.scale = scale

        # create generator
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return (self.scale**-1) * m.gamma(1 + self.shape**-1) + self.loc

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.scale ** -2 \
            * (m.gamma(1 + 2 * self.shape ** -1) - m.gamma(1 + self.shape ** -1) ** 2)

    def sample(self, num_samples=1):
        """Generate random numbers from Weib(shape,loc,scale).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Weib(shape,loc,scale).
        """

        # shortcut
        shape = self.shape
        loc = self.loc
        scale = self.scale

        # some sampling
        U = self.UG.sample(num_samples)
        X = 1 / scale * (-np.log(U))**(1 / shape)
        return scale * X + loc

    def c_pdf(self, x):
        """This method calculates the density Weib(shape,loc,scale).

        :param x Which value should be evaluated.
        :returns The probability that this element occurs.
        """

        assert x > 0

        # shortcut
        shape = self.shape
        loc = self.loc
        scale = self.scale
        xn = np.subtract(x, loc) / scale

        # update x
        ft = shape * xn**(shape - 1) * np.exp(-xn**shape)
        return ft / scale
Esempio n. 21
0
class WaldDist(ProbDist):
    """Simple Wald distribution."""

    def __init__(self, loc = 0, scale = 1):
        """Creates Wald(loc,scale) distribution.

        :param loc Location of the distribution.
        :param scale Scale of the distribution
        """

        # save params
        self.loc = loc
        self.scale = scale

        # create generator
        self.NG = NormalDist()
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(0, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.loc

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.loc ** 3 / self.scale

    def sample(self, num_samples = 1):
        """Generate random numbers from Wald(loc,scale).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Wald(loc,scale).
        """

        # shortcut
        loc = self.loc
        scale = self.scale

        # some sampling
        W = self.NG.sample(num_samples)
        Y = W ** 2
        Z = loc + (loc ** 2 * Y / 2 * scale) + (loc / 2 * scale) * np.sqrt(4 * loc * scale * Y + loc ** 2 * Y ** 2)
        X = Z

        # sample uniforms
        bound = loc / (loc + Z)
        B = self.UG.sample(num_samples)

        # iterate
        for k in range(num_samples):
            if B[k] > bound: X[k] = loc ** 2 / Z[k]

        return X

    def c_pdf(self, x):
        """This method calculates the density Wald(loc,scale).

        :param x Which value should be evaluated.
        :returns The probability that this element occurs.
        """

        assert x > 0

        # shortcut
        loc = self.loc
        scale = self.scale

        # update x
        z = np.sqrt(scale / (2 * np.pi * np.power(x, 3)))
        b = np.exp(-0.5 * (scale / loc ** 2) * (np.subtract(x, loc) ** 2) / x)
        return z * b
Esempio n. 22
0
class GammaDist(ProbDist):
    """Simple gamma distribution."""
    def __init__(self, shape=1, scale=1):
        """Create Ga(shape,scale) distribution.

        :param shape Shape of Ga(shape,scale)
        :param scale Scale of Ga(shape,scale)
        """
        self.shape = shape
        self.scale = scale

        self.UG = UniformDist()
        if shape >= 1: self.NG = NormalDist()
        super().__init__(ContinuousSpace(0, np.inf, open_brackets=False))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.shape / self.scale

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.shape / self.scale**2

    def sample(self, num_samples=1):
        """Generate random numbers from Ga(shape,scale) by using acceptance rejection distributions.

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Ga(shape,scale).
        """

        # extract vars
        shape = self.shape

        # when the shape is bigger than 1
        elements = self.rand_shp_gt_1(num_samples) \
            if shape >= 1 else \
            self.rand_shp_st_1(num_samples)

        return elements / self.scale

    def rand_shp_gt_1(self, num_samples):
        """Creates random variables, if gamma has shape bigger or equal to one.
        Marsaglia and Tsang's method from [1] implemented underneath.

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Ga(shape,scale).

        Refs: [1] https://dl.acm.org/citation.cfm?id=358414.
        """

        # some pre settings
        elements = np.empty(num_samples)
        shape = self.shape
        d = shape - 1 / 3
        c = 1 / m.sqrt(9 * d)

        # create all samples
        for k in range(num_samples):

            # generate normal and unif
            z = self.NG.sample()
            u = self.UG.sample()
            v = (1 + c * z)**3

            # first check
            while z <= -(1 / c) or m.log(
                    u) > 0.5 * z**2 + d - d * v + d * m.log(v):
                z = self.NG.sample()
                u = self.UG.sample()
                v = (1 + c * z)**3

            elements[k] = d * v

        return elements

    def rand_shp_st_1(self, num_samples):
        """Creates random variables, if gamma has shape smaller than one.
        Best's method from [1] implemented underneath.

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Ga(shape,scale).

        Refs: [1] https://link.springer.com/article/10.1007/BF02280789.
        """

        # some pre settings
        elements = np.empty(num_samples)
        shape = self.shape

        # some pre settings
        d = 0.07 + 0.75 * m.sqrt(1 - shape)
        b = 1 + m.exp(-d) * (shape / d)

        # create all samples
        for k in range(num_samples):

            found = False

            # repeat till found
            while not found:

                # two uniform ones
                u1 = self.UG.sample()
                u2 = self.UG.sample()
                v = b * u1

                if v <= 1:

                    # shorthand
                    x = d * v**(1 / shape)

                    # acceptance check
                    if u2 <= (2 - x) / (2 + x) or u2 <= m.exp(-x):
                        elements[k] = x
                        found = True
                else:

                    # shorthand
                    x = -m.log(d * (b - v) / shape)
                    y = x / d

                    # acceptance check
                    if u2 * (shape + y *
                             (1 - shape)) <= 1 or u2 < y**(shape - 1):
                        elements[k] = x
                        found = True

        return elements

    def c_pdf(self, x):
        """This method calculates the density Ga(x|shape,scale).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        shape = self.shape
        scale = self.scale
        z = scale**shape / m.gamma(shape)
        xa = np.power(x, (shape - 1))
        ex = np.exp(np.multiply(-scale, x))
        return z * xa * ex
Esempio n. 23
0
class PoissonDist(ProbDist):
    """Simple Poi(rate) distribution."""
    def __init__(self, rate=1):
        """Create Poi(rate) distribution.

        :param rate The rate parameter.
        """

        # save params
        assert 0 < rate
        self.rate = rate

        # create distribution for sampling
        self.UG = UniformDist()
        super().__init__(DiscreteSpace(0, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.rate

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.rate

    def sample(self, num_samples=1):
        """Generate random numbers from Poi(rate).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers x ~ Poi(rate).
        """

        X = np.empty(num_samples)
        for k in range(len(X)):

            # starting
            n = 1
            a = 1
            Un = self.UG.sample()
            a = a * Un

            # iterate over
            while a >= np.exp(-self.rate):
                n = n + 1
                Un = self.UG.sample()
                a = a * Un

            X[k] = n - 1

        return X

    def __density(self, x):
        """This method calculates the mass Poi(rate).

        :param x Which value should be evaluated.
        :returns The probability this element occurs.
        """

        z = np.power(self.rate, x) / m.factorial(x)
        return z * np.exp(-self.rate)
Esempio n. 24
0
class NormalDist(ProbDist):
    """Simple gaussian distribution."""
    def __init__(self, mean=0, var=1):
        """Create N(mean, var) distribution.

        :param mean Center of the gaussian
        :param var Variance around the center.
        """
        self.mean = mean
        self.var = var

        # create random generators
        self.EG = ExpDist()
        self.UG = UniformDist()
        super().__init__(ContinuousSpace(-np.inf, np.inf))

    def expectation(self):
        """Calculates the expectations for that distribution.

        :returns The expectation of the distribution"""

        return self.mean

    def var(self):
        """Calculates the variance for that distribution.

        :returns The variance of the distribution"""

        return self.var

    def sample(self, num_samples=1):
        """Generate random numbers from N(mean, var) by using an acceptance
        rejection algorithm using Exp(1) and U(0,1).

        :param num_samples How many random numbers should be generated.
        :returns Random numbers from N(mean, var).
        """

        # generate some samples
        elements = np.empty(num_samples)

        for k in range(num_samples):

            # generate sample
            x = self.EG.sample()
            un = self.UG.sample()

            # reject
            while un > np.exp(-(x - 1)**2 / 2):
                x = self.sample()
                un = self.UG.sample()

            # accept
            u = self.UG.sample()
            elements[k] = (1 - 2 * int(u <= 0.5)) * x

        return np.sqrt(self.var) * elements + self.mean

    def c_pdf(self, x):
        """This method calculates the density N(x|mean, var).

        :param x What values should be evaluated.
        :returns The probability this element occurs.
        """

        var = self.var
        mean = self.mean
        return 1 / np.sqrt(2 * var * np.pi) * np.exp(
            -0.5 * (np.subtract(x, mean)**2) / var)