6
6
import numpy as np
7
7
import pandas as pd
8
8
import pytz
9
+ import warnings
9
10
10
11
11
12
def cosd (angle ):
@@ -286,14 +287,17 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
286
287
287
288
Parameters
288
289
----------
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.
291
293
292
294
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.
294
297
295
298
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.
297
301
298
302
func: function
299
303
Function to be optimized. Must be in the form
@@ -312,6 +316,7 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
312
316
Notes
313
317
-----
314
318
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.
315
320
316
321
See also
317
322
--------
@@ -326,10 +331,15 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
326
331
327
332
converged = False
328
333
iterations = 0
329
- iterlimit = 1 + np .max (
330
- np .trunc (np .log (atol / (df ['VH' ] - df ['VL' ])) / np .log (phim1 )))
331
334
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 ):
333
343
334
344
phi = phim1 * (df ['VH' ] - df ['VL' ])
335
345
df ['V1' ] = df ['VL' ] + phi
@@ -345,15 +355,23 @@ def _golden_sect_DataFrame(params, lower, upper, func, atol=1e-8):
345
355
err = abs (df ['V2' ] - df ['V1' ])
346
356
347
357
# works with single value because err is np.float64
348
- converged = (err < atol ).all ()
358
+ converged = (err [ ~ np . isnan ( err )] < atol ).all ()
349
359
# err will be less than atol before iterations hit the limit
350
360
# but just to be safe
351
361
iterations += 1
352
362
353
363
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 ()
355
373
356
- return func ( df , 'V1' ), df [ 'V1' ]
374
+ return func_result , x
357
375
358
376
359
377
def _get_sample_intervals (times , win_length ):
0 commit comments