clearly distinguish seeds for tessellation and seeds for RNG
This commit is contained in:
parent
1541ac0add
commit
fd8743af5e
|
@ -1233,6 +1233,7 @@ class Orientation(Rotation):
|
|||
array([[ 0.000, 0.000, 0.000],
|
||||
[ 0.577, -0.000, 0.816],
|
||||
[ 0.000, 0.000, 0.000]])
|
||||
|
||||
"""
|
||||
d = self.to_frame(uvw=self.kinematics[mode]['direction'],with_symmetry=False)
|
||||
p = self.to_frame(hkl=self.kinematics[mode]['plane'] ,with_symmetry=False)
|
||||
|
|
|
@ -682,7 +682,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def from_random(shape = None,
|
||||
seed = None,
|
||||
rng_seed = None,
|
||||
**kwargs):
|
||||
"""
|
||||
Draw random rotation.
|
||||
|
@ -694,12 +694,12 @@ class Rotation:
|
|||
shape : tuple of ints, optional
|
||||
Shape of the sample. Defaults to None which gives a
|
||||
single rotation
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = np.random.default_rng(seed)
|
||||
rng = np.random.default_rng(rng_seed)
|
||||
r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3))
|
||||
|
||||
A = np.sqrt(r[...,2])
|
||||
|
@ -718,7 +718,7 @@ class Rotation:
|
|||
N = 500,
|
||||
degrees = True,
|
||||
fractions = True,
|
||||
seed = None,
|
||||
rng_seed = None,
|
||||
**kwargs):
|
||||
"""
|
||||
Sample discrete values from a binned ODF.
|
||||
|
@ -737,7 +737,7 @@ class Rotation:
|
|||
fractions : boolean, optional
|
||||
ODF values correspond to volume fractions, not probability density.
|
||||
Defaults to True.
|
||||
seed: {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed: {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy
|
||||
will be pulled from the OS.
|
||||
|
||||
|
@ -768,7 +768,7 @@ class Rotation:
|
|||
dg = 1.0 if fractions else _dg(Eulers,degrees)
|
||||
dV_V = dg * np.maximum(0.0,weights.squeeze())
|
||||
|
||||
return Rotation.from_Eulers(Eulers[util.hybrid_IA(dV_V,N,seed)],degrees)
|
||||
return Rotation.from_Eulers(Eulers[util.hybrid_IA(dV_V,N,rng_seed)],degrees)
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
@ -776,7 +776,7 @@ class Rotation:
|
|||
sigma,
|
||||
N = 500,
|
||||
degrees = True,
|
||||
seed = None,
|
||||
rng_seed = None,
|
||||
**kwargs):
|
||||
"""
|
||||
Calculate set of rotations with Gaussian distribution around center.
|
||||
|
@ -791,12 +791,12 @@ class Rotation:
|
|||
Number of samples, defaults to 500.
|
||||
degrees : boolean, optional
|
||||
sigma is given in degrees.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy
|
||||
will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = np.random.default_rng(seed)
|
||||
rng = np.random.default_rng(rng_seed)
|
||||
sigma = np.radians(sigma) if degrees else sigma
|
||||
u,Theta = (rng.random((N,2)) * 2.0 * np.array([1,np.pi]) - np.array([1.0, 0])).T
|
||||
omega = abs(rng.normal(scale=sigma,size=N))
|
||||
|
@ -813,7 +813,7 @@ class Rotation:
|
|||
sigma = 0.0,
|
||||
N = 500,
|
||||
degrees = True,
|
||||
seed = None,
|
||||
rng_seed = None,
|
||||
**kwargs):
|
||||
"""
|
||||
Calculate set of rotations with Gaussian distribution around direction.
|
||||
|
@ -831,12 +831,12 @@ class Rotation:
|
|||
Number of samples, defaults to 500.
|
||||
degrees : boolean, optional
|
||||
sigma, alpha, and beta are given in degrees.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy
|
||||
will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = np.random.default_rng(seed)
|
||||
rng = np.random.default_rng(rng_seed)
|
||||
sigma_,alpha_,beta_ = map(np.radians,(sigma,alpha,beta)) if degrees else (sigma,alpha,beta)
|
||||
|
||||
d_cr = np.array([np.sin(alpha_[0])*np.cos(alpha_[1]), np.sin(alpha_[0])*np.sin(alpha_[1]), np.cos(alpha_[0])])
|
||||
|
|
|
@ -5,7 +5,7 @@ from . import util
|
|||
from . import grid_filters
|
||||
|
||||
|
||||
def from_random(size,N_seeds,grid=None,seed=None):
|
||||
def from_random(size,N_seeds,grid=None,rng_seed=None):
|
||||
"""
|
||||
Random seeding in space.
|
||||
|
||||
|
@ -18,12 +18,12 @@ def from_random(size,N_seeds,grid=None,seed=None):
|
|||
grid : numpy.ndarray of shape (3), optional.
|
||||
If given, ensures that all seeds initiate one grain if using a
|
||||
standard Voronoi tessellation.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = _np.random.default_rng(seed)
|
||||
rng = _np.random.default_rng(rng_seed)
|
||||
if grid is None:
|
||||
coords = rng.random((N_seeds,3)) * size
|
||||
else:
|
||||
|
@ -34,7 +34,7 @@ def from_random(size,N_seeds,grid=None,seed=None):
|
|||
return coords
|
||||
|
||||
|
||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,seed=None):
|
||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed=None):
|
||||
"""
|
||||
Seeding in space according to a Poisson disc distribution.
|
||||
|
||||
|
@ -50,12 +50,12 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,seed=None
|
|||
Minimum acceptable distance to other seeds.
|
||||
periodic : boolean, optional
|
||||
Calculate minimum distance for periodically repeated grid.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = _np.random.default_rng(seed)
|
||||
rng = _np.random.default_rng(rng_seed)
|
||||
coords = _np.empty((N_seeds,3))
|
||||
coords[0] = rng.random(3) * size
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ def srepr(arg,glue = '\n'):
|
|||
arg : iterable
|
||||
Items to join.
|
||||
glue : str, optional
|
||||
Defaults to \n.
|
||||
Glue used for joining operation. Defaults to \n.
|
||||
|
||||
"""
|
||||
if (not hasattr(arg, "strip") and
|
||||
|
@ -163,7 +163,15 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50):
|
|||
|
||||
|
||||
def scale_to_coprime(v):
|
||||
"""Scale vector to co-prime (relatively prime) integers."""
|
||||
"""
|
||||
Scale vector to co-prime (relatively prime) integers.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
v : numpy.ndarray of shape (:)
|
||||
Vector to scale.
|
||||
|
||||
"""
|
||||
MAX_DENOMINATOR = 1000000
|
||||
|
||||
def get_square_denominator(x):
|
||||
|
@ -214,7 +222,21 @@ def execution_stamp(class_name,function_name=None):
|
|||
return f'damask.{class_name}{_function_name} v{version} ({now})'
|
||||
|
||||
|
||||
def hybrid_IA(dist,N,seed=None):
|
||||
def hybrid_IA(dist,N,rng_seed=None):
|
||||
"""
|
||||
Hybrid integer approximation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dist : numpy.ndarray
|
||||
Distribution to be approximated
|
||||
N : int
|
||||
Number of samples to draw.
|
||||
rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
N_opt_samples,N_inv_samples = (max(np.count_nonzero(dist),N),0) # random subsampling if too little samples requested
|
||||
|
||||
scale_,scale,inc_factor = (0.0,float(N_opt_samples),1.0)
|
||||
|
@ -225,7 +247,7 @@ def hybrid_IA(dist,N,seed=None):
|
|||
if N_inv_samples < N_opt_samples else \
|
||||
(scale_,0.5*(scale_ + scale), 1.0)
|
||||
|
||||
return np.repeat(np.arange(len(dist)),repeats)[np.random.default_rng(seed).permutation(N_inv_samples)[:N]]
|
||||
return np.repeat(np.arange(len(dist)),repeats)[np.random.default_rng(rng_seed).permutation(N_inv_samples)[:N]]
|
||||
|
||||
|
||||
def shapeshifter(fro,to,mode='left',keep_ones=False):
|
||||
|
|
|
@ -18,6 +18,7 @@ def patch_damask_version(monkeypatch):
|
|||
"""Set damask.version for reproducible tests results."""
|
||||
monkeypatch.setattr(damask, 'version', patched_version)
|
||||
|
||||
|
||||
patched_date = datetime.datetime(2019, 11, 2, 11, 58, 0)
|
||||
@pytest.fixture
|
||||
def patch_datetime_now(monkeypatch):
|
||||
|
@ -29,6 +30,7 @@ def patch_datetime_now(monkeypatch):
|
|||
|
||||
monkeypatch.setattr(datetime, 'datetime', mydatetime)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_execution_stamp(monkeypatch):
|
||||
"""Set damask.util.execution_stamp for reproducible tests results."""
|
||||
|
@ -38,6 +40,7 @@ def patch_execution_stamp(monkeypatch):
|
|||
|
||||
monkeypatch.setattr(damask.util, 'execution_stamp', execution_stamp)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_plt_show(monkeypatch):
|
||||
def _None(block=None):
|
||||
|
@ -50,16 +53,19 @@ def pytest_addoption(parser):
|
|||
action="store_true",
|
||||
default=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def update(request):
|
||||
"""Store current results as new reference results."""
|
||||
return request.config.getoption("--update")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def reference_dir_base():
|
||||
"""Directory containing reference results."""
|
||||
return Path(__file__).parent/'reference'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def set_of_quaternions():
|
||||
"""A set of n random rotations."""
|
||||
|
|
|
@ -125,9 +125,9 @@ class TestOrientation:
|
|||
|
||||
def test_from_fiber_component(self):
|
||||
r = Rotation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
||||
sigma=0.0,N=1,seed=0)
|
||||
sigma=0.0,N=1,rng_seed=0)
|
||||
assert np.all(Orientation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
||||
sigma=0.0,N=1,seed=0,lattice='triclinic').quaternion
|
||||
sigma=0.0,N=1,rng_seed=0,lattice='triclinic').quaternion
|
||||
== r.quaternion)
|
||||
|
||||
@pytest.mark.parametrize('kwargs',[
|
||||
|
@ -175,8 +175,8 @@ class TestOrientation:
|
|||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||
@pytest.mark.parametrize('N',[1,8,32])
|
||||
def test_disorientation(self,lattice,N):
|
||||
o = Orientation.from_random(lattice=lattice,shape=N,seed=0)
|
||||
p = Orientation.from_random(lattice=lattice,shape=N,seed=1)
|
||||
o = Orientation.from_random(lattice=lattice,shape=N)
|
||||
p = Orientation.from_random(lattice=lattice,shape=N)
|
||||
|
||||
d,ops = o.disorientation(p,return_operators=True)
|
||||
|
||||
|
@ -198,8 +198,8 @@ class TestOrientation:
|
|||
(None,None),
|
||||
])
|
||||
def test_disorientation_blending(self,lattice,a,b):
|
||||
o = Orientation.from_random(lattice=lattice,shape=a,seed=0)
|
||||
p = Orientation.from_random(lattice=lattice,shape=b,seed=1)
|
||||
o = Orientation.from_random(lattice=lattice,shape=a)
|
||||
p = Orientation.from_random(lattice=lattice,shape=b)
|
||||
blend = util.shapeblender(o.shape,p.shape)
|
||||
for loc in np.random.randint(0,blend,(10,len(blend))):
|
||||
assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \
|
||||
|
@ -214,7 +214,7 @@ class TestOrientation:
|
|||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
||||
def test_reduced_vectorization(self,lattice,shape):
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape,seed=0)
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
||||
for r, theO in zip(o.reduced.flatten(),o.flatten()):
|
||||
assert r == theO.reduced
|
||||
|
||||
|
@ -223,7 +223,7 @@ class TestOrientation:
|
|||
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
||||
@pytest.mark.parametrize('proper',[True,False])
|
||||
def test_to_SST_vectorization(self,lattice,shape,vector,proper):
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape,seed=0)
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
||||
for r, theO in zip(o.to_SST(vector=vector,proper=proper).reshape((-1,3)),o.flatten()):
|
||||
assert np.allclose(r,theO.to_SST(vector=vector,proper=proper))
|
||||
|
||||
|
@ -232,7 +232,7 @@ class TestOrientation:
|
|||
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
||||
@pytest.mark.parametrize('proper',[True,False])
|
||||
def test_IPF_color_vectorization(self,lattice,shape,vector,proper):
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape,seed=0)
|
||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
||||
poles = o.to_SST(vector=vector,proper=proper)
|
||||
for r, theO in zip(o.IPF_color(poles,proper=proper).reshape((-1,3)),o.flatten()):
|
||||
assert np.allclose(r,theO.IPF_color(theO.to_SST(vector=vector,proper=proper),proper=proper))
|
||||
|
@ -245,7 +245,7 @@ class TestOrientation:
|
|||
(None,(3,)),
|
||||
])
|
||||
def test_to_SST_blending(self,lattice,a,b):
|
||||
o = Orientation.from_random(lattice=lattice,shape=a,seed=0)
|
||||
o = Orientation.from_random(lattice=lattice,shape=a)
|
||||
v = np.random.random(b+(3,))
|
||||
blend = util.shapeblender(o.shape,b)
|
||||
for loc in np.random.randint(0,blend,(10,len(blend))):
|
||||
|
|
|
@ -778,7 +778,7 @@ class TestRotation:
|
|||
assert r.shape == shape
|
||||
|
||||
def test_equal(self):
|
||||
assert Rotation.from_random(seed=1) == Rotation.from_random(seed=1)
|
||||
assert Rotation.from_random(rng_seed=1) == Rotation.from_random(rng_seed=1)
|
||||
|
||||
def test_inversion(self):
|
||||
r = Rotation.from_random()
|
||||
|
|
Loading…
Reference in New Issue