Exemple #1
0
 def fill_order(self, order):
     if self.filled_for_order[order-1]:
         return
     #----------------------------------------#
     tens = self.tensors[order]
     if order <= self.max_analytic_order:
         #TODO this will need to be significantly modified for hessians and higher, since the transformation to interal coordinates requires all lower derivatives as well...
         tens[...] = self.base_molecule.get_property(
             PropertyDerivative(self.molecular_property, order) if order > 0 else self.molecular_property,
             details=self.displacement_manager.details
         ).value.in_representation(self.representation)
     #----------------------------------------#
     else:
         for f_coords in symmetric_product(self.representation, order-self.max_analytic_order):
             if self.max_analytic_order == 0 or isinstance(self.representation, CartesianRepresentation):
                 spread_val = FiniteDifferenceDerivative(
                     self.displacement_manager,
                     *f_coords,
                     target_robustness=self.robustness
                 ).value
             else:
                 spread_val = RepresentationDependentTensor(
                     FiniteDifferenceDerivative(
                         self.displacement_manager,
                         *f_coords,
                         target_robustness=self.robustness
                     ).value,
                     representation=self.representation.molecule.cartesian_representation
                 )
                 spread_val = spread_val.in_representation(self.representation)
             for perm in permutations(f_coords):
                 tens[perm] = spread_val
     #----------------------------------------#
     self.filled_for_order[order-1] = True
Exemple #2
0
 def assertHasValidBVector(self, coord, robustness=8, places=9):
     fdiffs = [
         FiniteDifferenceDerivative(coord, c, robustness=robustness)
         for c in coord.variables
     ]
     values = [float(f.value) for f in fdiffs]
     self.assertSequenceAlmostEqual(values, coord.b_vector, places=places)
Exemple #3
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
Exemple #4
0
 def all_computations(self):
     all_comps = set()
     for order in xrange(self.max_analytic_order + 1, self.max_order + 1):
         for coords in symmetric_product(self.representation,
                                         order - self.max_analytic_order):
             fd = FiniteDifferenceDerivative(
                 self.displacement_manager,
                 *coords,
                 target_robustness=self.robustness)
             for incs in fd.needed_increments:
                 increments = [0] * len(self.representation)
                 for coord, inc in zip(fd.variables, incs):
                     increments[coord.index] = inc
                 dmol = self.displacement_manager.displacement_for(
                     tuple(increments)).displaced_molecule
                 comp = dmol.get_computation_for_property(
                     self.computed_property,
                     self.displacement_manager.details)
                 if comp not in all_comps:
                     all_comps.add(comp)
     if self.max_analytic_order == 1:
         comp = self.base_molecule.get_computation_for_property(
             self.computed_property, self.displacement_manager.details)
         if comp not in all_comps:
             all_comps.add(comp)
     elif self.max_analytic_order > 2:
         # TODO figure out how many analytic computations need to be done
         raise NotImplementedError
     return list(all_comps)
