5
5
import math
6
6
import inspect
7
7
import scipy .optimize
8
- from scipy ._lib ._util import check_random_state
8
+ from scipy ._lib ._util import check_random_state , _transition_to_rng
9
9
10
10
__all__ = ['basinhopping' ]
11
11
@@ -264,25 +264,17 @@ class RandomDisplacement:
264
264
----------
265
265
stepsize : float, optional
266
266
Maximum stepsize in any dimension
267
- random_gen : {None, int, `numpy.random.Generator`,
268
- `numpy.random.RandomState`}, optional
269
-
270
- If `seed` is None (or `np.random`), the `numpy.random.RandomState`
271
- singleton is used.
272
- If `seed` is an int, a new ``RandomState`` instance is used,
273
- seeded with `seed`.
274
- If `seed` is already a ``Generator`` or ``RandomState`` instance then
275
- that instance is used.
276
-
267
+ rng : {None, int, `numpy.random.Generator`}, optional
268
+ Random number generator
277
269
"""
278
270
279
- def __init__ (self , stepsize = 0.5 , random_gen = None ):
271
+ def __init__ (self , stepsize = 0.5 , rng = None ):
280
272
self .stepsize = stepsize
281
- self .random_gen = check_random_state (random_gen )
273
+ self .rng = check_random_state (rng )
282
274
283
275
def __call__ (self , x ):
284
- x += self .random_gen .uniform (- self .stepsize , self .stepsize ,
285
- np .shape (x ))
276
+ x += self .rng .uniform (- self .stepsize , self .stepsize ,
277
+ np .shape (x ))
286
278
return x
287
279
288
280
@@ -309,25 +301,17 @@ class Metropolis:
309
301
----------
310
302
T : float
311
303
The "temperature" parameter for the accept or reject criterion.
312
- random_gen : {None, int, `numpy.random.Generator`,
313
- `numpy.random.RandomState`}, optional
314
-
315
- If `seed` is None (or `np.random`), the `numpy.random.RandomState`
316
- singleton is used.
317
- If `seed` is an int, a new ``RandomState`` instance is used,
318
- seeded with `seed`.
319
- If `seed` is already a ``Generator`` or ``RandomState`` instance then
320
- that instance is used.
304
+ rng : {None, int, `numpy.random.Generator`}, optional
321
305
Random number generator used for acceptance test.
322
306
323
307
"""
324
308
325
- def __init__ (self , T , random_gen = None ):
309
+ def __init__ (self , T , rng = None ):
326
310
# Avoid ZeroDivisionError since "MBH can be regarded as a special case
327
311
# of the BH framework with the Metropolis criterion, where temperature
328
312
# T = 0." (Reject all steps that increase energy.)
329
313
self .beta = 1.0 / T if T != 0 else float ('inf' )
330
- self .random_gen = check_random_state (random_gen )
314
+ self .rng = check_random_state (rng )
331
315
332
316
def accept_reject (self , res_new , res_old ):
333
317
"""
@@ -348,7 +332,7 @@ def accept_reject(self, res_new, res_old):
348
332
prod = - (res_new .fun - res_old .fun ) * self .beta
349
333
w = math .exp (min (0 , prod ))
350
334
351
- rand = self .random_gen .uniform ()
335
+ rand = self .rng .uniform ()
352
336
return w >= rand and (res_new .success or not res_old .success )
353
337
354
338
def __call__ (self , * , res_new , res_old ):
@@ -358,10 +342,11 @@ def __call__(self, *, res_new, res_old):
358
342
return bool (self .accept_reject (res_new , res_old ))
359
343
360
344
345
+ @_transition_to_rng ("seed" , position_num = 12 , replace_doc = True )
361
346
def basinhopping (func , x0 , niter = 100 , T = 1.0 , stepsize = 0.5 ,
362
347
minimizer_kwargs = None , take_step = None , accept_test = None ,
363
348
callback = None , interval = 50 , disp = False , niter_success = None ,
364
- seed = None , * , target_accept_rate = 0.5 , stepwise_factor = 0.9 ):
349
+ rng = None , * , target_accept_rate = 0.5 , stepwise_factor = 0.9 ):
365
350
"""Find the global minimum of a function using the basin-hopping algorithm.
366
351
367
352
Basin-hopping is a two-phase method that combines a global stepping
@@ -432,15 +417,13 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
432
417
niter_success : integer, optional
433
418
Stop the run if the global minimum candidate remains the same for this
434
419
number of iterations.
435
- seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
436
- If `seed` is None (or `np.random`), the `numpy.random.RandomState`
437
- singleton is used.
438
- If `seed` is an int, a new ``RandomState`` instance is used,
439
- seeded with `seed`.
440
- If `seed` is already a ``Generator`` or ``RandomState`` instance then
441
- that instance is used.
442
- Specify `seed` for repeatable minimizations. The random numbers
443
- generated with this seed only affect the default Metropolis
420
+ rng : `numpy.random.Generator`, optional
421
+ Pseudorandom number generator state. When `rng` is None, a new
422
+ `numpy.random.Generator` is created using entropy from the
423
+ operating system. Types other than `numpy.random.Generator` are
424
+ passed to `numpy.random.default_rng` to instantiate a ``Generator``.
425
+
426
+ The random numbers generated only affect the default Metropolis
444
427
`accept_test` and the default `take_step`. If you supply your own
445
428
`take_step` and `accept_test`, and these functions use random
446
429
number generation, then those functions are responsible for the state
@@ -641,7 +624,7 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
641
624
642
625
>>> rng = np.random.default_rng()
643
626
>>> ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs,
644
- ... niter=10, callback=print_fun, seed =rng)
627
+ ... niter=10, callback=print_fun, rng =rng)
645
628
at minimum 0.4159 accepted 1
646
629
at minimum -0.4317 accepted 1
647
630
at minimum -1.0109 accepted 1
@@ -666,7 +649,7 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
666
649
x0 = np .array (x0 )
667
650
668
651
# set up the np.random generator
669
- rng = check_random_state (seed )
652
+ rng = check_random_state (rng )
670
653
671
654
# set up minimizer
672
655
if minimizer_kwargs is None :
@@ -690,7 +673,7 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
690
673
take_step_wrapped = take_step
691
674
else :
692
675
# use default
693
- displace = RandomDisplacement (stepsize = stepsize , random_gen = rng )
676
+ displace = RandomDisplacement (stepsize = stepsize , rng = rng )
694
677
take_step_wrapped = AdaptiveStepsize (displace , interval = interval ,
695
678
accept_rate = target_accept_rate ,
696
679
factor = stepwise_factor ,
@@ -704,7 +687,7 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
704
687
accept_tests = [accept_test ]
705
688
706
689
# use default
707
- metropolis = Metropolis (T , random_gen = rng )
690
+ metropolis = Metropolis (T , rng = rng )
708
691
accept_tests .append (metropolis )
709
692
710
693
if niter_success is None :
0 commit comments