def __init__(self, atoms, constraints): self.atoms = atoms natoms = len(self.atoms) nconst = sum([len(c) for c in constraints]) b = N.zeros((nconst, natoms), N.Float) c = N.zeros((nconst,), N.Float) i = 0 for cons in constraints: cons.setCoefficients(self.atoms, b, c, i) i = i + len(cons) u, s, vt = LA.singular_value_decomposition(b) self.rank = 0 for i in range(min(natoms, nconst)): if s[i] > 0.: self.rank = self.rank + 1 self.b = b self.bi = LA.generalized_inverse(b) self.p = N.identity(natoms)-N.dot(self.bi, self.b) self.c = c self.bi_c = N.dot(self.bi, c) c_test = N.dot(self.b, self.bi_c) if N.add.reduce((c_test-c)**2)/nconst > 1.e-12: Utility.warning("The charge constraints are inconsistent." " They will be applied as a least-squares" " condition.")
def __init__(self, atoms, constraints): self.atoms = atoms natoms = len(self.atoms) nconst = sum([len(c) for c in constraints]) b = N.zeros((nconst, natoms), N.Float) c = N.zeros((nconst, ), N.Float) i = 0 for cons in constraints: cons.setCoefficients(self.atoms, b, c, i) i = i + len(cons) u, s, vt = LA.singular_value_decomposition(b) self.rank = 0 for i in range(min(natoms, nconst)): if s[i] > 0.: self.rank = self.rank + 1 self.b = b self.bi = LA.generalized_inverse(b) self.p = N.identity(natoms) - N.dot(self.bi, self.b) self.c = c self.bi_c = N.dot(self.bi, c) c_test = N.dot(self.b, self.bi_c) if N.add.reduce((c_test - c)**2) / nconst > 1.e-12: Utility.warning("The charge constraints are inconsistent." " They will be applied as a least-squares" " condition.")
def symmetricTensorBasis(cell, space_group): from CDTK.Crystal import UnitCell subspace = 1. * N.equal.outer(N.arange(6), N.arange(6)) for tr in cartesianCoordinateSymmetryTransformations(cell, space_group): rot = symmetricTensorRotationMatrix(tr.tensor.array) ev, axes = LA.eigenvectors(rot) new_subspace = [] for i in range(6): if abs(ev[i] - 1.) < 1.e-12: p = N.dot(N.transpose(subspace), N.dot(subspace, axes[i].real)) new_subspace.append(p) m, s, subspace = LA.singular_value_decomposition(N.array(new_subspace)) nb = N.sum(s / s[0] > 1.e-12) subspace = subspace[:nb] return [SymmetricTensor(a) for a in subspace]
def __init__(self, system, points, constraints = None): """ :param system: any chemical object (usually a molecule) :param points: a list of point/potential pairs (a vector for the evaluation point, a number for the potential), or a dictionary whose keys are Configuration objects and whose values are lists of point/potential pairs. The latter case permits combined fits for several conformations of the system. :param constraints: an optional list of constraint objects (:class:`~MMTK.ChargeFit.TotalChargeConstraint` and/or :class:`~MMTK.ChargeFit.EqualityConstraint` objects). If the constraints are inconsistent, a warning is printed and the result will satisfy the constraints only in a least-squares sense. """ self.atoms = system.atomList() if type(points) != type({}): points = {None: points} if constraints is not None: constraints = ChargeConstraintSet(self.atoms, constraints) npoints = sum([len(v) for v in points.values()]) natoms = len(self.atoms) if npoints < natoms: raise ValueError("Not enough data points for fit") m = N.zeros((npoints, natoms), N.Float) phi = N.zeros((npoints,), N.Float) i = 0 for conf, pointlist in points.items(): for r, p in pointlist: for j in range(natoms): m[i, j] = 1./(r-self.atoms[j].position(conf)).length() phi[i] = p i = i + 1 m = m*Units.electrostatic_energy m_test = m phi_test = phi if constraints is not None: phi -= N.dot(m, constraints.bi_c) m = N.dot(m, constraints.p) c_rank = constraints.rank else: c_rank = 0 u, s, vt = LA.singular_value_decomposition(m) s_test = s[:len(s)-c_rank] cutoff = 1.e-10*N.maximum.reduce(s_test) nonzero = N.repeat(s_test, N.not_equal(s_test, 0.)) self.rank = len(nonzero) self.condition = N.maximum.reduce(nonzero) / \ N.minimum.reduce(nonzero) self.effective_rank = N.add.reduce(N.greater(s, cutoff)) if self.effective_rank < self.rank: self.effective_condition = N.maximum.reduce(nonzero) / cutoff else: self.effective_condition = self.condition if self.effective_rank < natoms-c_rank: Utility.warning('Not all charges are uniquely determined' + ' by the available data') for i in range(natoms): if s[i] > cutoff: s[i] = 1./s[i] else: s[i] = 0. q = N.dot(N.transpose(vt), s*N.dot(N.transpose(u)[:natoms, :], phi)) if constraints is not None: q = constraints.bi_c + N.dot(constraints.p, q) deviation = N.dot(m_test, q)-phi_test self.rms_error = N.sqrt(N.dot(deviation, deviation)) deviation = N.fabs(deviation/phi_test) self.relative_rms_error = N.sqrt(N.dot(deviation, deviation)) self.charges = {} for i in range(natoms): self.charges[self.atoms[i]] = q[i]
def __init__(self, system, points, constraints=None): """ :param system: any chemical object (usually a molecule) :param points: a list of point/potential pairs (a vector for the evaluation point, a number for the potential), or a dictionary whose keys are Configuration objects and whose values are lists of point/potential pairs. The latter case permits combined fits for several conformations of the system. :param constraints: an optional list of constraint objects (:class:`~MMTK.ChargeFit.TotalChargeConstraint` and/or :class:`~MMTK.ChargeFit.EqualityConstraint` objects). If the constraints are inconsistent, a warning is printed and the result will satisfy the constraints only in a least-squares sense. """ self.atoms = system.atomList() if type(points) != type({}): points = {None: points} if constraints is not None: constraints = ChargeConstraintSet(self.atoms, constraints) npoints = sum([len(v) for v in points.values()]) natoms = len(self.atoms) if npoints < natoms: raise ValueError("Not enough data points for fit") m = N.zeros((npoints, natoms), N.Float) phi = N.zeros((npoints, ), N.Float) i = 0 for conf, pointlist in points.items(): for r, p in pointlist: for j in range(natoms): m[i, j] = 1. / (r - self.atoms[j].position(conf)).length() phi[i] = p i = i + 1 m = m * Units.electrostatic_energy m_test = m phi_test = phi if constraints is not None: phi -= N.dot(m, constraints.bi_c) m = N.dot(m, constraints.p) c_rank = constraints.rank else: c_rank = 0 u, s, vt = LA.singular_value_decomposition(m) s_test = s[:len(s) - c_rank] cutoff = 1.e-10 * N.maximum.reduce(s_test) nonzero = N.repeat(s_test, N.not_equal(s_test, 0.)) self.rank = len(nonzero) self.condition = N.maximum.reduce(nonzero) / \ N.minimum.reduce(nonzero) self.effective_rank = N.add.reduce(N.greater(s, cutoff)) if self.effective_rank < self.rank: self.effective_condition = N.maximum.reduce(nonzero) / cutoff else: self.effective_condition = self.condition if self.effective_rank < natoms - c_rank: Utility.warning('Not all charges are uniquely determined' + ' by the available data') for i in range(natoms): if s[i] > cutoff: s[i] = 1. / s[i] else: s[i] = 0. q = N.dot(N.transpose(vt), s * N.dot(N.transpose(u)[:natoms, :], phi)) if constraints is not None: q = constraints.bi_c + N.dot(constraints.p, q) deviation = N.dot(m_test, q) - phi_test self.rms_error = N.sqrt(N.dot(deviation, deviation)) deviation = N.fabs(deviation / phi_test) self.relative_rms_error = N.sqrt(N.dot(deviation, deviation)) self.charges = {} for i in range(natoms): self.charges[self.atoms[i]] = q[i]
def __init__(self, object, points, constraints = None): self.atoms = object.atomList() if type(points) != type({}): points = {None: points} if constraints is not None: constraints = ChargeConstraintSet(self.atoms, constraints) npoints = reduce(operator.add, map(len, points.values())) natoms = len(self.atoms) if npoints < natoms: raise ValueError("Not enough data points for fit") m = Numeric.zeros((npoints, natoms), Numeric.Float) phi = Numeric.zeros((npoints,), Numeric.Float) i = 0 for conf, pointlist in points.items(): for r, p in pointlist: for j in range(natoms): m[i, j] = 1./(r-self.atoms[j].position(conf)).length() phi[i] = p i = i + 1 m = m*Units.electrostatic_energy m_test = m phi_test = phi if constraints is not None: phi = phi-Numeric.dot(m, constraints.bi_c) m = Numeric.dot(m, constraints.p) c_rank = constraints.rank else: c_rank = 0 u, s, vt = LinearAlgebra.singular_value_decomposition(m) s_test = s[:len(s)-c_rank] cutoff = 1.e-10*Numeric.maximum.reduce(s_test) nonzero = Numeric.repeat(s_test, Numeric.not_equal(s_test, 0.)) self.rank = len(nonzero) self.condition = Numeric.maximum.reduce(nonzero) / \ Numeric.minimum.reduce(nonzero) self.effective_rank = Numeric.add.reduce(Numeric.greater(s, cutoff)) if self.effective_rank < self.rank: self.effective_condition = Numeric.maximum.reduce(nonzero) / cutoff else: self.effective_condition = self.condition if self.effective_rank < natoms-c_rank: Utility.warning('Not all charges are uniquely determined' + ' by the available data') for i in range(natoms): if s[i] > cutoff: s[i] = 1./s[i] else: s[i] = 0. q = Numeric.dot(Numeric.transpose(vt), s*Numeric.dot(Numeric.transpose(u)[:natoms, :], phi)) if constraints is not None: q = constraints.bi_c + Numeric.dot(constraints.p, q) deviation = Numeric.dot(m_test, q)-phi_test self.rms_error = Numeric.sqrt(Numeric.dot(deviation, deviation)) deviation = Numeric.fabs(deviation/phi_test) self.relative_rms_error = Numeric.sqrt(Numeric.dot(deviation, deviation)) self.charges = {} for i in range(natoms): self.charges[self.atoms[i]] = q[i]
def __init__(self, object, points, constraints=None): self.atoms = object.atomList() if type(points) != type({}): points = {None: points} if constraints is not None: constraints = ChargeConstraintSet(self.atoms, constraints) npoints = reduce(operator.add, map(len, points.values())) natoms = len(self.atoms) if npoints < natoms: raise ValueError("Not enough data points for fit") m = Numeric.zeros((npoints, natoms), Numeric.Float) phi = Numeric.zeros((npoints, ), Numeric.Float) i = 0 for conf, pointlist in points.items(): for r, p in pointlist: for j in range(natoms): m[i, j] = 1. / (r - self.atoms[j].position(conf)).length() phi[i] = p i = i + 1 m = m * Units.electrostatic_energy m_test = m phi_test = phi if constraints is not None: phi = phi - Numeric.dot(m, constraints.bi_c) m = Numeric.dot(m, constraints.p) c_rank = constraints.rank else: c_rank = 0 u, s, vt = LinearAlgebra.singular_value_decomposition(m) s_test = s[:len(s) - c_rank] cutoff = 1.e-10 * Numeric.maximum.reduce(s_test) nonzero = Numeric.repeat(s_test, Numeric.not_equal(s_test, 0.)) self.rank = len(nonzero) self.condition = Numeric.maximum.reduce(nonzero) / \ Numeric.minimum.reduce(nonzero) self.effective_rank = Numeric.add.reduce(Numeric.greater(s, cutoff)) if self.effective_rank < self.rank: self.effective_condition = Numeric.maximum.reduce(nonzero) / cutoff else: self.effective_condition = self.condition if self.effective_rank < natoms - c_rank: Utility.warning('Not all charges are uniquely determined' + ' by the available data') for i in range(natoms): if s[i] > cutoff: s[i] = 1. / s[i] else: s[i] = 0. q = Numeric.dot(Numeric.transpose(vt), s * Numeric.dot(Numeric.transpose(u)[:natoms, :], phi)) if constraints is not None: q = constraints.bi_c + Numeric.dot(constraints.p, q) deviation = Numeric.dot(m_test, q) - phi_test self.rms_error = Numeric.sqrt(Numeric.dot(deviation, deviation)) deviation = Numeric.fabs(deviation / phi_test) self.relative_rms_error = Numeric.sqrt( Numeric.dot(deviation, deviation)) self.charges = {} for i in range(natoms): self.charges[self.atoms[i]] = q[i]