Exemple #5
0
 def test_one_var_huge(self):
     FiniteDifferenceDerivative.precompute_single_variable(3, 60)
     terms = []
     for exp in range(1, 45):
         terms.append('{}x^{}'.format(45 - exp, exp))
     p = Polynomial(' + '.join(terms), [1.25])
     #self.assertOkayFdiffDerivative(p, 'x', robustness=2, places=2)
     #self.assertOkayFdiffDerivative(p, 'x', robustness=4, places=3)
     #for rob in range(6, 12, 2):
     #    self.assertOkayFdiffDerivative(p, 'x', robustness=rob, places=6)
     #for rob in range(12, 58, 2):
     #    self.assertOkayFdiffDerivative(p, 'x', robustness=rob, places=10)
     self.assertOkayFdiffDerivative(p, 'xx', robustness=2, places=2)
     self.assertOkayFdiffDerivative(p, 'xx', robustness=4, places=3)
     for rob in range(6, 12, 1):
         self.assertOkayFdiffDerivative(p, 'xx', robustness=rob, places=6)
     for rob in range(12, 58, 1):
         self.assertOkayFdiffDerivative(p, 'xx', robustness=rob, places=10)
     for rob in range(6, 12, 2):
         self.assertOkayFdiffDerivative(p, 'xxx', robustness=rob, places=6)
     for rob in range(12, 58, 2):
         self.assertOkayFdiffDerivative(p, 'xxx', robustness=rob, places=10)
 def test_one_var_huge(self):
     FiniteDifferenceDerivative.precompute_single_variable(3, 60)
     terms = []
     for exp in range(1, 45):
         terms.append('{}x^{}'.format(45-exp,exp))
     p = Polynomial(' + '.join(terms), [1.25])
     #self.assertOkayFdiffDerivative(p, 'x', robustness=2, places=2)
     #self.assertOkayFdiffDerivative(p, 'x', robustness=4, places=3)
     #for rob in range(6, 12, 2):
     #    self.assertOkayFdiffDerivative(p, 'x', robustness=rob, places=6)
     #for rob in range(12, 58, 2):
     #    self.assertOkayFdiffDerivative(p, 'x', robustness=rob, places=10)
     self.assertOkayFdiffDerivative(p, 'xx', robustness=2, places=2)
     self.assertOkayFdiffDerivative(p, 'xx', robustness=4, places=3)
     for rob in range(6, 12, 1):
         self.assertOkayFdiffDerivative(p, 'xx', robustness=rob, places=6)
     for rob in range(12, 58, 1):
         self.assertOkayFdiffDerivative(p, 'xx', robustness=rob, places=10)
     for rob in range(6, 12, 2):
         self.assertOkayFdiffDerivative(p, 'xxx', robustness=rob, places=6)
     for rob in range(12, 58, 2):
         self.assertOkayFdiffDerivative(p, 'xxx', robustness=rob, places=10)
Exemple #7
0
 def fill_order(self, order):
     if self.filled_for_order[order - 1]:
         return
     #----------------------------------------#
     tens = self.tensors[order]
     if order <= self.max_analytic_order:
         #TODO this will need to be significantly modified for hessians and higher, since the transformation to interal coordinates requires all lower derivatives as well...
         tens[...] = self.base_molecule.get_property(
             PropertyDerivative(self.molecular_property, order)
             if order > 0 else self.molecular_property,
             details=self.displacement_manager.details
         ).value.in_representation(self.representation)
     #----------------------------------------#
     else:
         for f_coords in symmetric_product(self.representation,
                                           order - self.max_analytic_order):
             if self.max_analytic_order == 0 or isinstance(
                     self.representation, CartesianRepresentation):
                 spread_val = FiniteDifferenceDerivative(
                     self.displacement_manager,
                     *f_coords,
                     target_robustness=self.robustness).value
             else:
                 spread_val = RepresentationDependentTensor(
                     FiniteDifferenceDerivative(
                         self.displacement_manager,
                         *f_coords,
                         target_robustness=self.robustness).value,
                     representation=self.representation.molecule.
                     cartesian_representation)
                 spread_val = spread_val.in_representation(
                     self.representation)
             for perm in permutations(f_coords):
                 tens[perm] = spread_val
     #----------------------------------------#
     self.filled_for_order[order - 1] = True
Exemple #8
0
 def get_b_tensor_entry(self, internal_coord, cart_coords):
     fdiff_key = (internal_coord, cart_coords)
     fdiff = self.fdiff_instances.get(fdiff_key, None)
     if fdiff is None:
         fdiff = FiniteDifferenceDerivative(
             #--------------#
             # function =
             internal_coord,
             #--------------#
             # *variables =
             cart_coords[0],
             #--------------#
             value_function=partial(
                 self.value_for_coords_and_displacements,
                 internal_coord=internal_coord,
                 cart_coords=cart_coords[1:]),
             forward=self.forward,
             delta=self.delta,
             robustness=self.robustness
         )
         self.fdiff_instances[fdiff_key] = fdiff
     ret_val = fdiff.value
     return ret_val
Exemple #9
0
 def test_one_var(self):
     p = Polynomial('3x^2 + 2x + 1', [5.5])
     f = FiniteDifferenceDerivative(p, 'x')
     self.assertAlmostEqual(f.value, p.actual_derivative('x'))