OperatorCombination: Self-Adaptive Operator Combinations

OperatorCombinationR Documentation

Self-Adaptive Operator Combinations

Description

Combines multiple operators and makes operator-configuration parameters self-adaptive.

The OperatorCombination operators combine operators for different subspaces of individuals by wraping other MiesOperators given during construction. Different MiesOperators are assigned to different components or sets of components and operate on them independently of the rest of the components or the other operators. An operator can be assigned to a single component by giving it in operators with the name of the component, or to multiple components by giving it in operators with the name of a group. Groups are created by the groups argument, but several default groups that catch components by type exist.

Details

Operators can be made self-adaptive by coupling their configuration parameter values to values in individuals. This is done by giving functions in adaptions; these functions are executed for each individual before an operator is applied, and the result given to a named operator configuration parameter.

OperatorCombination is the base class from which MutatorCombination and RecombinatorCombination inherit. The latter two are to be used for Mutator and Recombinator objects, respectively.

Besides groups created with the groups construction argument, there are special groups that all unnamed operators fall into based on their Domain class: "ParamInt", "ParamDbl", "ParamFct", and "ParamLgl". A component of an individual that is not named directly in operators or made part of a group in groups is automatically in one of these special groups. There is furthermore a special catch-all group "ParamAny", which catches all components that are are not operated directly, not in a group, and not in another special group that is itself named directly or in a group. I.e., all components that would otherwise have no assigned operation.

RecombinatorCombination can only combine operators where ⁠$n_indivs_in⁠ and ⁠$n_indivs_out⁠ can be combined. This is currently supported either when ⁠$n_indivs_in⁠ and ⁠$n_indivs_out⁠ for each operator are the same (but ⁠$n_indivs_in⁠ may be unequal ⁠$n_indivs_out⁠ in eacho of them); or when ⁠$n_indivs_in⁠ is equal to ⁠$n_indivs_out⁠ for each operator and the set of all ⁠$n_indivs_in⁠ that occur contains 1 and one more integer. ⁠$n_indivs_in⁠ and ⁠$n_indivs_out⁠ for the resulting RecombinatorCombination operator will be set the maximum of occuring ⁠$n_indivs_in⁠ and ⁠$n_indivs_out⁠, respectively.

Supported Operand Types

Supported Domain classes are calculated based on the supported classes of the wrapped operators. They are frequently just the set union of supported classes, unless inference can be drawn from type-specific groups that an operator is assigned to. If e.g. an operator that supports p_dbl and p_int is assigned to group "ParamInt", and an operator that supports p_lgl is assigned to component "a", then the result will support p_lgl and p_int only.

Configuration Parameters

The OperatorCombination has the configuration parameters of all encapsulated MiesOperators, minus the configuration parameters that are named in the adaptions. Configuration parameter names are prefixed with the name of the MiesOperator in the operators list.

Dictionary

This Mutator can be created with the short access form mut() (muts() to get a list), or through the the dictionary dict_mutators in the following way:

# preferred:
mut("combine", <operators>, ...)
muts("combine", <operators>, ...)  # takes vector IDs, returns list of Mutators

# long form:
dict_mutators$get("combine", <operators>, ...)

This Recombinator can be created with the short access form rec() (recs() to get a list), or through the the dictionary dict_recombinators in the following way:

# preferred:
rec("combine", <operators>, ...)
recs("combine", <operators>, ...)  # takes vector IDs, returns list of Recombinators

# long form:
dict_recombinators$get("combine", <operators>, ...)

Super class

miesmuschel::MiesOperator -> OperatorCombination

Active bindings

operators

(named list of MiesOperator)
List of operators to apply to components of individuals, as set during construction. Read-only.

groups

(named list of character)
List of groups that operators can act on, as set during construction. Read-only.

adaptions

(named list of function)
List of functions used for self-adaption of operators, as set during construction. Read-only.

binary_fct_as_logical

(logical(1))
Whether to treat binary p_fct components of ParamSets as p_lgl with respect to the special groups "ParamLgl" and "ParamFct", as set during construction. Read-only.

on_type_not_present

(character(1))
Action to perform during ⁠$prime()⁠ when an operator is assigned to a type special group but there is no component available that falls in this group. See the construction argument. Can be changed during the object's lifetime.

on_name_not_present

(character(1))
Action to perform during ⁠$prime()⁠ when an operator is assigned to a specifically named component, but the component is not present. See the construction argument. Can be changed during the object's lifetime.

Methods

Public methods

Inherited methods

Method new()

Initialize the OperatorCombination object.

Usage
OperatorCombination$new(
  operators,
  groups = list(),
  adaptions = list(),
  binary_fct_as_logical = FALSE,
  on_type_not_present = "warn",
  on_name_not_present = "stop",
  granularity = 1,
  dict_entry = NULL,
  dict_shortaccess = NULL
)
Arguments
operators

