예제 #1
0
    def __call__(self, *args, **kwargs):
        fail_reasons = []
        for typespec in self._versions:
            fargs, fkwargs_or_fail_reason = typespec.get_arg_list(*args, **kwargs)
            if fargs is not None:
                return typespec.func(*fargs, **fkwargs_or_fail_reason)
            else:
                fail_reasons.append(fkwargs_or_fail_reason or '<unknown reason for failed match>')
        # Should we fall back on the original function's code here?  If so, we should catch and reraise any type errors
        raise TypeError("invalid function signature {0}.\n  Available signatures are:\n{1}".format(
            argtypespec.get_call_signature(self.__name__, *args, **kwargs),
            indented('\n'.join(line + "\n" + indented("Not valid signature because: " + reason)
                        for line, reason in zip(self._build_allowed_string().splitlines(), fail_reasons)))

        ))
예제 #2
0
def parse_qchem_matrix(data):
    ret_val = [[]]

    def parse_line(cols, m):
        row = int(m.group(1)) - 1
        data = [float(f) for f in m.group(2).strip().split()]
        while len(ret_val) < row + 1:
            ret_val.append([])
        while len(ret_val[row]) < cols[-1] + 1:
            ret_val[row].append(None)
        if len(cols) != len(data):
            raise OutputParsingError("ragged matrix in output:\n{}".format(indented(data)))
        for d, col in zip(data, cols):
            ret_val[row][col] = d

    def parse_group_of_lines(m):
        columns = [int(s.strip()) - 1 for s in m.group(1).split()]
        re.sub(r"(\d)((?:\s+-?\d+\.\d+)+)", partial(parse_line, columns), m.group(2))

    re.sub(r"((?:\d+[ \t]*)+\n)[ \t]+((?:\d+(?:\s+-?\d+\.\d+)+\s+)+)", parse_group_of_lines, data)

    if None in flattened(ret_val):
        raise OutputParsingError("output matrix missing value:\n{}".format(indented(data)))

    return Matrix(ret_val)
예제 #3
0
 def __str__(self):
     return "InternalRepresentation of {} with coordinates\n{}".format(
         shortstr(self.molecule),
         indented('\n'.join('[{}] {}: {}'.format(
             i, shortstr(coord), str(coord.value_with_units)
         ) for i, coord in enumerate(self.coords)))
     )
예제 #4
0
 def assertOkayFdiffDerivative(self,
                               poly,
                               vars,
                               places=4,
                               robustness=2,
                               forward=False):
     """ Assert almost equal with significant figures rather than digits after the decimal
     """
     df = FiniteDifferenceDerivative(poly,
                                     *tuple(vars),
                                     robustness=robustness,
                                     forward=forward).value
     exp = poly.actual_derivative(*tuple(vars))
     if abs(exp) > 0:
         div = 10.0**float(math.ceil(math.log(abs(exp), 10.0)))
         ract = round(df / div, places)
         rexp = round(exp / div, places)
     else:
         ract = round(df, places)
         rexp = round(exp, places)
     tmp = self.longMessage
     self.longMessage = True
     try:
         #("%"+str(places+1)+"f") % rexp, ("%"+str(places+1)+"f") % ract,
         self.assertAlmostEqual(
             ract,
             rexp,
             places,
             msg="\nfor derivative {} with robustness {} of function:\n{}".
             format(vars, robustness, indented(str(poly))))
     finally:
         self.longMessage = tmp
예제 #5
0
 def validate(self):
     bmat = self.b_matrix
     evals = np.linalg.eigvalsh(bmat * bmat.T)
     nvalid = len([e for e in evals if abs(e) > InternalRepresentation.zero_eigenvalue])
     if nvalid != self.molecule.ninternals:
         raise RepresentationError("Have {} nonredundant internal coordinates, but need {}.\nCoordnates are:\n{}".format(
             nvalid,
             self.molecule.ninternals,
             indented('\n'.join('[' + str(i) + '] ' + shortstr(c) for i, c in enumerate(self.coords)))
         ))
예제 #6
0
 def __repr__(self):
     return "FiniteDifferenceFormula({dord}, {rob}, [\n{terms}\n])".format(
         dord=repr(self.orders),
         rob=self.robustness,
         terms=indented(
             ',\n'.join(repr((coeff, deltas)) for deltas, coeff in
                 sorted(self.coefficients.items(), key=lambda x: ' '.join(str(i) for i in x[0]))
                     if coeff != 0)
             )
     )
