66import numpy as np
77import pandas as pd
88import pytz
9+ import warnings
910
1011
1112def cosd (angle ):
@@ -286,14 +287,17 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
286287
287288 Parameters
288289 ----------
289- params : dict or Dataframe
290- Parameters to be passed to `func`.
290+ params : dict of numeric
291+ Parameters to be passed to `func`. Each entry must be of the same
292+ length.
291293
292294 lower: numeric
293- Lower bound for the optimization
295+ Lower bound for the optimization. Must be the same length as each
296+ entry of params.
294297
295298 upper: numeric
296- Upper bound for the optimization
299+ Upper bound for the optimization. Must be the same length as each
300+ entry of params.
297301
298302 func: function
299303 Function to be optimized. Must be in the form
@@ -312,6 +316,7 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
312316 Notes
313317 -----
314318 This function will find the points where the function is maximized.
319+ Returns nan where lower or upper is nan, or where func evaluates to nan.
315320
316321 See also
317322 --------
@@ -326,10 +331,15 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
326331
327332 converged = False
328333 iterations = 0
329- iterlimit = 1 + np .max (
330- np .trunc (np .log (atol / (df ['VH' ] - df ['VL' ])) / np .log (phim1 )))
331334
332- while not converged and (iterations < iterlimit ):
335+ # handle all NaN case gracefully
336+ with warnings .catch_warnings ():
337+ warnings .filterwarnings (action = 'ignore' ,
338+ message = 'All-NaN slice encountered' )
339+ iterlimit = 1 + np .nanmax (
340+ np .trunc (np .log (atol / (df ['VH' ] - df ['VL' ])) / np .log (phim1 )))
341+
342+ while not converged and (iterations <= iterlimit ):
333343
334344 phi = phim1 * (df ['VH' ] - df ['VL' ])
335345 df ['V1' ] = df ['VL' ] + phi
@@ -345,15 +355,23 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
345355 err = abs (df ['V2' ] - df ['V1' ])
346356
347357 # works with single value because err is np.float64
348- converged = (err < atol ).all ()
358+ converged = (err [ ~ np . isnan ( err )] < atol ).all ()
349359 # err will be less than atol before iterations hit the limit
350360 # but just to be safe
351361 iterations += 1
352362
353363 if iterations > iterlimit :
354- raise Exception ("iterations exceeded maximum" ) # pragma: no cover
364+ raise Exception ("Iterations exceeded maximum. Check that func" ,
365+ " is not NaN in (lower, upper)" ) # pragma: no cover
366+
367+ try :
368+ func_result = func (df , 'V1' )
369+ x = np .where (np .isnan (func_result ), np .nan , df ['V1' ])
370+ except KeyError :
371+ func_result = np .full_like (upper , np .nan )
372+ x = func_result .copy ()
355373
356- return func ( df , 'V1' ), df [ 'V1' ]
374+ return func_result , x
357375
358376
359377def _get_sample_intervals (times , win_length ):
0 commit comments