Coverage for moptipy / operators / op0_forward.py: 95%

21 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-24 08:49 +0000

1""" 

2A nullary operator forwarding to another function. 

3 

4This is a nullary operator (an instance of 

5:class:`~moptipy.api.operators.Op0`) whose method 

6:meth:`~moptipy.api.operators.Op0.op0` forwards to another `Callable`. 

7This other `Callable` can then return a solution that is created in some 

8special way, or maybe even the current best solution of a search process. 

9 

10This operator has been designed to be used in conjunction with 

11:func:`~moptipy.api.subprocesses.from_starting_point`, which is an 

12optimization :class:`~moptipy.api.process.Process` where a starting point 

13has been defined, i.e., where the methods 

14:meth:`~moptipy.api.process.Process.get_copy_of_best_x` and 

15:meth:`~moptipy.api.process.Process.get_best_f` return pre-defined values. 

16By setting :meth:`~moptipy.operators.op0_forward.Op0Forward.forward_to` to 

17:meth:`~moptipy.api.process.Process.get_copy_of_best_x`, this nullary operator 

18will return the current-best solution of the optimization process, which, in 

19this case, will be the pre-defined starting point. 

20Any optimization algorithm (e.g., an instance of 

21:class:`~moptipy.api.algorithm.Algorithm0`) using this nullary operator to get 

22its initial solution will then begin the search at this pre-defined starting 

23point. This allows using one algorithm as a sub-algorithm of another one. 

24Wrapping :func:`~moptipy.api.subprocesses.from_starting_point` around the 

25result of a call to :func:`~moptipy.api.subprocesses.for_fes` would allow to 

26limit the number of objective function evaluations consumed by the 

27sub-algorithm. 

28""" 

29from typing import Any, Callable 

30 

31import numpy as np 

32from numpy.random import Generator 

33from pycommons.types import type_error 

34 

35from moptipy.api.operators import Op0 

36 

37 

38class Op0Forward(Op0): 

39 """A nullary operator that forwards all calls to `op0` to a `Callable`.""" 

40 

41 def __init__(self): 

42 """Initialize this operator.""" 

43 #: the internal blueprint for filling permutations 

44 self.__call: Callable[[Any], None] | None = None 

45 

46 def op0(self, random: Generator, dest: np.ndarray) -> None: 

47 """ 

48 Forward the call. 

49 

50 :param random: ignored 

51 :param dest: the destination data structure to be filled with the data 

52 of the point in the search space by the internal `Callable` set by 

53 :meth:`forward_to`. 

54 """ 

55 self.__call(dest) 

56 

57 def forward_to(self, call: Callable[[Any], None]) -> None: 

58 """ 

59 Set the `Callable` to forward all calls from :meth:`op0` to. 

60 

61 :param call: the `Callable` to which all calls to :meth:`op0` should 

62 be delegated to. 

63 """ 

64 if not callable(call): 

65 raise type_error(call, "call", call=True) 

66 self.__call = call 

67 

68 def stop_forwarding(self) -> None: 

69 """Stop forwarding the call.""" 

70 self.__call = None 

71 

72 def __str__(self) -> str: 

73 """ 

74 Get the name of this operator. 

75 

76 :return: "forward" 

77 """ 

78 return "forward" 

79 

80 def initialize(self) -> None: 

81 """Initialize this operator by stopping to forward.""" 

82 super().initialize() 

83 self.stop_forwarding()