예제 #7
0
 def __call__(self, *args, **kwargs):
     fargs, fkwargs = self._typespec.get_arg_list(*args, **kwargs)
     if fargs is not None:
         return self._typespec.func(*fargs, **fkwargs)
     else:
         raise TypeError("invalid function signature {0}.\n  Function call must have" \
                         " the form:\n{1}\n    which is not a valid signature because: {2}".format(
             argtypespec.get_call_signature(self.__name__, *args, **kwargs),
             indented(self._typespec.signature),
             fkwargs
         ))
예제 #8
0
 def parse_line(cols, m):
     row = int(m.group(1)) - 1
     data = [float(f) for f in m.group(2).strip().split()]
     while len(ret_val) < row + 1:
         ret_val.append([])
     while len(ret_val[row]) < cols[-1] + 1:
         ret_val[row].append(None)
     if len(cols) != len(data):
         raise OutputParsingError("ragged matrix in output:\n{}".format(indented(data)))
     for d, col in zip(data, cols):
         ret_val[row][col] = d
예제 #9
0
 def __call__(self, *args, **kwargs):
     fail_reasons = []
     for typespec in self._versions:
         fargs, fkwargs_or_fail_reason = typespec.get_arg_list(
             *args, **kwargs)
         if fargs is not None:
             return typespec.func(*fargs, **fkwargs_or_fail_reason)
         else:
             fail_reasons.append(fkwargs_or_fail_reason
                                 or '<unknown reason for failed match>')
     # Should we fall back on the original function's code here?  If so, we should catch and reraise any type errors
     raise TypeError(
         "invalid function signature {0}.\n  Available signatures are:\n{1}"
         .format(
             argtypespec.get_call_signature(self.__name__, *args, **kwargs),
             indented('\n'.join(
                 line + "\n" +
                 indented("Not valid signature because: " + reason)
                 for line, reason in zip(
                     self._build_allowed_string().splitlines(),
                     fail_reasons)))))
예제 #10
0
 def __repr__(self):
     return "FiniteDifferenceFormula({dord}, {rob}, [\n{terms}\n])".format(
         dord=repr(self.orders),
         rob=self.robustness,
         terms=indented(
             ",\n".join(
                 repr((coeff, deltas))
                 for deltas, coeff in sorted(self.coefficients.items(), key=lambda x: " ".join(str(i) for i in x[0]))
                 if coeff != 0
             )
         ),
     )
예제 #11
0
 def validate(self):
     bmat = self.b_matrix
     evals = np.linalg.eigvalsh(bmat * bmat.T)
     nvalid = len([
         e for e in evals if abs(e) > InternalRepresentation.zero_eigenvalue
     ])
     if nvalid != self.molecule.ninternals:
         raise RepresentationError(
             "Have {} nonredundant internal coordinates, but need {}.\nCoordnates are:\n{}"
             .format(
                 nvalid, self.molecule.ninternals,
                 indented('\n'.join('[' + str(i) + '] ' + shortstr(c)
                                    for i, c in enumerate(self.coords)))))
예제 #12
0
 def assertOkayFdiffDerivative(self, poly, vars, places=4, robustness=2, forward=False):
     """ Assert almost equal with significant figures rather than digits after the decimal
     """
     df = FiniteDifferenceDerivative(poly, *tuple(vars), robustness=robustness, forward=forward).value
     exp = poly.actual_derivative(*tuple(vars))
     if abs(exp) > 0:
         div = 10.0 ** float(math.ceil(math.log(abs(exp), 10.0)))
         ract = round(df/div, places)
         rexp = round(exp/div, places)
     else:
         ract = round(df, places)
         rexp = round(exp, places)
     tmp = self.longMessage
     self.longMessage = True
     try:
         #("%"+str(places+1)+"f") % rexp, ("%"+str(places+1)+"f") % ract,
         self.assertAlmostEqual(ract, rexp, places,
             msg="\nfor derivative {} with robustness {} of function:\n{}".format(
                 vars, robustness, indented(str(poly)))
         )
     finally:
         self.longMessage = tmp
예제 #13
0
 def __str__(self):
     return "InternalRepresentation of {} with coordinates\n{}".format(
         shortstr(self.molecule),
         indented('\n'.join('[{}] {}: {}'.format(
             i, shortstr(coord), str(coord.value_with_units))
                            for i, coord in enumerate(self.coords))))