(named list of MiesOperator)
List of operators to apply to components of individuals. Names are either names of individual components, or group names which are either as defined through groups or special groups. Individual components can only be member of either a (non-special) group or named in operators, so a name that occurs in operators may not be a member of a group as defined in groups.
The ⁠$operators⁠ field will reflect this value.

groups

(named list of character)
List of groups that operators can act on. Names of this list define new groups. The content of each list element contains the names of components or special groups (a Domain subclass name or "ParamAny") to subsume under the group. Individual components can only be member of either a (non-special) group or named in operators, so a name that occurs in operators may not be a member of a group as defined in groups. The default is the empty list.
The ⁠$groups⁠ field will reflect this value.

adaptions

(named list of function)
List of functions used for self-adaption of operators. The names of the list must be names of configuration parameters of wrapped operators, prefixed with the corresponding name in the operators list. This is the same name as the configuration parameter would otherwise have if exposed by the OperatorCombination object. The values in the list must be functions that receive a single input, the individual or individuals being operated on, as a data.table. It must return a value that is then assigned to the configuration parameter of the operator to which it pertains. Note that MutatorCombination adaption functions are always called with a data.table containing a single row, while RecombinatorCombination adaption functions are called with data.tables with multiple rows according to ⁠$n_indivs_in⁠. In both cases, the return value must be a scalar. The default is the empty list.
The ⁠$adaption⁠ field will reflect this value.

binary_fct_as_logical

(logical(1))
Whether to treat binary p_fct components of ParamSets as p_lgl with respect to the special groups "ParamLgl" and "ParamFct". This does not perform any conversion, so a MiesOperator assigned to the "ParamLgl" special group when binary_fct_as_logical is TRUE and there are binary p_fcts present will receive a factorial value and must also support p_fct in this case. This is checked during ⁠$prime()⁠, but not during construction. Default is FALSE.
The ⁠$binary_fct_as_logical⁠ field will reflect this value.

on_type_not_present

(character(1))
Action to perform during ⁠$prime()⁠ when an operator is assigned to a type special group but there is no component available that falls in this group, either because no components of the respective type are present, or because all these components are also directly named in operators or in groups. One of "quiet" (do nothing), "warn" (give warning, default), or "stop" (generate an error).
The writable ⁠$on_type_not_present⁠ field will reflect this value.

on_name_not_present

(character(1))
Action to perform during ⁠$prime()⁠ when an operator is assigned to a specifically named component, but the component is not present. One of "quiet" (do nothing), "warn" (give warning), or "stop" (generate an error, default).
The writable ⁠$on_name_not_present⁠ field will reflect this value.

granularity

(integer(1))
At what granularity to query adaptions for sets of individuals. Functions in adaptions are always called once per granularity individuals in input values, and the function argument in these calls will then have granularity number of rows. This is used internally, it is set to 1 for MutatorCombination, and to ⁠$n_indivs_in⁠ for RecombinatorCombination.

dict_entry

(character(1) | NULL)
Key of the class inside the Dictionary (usually one of dict_mutators, dict_recombinators, dict_selectors), where it can be retrieved using a short access function. May be NULL if the operator is not entered in a dictionary.
The ⁠$dict_entry⁠ field will reflect this value.

dict_shortaccess

(character(1) | NULL)
Name of the Dictionary short access function in which the operator is registered. This is used to inform the user about how to construct a given object. Should ordinarily be one of "mut", "rec", "sel".
The ⁠$dict_shortaccess⁠ field will reflect this value.


Method prime()

See MiesOperator method. Primes both this operator, as well as the wrapped operators given to operators during construction. Priming of wrapped operators happens according to component assignments to wrapped operators.

Usage
OperatorCombination$prime(param_set)
Arguments
param_set

(ParamSet)
Passed to MiesOperator⁠$prime()⁠.

Returns

invisible self.


Method clone()

The objects of this class are cloneable with this method.

Usage
OperatorCombination$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Super classes

miesmuschel::MiesOperator -> miesmuschel::OperatorCombination -> MutatorCombination

Methods

Public methods

Inherited methods

Method new()

Initialize the MutatorCombination object.

Usage
MutatorCombination$new(
  operators = list(),
  groups = list(),
  adaptions = list(),
  binary_fct_as_logical = FALSE,
  on_type_not_present = "warn",
  on_name_not_present = "stop"
)
Arguments
operators

see above.

groups

see above.

adaptions

see above.

binary_fct_as_logical

see above.

on_type_not_present

see above.

on_name_not_present

see above.


Method clone()

The objects of this class are cloneable with this method.

Usage
MutatorCombination$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Super classes

miesmuschel::MiesOperator -> miesmuschel::OperatorCombination -> RecombinatorCombination

Active bindings

n_indivs_in

(integer(1))
Number of individuals to consider at the same time. When operating, the number of input individuals must be divisible by this number.

