@@ -18,13 +18,14 @@ def optimize_loop(self, tractor, dchisq=0., steps=50,
1818 # for s in tractor.catalog:
1919 # print(s)
2020 R = {}
21- self .hitLimit = False
21+ self .hit_limit = False
22+ self .last_step_hit_limit = False
2223 for step in range (steps ):
2324 #print('Optimize_loop: step', step)
2425 self .stepLimited = False
2526 dlnp ,_ ,_ = self .optimize (tractor , ** kwargs )
2627 #print('Optimize_loop: step', step, 'dlnp', dlnp, 'hit limit:',
27- # self.hitLimit , 'step limit:', self.stepLimited)
28+ # self.hit_limit , 'step limit:', self.stepLimited)
2829 #for s in tractor.catalog:
2930 # print(s)
3031
@@ -33,7 +34,8 @@ def optimize_loop(self, tractor, dchisq=0., steps=50,
3334 if self .stepLimited and dlnp <= dchisq_limited :
3435 break
3536 R .update (steps = step )
36- R .update (hit_limit = self .hitLimit )
37+ R .update (hit_limit = self .last_step_hit_limit ,
38+ ever_hit_limit = self .hit_limit )
3739 return R
3840
3941 def tryUpdates (self , tractor , X , alphas = None ):
@@ -56,13 +58,14 @@ def tryUpdates(self, tractor, X, alphas=None):
5658
5759 maxsteps = tractor .getMaxStep ()
5860 #print('Max step sizes:', maxsteps)
59-
61+
6062 for alpha in alphas :
6163 #print('Stepping with alpha =', alpha)
6264 #logverb(' Stepping with alpha =', alpha)
6365 pa = [p + alpha * d for p , d in zip (p0 , X )]
6466
6567 # Check parameter limits
68+ step_hit_limit = False
6669 maxalpha = alpha
6770 bailout = False
6871 for i ,(l ,u ,px ) in enumerate (zip (lowers , uppers , pa )):
@@ -75,7 +78,8 @@ def tryUpdates(self, tractor, X, alphas=None):
7578 # 'with alpha', alpha, '; max alpha', a)
7679 #print('Limiting step size to hit lower limit: param', i, 'limit', l, 'step size->', a)
7780 maxalpha = min (maxalpha , a )
78- self .hitLimit = True
81+ step_hit_limit = True
82+ self .hit_limit = True
7983 if u is not None and px > u :
8084 # This parameter hits the limit; compute the step size
8185 # to just hit the limit.
@@ -85,8 +89,19 @@ def tryUpdates(self, tractor, X, alphas=None):
8589 # 'with alpha', alpha, '; max alpha', a)
8690 #print('Limiting step size to hit upper limit: param', i, 'limit', u, 'step size->', a)
8791 maxalpha = min (maxalpha , a )
88- self .hitLimit = True
92+ step_hit_limit = True
93+ self .hit_limit = True
94+
95+ if maxalpha < 1e-8 :
96+ # Here, we're ceasing line-search because we're very
97+ # close to (or up against) a limit. This can only
98+ # happen on the first line-search step, so alphaBest
99+ # is None and we're going to return quickly.
100+ self .last_step_hit_limit = True
101+ self .hit_limit = True
102+ break
89103
104+ # Check parameter step-size limits
90105 for i ,(d ,m ) in enumerate (zip (X , maxsteps )):
91106 if m is None :
92107 continue
@@ -98,18 +113,11 @@ def tryUpdates(self, tractor, X, alphas=None):
98113 maxalpha = min (maxalpha , a )
99114 #print('Limiting step size for param max-step: param', i, 'max-step', m, 'step size->', a)
100115
101- if maxalpha < 1e-8 and not self .stepLimited :
102- #print('Tiny maxalpha; bailing out without parameter update')
103- self .hitLimit = True
104- break
105-
106116 if maxalpha < alpha :
107117 alpha = maxalpha
118+ # Cease line search (further steps want to exceed a limit, or have
119+ # parameter step sizes that are significantly non-linear).
108120 bailout = True
109- # Here, we "want" to hit the limit, but we won't necessarily
110- # accept the update that hits the limit. Still want this flag
111- # set, or wait to check whether it improves the log-prob?
112- #self.hitLimit = True
113121 # We could just multiply by alpha, but in case of numerical
114122 # instability, clip values right to limits.
115123 pa = []
@@ -144,9 +152,12 @@ def tryUpdates(self, tractor, X, alphas=None):
144152 break
145153
146154 if pAfter < (pBest - 1. ):
155+ # We're getting significantly worse -- quit line search
147156 break
148157
149158 if pAfter > pBest :
159+ # Best we've found so far -- accept this step!
160+ self .last_step_hit_limit = step_hit_limit
150161 alphaBest = alpha
151162 pBest = pAfter
152163
0 commit comments