27
27
28
28
def line_search_armijo (
29
29
f , xk , pk , gfk , old_fval , args = (), c1 = 1e-4 ,
30
- alpha0 = 0.99 , alpha_min = None , alpha_max = None , nx = None , ** kwargs
30
+ alpha0 = 0.99 , alpha_min = 0. , alpha_max = None , nx = None , ** kwargs
31
31
):
32
32
r"""
33
33
Armijo linesearch function that works with matrices
@@ -56,7 +56,7 @@ def line_search_armijo(
56
56
:math:`c_1` const in armijo rule (>0)
57
57
alpha0 : float, optional
58
58
initial step (>0)
59
- alpha_min : float, optional
59
+ alpha_min : float, default=0.
60
60
minimum value for alpha
61
61
alpha_max : float, optional
62
62
maximum value for alpha
@@ -89,6 +89,14 @@ def line_search_armijo(
89
89
fc = [0 ]
90
90
91
91
def phi (alpha1 ):
92
+ # it's necessary to check boundary condition here for the coefficient
93
+ # as the callback could be evaluated for negative value of alpha by
94
+ # `scalar_search_armijo` function here:
95
+ #
96
+ # https://github.com/scipy/scipy/blob/11509c4a98edded6c59423ac44ca1b7f28fba1fd/scipy/optimize/linesearch.py#L686
97
+ #
98
+ # see more details https://github.com/PythonOT/POT/issues/502
99
+ alpha1 = np .clip (alpha1 , alpha_min , alpha_max )
92
100
# The callable function operates on nx backend
93
101
fc [0 ] += 1
94
102
alpha10 = nx .from_numpy (alpha1 )
@@ -109,13 +117,12 @@ def phi(alpha1):
109
117
110
118
derphi0 = np .sum (pk * gfk ) # Quickfix for matrices
111
119
alpha , phi1 = scalar_search_armijo (
112
- phi , phi0 , derphi0 , c1 = c1 , alpha0 = alpha0 )
120
+ phi , phi0 , derphi0 , c1 = c1 , alpha0 = alpha0 , amin = alpha_min )
113
121
114
122
if alpha is None :
115
123
return 0. , fc [0 ], nx .from_numpy (phi0 , type_as = xk0 )
116
124
else :
117
- if alpha_min is not None or alpha_max is not None :
118
- alpha = np .clip (alpha , alpha_min , alpha_max )
125
+ alpha = np .clip (alpha , alpha_min , alpha_max )
119
126
return nx .from_numpy (alpha , type_as = xk0 ), fc [0 ], nx .from_numpy (phi1 , type_as = xk0 )
120
127
121
128
0 commit comments