예제 #14
0
    def __str__(self):
        max_width = 80
        indent_size = 4
        function_name = "F"
        disp_name = "h"
        # ----------------------------------------#
        def var(idx):
            vars = "xyz" + str(reversed(string.ascii_lowercase[:-3]))
            vars = vars.replace(disp_name, "")
            vars = vars.replace(function_name, "")
            try:
                return vars[idx]
            except IndexError:
                return "x_" + idx

        # ----------------------------------------#
        flines = []
        curr_line = "["
        for dispnum, (disp, coeff) in enumerate(sorted(self.coefficients.items())):
            if coeff == 0:
                continue
            if coeff.denominator == 1:
                # Only print non-unit coefficients
                if abs(coeff) != 1:
                    disp_f = str(abs(coeff))
                else:
                    disp_f = ""
            else:
                disp_f = "(" + str(abs(coeff)) + ")"
            disp_f += function_name + "("
            for idx, d in enumerate(disp):
                disp_f += var(idx)
                if d == -1:
                    disp_f += " - " + disp_name + "_" + var(idx)
                elif d == 1:
                    disp_f += " + " + disp_name + "_" + var(idx)
                elif d < 0:
                    disp_f += " - " + str(abs(d)) + disp_name + "_" + var(idx)
                elif d > 0:
                    disp_f += " + " + str(d) + disp_name + "_" + var(idx)
                if d is not disp[-1]:
                    disp_f += ", "
            disp_f += ")"
            if dispnum != 0:
                if coeff < 0:
                    disp_f = " - " + disp_f
                else:
                    disp_f = " + " + disp_f
            elif coeff < 0:  # and dispnum == 0
                disp_f = "-" + disp_f
            if len(curr_line + disp_f) > (max_width if len(flines) == 0 else max_width - indent_size):
                if curr_line != "":
                    flines.append(curr_line)
                    curr_line = disp_f
                else:
                    # one term per line is the best we can do, and we still overflow...yikes...
                    flines.append(disp_f)
            else:
                curr_line += disp_f
        denom = "] / "
        if len(self.orders) > 1:
            denom += "("
        for idx, exp in enumerate(self.orders):
            denom += disp_name + "_" + var(idx)
            if exp > 1:
                denom += "^" + str(exp)
        if len(self.orders) > 1:
            denom += ")"
        if len(curr_line + denom) > (max_width if len(flines) == 0 else max_width - indent_size):
            if curr_line != "":
                flines.append(curr_line)
                curr_line = denom
            else:
                curr_line = denom
        else:
            curr_line += denom
        flines.append(curr_line)

        return (
            "{cent} finite difference formula for df/{dvars},"
            " correct to order {order} in displacement ({terms} terms):\n{formula}".format(
                cent="Central" if self.direction == FiniteDifferenceFormula.CENTRAL else "Forward",
                order=self.robustness,
                dvars="".join(
                    "d" + var(idx) + ("^" + str(exp) if exp > 1 else "") for idx, exp in enumerate(self.orders)
                ),
                formula=indented(("\n" + " " * indent_size).join(flines), indent_size),
                terms=len([c for c in self.coefficients.values() if c != 0]),
            )
        )
예제 #15
0
 def value_for_displacements(self, pairs):
     # Type checking and sanity checking
     if type_checking_enabled:
         if not all(len(pair) == 2 and isinstance(pair[0], FiniteDifferenceVariable) and isinstance(pair[1], int) for pair in pairs):
             raise TypeError
     if sanity_checking_enabled:
         for pair in pairs:
             if not isinstance(pair[0], Coordinate):
                 raise ValueError(
                     "FiniteDifferenceVariable instances passed to"
                     " DisplacementManager.value_for_displacements"
                     " must be instances of Coordinate subclasses."
                     "  (Got at least one that was a {0})".format(
                         type(pair[0]).__name__
                     ))
     #--------------------------------------------------------------------------------#
     # prepare the increments
     increments = [0]*len(self.representation)
     for coord, ndeltas in pairs:
         i = self.representation.coords.index(coord)
         increments[i] = ndeltas
     increments = tuple(increments)
     #--------------------------------------------------------------------------------#
     # get the displacement, and ask the displaced molecule for the property
     try:
         displacement = self.displacement_for(increments)
         rv = displacement.displaced_molecule.get_property(
             self.differentiable,
             details=self.details
         )
         if rv is None:
             raise ValueError("couldn't get displacement for increments {}".format(increments))
         return rv
     #--------------------------------------------------------------------------------#
     # Old debugging code.  Only applies to LegacyXMLResultGetter
     except RuntimeError as e:
         if all(isinstance(rg, LegacyXMLResultGetter)
                 for rg in self.displacements[increments].displaced_molecule.result_getters):
             legacy_getters = [rg
                                  for rg in self.base_molecule.result_getters
                                      if isinstance(rg, LegacyXMLResultGetter)]
             molecule = self.displacements[increments].displaced_molecule
             smallest_dist = float('inf') * molecule.cartesian_units
             smallest_dist_stub = None
             best_rg = None
             mol = copy(molecule); mol.convert_units(DistanceUnit.default)
             for rg in legacy_getters:
                 for stub in rg.properties.keys():
                     st = copy(stub); st.convert_units(DistanceUnit.default)
                     ldiff = rg.properties.key_representation.value_for_molecule(stub)
                     ldiff -= rg.properties.key_representation.value_for_molecule(mol)
                     ldiff = abs(ldiff)
                     if max(ldiff) < smallest_dist:
                         best_rg = rg
                         smallest_dist = max(ldiff)
                         smallest_dist_stub = st
             if smallest_dist_stub is not None:
                 # Print debugging information for legacy xml parser
                 print("Failed to find match.  Smallest " \
                       "maximum geometric difference was {}".format(smallest_dist),
                     file=sys.stderr)
                 print(indented(
                         "Desired molecule representation " \
                         "was:\n{}".format(indented(str(molecule.internal_representation.copy_with_molecule(mol))))
                     ), file=sys.stderr)
                 print(indented(
                     '-'*40 +
                     "\nClosest stub in the same representation:\n{}".format(
                         indented(str(molecule.internal_representation.copy_with_molecule(smallest_dist_stub))))
                 ), file=sys.stderr)
                 print("Tree leaf: \n{}".format(
                     best_rg.properties._get_possibilities(mol)
                 ), file=sys.stderr)
                 print("Chains: \nMolecule:\n{}\nStub:\n{}".format(
                     indented(str(best_rg.properties._key_chain_str(mol))),
                     indented(str(best_rg.properties._key_chain_str(smallest_dist_stub))),
                 ), file=sys.stderr)
                 sys.stderr.flush()
             raise RuntimeError("couldn't get {} for displacements {}".format(
                 self.differentiable.__name__,
                 increments
             ))
         else:
             raise