n_indivs_out

(integer(1))
Number of individuals produced for each group of ⁠$n_indivs_in⁠ individuals.

Methods

Public methods

Inherited methods

Method new()

Initialize the RecombinatorCombination object.

Usage
RecombinatorCombination$new(
  operators = list(),
  groups = list(),
  adaptions = list(),
  binary_fct_as_logical = FALSE,
  on_type_not_present = "warn",
  on_name_not_present = "stop"
)
Arguments
operators

see above.

groups

see above.

adaptions

see above.

binary_fct_as_logical

see above.

on_type_not_present

see above.

on_name_not_present

see above.


Method clone()

The objects of this class are cloneable with this method.

Usage
RecombinatorCombination$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

See Also

Other base classes: Filtor, FiltorSurrogate, MiesOperator, Mutator, MutatorDiscrete, MutatorNumeric, Recombinator, RecombinatorPair, Scalor, Selector, SelectorScalar

Other mutators: Mutator, MutatorDiscrete, MutatorNumeric, dict_mutators_cmpmaybe, dict_mutators_erase, dict_mutators_gauss, dict_mutators_maybe, dict_mutators_null, dict_mutators_proxy, dict_mutators_sequential, dict_mutators_unif

Other mutator wrappers: dict_mutators_cmpmaybe, dict_mutators_maybe, dict_mutators_proxy, dict_mutators_sequential

Other recombinators: Recombinator, RecombinatorPair, dict_recombinators_cmpmaybe, dict_recombinators_convex, dict_recombinators_cvxpair, dict_recombinators_maybe, dict_recombinators_null, dict_recombinators_proxy, dict_recombinators_sbx, dict_recombinators_sequential, dict_recombinators_swap, dict_recombinators_xonary, dict_recombinators_xounif

Other recombinator wrappers: dict_recombinators_cmpmaybe, dict_recombinators_maybe, dict_recombinators_proxy, dict_recombinators_sequential

Examples

set.seed(1)
data = data.frame(x = 0, y = 0, a = TRUE, b = "a",
  stringsAsFactors = FALSE)  # necessary for R <= 3.6
p = ps(x = p_dbl(-1, 1), y = p_dbl(-1, 1), a = p_lgl(), b = p_fct(c("a", "b")))

# Demo operators:
m0 = mut("null")  # no mutation
msmall = mut("gauss", sdev = 0.1)  # mutates to small value around 0
mbig = mut("gauss", sdev = 100)  # likely mutates to +1 or -1
mflip = mut("unif", can_mutate_to_same = FALSE)  # flips TRUE/"a" to FALSE/"b"

# original:
data

# operators by name
op = mut("combine", operators = list(x = msmall, y = mbig, a = m0, b = mflip))
op$prime(p)
op$operate(data)

# operators by type
op = mut("combine",
  operators = list(ParamDbl = msmall, ParamLgl = m0, ParamFct = mflip)
)
op$prime(p)
op$operate(data)

# the binary ParamFct 'b' counts as 'ParamLgl' when
# 'binary_fct_as_logical' is set to 'TRUE'.
op = mut("combine",
  operators = list(ParamDbl = msmall, ParamLgl = m0),
  binary_fct_as_logical = TRUE
)
op$prime(p)
op$operate(data)

# operators by type; groups can be mixed types
op = mut("combine",
  operators = list(group1 = m0, group2 = msmall, group3 = mflip),
  groups = list(group1 = c("a", "x"), group2 = "y", group3 = "b")
)
op$prime(p)
op$operate(data)

# Special type-groups can be used inside groups.
op = mut("combine",
  operators = list(group1 = m0, b = mflip),
  groups = list(group1 = c("ParamDbl", "a"))
)
op$prime(p)
op$operate(data)

# Type-groups only capture all parameters that were not caught by name.
# The special 'ParamAny' group captures all that is left.
op = mut("combine",
  operators = list(ParamAny = m0, ParamDbl = msmall, x = mbig)
)
op$prime(p)
op$operate(data)

# Configuration parameters are named by names in the 'operators' list.
op$param_set

###
# Self-adaption:
# In this example, the 'ParamDbl''s operation is changed depending on the
# value of 'b'.
op = mut("combine",
  operators = list(ParamAny = m0, ParamLgl = mflip, ParamDbl = msmall),
  adaptions = list(ParamDbl.sdev = function(x) if (x$a) 100 else 0.1)
)
op$prime(p)

data2 = data[c(1, 1, 1, 1), ]
data2$a = c(TRUE, TRUE, FALSE, FALSE)

data2
# Note the value of x$a gets used line-wise, and that it is used *before*
# being flipped here. So the first two lines get large mutations, even though
# they have 'a' 'FALSE' after the operation.
op$operate(data2)

miesmuschel documentation built on Sept. 11, 2024, 8:23 p.m.