/usr/share/pyshared/MMTK/Random.py is in python-mmtk 2.7.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | # Functions for finding random points and orientations.
#
# Written by: Konrad Hinsen
#
"""
Random quantities for use in molecular simulations
"""
__docformat__ = 'restructuredtext'
from Scientific.Geometry import Vector
from Scientific.Geometry.Transformation import Rotation
from Scientific import N
from MMTK import ParticleProperties, Units
try:
numeric = N.package
except AttributeError:
numeric = "Numeric"
RNG = None
try:
if numeric == "Numeric":
import RNG
elif numeric == "NumPy":
import numpy.oldnumeric.rng as RNG
except ImportError:
pass
if RNG is None:
if numeric == "Numeric":
from RandomArray import uniform, seed
elif numeric == "NumPy":
from numpy.oldnumeric.random_array import uniform, seed
random = __import__('random')
seed(1, 1)
random.seed(1)
def initializeRandomNumbersFromTime():
random.seed()
seed(0, 0)
def gaussian(mean, std, shape=None):
if shape is None:
x = random.normalvariate(0., 1.)
else:
x = N.zeros(shape, N.Float)
xflat = N.ravel(x)
for i in range(len(xflat)):
xflat[i] = random.normalvariate(0., 1.)
return mean + std*x
else:
_uniform_generator = \
RNG.CreateGenerator(-1, RNG.UniformDistribution(0., 1.))
_gaussian_generator = \
RNG.CreateGenerator(-1, RNG.NormalDistribution(0., 1.))
def initializeRandomNumbersFromTime():
global _uniform_generator, _gaussian_generator
_uniform_generator = \
RNG.CreateGenerator(0, RNG.UniformDistribution(0., 1.))
_gaussian_generator = \
RNG.CreateGenerator(0, RNG.NormalDistribution(0., 1.))
def uniform(x1, x2, shape=None):
if shape is None:
x = _uniform_generator.ranf()
else:
n = N.multiply.reduce(shape)
x = _uniform_generator.sample(n)
x.shape = shape
return x1+(x2-x1)*x
def gaussian(mean, std, shape=None):
if shape is None:
x = _gaussian_generator.ranf()
else:
n = N.multiply.reduce(shape)
x = _gaussian_generator.sample(n)
x.shape = shape
return mean+std*x
del numeric
#
# Random point in a rectangular box centered around the origin
#
def randomPointInBox(a, b = None, c = None):
"""
:param a: the edge length of a box along the x axis
:type a: float
:param b: the edge length of a box along the y axis (default: a)
:type b: float
:param c: the edge length of a box along the z axis (default: a)
:type c: float
:returns: a vector drawn from a uniform distribution within a
rectangular box with edge lengths a, b, c.
:rtype: Scientific.Geometry.Vector
"""
if b is None: b = a
if c is None: c = a
x = uniform(-0.5*a, 0.5*a)
y = uniform(-0.5*b, 0.5*b)
z = uniform(-0.5*c, 0.5*c)
return Vector(x, y, z)
#
# Random point in a sphere around the origin.
#
def randomPointInSphere(r):
"""
:param r: the radius of a sphere
:type r: float
:returns: a vector drawn from a uniform distribution within
a sphere of radius r.
:rtype: Scientific.Geometry.Vector
"""
rsq = r*r
while 1:
x = N.array([uniform(-r, r), uniform(-r, r), uniform(-r, r)])
if N.dot(x, x) < rsq: break
return Vector(x)
#
# Random direction (unit vector).
#
def randomDirection():
"""
:returns: a vector drawn from a uniform distribution on the surface
of a unit sphere.
:rtype: Scientific.Geometry.Vector
"""
r = randomPointInSphere(1.)
return r.normal()
def randomDirections(n):
"""
:param n: the number of direction vectors
:returns: a list of n vectors drawn from a uniform distribution on
the surface of a unit sphere. If n is negative, returns
a deterministic list of not more than -n vectors of unit
length (useful for testing purposes).
:rtype: list
"""
if n < 0:
vs = [Vector(1., 0., 0.), Vector(0., -1., 0.), Vector(0., 0., 1.),
Vector(-1., 1., 0.).normal(), Vector(-1., 0., 1.).normal(),
Vector(0., 1., -1.).normal(), Vector(1., -1., 1.).normal()]
return vs[:-n]
else:
return [randomDirection() for i in range(n)]
#
# Random rotation.
#
def randomRotation(max_angle = N.pi):
"""
:param max_angle: the upper limit for the rotation angle
:type max_angle: float
:returns: a random rotation with a uniform axis distribution
and angles drawn from a uniform distribution between
-max_angle and max_angle.
:rtype: Scientific.Geometry.Transformations.Rotation
"""
return Rotation(randomDirection(), uniform(-max_angle, max_angle))
#
# Random velocity (gaussian)
#
def randomVelocity(temperature, mass):
"""
:param temperature: the temperature defining a Maxwell distribution
:type temperature: float
:param mass: the mass of a particle
:type mass: float
:returns: a random velocity vector for a particle of a given mass
at a given temperature
:rtype: Scientific.Geometry.Vector
"""
sigma = N.sqrt((temperature*Units.k_B)/(mass*Units.amu))
return Vector(gaussian(0., sigma, (3,)))
#
# Random ParticleVector (gaussian)
#
def randomParticleVector(universe, width):
"""
:param universe: a universe
:type universe: :class:`~MMTK.Universe.Universe`
:param width: the width (standard deviation) of a Gaussian distribution
:type width: float
:returns: a set of vectors drawn from a Gaussian distribution
with a given width centered around zero.
:rtype: :class:`~MMTK.ParticleProperties.ParticleVector`
"""
data = gaussian(0., 0.577350269189*width, (universe.numberOfPoints(), 3))
return ParticleProperties.ParticleVector(universe, data)
|