Esempio n. 1
0
 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.")
Esempio n. 2
0
 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.")
Esempio n. 3
0
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]
Esempio n. 4
0
    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]
Esempio n. 5
0
    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]
Esempio n. 6
0
    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]
Esempio n. 7
0
    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]