55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
![]() |
'''
|
||
|
This module calculates the reduction ratio for trust-region methods.
|
||
|
|
||
|
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 .consts import DEBUGGING, REALMAX
|
||
|
import numpy as np
|
||
|
|
||
|
def redrat(ared, pred, rshrink):
|
||
|
'''
|
||
|
This function evaluates the reduction ratio of a trust-region step, handling inf/nan properly.
|
||
|
'''
|
||
|
|
||
|
# Preconditions
|
||
|
if DEBUGGING:
|
||
|
assert rshrink >= 0
|
||
|
|
||
|
#====================#
|
||
|
# Calculation starts #
|
||
|
#====================#
|
||
|
|
||
|
if np.isnan(ared):
|
||
|
# This should not happen in unconstrained problems due to the moderated extreme barrier.
|
||
|
ratio = -REALMAX
|
||
|
elif np.isnan(pred) or pred <= 0:
|
||
|
# The trust-region subproblem solver fails in this rare case. Instead of terminating as Powell's
|
||
|
# original code does, we set ratio as follows so that the solver may continue to progress.
|
||
|
if ared > 0:
|
||
|
# The trial point will be accepted, but the trust-region radius will be shrunk if rshrink>0
|
||
|
ratio = rshrink/2
|
||
|
else:
|
||
|
# Set the ration to a large negative number to signify a bad trust-region step, so that the
|
||
|
# solver will check whether to take a geometry step or reduce rho.
|
||
|
ratio = -REALMAX
|
||
|
elif np.isposinf(pred) and np.isposinf(ared):
|
||
|
ratio = 1 # ared/pred = NaN if calculated directly
|
||
|
elif np.isposinf(pred) and np.isneginf(ared):
|
||
|
ratio = -REALMAX # ared/pred = NaN if calculated directly
|
||
|
else:
|
||
|
ratio = ared/pred
|
||
|
|
||
|
#==================#
|
||
|
# Calculation ends #
|
||
|
#==================#
|
||
|
|
||
|
# Postconditions
|
||
|
if DEBUGGING:
|
||
|
assert not np.isnan(ratio)
|
||
|
return ratio
|