예제 #16
0
    def __str__(self):
        max_width=80
        indent_size = 4
        function_name = 'F'
        disp_name = 'h'
        #----------------------------------------#
        def var(idx):
            vars = 'xyz' + str(reversed(string.ascii_lowercase[:-3]))
            vars = vars.replace(disp_name, '')
            vars = vars.replace(function_name, '')
            try:
                return vars[idx]
            except IndexError:
                return 'x_' + idx
        #----------------------------------------#
        flines = []
        curr_line = '['
        for dispnum, (disp, coeff) in enumerate(sorted(self.coefficients.items())):
            if coeff == 0:
                continue
            if coeff.denominator == 1:
                # Only print non-unit coefficients
                if abs(coeff) != 1:
                    disp_f = str(abs(coeff))
                else:
                    disp_f = ''
            else:
                disp_f = '(' + str(abs(coeff)) + ')'
            disp_f += function_name + '('
            for idx, d in enumerate(disp):
                disp_f += var(idx)
                if d == -1:
                    disp_f += ' - ' + disp_name + '_' + var(idx)
                elif d == 1:
                    disp_f += ' + ' + disp_name + '_' + var(idx)
                elif d < 0:
                    disp_f += ' - ' + str(abs(d)) + disp_name + '_' + var(idx)
                elif d > 0:
                    disp_f += ' + ' + str(d) + disp_name + '_' + var(idx)
                if d is not disp[-1]:
                    disp_f += ', '
            disp_f += ')'
            if dispnum != 0:
                if coeff < 0:
                    disp_f = ' - ' + disp_f
                else:
                    disp_f = ' + ' + disp_f
            elif coeff < 0:  # and dispnum == 0
                disp_f = '-' + disp_f
            if len(curr_line + disp_f) > (max_width if len(flines) == 0 else max_width - indent_size):
                if curr_line != '':
                    flines.append(curr_line)
                    curr_line = disp_f
                else:
                    # one term per line is the best we can do, and we still overflow...yikes...
                    flines.append(disp_f)
            else:
                curr_line += disp_f
        denom = '] / '
        if len(self.orders) > 1:
            denom += '('
        for idx, exp in enumerate(self.orders):
            denom += disp_name + '_' + var(idx)
            if exp > 1:
                denom += '^' + str(exp)
        if len(self.orders) > 1:
            denom += ')'
        if len(curr_line + denom) > (max_width if len(flines) == 0 else max_width - indent_size):
            if curr_line != '':
                flines.append(curr_line)
                curr_line = denom
            else:
                curr_line = denom
        else:
            curr_line += denom
        flines.append(curr_line)

        return '{cent} finite difference formula for df/{dvars},' \
             ' correct to order {order} in displacement ({terms} terms):\n{formula}'.format(
            cent='Central' if self.direction == FiniteDifferenceFormula.CENTRAL else 'Forward',
            order = self.robustness,
            dvars=''.join('d' + var(idx) + ('^'+str(exp) if exp > 1 else '')
                              for idx, exp in enumerate(self.orders)),
            formula=indented(('\n' + ' ' * indent_size).join(flines), indent_size),
            terms=len([c for c in self.coefficients.values() if c != 0])
        )