def test_check_anagrad_diag_prec(self): x_init = np.zeros(2, float) prec_fun = DiagonalPreconditioner(fun, 20, 1e-2) prec_fun.scales = np.random.uniform(1, 2, 2) check_anagrad(prec_fun, x_init, 1e-5, 1e-4) dxs = random_unit((100, len(x_init))) * 1e-4 check_delta(prec_fun, x_init, dxs)
def test_superpose(self): # create a few test sets with random data points, including degenerate # situations. (e.g. one point, two points, linear points) references = [ # a list of 2-tuples: (points, degenerate) (numpy.random.normal(0, 5, (n, 3)), False) for n in xrange(4, 40) ] + [ #(numpy.array([[0,0,1]], float), True), #(numpy.array([[0,0,0],[0,0,1]], float), True), #(numpy.array([[0,0,0],[0,0,1],[0,0,2]], float), True), #(numpy.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True), #(numpy.random.normal(0, 5, (3, 3)), True) ] # Do a random transformation on the points randomized = [] for points, degenerate in references: #points[:] -= points.mean(axis=0) axis = random_unit(3) angle = numpy.random.uniform(0, numpy.pi * 2) transformation = Complete() transformation.set_rotation_properties(angle, axis, False) transformation.t[:] = numpy.random.normal(0, 5, 3) randomized.append( (numpy.array([transformation.vector_apply(p) for p in points]), transformation)) for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized): check_transf = superpose(ref_points, tr_points) # check whether the rotation matrix is orthogonal self.assertArraysAlmostEqual( numpy.dot(check_transf.r, check_transf.r.transpose()), numpy.identity(3, float), 1e-5) # first check whether check_transf brings the tr_points back to the ref_points check_points = numpy.dot( tr_points, check_transf.r.transpose()) + check_transf.t self.assertArraysAlmostEqual(ref_points, check_points, 1e-5, doabs=True) if not degenerate: # if the set of points is not degenerate, check whether transf and check_transf # are each other inverses tmp = Complete() tmp.apply_before(transf) tmp.apply_before(check_transf) self.assertArraysAlmostEqual( numpy.dot(transf.r, check_transf.r), numpy.identity(3, float), 1e-5) self.assertArrayAlmostZero(tmp.t, 1e-5) # Add some distortion to the transformed points randomized = [] for tr_points, transf in randomized: tr_points[:] += numpy.random.normal(0, 1.0, len(tr_points)) # Do a blind test for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized): superpose(ref_points, tr_points)
def test_radius_ranges(self): for i in xrange(20): uc = self.get_random_uc() radius = numpy.random.uniform(1,5) ranges = uc.get_radius_ranges(radius) for j in xrange(100): c0 = uc.to_cartesian(numpy.random.uniform(-0.5, 0.5, 3)) c1 = c0 + radius*random_unit() f1 = uc.to_fractional(c1) self.assert_((abs(f1) <= ranges+0.5).all(), "f1=%s ranges=%s" % (f1, ranges))
def test_check_anagrad_full_prec(self): raise SkipTest x_init = np.zeros(2, float) prec_fun = FullPreconditioner(fun, 20, 1e-2) A = np.random.normal(0, 1, (2, 2)) A = 0.5 * (A + A.transpose()) evals, evecs = np.linalg.eigh(A) prec_fun.scales = abs(evals) + 1.0 prec_fun.rotation = evecs check_anagrad(prec_fun, x_init, 1e-5, 1e-4) dxs = random_unit((100, len(x_init))) * 1e-4 check_delta(prec_fun, x_init, dxs)
def test_superpose(self): # create a few test sets with random data points, including degenerate # situations. (e.g. one point, two points, linear points) references = [ # a list of 2-tuples: (points, degenerate) (numpy.random.normal(0, 5, (n, 3)), False) for n in xrange(4, 40) ] + [ #(numpy.array([[0,0,1]], float), True), #(numpy.array([[0,0,0],[0,0,1]], float), True), #(numpy.array([[0,0,0],[0,0,1],[0,0,2]], float), True), #(numpy.array([[0,0,0],[0,0,1],[0,0,2],[0,0,4]], float), True), #(numpy.random.normal(0, 5, (3, 3)), True) ] # Do a random transformation on the points randomized = [] for points, degenerate in references: #points[:] -= points.mean(axis=0) axis = random_unit(3) angle = numpy.random.uniform(0, numpy.pi*2) transformation = Complete() transformation.set_rotation_properties(angle, axis, False) transformation.t[:] = numpy.random.normal(0, 5, 3) randomized.append(( numpy.array([transformation.vector_apply(p) for p in points]), transformation )) for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized): check_transf = superpose(ref_points, tr_points) # check whether the rotation matrix is orthogonal self.assertArraysAlmostEqual(numpy.dot(check_transf.r, check_transf.r.transpose()), numpy.identity(3, float), 1e-5) # first check whether check_transf brings the tr_points back to the ref_points check_points = numpy.dot(tr_points, check_transf.r.transpose()) + check_transf.t self.assertArraysAlmostEqual(ref_points, check_points, 1e-5, doabs=True) if not degenerate: # if the set of points is not degenerate, check whether transf and check_transf # are each other inverses tmp = Complete() tmp.apply_before(transf) tmp.apply_before(check_transf) self.assertArraysAlmostEqual(numpy.dot(transf.r, check_transf.r), numpy.identity(3, float), 1e-5) self.assertArrayAlmostZero(tmp.t, 1e-5) # Add some distortion to the transformed points randomized = [] for tr_points, transf in randomized: tr_points[:] += numpy.random.normal(0, 1.0, len(tr_points)) # Do a blind test for (ref_points, degenerate), (tr_points, transf) in zip(references, randomized): superpose(ref_points, tr_points)
def random_rotation(): from molmod.vectors import random_unit, trivial_orthonormal result = Rotation() # first generate a random unit vector, the new x-axis result.r[:,0] = random_unit(3) x = result.r[:,0] # generate a not so random y-axis and z-axis y = trivial_orthonormal(x) z = numpy.cross(x, y) # rotate y,z with about the x-axis by a random angle angle = numpy.random.uniform(0, 2*numpy.pi) result.r[:,1] = numpy.cos(angle)*y - numpy.sin(angle)*z result.r[:,2] = numpy.sin(angle)*y + numpy.cos(angle)*z return result
def random(cls): """Return a random rotation""" axis = random_unit() angle = numpy.random.uniform(0, 2 * numpy.pi) invert = bool(numpy.random.randint(0, 2)) return Rotation.from_properties(angle, axis, invert)
def random_dimer(molecule0, molecule1, thresholds, shoot_max): """Create a random dimer. molecule0 and molecule1 are placed in one reference frame at random relative positions. Interatomic distances are above the thresholds. Initially a dimer is created where one interatomic distance approximates the threshold value. Then the molecules are given an additional separation in the range [0, shoot_max]. thresholds has the following format: {frozenset([atom_number1, atom_number2]): distance} """ # apply a random rotation to molecule1 center = np.zeros(3, float) angle = np.random.uniform(0, 2 * np.pi) axis = random_unit() rotation = Complete.about_axis(center, angle, axis) cor1 = np.dot(molecule1.coordinates, rotation.r) # select a random atom in each molecule atom0 = np.random.randint(len(molecule0.numbers)) atom1 = np.random.randint(len(molecule1.numbers)) # define a translation of molecule1 that brings both atoms in overlap delta = molecule0.coordinates[atom0] - cor1[atom1] cor1 += delta # define a random direction direction = random_unit() cor1 += 1 * direction # move molecule1 along this direction until all intermolecular atomic # distances are above the threshold values threshold_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) distance_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) for i1, n1 in enumerate(molecule0.numbers): for i2, n2 in enumerate(molecule1.numbers): threshold = thresholds.get(frozenset([n1, n2])) threshold_mat[i1, i2] = threshold**2 while True: cor1 += 0.1 * direction distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # translate over a random distance [0, shoot] along the same direction # (if necessary repeat until no overlap is found) while True: cor1 += direction * np.random.uniform(0, shoot_max) distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # done dimer = Molecule(np.concatenate([molecule0.numbers, molecule1.numbers]), np.concatenate([molecule0.coordinates, cor1])) dimer.direction = direction dimer.atom0 = atom0 dimer.atom1 = atom1 return dimer
def random_dimer(molecule0, molecule1, thresholds, shoot_max, max_tries=1000): """Create a random dimer. molecule0 and molecule1 are placed in one reference frame at random relative positions. Interatomic distances are above the thresholds. Initially a dimer is created where one interatomic distance approximates the threshold value. Then the molecules are given an additional separation in the range [0,shoot_max]. thresholds has the following format: {frozenset([atom_number1, atom_number2]): distance} """ # apply a random rotation to molecule1 center = numpy.zeros(3, float) angle = numpy.random.uniform(0, 2*numpy.pi) axis = random_unit(3) rotation = rotation_around_center(center, angle, axis) cor1 = numpy.dot(molecule1.coordinates, rotation.r) # select a random atom in each molecule atom0 = numpy.random.randint(len(molecule0.numbers)) atom1 = numpy.random.randint(len(molecule1.numbers)) # define a translation of molecule1 that brings both atoms in overlap delta = molecule0.coordinates[atom0] - cor1[atom1] cor1 += delta # define a random direction direction = random_unit(3) cor1 += 1*direction # move molecule1 along this direction until all intermolecular atomic # distances are above the threshold values threshold_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) distance_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) for i1, n1 in enumerate(molecule0.numbers): for i2, n2 in enumerate(molecule1.numbers): threshold = thresholds.get(frozenset([n1,n2])) threshold_mat[i1,i2] = threshold**2 while True: cor1 += 0.1*direction distance_mat[:] = 0 for i in 0,1,2: distance_mat += numpy.subtract.outer(molecule0.coordinates[:,i], cor1[:,i])**2 if (distance_mat > threshold_mat).all(): break # translate over a random distance [0,shoot] along the same direction # (if necessary repeat until no overlap is found) while True: cor1 += direction*numpy.random.uniform(0,shoot_max) distance_mat[:] = 0 for i in 0,1,2: distance_mat += numpy.subtract.outer(molecule0.coordinates[:,i], cor1[:,i])**2 if (distance_mat > threshold_mat).all(): break # done dimer = Molecule( numpy.concatenate([molecule0.numbers, molecule1.numbers]), numpy.concatenate([molecule0.coordinates, cor1]) ) dimer.direction = direction dimer.atom0 = atom0 dimer.atom1 = atom1 return dimer