ForceBalance API  1.3
Automated optimization of force fields and empirical potentials
leastsq.py
Go to the documentation of this file.
1 """ @package forcebalance.abinitio Ab-initio fitting module (energies, forces, resp).
2 
3 @author Lee-Ping Wang
4 @date 05/2012
5 """
6 from __future__ import division
7 
8 from builtins import range
9 import os
10 import shutil
11 import numpy as np
12 from forcebalance.nifty import col, eqcgmx, flat, floatornan, fqcgmx, invert_svd, kb, printcool, bohr2ang
13 from forcebalance.target import Target
14 from forcebalance.molecule import Molecule, format_xyz_coord
15 from re import match, sub
16 import subprocess
17 from subprocess import PIPE
18 from forcebalance.finite_difference import fdwrap, f1d2p, f12d3p, in_fd
19 
20 from forcebalance.output import getLogger
21 logger = getLogger(__name__)
22 
23 CHECK_BASIS = False
24 def CheckBasis():
25  global CHECK_BASIS
26  return CHECK_BASIS
27 
28 LAST_MVALS = None
29 def LastMvals():
30  global LAST_MVALS
31  return LAST_MVALS
32 
33 class LeastSquares(Target):
34 
35  """ Subclass of Target for general least squares fitting. """
36 
37  def __init__(self,options,tgt_opts,forcefield):
38  super(LeastSquares,self).__init__(options,tgt_opts,forcefield)
39 
40  def indicate(self):
41  #RMSD = sqrt(mean(self.D ** 2))
42  MAD = np.mean(np.abs(self.D))
43  logger.info( "\rTarget: %-15s MeanAbsErr/MeanExact: %.5e Objective = %.5e" % (self.name, MAD / self.MAQ, self.objective))
44  return
45 
46  def get(self, mvals, AGrad=False, AHess=False):
47  """
48  LPW 05-30-2012
49 
50  This subroutine builds the objective function (and optionally
51  its derivatives) from a general software.
52 
53  This subroutine interfaces with simulation software 'drivers'.
54  The driver is expected to give exact values, fitting values, and weights.
55 
56  @param[in] mvals Mathematical parameter values
57  @param[in] AGrad Switch to turn on analytic gradient
58  @param[in] AHess Switch to turn on analytic Hessian
59  @return Answer Contribution to the objective function
60  """
61  global LAST_MVALS, CHECK_BASIS
62  # print mvals
63  # print LAST_MVALS
64  # print mvals == LAST_MVALS
65  if LAST_MVALS is None or not (mvals == LAST_MVALS).all():
66  CHECK_BASIS = False
67  else:
68  CHECK_BASIS = False
69  Answer = {}
70  Fac = 1000000
71 
72  dM = {}
73  # Create the new force field!!
74  NP = len(mvals)
75  G = np.zeros(NP)
76  H = np.zeros((NP,NP))
77  pvals = self.FF.make(mvals)
78  if float('Inf') in pvals:
79  return {'X' : 1e10, 'G' : G, 'H' : H}
80  Ans = self.driver()
81  W = Ans[:,2]
82  M = Ans[:,1]
83  Q = Ans[:,0]
84  D = M - Q
85 
86  self.MAQ = np.mean(np.abs(Q))
87 
88  ns = len(M)
89  # Wrapper to the driver, which returns just the part that changes.
90  def callM(mvals_):
91  self.FF.make(mvals_)
92  Ans2 = self.driver()
93  M_ = Ans2[:,1]
94  D_ = M_ - Q
95  return Ans2[:,1]
96  if AGrad:
97  # Leaving comment here if we want to reintroduce second deriv someday.
98  # dM[p,:], ddM[p,:] = f12d3p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
99  xgrad = []
100  for p in self.pgrad:
101  dM_arr = f1d2p(fdwrap(callM, mvals, p), h = self.h, f0 = M)
102  if np.max(np.abs(dM_arr)) == 0.0 and (not self.evaluated):
103  logger.info("\r Simulation %s will skip over parameter %i in subsequent steps\n" % (self.name, p))
104  xgrad.append(p)
105  else:
106  dM[p] = dM_arr.copy()
107  for p in xgrad:
108  self.pgrad.remove(p)
109  Objective = np.dot(W, D**2) * Fac
110  if AGrad:
111  for p in self.pgrad:
112  G[p] = 2 * np.dot(W, D*dM[p])
113  if not AHess: continue
114  H[p, p] = 2 * np.dot(W, dM[p]**2)
115  for q in range(p):
116  if q not in self.pgrad: continue
117  GNP = 2 * np.dot(W, dM[p] * dM[q])
118  H[q,p] = GNP
119  H[p,q] = GNP
120  G *= Fac
121  H *= Fac
122  Answer = {'X':Objective, 'G':G, 'H':H}
123  if not in_fd():
124  self.D = D
125  self.objective = Answer['X']
126  LAST_MVALS = mvals.copy()
127  return Answer
Nifty functions, intended to be imported by any module within ForceBalance.
Subclass of Target for general least squares fitting.
Definition: leastsq.py:36
def get(self, mvals, AGrad=False, AHess=False)
LPW 05-30-2012.
Definition: leastsq.py:63
def LastMvals()
Definition: leastsq.py:30
def in_fd()
Invoking this function from anywhere will tell us whether we're being called by a finite-difference f...
def fdwrap(func, mvals0, pidx, key=None, kwargs)
A function wrapper for finite difference designed for differentiating 'get'-type functions.
def CheckBasis()
Definition: leastsq.py:25
def __init__(self, options, tgt_opts, forcefield)
Definition: leastsq.py:39
MAQ
Dictionary for derivative terms.
Definition: leastsq.py:89
def f1d2p(f, h, f0=None)
A two-point finite difference stencil.