BFGS implementation in the notebook.

This commit is contained in:
Rowan Cockett
2013-11-19 15:59:37 -08:00
parent 1f3799caa0
commit fc435feb9e
2 changed files with 203 additions and 4 deletions
+197
View File
@@ -0,0 +1,197 @@
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"import SimPEG\n",
"from SimPEG import Solver\n",
"from SimPEG.mesh import TensorMesh\n",
"from SimPEG.regularization import Regularization\n",
"import SimPEG.inverse as inverse\n",
"from SimPEG.inverse import Minimize, Remember, IterationPrinters\n",
"import numpy as np\n",
"import scipy.sparse as sp"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"FUN = SimPEG.tests.Rosenbrock\n",
"FUN = SimPEG.tests.getQuadratic(sp.csr_matrix(([100,1],([0,1],[0,1])),shape=(2,2)),np.array([-5,-5]),100)\n",
"\n",
"\n",
"class BFGS(Minimize, Remember):\n",
" name = 'BFGS'\n",
" nbfgs = 10\n",
" \n",
" @property\n",
" def H0(self):\n",
" \"\"\"\n",
" Approximate Hessian used in preconditioning the problem.\n",
" \n",
" Must be a SimPEG.Solver\n",
" \"\"\"\n",
" _H0 = getattr(self,'_H0',None)\n",
" if _H0 is None:\n",
" return Solver(sp.identity(self.xc.size).tocsc())\n",
" return _H0\n",
" @H0.setter\n",
" def H0(self, value):\n",
" self._H0 = value\n",
" \n",
" def _startup_BFGS(self,x0):\n",
" self._bfgscnt = -1\n",
" self._bfgsY = np.zeros((x0.size, self.nbfgs))\n",
" self._bfgsS = np.zeros((x0.size, self.nbfgs))\n",
" if not np.any([p is IterationPrinters.comment for p in self.printers]):\n",
" self.printers.append(IterationPrinters.comment)\n",
" \n",
" def bfgs(self,n,d):\n",
" nn = min(self._bfgsS.shape[1],n)\n",
" ktop = nn\n",
" d = self.bfgsrec(ktop,n,nn,self._bfgsS,self._bfgsY,d)\n",
" return d\n",
"\n",
" def bfgsrec(self,k,n,nn,S,Y,d):\n",
" \"\"\"BFGS recursion\"\"\"\n",
" if k < 0:\n",
" d = self.H0.solve(d)\n",
" else:\n",
" khat = mod(n-nn+k,nn)\n",
" gamma = np.vdot(S[:,khat],d)/np.vdot(Y[:,khat],S[:,khat])\n",
" d = d - gamma*Y[:,khat]\n",
" d = self.bfgsrec(k-1,n,nn,S,Y,d)\n",
" d = d + (gamma - np.vdot(Y[:,khat],d)/np.vdot(Y[:,khat],S[:,khat]))*S[:,khat]\n",
" \n",
" return d\n",
" \n",
" def findSearchDirection(self):\n",
" return self.bfgs(self._bfgscnt,-self.g)\n",
" \n",
" def _doEndIteration_BFGS(self, xt):\n",
" if self._iter is 0: \n",
" self.g_last = self.g\n",
" return\n",
" \n",
" yy = self.g - self.g_last;\n",
" ss = self.xc - xt;\n",
" self.g_last = self.g\n",
" \n",
" if yy.dot(ss) > 0:\n",
" self._bfgscnt += 1\n",
" ktop = np.mod(self._bfgscnt,self.nbfgs)\n",
" self._bfgsY[:,ktop] = yy\n",
" self._bfgsS[:,ktop] = ss\n",
" self.comment = ''\n",
" else:\n",
" self.comment = 'Skip BFGS'\n",
" \n",
"\n",
"\n",
"x0 = np.array([1,0])\n",
"opt = BFGS()\n",
"xopt = opt.minimize(FUN,x0)\n",
"print xopt\n",
"opt = inverse.GaussNewton()\n",
"xopt = opt.minimize(FUN,x0)\n",
"print xopt\n",
"opt = inverse.SteepestDescent()\n",
"xopt = opt.minimize(FUN,x0)\n",
"print xopt"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"===================== BFGS =====================\n",
" # f |proj(x-g)-x| LS Comment \n",
"-----------------------------------------------\n",
" 0 1.45e+02 9.51e+01 0 \n",
" 1 1.14e+02 5.37e+01 6 \n",
" 2 1.04e+02 3.04e+01 6 \n",
" 3 8.83e+01 1.37e+01 0 \n",
" 4 8.76e+01 5.97e+00 0 Skip BFGS \n",
" 5 8.74e+01 2.61e+00 0 Skip BFGS \n",
" 6 8.74e+01 1.14e+00 0 Skip BFGS \n",
" 7 8.74e+01 5.01e-01 0 Skip BFGS \n",
" 8 8.74e+01 2.19e-01 0 Skip BFGS \n",
" 9 8.74e+01 9.60e-02 0 Skip BFGS \n",
"------------------------- STOP! -------------------------\n",
"1 : |fc-fOld| = 1.9437e-04 <= tolF*(1+|f0|) = 1.4600e+01\n",
"1 : |xc-x_last| = 1.2663e-03 <= tolX*(1+|x0|) = 2.0000e-01\n",
"1 : |proj(x-g)-x| = 9.5952e-02 <= tolG = 1.0000e-01\n",
"0 : |proj(x-g)-x| = 9.5952e-02 <= 1e3*eps = 1.0000e-02\n",
"0 : maxIter = 20 <= iter = 9\n",
"------------------------- DONE! -------------------------\n",
"[ 0.05095952 4.99977449]\n",
"=========== Gauss Newton ===========\n",
" # f |proj(x-g)-x| LS \n",
"-----------------------------------\n",
" 0 1.45e+02 9.51e+01 0 \n",
" 1 8.74e+01 4.44e-15 0 \n",
"------------------------- STOP! -------------------------\n",
"0 : |fc-fOld| = 5.7625e+01 <= tolF*(1+|f0|) = 1.4600e+01\n",
"0 : |xc-x_last| = 5.0894e+00 <= tolX*(1+|x0|) = 2.0000e-01\n",
"1 : |proj(x-g)-x| = 4.4409e-15 <= tolG = 1.0000e-01\n",
"1 : |proj(x-g)-x| = 4.4409e-15 <= 1e3*eps = 1.0000e-02\n",
"0 : maxIter = 20 <= iter = 1\n",
"------------------------- DONE! -------------------------\n",
"[ 0.05 5. ]\n",
"========= Steepest Descent =========\n",
" # f |proj(x-g)-x| LS \n",
"-----------------------------------\n",
" 0 1.45e+02 9.51e+01 0 \n",
" 1 1.14e+02 5.37e+01 6 \n",
" 2 1.04e+02 3.04e+01 6 \n",
" 3 1.00e+02 1.76e+01 6 \n",
" 4 9.88e+01 1.06e+01 6 \n",
" 5 9.82e+01 7.07e+00 6 \n",
" 6 9.80e+01 1.22e+01 5 \n",
" 7 9.73e+01 7.77e+00 6 \n",
" 8 9.68e+01 5.64e+00 6 \n",
" 9 9.65e+01 8.72e+00 5 \n",
" 10 9.60e+01 5.97e+00 6 \n",
" 11 9.58e+01 9.98e+00 5 \n",
" 12 9.53e+01 6.48e+00 6 \n",
" 13 9.53e+01 1.16e+01 5 \n",
" 14 9.46e+01 7.20e+00 6 \n",
" 15 9.43e+01 5.07e+00 6 \n",
" 16 9.41e+01 8.17e+00 5 \n",
" 17 9.37e+01 5.43e+00 6 \n",
" 18 9.36e+01 9.42e+00 5 \n",
" 19 9.32e+01 5.98e+00 6 \n",
" 20 9.29e+01 4.32e+00 6 \n",
"------------------------- STOP! -------------------------\n",
"1 : |fc-fOld| = 2.5913e-01 <= tolF*(1+|f0|) = 1.4600e+01\n",
"1 : |xc-x_last| = 9.3379e-02 <= tolX*(1+|x0|) = 2.0000e-01\n",
"0 : |proj(x-g)-x| = 4.3246e+00 <= tolG = 1.0000e-01\n",
"0 : |proj(x-g)-x| = 4.3246e+00 <= 1e3*eps = 1.0000e-02\n",
"1 : maxIter = 20 <= iter = 20\n",
"------------------------- DONE! -------------------------\n",
"[ 0.07777107 1.6849632 ]\n"
]
}
],
"prompt_number": 14
}
],
"metadata": {}
}
]
}