94 lines
3.4 KiB
Python
94 lines
3.4 KiB
Python
![]() |
'''
|
||
|
This module checks whether to break out of the solver loop.
|
||
|
|
||
|
Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.
|
||
|
|
||
|
Dedicated to late Professor M. J. D. Powell FRS (1936--2015).
|
||
|
|
||
|
Python translation by Nickolai Belakovski.
|
||
|
'''
|
||
|
|
||
|
from .infos import INFO_DEFAULT, NAN_INF_X, NAN_INF_F, FTARGET_ACHIEVED, MAXFUN_REACHED
|
||
|
|
||
|
import numpy as np
|
||
|
|
||
|
def checkbreak_unc(maxfun, nf, f, ftarget, x):
|
||
|
'''
|
||
|
This module checks whether to break out of the solver loop in the unconstrained case.
|
||
|
'''
|
||
|
|
||
|
# Outputs
|
||
|
info = INFO_DEFAULT
|
||
|
|
||
|
# Local variables
|
||
|
srname = "CHECKbreak_UNC"
|
||
|
|
||
|
# Preconditions
|
||
|
assert INFO_DEFAULT not in [NAN_INF_X, NAN_INF_F, FTARGET_ACHIEVED, MAXFUN_REACHED], f'NAN_INF_X, NAN_INF_F, FTARGET_ACHIEVED, and MAXFUN_REACHED differ from INFO_DFT {srname}'
|
||
|
# X does not contain NaN if the initial X does not contain NaN and the subroutines generating
|
||
|
# trust-region/geometry steps work properly so that they never produce a step containing NaN/Inf.
|
||
|
assert not any(np.isnan(x)), f'X does not contain NaN {srname}'
|
||
|
# With the moderated extreme barrier, F cannot be NaN/+Inf.
|
||
|
assert not (any(np.isnan(f)) or any(np.isposinf(f))), f'F is not NaN/+Inf {srname}'
|
||
|
|
||
|
#====================#
|
||
|
# Calculation starts #
|
||
|
#====================#
|
||
|
|
||
|
# Although X should not contain NaN unless there is a bug, we include the following for security.
|
||
|
# X can be Inf, as finite + finite can be Inf numerically.
|
||
|
if any(np.isnan(x)) or any(np.isinf(x)):
|
||
|
info = NAN_INF_X
|
||
|
|
||
|
# Although NAN_INF_F should not happen unless there is a bug, we include the following for security.
|
||
|
if any(np.isnan(f)) or any(np.isposinf(f)):
|
||
|
info = NAN_INF_F
|
||
|
|
||
|
if f <= ftarget:
|
||
|
info = FTARGET_ACHIEVED
|
||
|
|
||
|
if nf >= maxfun:
|
||
|
info = MAXFUN_REACHED
|
||
|
|
||
|
return info
|
||
|
|
||
|
def checkbreak_con(maxfun, nf, cstrv, ctol, f, ftarget, x):
|
||
|
'''
|
||
|
This module checks whether to break out of the solver loop in the constrained case.
|
||
|
'''
|
||
|
|
||
|
# Outputs
|
||
|
info = INFO_DEFAULT
|
||
|
|
||
|
# Local variables
|
||
|
srname = "CHECKbreak_CON"
|
||
|
|
||
|
# Preconditions
|
||
|
assert INFO_DEFAULT not in [NAN_INF_X, NAN_INF_F, FTARGET_ACHIEVED, MAXFUN_REACHED], f'NAN_INF_X, NAN_INF_F, FTARGET_ACHIEVED, and MAXFUN_REACHED differ from INFO_DFT {srname}'
|
||
|
# X does not contain NaN if the initial X does not contain NaN and the subroutines generating
|
||
|
# trust-region/geometry steps work properly so that they never produce a step containing NaN/Inf.
|
||
|
assert not any(np.isnan(x)), f'X does not contain NaN {srname}'
|
||
|
# With the moderated extreme barrier, F or CSTRV cannot be NaN/+Inf.
|
||
|
assert not (np.isnan(f) or np.isposinf(f) or np.isnan(cstrv) or np.isposinf(cstrv)), f'F or CSTRV is not NaN/+Inf {srname}'
|
||
|
|
||
|
#====================#
|
||
|
# Calculation starts #
|
||
|
#====================#
|
||
|
|
||
|
# Although X should not contain NaN unless there is a bug, we include the following for security.
|
||
|
# X can be Inf, as finite + finite can be Inf numerically.
|
||
|
if any(np.isnan(x)) or any(np.isinf(x)):
|
||
|
info = NAN_INF_X
|
||
|
|
||
|
# Although NAN_INF_F should not happen unless there is a bug, we include the following for security.
|
||
|
if np.isnan(f) or np.isposinf(f) or np.isnan(cstrv) or np.isposinf(cstrv):
|
||
|
info = NAN_INF_F
|
||
|
|
||
|
if cstrv <= ctol and f <= ftarget:
|
||
|
info = FTARGET_ACHIEVED
|
||
|
|
||
|
if nf >= maxfun:
|
||
|
info = MAXFUN_REACHED
|
||
|
|
||
|
return info
|