Changeset 418


Ignore:
Timestamp:
08/25/10 10:58:37 (6 years ago)
Author:
mmckerns
Message:

centralized support for (modified) scipy helper functions

Location:
branches/alta/mystic-0.2a1
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/alta/mystic-0.2a1/Make.mm

    r238 r418  
    2828    _genSow.py \ 
    2929    _scipy060optimize.py \ 
     30    _scipyoptimize.py \ 
    3031    abstract_map_solver.py \ 
    3132    abstract_nested_solver.py \ 
  • branches/alta/mystic-0.2a1/_scipy060optimize.py

    r124 r418  
    1111"""local copy of scipy.optimize""" 
    1212 
    13 __all__ = ['fmin', 'fmin_powell', 'fmin_ncg', 
    14            'fminbound','brent', 'golden','bracket','rosen','rosen_der', 
    15            'rosen_hess', 'rosen_hess_prod', 'brute', 'approx_fprime', 
    16            'line_search', 'check_grad'] 
     13#__all__ = ['fmin', 'fmin_powell', 'fmin_ncg', 
     14#           'fminbound','brent', 'golden','bracket','rosen','rosen_der', 
     15#           'rosen_hess', 'rosen_hess_prod', 'brute', 'approx_fprime', 
     16#           'line_search', 'check_grad'] 
    1717 
    1818import numpy 
  • branches/alta/mystic-0.2a1/scipy_bfgs.py

    r404 r418  
    5959# Helper methods and classes 
    6060 
    61 _epsilon = sqrt(numpy.finfo(float).eps) 
    62  
    63 def zoom(a_lo, a_hi, phi_lo, phi_hi, derphi_lo, 
    64          phi, derphi, phi0, derphi0, c1, c2): 
    65     maxiter = 10 
    66     i = 0 
    67     delta1 = 0.2  # cubic interpolant check 
    68     delta2 = 0.1  # quadratic interpolant check 
    69     phi_rec = phi0 
    70     a_rec = 0 
    71     while 1: 
    72         # interpolate to find a trial step length between a_lo and a_hi 
    73         # Need to choose interpolation here.  Use cubic interpolation and then if the 
    74         #  result is within delta * dalpha or outside of the interval bounded by a_lo or a_hi 
    75         #  then use quadratic interpolation, if the result is still too close, then use bisection 
    76  
    77         dalpha = a_hi-a_lo; 
    78         if dalpha < 0: a,b = a_hi,a_lo 
    79         else: a,b = a_lo, a_hi 
    80  
    81         # minimizer of cubic interpolant 
    82         #    (uses phi_lo, derphi_lo, phi_hi, and the most recent value of phi) 
    83         #      if the result is too close to the end points (or out of the interval) 
    84         #         then use quadratic interpolation with phi_lo, derphi_lo and phi_hi 
    85         #      if the result is stil too close to the end points (or out of the interval) 
    86         #         then use bisection 
    87  
    88         if (i > 0): 
    89             cchk = delta1*dalpha 
    90             a_j = _cubicmin(a_lo, phi_lo, derphi_lo, a_hi, phi_hi, a_rec, phi_rec) 
    91         if (i==0) or (a_j is None) or (a_j > b-cchk) or (a_j < a+cchk): 
    92             qchk = delta2*dalpha 
    93             a_j = _quadmin(a_lo, phi_lo, derphi_lo, a_hi, phi_hi) 
    94             if (a_j is None) or (a_j > b-qchk) or (a_j < a+qchk): 
    95                 a_j = a_lo + 0.5*dalpha 
    96 #                print "Using bisection." 
    97 #            else: print "Using quadratic." 
    98 #        else: print "Using cubic." 
    99  
    100         # Check new value of a_j 
    101  
    102         phi_aj = phi(a_j) 
    103         if (phi_aj > phi0 + c1*a_j*derphi0) or (phi_aj >= phi_lo): 
    104             phi_rec = phi_hi 
    105             a_rec = a_hi 
    106             a_hi = a_j 
    107             phi_hi = phi_aj 
    108         else: 
    109             derphi_aj = derphi(a_j) 
    110             if abs(derphi_aj) <= -c2*derphi0: 
    111                 a_star = a_j 
    112                 val_star = phi_aj 
    113                 valprime_star = derphi_aj 
    114                 break 
    115             if derphi_aj*(a_hi - a_lo) >= 0: 
    116                 phi_rec = phi_hi 
    117                 a_rec = a_hi 
    118                 a_hi = a_lo 
    119                 phi_hi = phi_lo 
    120             else: 
    121                 phi_rec = phi_lo 
    122                 a_rec = a_lo 
    123             a_lo = a_j 
    124             phi_lo = phi_aj 
    125             derphi_lo = derphi_aj 
    126         i += 1 
    127         if (i > maxiter): 
    128             a_star = a_j 
    129             val_star = phi_aj 
    130             valprime_star = None 
    131             break 
    132     return a_star, val_star, valprime_star 
    133  
    134  
    135 def _cubicmin(a,fa,fpa,b,fb,c,fc): 
    136     # finds the minimizer for a cubic polynomial that goes through the 
    137     #  points (a,fa), (b,fb), and (c,fc) with derivative at a of fpa. 
    138     # 
    139     # if no minimizer can be found return None 
    140     # 
    141     # f(x) = A *(x-a)^3 + B*(x-a)^2 + C*(x-a) + D 
    142  
    143     C = fpa 
    144     D = fa 
    145     db = b-a 
    146     dc = c-a 
    147     if (db == 0) or (dc == 0) or (b==c): return None 
    148     denom = (db*dc)**2 * (db-dc) 
    149     d1 = empty((2,2)) 
    150     d1[0,0] = dc**2 
    151     d1[0,1] = -db**2 
    152     d1[1,0] = -dc**3 
    153     d1[1,1] = db**3 
    154     [A,B] = numpy.dot(d1,asarray([fb-fa-C*db,fc-fa-C*dc]).flatten()) 
    155     A /= denom 
    156     B /= denom 
    157     radical = B*B-3*A*C 
    158     if radical < 0:  return None 
    159     if (A == 0): return None 
    160     xmin = a + (-B + sqrt(radical))/(3*A) 
    161     return xmin 
    162  
    163 def _quadmin(a,fa,fpa,b,fb): 
    164     # finds the minimizer for a quadratic polynomial that goes through 
    165     #  the points (a,fa), (b,fb) with derivative at a of fpa 
    166     # f(x) = B*(x-a)^2 + C*(x-a) + D 
    167     D = fa 
    168     C = fpa 
    169     db = b-a*1.0 
    170     if (db==0): return None 
    171     B = (fb-D-C*db)/(db*db) 
    172     if (B <= 0): return None 
    173     xmin = a  - C / (2.0*B) 
    174     return xmin 
    175  
    176  
    177 def line_search(f, myfprime, xk, pk, gfk, old_fval, old_old_fval, 
    178                 args=(), c1=1e-4, c2=0.9, amax=50, self=None): 
    179     """Find alpha that satisfies strong Wolfe conditions. 
    180  
    181     :Parameters: 
    182  
    183         f : callable f(x,*args) 
    184             Objective function. 
    185         myfprime : callable f'(x,*args) 
    186             Objective function gradient (can be None). 
    187         xk : ndarray 
    188             Starting point. 
    189         pk : ndarray 
    190             Search direction. 
    191         gfk : ndarray 
    192             Gradient value for x=xk (xk being the current parameter 
    193             estimate). 
    194         args : tuple 
    195             Additional arguments passed to objective function. 
    196         c1 : float 
    197             Parameter for Armijo condition rule. 
    198         c2 : float 
    199             Parameter for curvature condition rule. 
    200  
    201     :Returns: 
    202  
    203         alpha0 : float 
    204             Alpha for which ``x_new = x0 + alpha * pk``. 
    205         fc : int 
    206             Number of function evaluations made. 
    207         gc : int 
    208             Number of gradient evaluations made. 
    209  
    210     :Notes: 
    211  
    212         Uses the line search algorithm to enforce strong Wolfe 
    213         conditions.  See Wright and Nocedal, 'Numerical Optimization', 
    214         1999, pg. 59-60. 
    215  
    216         For the zoom phase it uses an algorithm by [...]. 
    217  
    218     """ 
    219  
    220     global _ls_fc, _ls_gc, _ls_ingfk 
    221     _ls_fc = 0 
    222     _ls_gc = 0 
    223     _ls_ingfk = None 
    224     def phi(alpha): 
    225         global _ls_fc 
    226         _ls_fc += 1 
    227         return f(xk+alpha*pk,*args) 
    228  
    229     if isinstance(myfprime,type(())): 
    230         def phiprime(alpha): 
    231             global _ls_fc, _ls_ingfk 
    232             _ls_fc += len(xk)+1 
    233             eps = myfprime[1] 
    234             fprime = myfprime[0] 
    235             newargs = (f,eps) + args 
    236             _ls_ingfk = fprime(xk+alpha*pk,*newargs)  # store for later use 
    237             return numpy.dot(_ls_ingfk,pk) 
    238     else: 
    239         fprime = myfprime 
    240         def phiprime(alpha): 
    241             global _ls_gc, _ls_ingfk 
    242             _ls_gc += 1 
    243             _ls_ingfk = fprime(xk+alpha*pk,*args)  # store for later use 
    244             return numpy.dot(_ls_ingfk,pk) 
    245  
    246     alpha0 = 0 
    247     phi0 = old_fval 
    248     derphi0 = numpy.dot(gfk,pk) 
    249  
    250     alpha1 = min(1.0,1.01*2*(phi0-old_old_fval)/derphi0) 
    251  
    252     if alpha1 == 0: 
    253         # This shouldn't happen. Perhaps the increment has slipped below 
    254         # machine precision?  For now, set the return variables skip the 
    255         # useless while loop, and raise warnflag=2 due to possible imprecision. 
    256         alpha_star = None 
    257         fval_star = old_fval 
    258         old_fval = old_old_fval 
    259         fprime_star = None 
    260  
    261     phi_a1 = phi(alpha1) 
    262     #derphi_a1 = phiprime(alpha1)  evaluated below 
    263  
    264     phi_a0 = phi0 
    265     derphi_a0 = derphi0 
    266  
    267     i = 1 
    268     maxiter = 10 
    269     while 1:         # bracketing phase 
    270         if alpha1 == 0: 
    271             break 
    272         if (phi_a1 > phi0 + c1*alpha1*derphi0) or \ 
    273            ((phi_a1 >= phi_a0) and (i > 1)): 
    274             alpha_star, fval_star, fprime_star = \ 
    275                         zoom(alpha0, alpha1, phi_a0, 
    276                              phi_a1, derphi_a0, phi, phiprime, 
    277                              phi0, derphi0, c1, c2) 
    278             break 
    279  
    280         derphi_a1 = phiprime(alpha1) 
    281         if (abs(derphi_a1) <= -c2*derphi0): 
    282             alpha_star = alpha1 
    283             fval_star = phi_a1 
    284             fprime_star = derphi_a1 
    285             break 
    286  
    287         if (derphi_a1 >= 0): 
    288             alpha_star, fval_star, fprime_star = \ 
    289                         zoom(alpha1, alpha0, phi_a1, 
    290                              phi_a0, derphi_a1, phi, phiprime, 
    291                              phi0, derphi0, c1, c2) 
    292             break 
    293  
    294         alpha2 = 2 * alpha1   # increase by factor of two on each iteration 
    295         i = i + 1 
    296         alpha0 = alpha1 
    297         alpha1 = alpha2 
    298         phi_a0 = phi_a1 
    299         phi_a1 = phi(alpha1) 
    300         derphi_a0 = derphi_a1 
    301  
    302         # stopping test if lower function not found 
    303         if (i > maxiter): 
    304             alpha_star = alpha1 
    305             fval_star = phi_a1 
    306             fprime_star = None 
    307             break 
    308  
    309         if self._EARLYEXIT: # In case it gets stuck in this loop, 'exit' will work 
    310             alpha_star = alpha1 
    311             fval_star = phi_a1 
    312             fprime_star = None 
    313             break 
    314  
    315     if fprime_star is not None: 
    316         # fprime_star is a number (derphi) -- so use the most recently 
    317         # calculated gradient used in computing it derphi = gfk*pk 
    318         # this is the gradient at the next step no need to compute it 
    319         # again in the outer loop. 
    320         fprime_star = _ls_ingfk 
    321  
    322     return alpha_star, _ls_fc, _ls_gc, fval_star, old_fval, fprime_star 
    323  
    324 def approx_fprime(xk,f,epsilon,*args): 
    325     f0 = f(*((xk,)+args)) 
    326     grad = numpy.zeros((len(xk),), float) 
    327     ei = numpy.zeros((len(xk),), float) 
    328     for k in range(len(xk)): 
    329         ei[k] = epsilon 
    330         grad[k] = (f(*((xk+ei,)+args)) - f0)/epsilon 
    331         ei[k] = 0.0 
    332     return grad 
     61from _scipyoptimize import zoom, _cubicmin, _quadmin, _epsilon 
     62from _scipyoptimize import line_search, approx_fprime 
    33363 
    33464########################################################################## 
  • branches/alta/mystic-0.2a1/scipy_cg.py

    r404 r418  
    5757# Helper methods and classes 
    5858 
    59 _epsilon = sqrt(numpy.finfo(float).eps) 
    60  
    61 def zoom(a_lo, a_hi, phi_lo, phi_hi, derphi_lo, 
    62          phi, derphi, phi0, derphi0, c1, c2): 
    63     maxiter = 10 
    64     i = 0 
    65     delta1 = 0.2  # cubic interpolant check 
    66     delta2 = 0.1  # quadratic interpolant check 
    67     phi_rec = phi0 
    68     a_rec = 0 
    69     while 1: 
    70         # interpolate to find a trial step length between a_lo and a_hi 
    71         # Need to choose interpolation here.  Use cubic interpolation and then if the 
    72         #  result is within delta * dalpha or outside of the interval bounded by a_lo or a_hi 
    73         #  then use quadratic interpolation, if the result is still too close, then use bisection 
    74  
    75         dalpha = a_hi-a_lo; 
    76         if dalpha < 0: a,b = a_hi,a_lo 
    77         else: a,b = a_lo, a_hi 
    78  
    79         # minimizer of cubic interpolant 
    80         #    (uses phi_lo, derphi_lo, phi_hi, and the most recent value of phi) 
    81         #      if the result is too close to the end points (or out of the interval) 
    82         #         then use quadratic interpolation with phi_lo, derphi_lo and phi_hi 
    83         #      if the result is stil too close to the end points (or out of the interval) 
    84         #         then use bisection 
    85  
    86         if (i > 0): 
    87             cchk = delta1*dalpha 
    88             a_j = _cubicmin(a_lo, phi_lo, derphi_lo, a_hi, phi_hi, a_rec, phi_rec) 
    89         if (i==0) or (a_j is None) or (a_j > b-cchk) or (a_j < a+cchk): 
    90             qchk = delta2*dalpha 
    91             a_j = _quadmin(a_lo, phi_lo, derphi_lo, a_hi, phi_hi) 
    92             if (a_j is None) or (a_j > b-qchk) or (a_j < a+qchk): 
    93                 a_j = a_lo + 0.5*dalpha 
    94 #                print "Using bisection." 
    95 #            else: print "Using quadratic." 
    96 #        else: print "Using cubic." 
    97  
    98         # Check new value of a_j 
    99  
    100         phi_aj = phi(a_j) 
    101         if (phi_aj > phi0 + c1*a_j*derphi0) or (phi_aj >= phi_lo): 
    102             phi_rec = phi_hi 
    103             a_rec = a_hi 
    104             a_hi = a_j 
    105             phi_hi = phi_aj 
    106         else: 
    107             derphi_aj = derphi(a_j) 
    108             if abs(derphi_aj) <= -c2*derphi0: 
    109                 a_star = a_j 
    110                 val_star = phi_aj 
    111                 valprime_star = derphi_aj 
    112                 break 
    113             if derphi_aj*(a_hi - a_lo) >= 0: 
    114                 phi_rec = phi_hi 
    115                 a_rec = a_hi 
    116                 a_hi = a_lo 
    117                 phi_hi = phi_lo 
    118             else: 
    119                 phi_rec = phi_lo 
    120                 a_rec = a_lo 
    121             a_lo = a_j 
    122             phi_lo = phi_aj 
    123             derphi_lo = derphi_aj 
    124         i += 1 
    125         if (i > maxiter): 
    126             a_star = a_j 
    127             val_star = phi_aj 
    128             valprime_star = None 
    129             break 
    130     return a_star, val_star, valprime_star 
    131  
    132 def _cubicmin(a,fa,fpa,b,fb,c,fc): 
    133     # finds the minimizer for a cubic polynomial that goes through the 
    134     #  points (a,fa), (b,fb), and (c,fc) with derivative at a of fpa. 
    135     # 
    136     # if no minimizer can be found return None 
    137     # 
    138     # f(x) = A *(x-a)^3 + B*(x-a)^2 + C*(x-a) + D 
    139  
    140     C = fpa 
    141     D = fa 
    142     db = b-a 
    143     dc = c-a 
    144     if (db == 0) or (dc == 0) or (b==c): return None 
    145     denom = (db*dc)**2 * (db-dc) 
    146     d1 = empty((2,2)) 
    147     d1[0,0] = dc**2 
    148     d1[0,1] = -db**2 
    149     d1[1,0] = -dc**3 
    150     d1[1,1] = db**3 
    151     [A,B] = numpy.dot(d1,asarray([fb-fa-C*db,fc-fa-C*dc]).flatten()) 
    152     A /= denom 
    153     B /= denom 
    154     radical = B*B-3*A*C 
    155     if radical < 0:  return None 
    156     if (A == 0): return None 
    157     xmin = a + (-B + sqrt(radical))/(3*A) 
    158     return xmin 
    159  
    160 def _quadmin(a,fa,fpa,b,fb): 
    161     # finds the minimizer for a quadratic polynomial that goes through 
    162     #  the points (a,fa), (b,fb) with derivative at a of fpa 
    163     # f(x) = B*(x-a)^2 + C*(x-a) + D 
    164     D = fa 
    165     C = fpa 
    166     db = b-a*1.0 
    167     if (db==0): return None 
    168     B = (fb-D-C*db)/(db*db) 
    169     if (B <= 0): return None 
    170     xmin = a  - C / (2.0*B) 
    171     return xmin 
    172  
    173 def line_search(f, myfprime, xk, pk, gfk, old_fval, old_old_fval, 
    174                 args=(), c1=1e-4, c2=0.9, amax=50, self=None): 
    175     """Find alpha that satisfies strong Wolfe conditions. 
    176  
    177     :Parameters: 
    178  
    179         f : callable f(x,*args) 
    180             Objective function. 
    181         myfprime : callable f'(x,*args) 
    182             Objective function gradient (can be None). 
    183         xk : ndarray 
    184             Starting point. 
    185         pk : ndarray 
    186             Search direction. 
    187         gfk : ndarray 
    188             Gradient value for x=xk (xk being the current parameter 
    189             estimate). 
    190         args : tuple 
    191             Additional arguments passed to objective function. 
    192         c1 : float 
    193             Parameter for Armijo condition rule. 
    194         c2 : float 
    195             Parameter for curvature condition rule. 
    196  
    197     :Returns: 
    198  
    199         alpha0 : float 
    200             Alpha for which ``x_new = x0 + alpha * pk``. 
    201         fc : int 
    202             Number of function evaluations made. 
    203         gc : int 
    204             Number of gradient evaluations made. 
    205  
    206     :Notes: 
    207  
    208         Uses the line search algorithm to enforce strong Wolfe 
    209         conditions.  See Wright and Nocedal, 'Numerical Optimization', 
    210         1999, pg. 59-60. 
    211  
    212         For the zoom phase it uses an algorithm by [...]. 
    213  
    214     """ 
    215  
    216     global _ls_fc, _ls_gc, _ls_ingfk 
    217     _ls_fc = 0 
    218     _ls_gc = 0 
    219     _ls_ingfk = None 
    220     def phi(alpha): 
    221         global _ls_fc 
    222         _ls_fc += 1 
    223         return f(xk+alpha*pk,*args) 
    224  
    225     if isinstance(myfprime,type(())): 
    226         def phiprime(alpha): 
    227             global _ls_fc, _ls_ingfk 
    228             _ls_fc += len(xk)+1 
    229             eps = myfprime[1] 
    230             fprime = myfprime[0] 
    231             newargs = (f,eps) + args 
    232             _ls_ingfk = fprime(xk+alpha*pk,*newargs)  # store for later use 
    233             return numpy.dot(_ls_ingfk,pk) 
    234     else: 
    235         fprime = myfprime 
    236         def phiprime(alpha): 
    237             global _ls_gc, _ls_ingfk 
    238             _ls_gc += 1 
    239             _ls_ingfk = fprime(xk+alpha*pk,*args)  # store for later use 
    240             return numpy.dot(_ls_ingfk,pk) 
    241  
    242     alpha0 = 0 
    243     phi0 = old_fval 
    244     derphi0 = numpy.dot(gfk,pk) 
    245  
    246     alpha1 = min(1.0,1.01*2*(phi0-old_old_fval)/derphi0) 
    247  
    248     if alpha1 == 0: 
    249         # This shouldn't happen. Perhaps the increment has slipped below 
    250         # machine precision?  For now, set the return variables skip the 
    251         # useless while loop, and raise warnflag=2 due to possible imprecision. 
    252         alpha_star = None 
    253         fval_star = old_fval 
    254         old_fval = old_old_fval 
    255         fprime_star = None 
    256  
    257     phi_a1 = phi(alpha1) 
    258     #derphi_a1 = phiprime(alpha1)  evaluated below 
    259  
    260     phi_a0 = phi0 
    261     derphi_a0 = derphi0 
    262  
    263     i = 1 
    264     maxiter = 10 
    265     while 1:         # bracketing phase 
    266         if alpha1 == 0: 
    267             break 
    268         if (phi_a1 > phi0 + c1*alpha1*derphi0) or \ 
    269            ((phi_a1 >= phi_a0) and (i > 1)): 
    270             alpha_star, fval_star, fprime_star = \ 
    271                         zoom(alpha0, alpha1, phi_a0, 
    272                              phi_a1, derphi_a0, phi, phiprime, 
    273                              phi0, derphi0, c1, c2) 
    274             break 
    275  
    276         derphi_a1 = phiprime(alpha1) 
    277         if (abs(derphi_a1) <= -c2*derphi0): 
    278             alpha_star = alpha1 
    279             fval_star = phi_a1 
    280             fprime_star = derphi_a1 
    281             break 
    282  
    283         if (derphi_a1 >= 0): 
    284             alpha_star, fval_star, fprime_star = \ 
    285                         zoom(alpha1, alpha0, phi_a1, 
    286                              phi_a0, derphi_a1, phi, phiprime, 
    287                              phi0, derphi0, c1, c2) 
    288             break 
    289  
    290         alpha2 = 2 * alpha1   # increase by factor of two on each iteration 
    291         i = i + 1 
    292         alpha0 = alpha1 
    293         alpha1 = alpha2 
    294         phi_a0 = phi_a1 
    295         phi_a1 = phi(alpha1) 
    296         derphi_a0 = derphi_a1 
    297  
    298         # stopping test if lower function not found 
    299         if (i > maxiter): 
    300             alpha_star = alpha1 
    301             fval_star = phi_a1 
    302             fprime_star = None 
    303             break 
    304  
    305         if self._EARLYEXIT: # In case it gets stuck in this loop, 'exit' will work 
    306             alpha_star = alpha1 
    307             fval_star = phi_a1 
    308             fprime_star = None 
    309             break 
    310  
    311     if fprime_star is not None: 
    312         # fprime_star is a number (derphi) -- so use the most recently 
    313         # calculated gradient used in computing it derphi = gfk*pk 
    314         # this is the gradient at the next step no need to compute it 
    315         # again in the outer loop. 
    316         fprime_star = _ls_ingfk 
    317  
    318     return alpha_star, _ls_fc, _ls_gc, fval_star, old_fval, fprime_star 
    319  
    320  
    321 def approx_fprime(xk,f,epsilon,*args): 
    322     f0 = f(*((xk,)+args)) 
    323     grad = numpy.zeros((len(xk),), float) 
    324     ei = numpy.zeros((len(xk),), float) 
    325     for k in range(len(xk)): 
    326         ei[k] = epsilon 
    327         grad[k] = (f(*((xk+ei,)+args)) - f0)/epsilon 
    328         ei[k] = 0.0 
    329     return grad 
     59from _scipyoptimize import zoom, _cubicmin, _quadmin, _epsilon 
     60from _scipyoptimize import line_search, approx_fprime 
    33061 
    33162########################################################################## 
  • branches/alta/mystic-0.2a1/scipy_ncg.py

    r417 r418  
    5555# Helper methods and classes 
    5656 
    57 def line_search_BFGS(f, xk, pk, gfk, old_fval, args=(), c1=1e-4, alpha0=1,\ 
    58                      self=None): 
    59     """Minimize over alpha, the function ``f(xk+alpha pk)``. 
    60  
    61     Uses the interpolation algorithm (Armiijo backtracking) as suggested by 
    62     Wright and Nocedal in 'Numerical Optimization', 1999, pg. 56-57 
    63  
    64     :Returns: (alpha, fc, gc) 
    65  
    66     """ 
    67  
    68     xk = atleast_1d(xk) 
    69     fc = 0 
    70     phi0 = old_fval # compute f(xk) -- done in past loop 
    71     phi_a0 = f(*((xk+alpha0*pk,)+args)) 
    72     fc = fc + 1 
    73     derphi0 = numpy.dot(gfk,pk) 
    74  
    75     if (phi_a0 <= phi0 + c1*alpha0*derphi0): 
    76         return alpha0, fc, 0, phi_a0 
    77  
    78     # Otherwise compute the minimizer of a quadratic interpolant: 
    79  
    80     alpha1 = -(derphi0) * alpha0**2 / 2.0 / (phi_a0 - phi0 - derphi0 * alpha0) 
    81     phi_a1 = f(*((xk+alpha1*pk,)+args)) 
    82     fc = fc + 1 
    83  
    84     if (phi_a1 <= phi0 + c1*alpha1*derphi0):  
    85         return alpha1, fc, 0, phi_a1 
    86  
    87     # Otherwise loop with cubic interpolation until we find an alpha which 
    88     # satifies the first Wolfe condition (since we are backtracking, we will 
    89     # assume that the value of alpha is not too small and satisfies the second 
    90     # condition. 
    91  
    92     while 1:       # we are assuming pk is a descent direction 
    93         factor = alpha0**2 * alpha1**2 * (alpha1-alpha0) 
    94         a = alpha0**2 * (phi_a1 - phi0 - derphi0*alpha1) - \ 
    95             alpha1**2 * (phi_a0 - phi0 - derphi0*alpha0) 
    96         a = a / factor 
    97         b = -alpha0**3 * (phi_a1 - phi0 - derphi0*alpha1) + \ 
    98             alpha1**3 * (phi_a0 - phi0 - derphi0*alpha0) 
    99         b = b / factor 
    100  
    101         alpha2 = (-b + numpy.sqrt(abs(b**2 - 3 * a * derphi0))) / (3.0*a) 
    102         phi_a2 = f(*((xk+alpha2*pk,)+args)) 
    103         fc = fc + 1 
    104  
    105         if (phi_a2 <= phi0 + c1*alpha2*derphi0): 
    106             return alpha2, fc, 0, phi_a2 
    107  
    108         if (alpha1 - alpha2) > alpha1 / 2.0 or (1 - alpha2/alpha1) < 0.96: 
    109             alpha2 = alpha1 / 2.0 
    110  
    111         alpha0 = alpha1 
    112         alpha1 = alpha2 
    113         phi_a0 = phi_a1 
    114         phi_a1 = phi_a2 
    115  
    116         # In case it gets stuck in this loop, to make 'exit' work. 
    117         if self._EARLYEXIT: 
    118             return alpha2, fc, 0, phi_a2 
    119  
    120 def approx_fhess_p(x0,p,fprime,epsilon,*args): 
    121     f2 = fprime(*((x0+epsilon*p,)+args)) 
    122     f1 = fprime(*((x0,)+args)) 
    123     return (f2 - f1)/epsilon 
    124  
    125 _epsilon = sqrt(numpy.finfo(float).eps) 
    126  
    127  
    128 # from scipy_bfgs 
    129 def approx_fprime(xk,f,epsilon,*args): 
    130     xk = xk.copy() 
    131     f0 = f(*((xk,)+args)) 
    132     grad = numpy.zeros((len(xk),), float) 
    133     ei = numpy.zeros((len(xk),), float) 
    134     for k in range(len(xk)): 
    135         ei[k] = epsilon 
    136         grad[k] = (f(*((xk+ei,)+args)) - f0)/epsilon 
    137         ei[k] = 0.0 
    138     return grad 
     57from _scipyoptimize import line_search_BFGS, _epsilon 
     58from _scipyoptimize import approx_fprime, approx_fhess_p 
    13959 
    14060######################################################################### 
  • branches/alta/mystic-0.2a1/scipy_optimize.py

    r403 r418  
    6868from numpy import clip, squeeze 
    6969 
    70 abs = absolute 
    71  
    72 from _scipy060optimize import brent #XXX: local copy to avoid dependency! 
     70from _scipyoptimize import _linesearch_powell 
    7371 
    7472from abstract_solver import AbstractSolver 
     
    464462############################################################################ 
    465463 
    466 def _linesearch_powell(func, p, xi, tol=1e-3): 
    467     # line-search algorithm using fminbound 
    468     #  find the minimium of the function 
    469     #  func(x0+ alpha*direc) 
    470     def myfunc(alpha): 
    471         return func(p + alpha * xi) 
    472     alpha_min, fret, iter, num = brent(myfunc, full_output=1, tol=tol) 
    473     xi = alpha_min*xi 
    474     return squeeze(fret), p+xi, xi 
    475  
    476  
    477464class PowellDirectionalSolver(AbstractSolver): 
    478465    """ 
Note: See TracChangeset for help on using the changeset viewer.