ratio.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. '''
  2. This module calculates the reduction ratio for trust-region methods.
  3. Translated from Zaikun Zhang's modern-Fortran reference implementation in PRIMA.
  4. Dedicated to late Professor M. J. D. Powell FRS (1936--2015).
  5. Python translation by Nickolai Belakovski.
  6. '''
  7. from .consts import DEBUGGING, REALMAX
  8. import numpy as np
  9. def redrat(ared, pred, rshrink):
  10. '''
  11. This function evaluates the reduction ratio of a trust-region step, handling inf/nan properly.
  12. '''
  13. # Preconditions
  14. if DEBUGGING:
  15. assert rshrink >= 0
  16. #====================#
  17. # Calculation starts #
  18. #====================#
  19. if np.isnan(ared):
  20. # This should not happen in unconstrained problems due to the moderated extreme barrier.
  21. ratio = -REALMAX
  22. elif np.isnan(pred) or pred <= 0:
  23. # The trust-region subproblem solver fails in this rare case. Instead of terminating as Powell's
  24. # original code does, we set ratio as follows so that the solver may continue to progress.
  25. if ared > 0:
  26. # The trial point will be accepted, but the trust-region radius will be shrunk if rshrink>0
  27. ratio = rshrink/2
  28. else:
  29. # Set the ration to a large negative number to signify a bad trust-region step, so that the
  30. # solver will check whether to take a geometry step or reduce rho.
  31. ratio = -REALMAX
  32. elif np.isposinf(pred) and np.isposinf(ared):
  33. ratio = 1 # ared/pred = NaN if calculated directly
  34. elif np.isposinf(pred) and np.isneginf(ared):
  35. ratio = -REALMAX # ared/pred = NaN if calculated directly
  36. else:
  37. ratio = ared/pred
  38. #==================#
  39. # Calculation ends #
  40. #==================#
  41. # Postconditions
  42. if DEBUGGING:
  43. assert not np.isnan(ratio)
  44. return ratio