Beispiel #1
0
    def compute_axis_angle(self):
        x = vonmises.rvs(self.kappa, size=1)
        y = uniform(0, np.pi)

        vec_a = self.compute_mean_normal()
        vec_b, vec_c = self.compute_fracture_normal(vec_a)

        vec_n = cos(x)*vec_a + sin(x)*(sin(y)*vec_b + cos(y)*vec_c)

        axis = np.cross(vec_n, vec_a)
        angle = np.arccos(np.dot(vec_n, vec_a)/2)

        return axis, angle
Beispiel #2
0
def gen_bucketed_vonmesis():
    bucketed_data = np.zeros([SAMPLE_SIZE, NUM_BUCKETS + 1])
    for kappa in range(1, 6):
        for i in range(1000):
            vm_dist = vonmises.rvs(kappa, size=SAMPLE_SIZE)
            positives = [x + pi for x in vm_dist]
            bucket_number = [int((x * 180 / pi) // 10) for x in positives]
            for num in bucket_number:
                bucketed_data[i][num] += 1
            # label the data
            bucketed_data[i][NUM_BUCKETS] = -2 - kappa
        np.savetxt('vonmesis_{}.csv'.format(kappa),
                   bucketed_data,
                   delimiter=",")
Beispiel #3
0
    def computeDirection(self, repellTargets, orientTargets, attractTargets):
        newWishedDirection = np.zeros(3)
        # zone of repulsion - highest priority
        if repellTargets.size > 0:
            for fish in repellTargets:
                diff = fish.location - self.location
                assert np.linalg.norm(diff) > 1e-12, print(
                    diff, "are you satisfying speed*dt<=rRepulsion?")
                assert np.linalg.norm(diff) < 1e12, print(diff)
                newWishedDirection -= diff / np.linalg.norm(diff)
        else:
            orientDirect = np.zeros(3)
            attractDirect = np.zeros(3)
            # zone of orientation
            if orientTargets.size > 0:
                for fish in orientTargets:
                    orientDirect += fish.curDirection / np.linalg.norm(
                        fish.curDirection)
            # zone of attraction
            if attractTargets.size > 0:
                for fish in attractTargets:
                    diff = fish.location - self.location
                    attractDirect += diff / np.linalg.norm(diff)

            newWishedDirection = orientDirect + attractDirect

        if np.linalg.norm(newWishedDirection) < 1e-12:
            newWishedDirection = self.curDirection

        ## stochastic effect, replicates "spherically wrapped Gaussian distribution"
        # get random unit direction orthogonal to newWishedDirection
        randVector = self.randUnitDirection()
        rotVector = np.cross(newWishedDirection, randVector)
        while np.isclose(np.linalg.norm(rotVector), 0.0):
            randVector = self.randUnitDirection()
            rotVector = np.cross(newWishedDirection, randVector)
        rotVector /= np.linalg.norm(rotVector)
        # compute random angle from wrapped Gaussian ~ van Mises distribution
        randAngle = vonmises.rvs(1 / self.sigma**2)
        # create rotation
        rotVector *= randAngle
        r = Rotation.from_rotvec(rotVector)
        # apply rotation
        self.wishedDirection = r.apply(newWishedDirection)
Beispiel #4
0
def randvonmises(anglegram, i, kappa_scalar=8, random_state=1):
    """
    Sample random value from a von Mises distribution fitted to a histogram
    """
    np.random.seed(random_state)

    xtorsion = torch.linspace(-np.pi, np.pi, 36)

    vmexp = torch.sum(xtorsion * anglegram[0, 1:, 0, i])
    vmvar = torch.sum(anglegram[0, 1:, 0, i] * (xtorsion - vmexp)**2)

    vmkappa = 1 / vmvar

    randvar = vonmises.rvs(kappa=kappa_scalar * vmkappa, loc=vmexp)
    if randvar < -np.pi:
        randvar = 2 * np.pi + randvar
    elif randvar > np.pi:
        randvar = -2 * np.pi + randvar
    return randvar
Beispiel #5
0
def _make_von_mises_multimodal_sampler(neigh,
                                       dirs,
                                       vm_distr_kappa=12,
                                       approx_len=5000):
    # Returns a lambda function that is a quick and reliable way to simulate
    # draws from a Von Mises mixture distribution:
    # 1.) Chooses a direction by neighborhood-weighted probability
    # 2.) Makes a random draw from a Von Mises dist centered on the direction,
    # with a vm_distr_kappa value set such that the net effect,
    # when doing this a ton of times for a given neighborhood and then
    # plotting the resulting histogram, gives the visually/heuristically
    # satisfying approximation of a Von Mises mixture distribution

    # NOTE: Just visually, heuristically, vm_distr_kappa = 10 seemed
    # like a perfect middle value (vm_distr_kappa ~3 gives too
    # wide of a Von Mises variance and just chooses values around
    # the entire circle regardless of neighborhood
    # probability, whereas vm_distr_kappa ~20 produces noticeable reductions
    # in probability of moving to directions between the 8 queen's
    # neighborhood directions (i.e. doesn't simulate the mixing well enough)
    # and would generate artefactual movement behavior); 12 also
    # seemed to really well in generating probability valleys
    # when tested on neighborhoods that should generate bimodal distributions
    d = list(dirs.ravel())
    n = list(neigh.ravel())
    del d[4]
    del n[4]
    sum_n = float(sum(n))
    if sum_n > 0:
        n_probs = [i / sum_n for i in n]
    else:
        n_probs = [.125] * 8
    loc_choices = r.choice(d, approx_len, replace=True, p=n_probs)
    loc_choices = list(C(loc_choices).items())
    approx = np.hstack([
        s_vonmises.rvs(vm_distr_kappa, loc=loc, scale=1, size=size)
        for loc, size in loc_choices
    ])
    return approx
Beispiel #6
0
def _make_von_mises_unimodal_sampler(neigh,
                                     dirs,
                                     vm_distr_kappa=12,
                                     approx_len=5000):
    """Return a list of values approximating a unimodal von Mises distribution
       pointing in the direction of the maximum-valued cell."""
    # list out the directons and their values
    d = list(dirs.ravel())
    n = list(neigh.ravel())
    # get rid of focal cell's values
    del d[4]
    del n[4]
    # identify the direction associated with the maximum-valued cell
    loc = [dirx for idx, dirx in enumerate(d) if n[idx] == max(n)]
    # get mean of max-valued directions, if there are more than 1
    if len(loc) > 1:
        loc = np.mean(loc)
    else:
        loc = loc[0]
    # make the draws for the approximation vector
    approx = s_vonmises.rvs(vm_distr_kappa, loc=loc, scale=1, size=approx_len)
    return approx
def getConnections(neuron):

    # Sample from circular distribution
    synapseAngles = vonmises.rvs(kappa=neuron['angleHomogeneity'],
                                 loc=neuron['meanAngle'],
                                 scale=neuron['angleDistScale'],
                                 size=neuron['nSynapses'])

    # Get synapse distances (sampled from normal distribution)
    synapseDistances = normal(loc=0.0,
                              scale=neuron['distanceSTD'],
                              size=neuron['nSynapses'])
    synapseDistances = np.abs(
        synapseDistances)  # Take just positive side of distribution

    # Generate synapse lines
    synapses = []
    for s in range(neuron['nSynapses']):
        xEnd = neuron['xPos'] + (np.cos(synapseAngles[s]) *
                                 synapseDistances[s])
        yEnd = neuron['yPos'] + (np.sin(synapseAngles[s]) *
                                 synapseDistances[s])
        synapses.append([[neuron['xPos'], xEnd], [neuron['yPos'], yEnd]])
    return synapses
Beispiel #8
0
def draw_vonmises(kappa, loc, nsamples):
#    print "kappa, loc: ", kappa, loc
#    x = 180/pi * vonmises.rvs(kappa, loc=loc, size=nsamples)
    x = vonmises.rvs(kappa, loc=loc, size=nsamples)
    return x
# Display the probability density function (``pdf``):

x = np.linspace(vonmises.ppf(0.01, kappa), vonmises.ppf(0.99, kappa), 100)
ax.plot(x, vonmises.pdf(x, kappa), 'r-', lw=5, alpha=0.6, label='vonmises pdf')

# Alternatively, the distribution object can be called (as a function)
# to fix the shape, location and scale parameters. This returns a "frozen"
# RV object holding the given parameters fixed.

# Freeze the distribution and display the frozen ``pdf``:

rv = vonmises(kappa)
ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

# Check accuracy of ``cdf`` and ``ppf``:

vals = vonmises.ppf([0.001, 0.5, 0.999], kappa)
np.allclose([0.001, 0.5, 0.999], vonmises.cdf(vals, kappa))
# True

# Generate random numbers:

r = vonmises.rvs(kappa, size=1000)

# And compare the histogram:

ax.hist(r, normed=True, histtype='stepfilled', alpha=0.2)
ax.legend(loc='best', frameon=False)
plt.show()
Beispiel #10
0
def sim(a, b, plot=False, n=int(1e8)):
    unwrapped = vonmises.rvs(a, size=n) + vonmises.rvs(b, size=n)
    unwrapped = unwrapped
    wrapped = (unwrapped + np.pi) % (2 * np.pi) - np.pi
    kappa, _, _ = vonmises.fit(wrapped, floc=0, fscale=1)
    if plot is True:
        plt.hist(wrapped, normed=True, bins=100)
        x = np.linspace(-np.pi, np.pi)
        y = vonmises.pdf(x, kappa)
        plt.plot(x, y)
    return kappa


# import numpy as np
# import pymc3 as pm
# import matplotlib.pyplot as plt
# import theano.tensor as tt
# from scipy.stats import norm, vonmises
# from scipy.integrate import quad
#
#
# n = 10000
# mu = 3
# sigma = 3
#
# k = np.exp(norm.rvs(mu, sigma, size=n))
# x = vonmises.rvs(kappa=k, size=n)
#
# with pm.Model():
#
#     mu = pm.Normal(name="mu", mu=0, sigma=10)
#     sigma = pm.HalfCauchy(name="sigma", beta=1)
#     delta = pm.Normal(name="delta", mu=0, sigma=1, shape=n)
#     kappa = tt.exp(mu + delta * sigma)  # IMPORTANT! Use non-centered parameterization
#     pm.VonMises(name="obs", mu=0, kappa=kappa, observed=x)
#     trace = pm.sample(10000, tune=5000, chains=2)
#     pm.traceplot(trace, compact=True, var_names=["mu", "sigma"])
#     plt.savefig("tmp.png")
#
# # hist(x, bins=100, normed=True)
# #
# # x = np.linspace(-np.pi, np.pi, 100)
# #
# # def pdf(x, mu, sigma, a):
# #     g = 1
# #     v = vonmises.pdf(x, kappa=mu)
# #     def f(k, x):
# #         g = gamma.pdf(k, mu**2 / sigma**2, scale=1. / (mu / sigma**2))
# #         v = vonmises.pdf(x, kappa=k)
# #         return g * v
# #     return [quad(f, 0, a, _x)[0] for _x in x]
# #
# # def logpdf(x, mu, sigma, a):
# #     g = 1
# #     v = vonmises.pdf(x, kappa=mu)
# #     def f(k, x):
# #         g = gamma.logpdf(k, mu**2 / sigma**2, scale=1. / (mu / sigma**2))
# #         v = vonmises.logpdf(x, kappa=k)
# #         return g * v
# #     return [quad(f, 0, a, _x)[0] for _x in x]
# #
# # [plot(x, pdf(x, mu, sigma, a)) for a in [500]]
# #
# #
# # plot(x, np.log(pdf(x, mu, sigma)))
#
#
#
#
#
#
# # from scipy.integrate import quad
# # import theano
# # import theano.tensor as tt
# # import numpy as np
# # import pymc3 as pm
# #
# #
# # class Integrate(theano.Op):
# #     def __init__(self, expr, var, *extra_vars):
# #         super().__init__()
# #         self._expr = expr
# #         self._var = var
# #         self._extra_vars = extra_vars
# #         self._func = theano.function(
# #             [var] + list(extra_vars),
# #             self._expr,
# #             on_unused_input='ignore')
# #
# #     def make_node(self, start, stop, *extra_vars):
# #         self._extra_vars_node = extra_vars
# #         assert len(self._extra_vars) == len(extra_vars)
# #         self._start = start
# #         self._stop = stop
# #         vars = [start, stop] + list(extra_vars)
# #         # vars = list(extra_vars)
# #         return theano.Apply(self, vars, [tt.dscalar().type()])
# #
# #     def perform(self, node, inputs, out):
# #         start, stop, *args = inputs
# #         val = quad(self._func, start, stop, args=tuple(args))[0]
# #         out[0][0] = np.array(val)
# #
# #     def grad(self, inputs, grads):
# #         start, stop, *args = inputs
# #         out, = grads
# #         replace = dict(zip(self._extra_vars, args))
# #
# #         replace_ = replace.copy()
# #         replace_[self._var] = start
# #         dstart = out * theano.clone(-self._expr, replace=replace_)
# #
# #         replace_ = replace.copy()
# #         replace_[self._var] = stop
# #         dstop = out * theano.clone(self._expr, replace=replace_)
# #
# #         grads = tt.grad(self._expr, self._extra_vars)
# #         dargs = []
# #         for grad in grads:
# #             integrate = Integrate(grad, self._var, *self._extra_vars)
# #             darg = out * integrate(start, stop, *args)
# #             dargs.append(darg)
# #
# #         return [dstart, dstop] + dargs
# #
# #
# # y_obs = 8.3
# #
# # start = theano.shared(1.)
# # stop = theano.shared(2.)
# # with pm.Model() as basic_model:
# #     a = pm.Uniform('a', 1.5, 3.5)
# #     b = pm.Uniform('b', 4., 6.)
# #
# #     # Define the function to integrate in plain theano
# #     t = tt.dscalar('t')
# #     t.tag.test_value = np.zeros(())
# #     a_ = tt.dscalar('a_')
# #     a_.tag.test_value = np.ones(())*2.
# #     b_ = tt.dscalar('b_')
# #     b_.tag.test_value = np.ones(())*5.
# #     func = t**a_ + b_
# #     integrate = Integrate(func, t, a_, b_)
# #
# #     # Now we plug in the values from the model.
# #     # The `a_` and `b_` from above corresponds to the `a` and `b` here.
# #     mu = integrate(start, stop, a, b)
# #     y = pm.Normal('y', mu=mu, sd=0.4, observed=y_obs)
# #     trace = pm.sample(1500, tune=500, cores=2, chains=2)
Beispiel #11
0
def draw_vonmises(kappa, loc, nsamples):
#    print "kappa, loc: ", kappa, loc
#    x = 180/pi * vonmises.rvs(kappa, loc=loc, size=nsamples)
    x = vonmises.rvs(kappa, loc=loc, size=nsamples)
#    fvm.write("%f\n" % x[0])
    return x
Beispiel #12
0
    ncounts = 1000

    xx = []
    yy = []
    zz = []

    # Loop through all photons
    for i in range(ncounts):

        # Select a wavelength
        wavelength = normalvariate(wavelength_mean, wavelength_sigma)
        if wavelength <= 0:
            continue

        # Select a divergence
        divangle = vonmises.rvs(divangle_kappa), uniform(0, 2 * pi)

        # Select a mosaic angular spread angle
        mosangle = vonmises.rvs(mosangle_kappa), uniform(0, 2 * pi)

        # Select a mosaic size point
        mossize_xyz = multivariate_normal(
            [0.0, 0.0, 0.0],
            [
                [mossize_sigma, 0.0, 0.0],
                [0.0, mossize_sigma, 0.0],
                [0.0, 0.0, mossize_sigma],
            ],
        )

        # Select a mosaic spread in unit cell sizes points
Beispiel #13
0
def draw_vonmises(kappa, loc, nsamples):
    #    print "kappa, loc: ", kappa, loc
    #    x = 180/pi * vonmises.rvs(kappa, loc=loc, size=nsamples)
    x = vonmises.rvs(kappa, loc=loc, size=nsamples)
    #    fvm.write("%f\n" % x[0])
    return x