diff --git a/cgp/cartesian_graph.py b/cgp/cartesian_graph.py index 3cab1afc..bbbc4064 100644 --- a/cgp/cartesian_graph.py +++ b/cgp/cartesian_graph.py @@ -52,8 +52,7 @@ def __init__(self, genome: "Genome") -> None: """ self._n_inputs: int self._n_outputs: int - self._n_columns: int - self._n_rows: int + self._n_hidden_units: int self._nodes: List self._parameter_names_to_values: Dict[str, float] @@ -82,29 +81,18 @@ def empty_node_str() -> str: s = "\n" - for row in range(max(self._n_inputs, self._n_rows)): - for column in range(-1, self._n_columns + 1): - - if column == -1: - if row < self._n_inputs: - s += pretty_node_str(self.input_nodes[row]) - else: - s += empty_node_str() - s += "\t" - - elif column < self._n_columns: - if row < self._n_rows: - s += pretty_node_str(self.hidden_nodes[row + column * self._n_rows]) - else: - s += empty_node_str() - s += "\t" - else: - if row < self._n_outputs: - s += pretty_node_str(self.output_nodes[row]) - else: - s += empty_node_str() - s += "\t" + for idx in range(self._n_inputs + self._n_hidden_units + self._n_outputs): + if idx < self._n_inputs: + s += pretty_node_str(self.input_nodes[idx]) + + elif idx < self._n_inputs + self._n_hidden_units: + s += pretty_node_str(self.hidden_nodes[idx - self._n_inputs]) + else: + s += pretty_node_str( + self.output_nodes[idx - self._n_inputs - self._n_hidden_units] + ) + s += "\t" s += "\n" return s @@ -115,8 +103,7 @@ def parse_genome(self, genome: "Genome") -> None: self._n_inputs = genome._n_inputs self._n_outputs = genome._n_outputs - self._n_columns = genome._n_columns - self._n_rows = genome._n_rows + self._n_hidden_units = genome._n_hidden_units self._parameter_names_to_values = copy.deepcopy(genome._parameter_names_to_values) self._nodes = [] @@ -137,7 +124,7 @@ def parse_genome(self, genome: "Genome") -> None: self._determine_active_nodes() def _hidden_column_idx(self, idx: int) -> int: - return (idx - self._n_inputs) // self._n_rows + return idx - self._n_inputs @property def input_nodes(self) -> List[Node]: diff --git a/cgp/genome.py b/cgp/genome.py index db72b9be..b4a4b77f 100644 --- a/cgp/genome.py +++ b/cgp/genome.py @@ -28,10 +28,8 @@ def __init__( self, n_inputs: int = 1, n_outputs: int = 1, - n_columns: int = 128, - n_rows: int = 1, + n_hidden_units: int = 128, primitives: Optional[Tuple[Type[Node], ...]] = None, - levels_back: Optional[int] = None, ) -> None: """Init function. @@ -41,41 +39,24 @@ def __init__( Number of inputs of the function represented by the genome. Defaults to 1. n_outputs : int, optional Number of outputs of the function represented by the genome. Defaults to 1. - n_columns : int, optional - Number of columns in the representation of the genome. Defaults to 12. - n_rows : int, optional - Number of rows in the representation of the genome. Defaults to 1. + n_hidden_units : int, optional + Number of hidden units in the representation of the genome. Defaults to 128. primitives : Tuple[Type[Node], ...], optional Tuple of primitives that the genome can refer to. Defaults to (+, -, *, 1.0). - levels_back : Optional[int], optional - Maximal column distance of inputs to an internal node. If - set to `None`, no restrictions are used. Defaults to None. """ if n_inputs <= 0: raise ValueError("n_inputs must be strictly positive") self._n_inputs = n_inputs - if n_columns < 0: + if n_hidden_units < 0: raise ValueError("n_columns must be non-negative") - self._n_columns = n_columns - - if n_rows < 0: - raise ValueError("n_rows must be non-negative") - self._n_rows = n_rows + self._n_hidden_units = n_hidden_units if n_outputs <= 0: raise ValueError("n_outputs must be strictly positive") self._n_outputs = n_outputs - if levels_back is None: - levels_back = n_columns - if levels_back == 0 and n_columns != 0: - raise ValueError("levels_back must be strictly positive") - if levels_back > n_columns: - raise ValueError("levels_back can not be larger than n_columns") - self._levels_back = levels_back - if primitives is None: # we need to delay this import to avoid circular imports: node_impl # -> node -> node_validation -> genome @@ -128,7 +109,7 @@ def dna(self, value: List[int]) -> None: @property def _n_hidden(self) -> int: - return self._n_columns * self._n_rows + return self._n_hidden_units @property def _n_regions(self) -> int: @@ -267,9 +248,7 @@ def randomize(self, rng: np.random.RandomState) -> None: # add hidden nodes for i in range(self._n_hidden): - if i % self._n_rows == 0: # only compute permissible addresses once per column - permissible_addresses = self._permissible_addresses(i + self._n_inputs) - + permissible_addresses = self._permissible_addresses(i + self._n_inputs) dna += self._create_random_hidden_region(rng, permissible_addresses) # add output nodes @@ -312,7 +291,7 @@ def splice_dna(self, new_dna: List[int], hidden_start_node: int = 0) -> int: if hidden_start_node < 0 or hidden_start_node > self._n_hidden: raise ValueError("hidden_start_node must be non-negative and smaller than n_hidden") - if hidden_start_node + n_inserted_nodes >= self._n_hidden: + if hidden_start_node + n_inserted_nodes > self._n_hidden: raise ValueError("New dna too long") dna = self.dna @@ -409,10 +388,6 @@ def reorder(self, rng: np.random.RandomState) -> None: ---------- None """ - if (self._n_rows != 1) or (self._levels_back != self._n_columns): - raise ValueError( - "Genome reordering is only implemented for n_rows=1" " and levels_back=n_columns" - ) dna = self._dna.copy() @@ -501,9 +476,7 @@ def _update_address_genes(self, dna: List[int], used_node_indices: List[int]) -> def _replace_invalid_address_alleles(self, dna: List[int], rng: np.random.RandomState) -> None: """Replace invalid alleles for unused address genes of all nodes by random permissible values. - WARNING: Works only if self.n_rows==1. """ - assert self._n_rows == 1 for gene_idx, gene_value in enumerate(dna): region_idx = self._get_region_idx(gene_idx) @@ -578,22 +551,22 @@ def _permissible_addresses(self, region_idx: int) -> List[int]: # all nodes can be connected to input permissible_addresses += [j for j in range(0, self._n_inputs)] - # add all nodes reachable according to levels back + # add all nodes reachable if self._is_hidden_region(region_idx): - hidden_column_idx = self._hidden_column_idx(region_idx) - lower = self._n_inputs + self._n_rows * max(0, (hidden_column_idx - self._levels_back)) - upper = self._n_inputs + self._n_rows * hidden_column_idx + hidden_idx = self._hidden_idx(region_idx) + lower = self._n_inputs + upper = self._n_inputs + hidden_idx else: assert self._is_output_region(region_idx) lower = self._n_inputs - upper = self._n_inputs + self._n_rows * self._n_columns + upper = self._n_inputs + self._n_hidden_units permissible_addresses += [j for j in range(lower, upper)] return permissible_addresses def _permissible_addresses_for_output_region(self) -> List[int]: - return self._permissible_addresses(self._n_inputs + self._n_rows * self._n_columns) + return self._permissible_addresses(self._n_inputs + self._n_hidden_units) def _validate_dna(self, dna: List[int]) -> None: @@ -635,13 +608,13 @@ def _validate_dna(self, dna: List[int]) -> None: if output_region[2:] != [self._id_unused_gene] * (self._primitives.max_arity - 1): raise ValueError("inactive address genes for output nodes need to be empty") - def _hidden_column_idx(self, region_idx: int) -> int: + def _hidden_idx(self, region_idx: int) -> int: assert self._n_inputs <= region_idx - assert region_idx < self._n_inputs + self._n_rows * self._n_columns - hidden_column_idx = (region_idx - self._n_inputs) // self._n_rows - assert 0 <= hidden_column_idx - assert hidden_column_idx < self._n_columns - return hidden_column_idx + assert region_idx < self._n_inputs + self._n_hidden_units + hidden_idx = region_idx - self._n_inputs + assert 0 <= hidden_idx + assert hidden_idx < self._n_hidden_units + return hidden_idx def iter_input_regions( self, dna: Optional[List[int]] = None @@ -788,12 +761,7 @@ def clone(self) -> "Genome": """ new = Genome( - self._n_inputs, - self._n_outputs, - self._n_columns, - self._n_rows, - tuple(self._primitives), - self._levels_back, + self._n_inputs, self._n_outputs, self._n_hidden_units, tuple(self._primitives) ) new.dna = self.dna.copy() diff --git a/cgp/node_validation.py b/cgp/node_validation.py index aea9dbc6..4444f6c5 100644 --- a/cgp/node_validation.py +++ b/cgp/node_validation.py @@ -27,7 +27,7 @@ def _create_genome(cls: Type["OperatorNode"]) -> "Genome": from .genome import ID_INPUT_NODE, ID_NON_CODING_GENE, ID_OUTPUT_NODE, Genome primitives = (cls,) - genome = Genome(1, 1, 1, 1, primitives) + genome = Genome(1, 1, 1, primitives) dna = [ID_INPUT_NODE] arity = max(cls._arity, 1) for _ in range(arity): diff --git a/examples/example_caching.py b/examples/example_caching.py index e4f2cb1c..ecc73138 100644 --- a/examples/example_caching.py +++ b/examples/example_caching.py @@ -63,7 +63,6 @@ def objective(individual): return individual -# %% # Finally, we call the `evolve` method to perform the evolutionary search. diff --git a/examples/example_differential_evo_regression.py b/examples/example_differential_evo_regression.py index aaa04a13..fc0e7e47 100644 --- a/examples/example_differential_evo_regression.py +++ b/examples/example_differential_evo_regression.py @@ -97,8 +97,6 @@ def objective(individual, seed): seed = 1234 genome_params = {"primitives": (cgp.Add, cgp.Sub, cgp.Mul, cgp.Parameter)} -# apply local search only to the top two individuals -ea_params = {"k_local_search": 2} evolve_params = {"max_generations": int(args["--max-generations"]), "termination_fitness": -1e-8} diff --git a/examples/example_evo_regression.py b/examples/example_evo_regression.py index af184a2a..65908f5d 100644 --- a/examples/example_evo_regression.py +++ b/examples/example_evo_regression.py @@ -128,9 +128,7 @@ def evolution(f_target): genome_params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 12, - "n_rows": 2, - "levels_back": 5, + "n_hidden_units": 12, "primitives": (cgp.Add, cgp.Sub, cgp.Mul, cgp.Div, cgp.ConstantFloat), } diff --git a/examples/example_evo_regression_numpy.py b/examples/example_evo_regression_numpy.py index a26bb759..7ffa1848 100644 --- a/examples/example_evo_regression_numpy.py +++ b/examples/example_evo_regression_numpy.py @@ -122,9 +122,7 @@ def evolution(f_target): genome_params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 12, - "n_rows": 2, - "levels_back": 5, + "n_hidden_units": 12, "primitives": (cgp.Add, cgp.Sub, cgp.Mul, cgp.Div, cgp.ConstantFloat), } diff --git a/examples/example_fec_caching.py b/examples/example_fec_caching.py index 7a44617e..91b3908b 100644 --- a/examples/example_fec_caching.py +++ b/examples/example_fec_caching.py @@ -77,7 +77,6 @@ def objective(individual): return individual -# %% # Finally, we call the `evolve` method to perform the evolutionary search. diff --git a/examples/example_local_search_evolution_strategies.py b/examples/example_local_search_evolution_strategies.py index 1f6d99f6..da6f28d6 100644 --- a/examples/example_local_search_evolution_strategies.py +++ b/examples/example_local_search_evolution_strategies.py @@ -84,7 +84,7 @@ def objective(individual, seed): seed = 1234 genome_params = { - "n_columns": 36, + "n_hidden_units": 36, "primitives": (cgp.Add, cgp.Sub, cgp.Mul, cgp.Parameter), } diff --git a/examples/example_parametrized_nodes.py b/examples/example_parametrized_nodes.py index cb13f020..93a429fc 100644 --- a/examples/example_parametrized_nodes.py +++ b/examples/example_parametrized_nodes.py @@ -104,7 +104,7 @@ def objective(individual, seed): genome_params = { "n_inputs": 2, - "n_columns": 5, + "n_hidden_units": 5, "primitives": (ParametrizedAdd, cgp.Add, cgp.Sub, cgp.Mul), } diff --git a/test/conftest.py b/test/conftest.py index 383cbcf1..362e701d 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -31,9 +31,7 @@ def genome_params(): return { "n_inputs": 2, "n_outputs": 1, - "n_columns": 3, - "n_rows": 3, - "levels_back": 2, + "n_hidden_units": 3, "primitives": (cgp.Add, cgp.Sub, cgp.ConstantFloat), } diff --git a/test/test_cartesian_graph.py b/test/test_cartesian_graph.py index 0d71ab7d..d1b96f9c 100644 --- a/test/test_cartesian_graph.py +++ b/test/test_cartesian_graph.py @@ -9,7 +9,7 @@ def test_to_func_simple(): primitives = (cgp.Add,) - genome = cgp.Genome(2, 1, 1, 1, primitives) + genome = cgp.Genome(2, 1, 1, primitives) genome.dna = [ ID_INPUT_NODE, @@ -34,7 +34,7 @@ def test_to_func_simple(): assert x[0] + x[1] == pytest.approx(y) primitives = (cgp.Sub,) - genome = cgp.Genome(2, 1, 1, 1, primitives) + genome = cgp.Genome(n_inputs=2, n_outputs=1, n_hidden_units=1, primitives=primitives) genome.dna = [ ID_INPUT_NODE, @@ -61,7 +61,7 @@ def test_to_func_simple(): def test_compile_two_columns(): primitives = (cgp.Add, cgp.Sub) - genome = cgp.Genome(2, 1, 2, 1, primitives, 1) + genome = cgp.Genome(n_inputs=2, n_outputs=1, n_hidden_units=2, primitives=primitives) genome.dna = [ ID_INPUT_NODE, @@ -89,58 +89,15 @@ def test_compile_two_columns(): assert x[0] - (x[0] + x[1]) == pytest.approx(y) -def test_compile_two_columns_two_rows(): - primitives = (cgp.Add, cgp.Sub) - genome = cgp.Genome(2, 2, 2, 2, primitives, 1) - - genome.dna = [ - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - 0, - 0, - 1, - 1, - 0, - 1, - 0, - 0, - 2, - 0, - 2, - 3, - ID_OUTPUT_NODE, - 4, - ID_NON_CODING_GENE, - ID_OUTPUT_NODE, - 5, - ID_NON_CODING_GENE, - ] - graph = cgp.CartesianGraph(genome) - f = graph.to_func() - - x = [5.0, 2.0] - y = f(*x) - - assert x[0] + (x[0] + x[1]) == pytest.approx(y[0]) - assert (x[0] + x[1]) + (x[0] - x[1]) == pytest.approx(y[1]) - - def test_compile_addsubmul(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 2, "n_rows": 2, "levels_back": 1} + params = { + "n_inputs": 2, + "n_outputs": 1, + "n_columns": 3, + } primitives = (cgp.Add, cgp.Sub, cgp.Mul) - genome = cgp.Genome( - params["n_inputs"], - params["n_outputs"], - params["n_columns"], - params["n_rows"], - primitives, - params["levels_back"], - ) + genome = cgp.Genome(params["n_inputs"], params["n_outputs"], params["n_columns"], primitives) genome.dna = [ ID_INPUT_NODE, ID_NON_CODING_GENE, @@ -151,15 +108,12 @@ def test_compile_addsubmul(): 2, 0, 1, - 1, + 0, 0, 1, 1, 2, 3, - 0, - 0, - 0, ID_OUTPUT_NODE, 4, ID_NON_CODING_GENE, @@ -170,12 +124,12 @@ def test_compile_addsubmul(): x = [5.0, 2.0] y = f(*x) - assert (x[0] * x[1]) - (x[0] - x[1]) == pytest.approx(y) + assert (x[0] * x[1]) - (x[0] + x[1]) == pytest.approx(y) def test_to_numpy(rng): primitives = (cgp.Add, cgp.Mul, cgp.ConstantFloat) - genome = cgp.Genome(1, 1, 2, 2, primitives, 1) + genome = cgp.Genome(n_inputs=1, n_outputs=1, n_hidden_units=3, primitives=primitives) # f(x) = x ** 2 + 1. genome.dna = [ ID_INPUT_NODE, @@ -190,9 +144,6 @@ def test_to_numpy(rng): 0, 1, 2, - 0, - 0, - 1, ID_OUTPUT_NODE, 3, ID_NON_CODING_GENE, @@ -209,7 +160,9 @@ def test_to_numpy(rng): batch_sizes = [1, 10] primitives = (cgp.Mul, cgp.ConstantFloat) -genome = [cgp.Genome(1, 1, 2, 2, primitives, 1) for i in range(2)] +genome = [ + cgp.Genome(n_inputs=1, n_outputs=1, n_hidden_units=2, primitives=primitives) for i in range(2) +] # Function: f(x) = 1*x genome[0].dna = [ ID_INPUT_NODE, @@ -218,17 +171,11 @@ def test_to_numpy(rng): 1, 0, 0, - 1, - 0, - 0, - 0, - 0, - 1, 0, 0, 1, ID_OUTPUT_NODE, - 3, + 2, ID_NON_CODING_GENE, ] # Function: f(x) = 1 @@ -242,18 +189,14 @@ def test_to_numpy(rng): 1, 0, 0, - 0, - 0, - 1, - 0, - 0, - 1, ID_OUTPUT_NODE, 1, ID_NON_CODING_GENE, ] -genome += [cgp.Genome(1, 2, 2, 2, primitives, 1) for i in range(2)] +genome += [ + cgp.Genome(n_inputs=1, n_outputs=2, n_hidden_units=3, primitives=primitives) for i in range(2) +] # Function: f(x) = (1*x, 1*1) genome[2].dna = [ ID_INPUT_NODE, @@ -262,9 +205,6 @@ def test_to_numpy(rng): 1, 0, 0, - 1, - 0, - 0, 0, 0, 1, @@ -272,10 +212,10 @@ def test_to_numpy(rng): 1, 1, ID_OUTPUT_NODE, - 3, + 2, ID_NON_CODING_GENE, ID_OUTPUT_NODE, - 4, + 3, ID_NON_CODING_GENE, ] # Function: f(x) = (1, x*x) @@ -286,9 +226,6 @@ def test_to_numpy(rng): 1, 0, 0, - 1, - 0, - 0, 0, 1, 1, @@ -299,7 +236,7 @@ def test_to_numpy(rng): 1, ID_NON_CODING_GENE, ID_OUTPUT_NODE, - 3, + 2, ID_NON_CODING_GENE, ] @@ -332,7 +269,7 @@ def test_to_sympy(rng): sympy = pytest.importorskip("sympy") primitives = (cgp.Add, cgp.ConstantFloat) - genome = cgp.Genome(1, 1, 2, 2, primitives, 1) + genome = cgp.Genome(n_inputs=1, n_outputs=1, n_hidden_units=3, primitives=primitives) # f = x_0 + x_0 + 1.0 genome.dna = [ @@ -348,9 +285,6 @@ def test_to_sympy(rng): 0, 1, 2, - 0, - 0, - 1, ID_OUTPUT_NODE, 3, ID_NON_CODING_GENE, @@ -373,7 +307,7 @@ def test_allow_sympy_expr_with_infinities(): pytest.importorskip("sympy") primitives = (cgp.Sub, cgp.Div) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(n_inputs=1, n_outputs=1, n_hidden_units=2, primitives=primitives) # x[0] / (x[0] - x[0]) genome.dna = [ @@ -401,21 +335,18 @@ def test_allow_powers_of_x_0(): pytest.importorskip("sympy") primitives = (cgp.Sub, cgp.Mul) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(n_inputs=1, n_outputs=1, n_hidden_units=1, primitives=primitives) # x[0] ** 2 genome.dna = [ ID_INPUT_NODE, ID_NON_CODING_GENE, ID_NON_CODING_GENE, - 0, - 0, - 0, 1, 0, 0, ID_OUTPUT_NODE, - 2, + 1, ID_NON_CODING_GENE, ] graph = cgp.CartesianGraph(genome) @@ -424,7 +355,7 @@ def test_allow_powers_of_x_0(): def test_input_dim_python(rng): - genome = cgp.Genome(2, 1, 1, 1, (cgp.ConstantFloat,)) + genome = cgp.Genome(n_inputs=2, n_outputs=1, n_hidden_units=1, primitives=(cgp.ConstantFloat,)) genome.randomize(rng) f = cgp.CartesianGraph(genome).to_func() @@ -442,7 +373,7 @@ def test_input_dim_python(rng): def test_input_dim_numpy(rng): - genome = cgp.Genome(2, 1, 1, 1, (cgp.ConstantFloat,)) + genome = cgp.Genome(2, 1, 1, (cgp.ConstantFloat,)) genome.randomize(rng) f = cgp.CartesianGraph(genome).to_numpy() @@ -465,7 +396,7 @@ def test_input_dim_numpy(rng): def test_input_dim_torch(rng): torch = pytest.importorskip("torch") - genome = cgp.Genome(2, 1, 1, 1, (cgp.ConstantFloat,)) + genome = cgp.Genome(2, 1, 1, (cgp.ConstantFloat,)) genome.randomize(rng) f = cgp.CartesianGraph(genome).to_torch() @@ -487,7 +418,7 @@ def test_input_dim_torch(rng): def test_pretty_str(): primitives = (cgp.Sub, cgp.Mul) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(1, 1, 2, primitives) # x[0] ** 2 genome.dna = [ @@ -516,73 +447,6 @@ def test_pretty_str(): assert node.__class__.__name__ in pretty_str -def test_pretty_str_with_unequal_inputs_rows_outputs(): - primitives = (cgp.Add,) - - # less rows than inputs/outputs - genome = cgp.Genome(1, 1, 1, 2, primitives) - # f(x) = x[0] + x[0] - genome.dna = [ - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - 0, - 0, - 0, - 0, - 0, - 0, - ID_OUTPUT_NODE, - 1, - ID_NON_CODING_GENE, - ] - graph = cgp.CartesianGraph(genome) - - expected_pretty_str = """ -00 * InputNode \t01 * Add (00,00) \t03 * OutputNode (01) \t - \t02 Add \t \t -""" - assert graph.pretty_str() == expected_pretty_str - - # more rows than inputs/outputs - genome = cgp.Genome(3, 3, 1, 2, primitives) - # f(x) = [x[0] + x[1], x[0] + x[1], x[1] + x[2]] - genome.dna = [ - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - ID_INPUT_NODE, - ID_NON_CODING_GENE, - ID_NON_CODING_GENE, - 0, - 0, - 1, - 0, - 1, - 2, - ID_OUTPUT_NODE, - 3, - ID_NON_CODING_GENE, - ID_OUTPUT_NODE, - 3, - ID_NON_CODING_GENE, - ID_OUTPUT_NODE, - 4, - ID_NON_CODING_GENE, - ] - graph = cgp.CartesianGraph(genome) - - expected_pretty_str = """ -00 * InputNode \t03 * Add (00,01) \t05 * OutputNode (03) \t -01 * InputNode \t04 * Add (01,02) \t06 * OutputNode (03) \t -02 * InputNode \t \t07 * OutputNode (04) \t -""" - assert graph.pretty_str() == expected_pretty_str - - def test_repr(rng, genome_params): genome = cgp.Genome(**genome_params) genome.randomize(rng) diff --git a/test/test_ea_mu_plus_lambda.py b/test/test_ea_mu_plus_lambda.py index 2bf0868c..0bb2afed 100644 --- a/test/test_ea_mu_plus_lambda.py +++ b/test/test_ea_mu_plus_lambda.py @@ -119,9 +119,7 @@ def objective(ind): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, - "levels_back": None, + "n_hidden_units": 1, "primitives": (cgp.Parameter,), } diff --git a/test/test_genome.py b/test/test_genome.py index 34ae3b47..abe57b7d 100644 --- a/test/test_genome.py +++ b/test/test_genome.py @@ -9,11 +9,11 @@ def test_check_dna_consistency(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Add,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) genome.dna = [ ID_INPUT_NODE, @@ -169,16 +169,15 @@ def test_check_dna_consistency(): def test_permissible_addresses(rng): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 4, "n_rows": 3, "levels_back": 2} + params = { + "n_inputs": 2, + "n_outputs": 1, + "n_hidden_units": 4, + } primitives = (cgp.Add,) genome = cgp.Genome( - params["n_inputs"], - params["n_outputs"], - params["n_columns"], - params["n_rows"], - primitives, - params["levels_back"], + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) genome.randomize(rng) @@ -187,30 +186,25 @@ def test_permissible_addresses(rng): with pytest.raises(AssertionError): genome._permissible_addresses(region_idx) - expected_for_hidden = [ - [0, 1], - [0, 1, 2, 3, 4], - [0, 1, 2, 3, 4, 5, 6, 7], - [0, 1, 5, 6, 7, 8, 9, 10], - ] + expected_for_hidden = [[0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]] - for column_idx in range(params["n_columns"]): - region_idx = params["n_inputs"] + params["n_rows"] * column_idx + for column_idx in range(params["n_hidden_units"]): + region_idx = params["n_inputs"] + column_idx assert expected_for_hidden[column_idx] == genome._permissible_addresses(region_idx) - expected_for_output = list(range(params["n_inputs"] + params["n_rows"] * params["n_columns"])) + expected_for_output = list(range(params["n_inputs"] + params["n_hidden_units"])) for output_idx in range(params["n_outputs"]): - region_idx = params["n_inputs"] + params["n_rows"] * params["n_columns"] + output_idx + region_idx = params["n_inputs"] + params["n_hidden_units"] + output_idx assert expected_for_output == genome._permissible_addresses(region_idx) def test_region_iterators(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Add,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) genome.dna = [ ID_INPUT_NODE, @@ -237,47 +231,9 @@ def test_region_iterators(): assert region == [ID_OUTPUT_NODE, 0, ID_NON_CODING_GENE] -def test_check_levels_back_consistency(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 4, "n_rows": 3, "levels_back": None} - - primitives = (cgp.Add,) - - params["levels_back"] = 0 - with pytest.raises(ValueError): - cgp.Genome( - params["n_inputs"], - params["n_outputs"], - params["n_columns"], - params["n_rows"], - primitives, - params["levels_back"], - ) - - params["levels_back"] = params["n_columns"] + 1 - with pytest.raises(ValueError): - cgp.Genome( - params["n_inputs"], - params["n_outputs"], - params["n_columns"], - params["n_rows"], - primitives, - params["levels_back"], - ) - - params["levels_back"] = params["n_columns"] - 1 - cgp.Genome( - params["n_inputs"], - params["n_outputs"], - params["n_columns"], - params["n_rows"], - primitives, - params["levels_back"], - ) - - def test_catch_invalid_allele_in_inactive_region(): primitives = (cgp.ConstantFloat,) - genome = cgp.Genome(1, 1, 1, 1, primitives) + genome = cgp.Genome(1, 1, 1, primitives) # should raise error: ConstantFloat node has no addresses, but silent # address gene should still specify valid address @@ -311,7 +267,7 @@ def objective(ind): def test_is_gene_in_input_region(rng): - genome = cgp.Genome(2, 1, 2, 1, (cgp.Add,)) + genome = cgp.Genome(2, 1, 2, (cgp.Add,)) genome.randomize(rng) assert genome._is_gene_in_input_region(0) @@ -319,7 +275,7 @@ def test_is_gene_in_input_region(rng): def test_is_gene_in_hidden_region(rng): - genome = cgp.Genome(2, 1, 2, 1, (cgp.Add,)) + genome = cgp.Genome(2, 1, 2, (cgp.Add,)) genome.randomize(rng) assert genome._is_gene_in_hidden_region(6) @@ -329,7 +285,7 @@ def test_is_gene_in_hidden_region(rng): def test_is_gene_in_output_region(rng): - genome = cgp.Genome(2, 1, 2, 1, (cgp.Add,)) + genome = cgp.Genome(2, 1, 2, (cgp.Add,)) genome.randomize(rng) assert genome._is_gene_in_output_region(12) @@ -339,21 +295,19 @@ def test_is_gene_in_output_region(rng): def test_mutation_rate(rng, mutation_rate): n_inputs = 1 n_outputs = 1 - n_columns = 4 - n_rows = 3 - genome = cgp.Genome(n_inputs, n_outputs, n_columns, n_rows, (cgp.Add, cgp.Sub)) + n_hidden_units = 4 + genome = cgp.Genome(n_inputs, n_outputs, n_hidden_units, (cgp.Add, cgp.Sub)) genome.randomize(rng) - def count_n_immutable_genes(n_inputs, n_outputs, n_rows): + def count_n_immutable_genes(n_inputs, n_outputs): length_per_region = genome.primitives.max_arity + 1 # function gene + address gene n_immutable_genes = n_inputs * length_per_region # none of the input genes are mutable n_immutable_genes += n_outputs * ( length_per_region - 1 ) # only one gene per output can be mutated if n_inputs == 1: - n_immutable_genes += ( - n_rows * genome.primitives.max_arity - ) # address gene in the first (hidden) column can't be mutated + n_immutable_genes += genome.primitives.max_arity + # address gene in the first (hidden) column can't be mutated # if only one input node exists return n_immutable_genes @@ -364,7 +318,7 @@ def count_mutations(dna0, dna1): n_differences += 1 return n_differences - n_immutable_genes = count_n_immutable_genes(n_inputs, n_outputs, n_rows) + n_immutable_genes = count_n_immutable_genes(n_inputs, n_outputs) n_mutations_mean_expected = mutation_rate * (len(genome.dna) - n_immutable_genes) n_mutations_std_expected = np.sqrt( (len(genome.dna) - n_immutable_genes) * mutation_rate * (1 - mutation_rate) @@ -407,24 +361,6 @@ def test_only_silent_mutations(genome_params, mutation_rate, rng): 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, ID_OUTPUT_NODE, 2, ID_NON_CODING_GENE, @@ -466,17 +402,17 @@ def select_gene_indices_non_silent(mutation_rate, rng): def test_permissible_values(genome_params): n_inputs = 2 n_outputs = 1 - n_columns = 3 - n_rows = 3 - levels_back = 2 + n_hidden_units = 3 + # n_rows = 3 + # levels_back = 2 primitives = (cgp.Add, cgp.Sub, cgp.ConstantFloat) - genome = cgp.Genome(n_inputs, n_outputs, n_columns, n_rows, primitives, levels_back) + genome = cgp.Genome(n_inputs, n_outputs, n_hidden_units, primitives) permissible_function_gene_values = np.arange(len(genome._primitives._primitives)) permissible_addresses_first_internal_column = np.array([0, 1]) - permissible_addresses_second_internal_column = np.array([0, 1, 2, 3, 4]) - permissible_addresses_third_internal_column = np.array([0, 1, 2, 3, 4, 5, 6, 7]) - permissible_addresses_output = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + permissible_addresses_second_internal_column = np.array([0, 1, 2]) + permissible_addresses_third_internal_column = np.array([0, 1, 2, 3]) + permissible_addresses_output = np.array([0, 1, 2, 3, 4]) permissible_values_expected = [ np.array(ID_INPUT_NODE), @@ -489,27 +425,9 @@ def test_permissible_values(genome_params): permissible_addresses_first_internal_column, permissible_addresses_first_internal_column, permissible_function_gene_values, - permissible_addresses_first_internal_column, - permissible_addresses_first_internal_column, - permissible_function_gene_values, - permissible_addresses_first_internal_column, - permissible_addresses_first_internal_column, - permissible_function_gene_values, permissible_addresses_second_internal_column, permissible_addresses_second_internal_column, permissible_function_gene_values, - permissible_addresses_second_internal_column, - permissible_addresses_second_internal_column, - permissible_function_gene_values, - permissible_addresses_second_internal_column, - permissible_addresses_second_internal_column, - permissible_function_gene_values, - permissible_addresses_third_internal_column, - permissible_addresses_third_internal_column, - permissible_function_gene_values, - permissible_addresses_third_internal_column, - permissible_addresses_third_internal_column, - permissible_function_gene_values, permissible_addresses_third_internal_column, permissible_addresses_third_internal_column, np.array(ID_OUTPUT_NODE), @@ -543,8 +461,7 @@ def test_genome_reordering_empirically(rng): genome_params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 14, - "n_rows": 1, + "n_hidden_units": 14, "primitives": (cgp.Mul, cgp.Sub, cgp.Add, cgp.ConstantFloat, cgp.Parameter), } @@ -618,40 +535,10 @@ def test_genome_reordering_empirically(rng): assert sympy_expression_after_reorder == sympy_expression -def test_genome_reordering_parameterization_consistency(rng): - - genome_params = { - "n_inputs": 2, - "n_outputs": 1, - "n_columns": 10, - "n_rows": 2, - "primitives": (cgp.Mul, cgp.Sub, cgp.Add, cgp.ConstantFloat), - } - - genome = cgp.Genome(**genome_params) - - with pytest.raises(ValueError): - genome.reorder(rng) - - genome_params = { - "n_inputs": 2, - "n_outputs": 1, - "n_columns": 10, - "n_rows": 1, - "primitives": (cgp.Mul, cgp.Sub, cgp.Add, cgp.ConstantFloat), - "levels_back": 5, - } - - genome = cgp.Genome(**genome_params) - - with pytest.raises(ValueError): - genome.reorder(rng) - - def test_parameters_to_numpy_array(): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 1, 2, 1, primitives) + genome = cgp.Genome(1, 1, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, @@ -684,7 +571,7 @@ def test_parameters_to_numpy_array(): def test_update_parameters_from_numpy_array(): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 1, 2, 1, primitives) + genome = cgp.Genome(1, 1, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, @@ -715,7 +602,7 @@ def test_update_parameters_from_numpy_array(): def test_parameters_numpy_array_consistency(): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 1, 2, 1, primitives) + genome = cgp.Genome(1, 1, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, @@ -752,8 +639,7 @@ def test_ncolumns_zero(rng): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 0, - "n_rows": 1, + "n_hidden_units": 0, "primitives": (cgp.Mul, cgp.Sub, cgp.Add, cgp.ConstantFloat), } genome = cgp.Genome(**genome_params) @@ -786,13 +672,13 @@ def test_splice_dna(genome_params, rng): with pytest.raises(ValueError): [] = genome.splice_dna(new_dna, hidden_start_node=-1) with pytest.raises(ValueError): - [] = genome.splice_dna(new_dna, hidden_start_node=9) # only 9 internal nodes + [] = genome.splice_dna(new_dna, hidden_start_node=3) # only 3 internal nodes address_node = genome.splice_dna(new_dna) assert address_node == 2 # 0 + n_inputs - address_node = genome.splice_dna(new_dna, hidden_start_node=2) - assert address_node == 4 # 2 + n_inputs + address_node = genome.splice_dna(new_dna, hidden_start_node=1) + assert address_node == 3 # 2 + n_inputs dna_insert = [0, 0, 1, 1, 1, 1] address_node = genome.splice_dna(dna_insert) @@ -812,7 +698,7 @@ def test_change_address_gene_of_output_node(genome_params, rng): genome.change_address_gene_of_output_node(new_address=10, output_node_idx=0) genome.change_address_gene_of_output_node(new_address=0, output_node_idx=1) - for new_address in range(9): + for new_address in range(4): genome.change_address_gene_of_output_node(new_address) assert genome.dna[-2] == new_address @@ -832,6 +718,8 @@ def test_change_address_gene_of_output_node(genome_params, rng): def test_set_expression_for_output(genome_params, rng): sympy = pytest.importorskip("sympy") + genome_params["n_hidden_units"] = 4 + genome = cgp.Genome(**genome_params) genome.randomize(rng) @@ -846,6 +734,6 @@ def test_set_expression_for_output(genome_params, rng): genome.set_expression_for_output(new_dna) assert CartesianGraph(genome).to_sympy() == x_0 - x_1 - new_dna = [0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 2, 3] # x_0+x_1; 1.0; 0; x_0+x_1 + 1.0 + new_dna = [0, 0, 1, 2, 0, 0, 0, 2, 3] # x_0+x_1; 1.0; x_0+x_1 + 1.0 genome.set_expression_for_output(new_dna) assert CartesianGraph(genome).to_sympy() == x_0 + x_1 + 1.0 diff --git a/test/test_hl_api.py b/test/test_hl_api.py index 2b6736cf..e78963a9 100644 --- a/test/test_hl_api.py +++ b/test/test_hl_api.py @@ -104,22 +104,8 @@ def f1(x): # contains parameters for two distinct CartesianGraphs as list of # two dicts genome_params = [ - { - "n_inputs": 1, - "n_outputs": 1, - "n_columns": 4, - "n_rows": 2, - "levels_back": 2, - "primitives": (cgp.Add, cgp.Mul), - }, - { - "n_inputs": 2, - "n_outputs": 1, - "n_columns": 2, - "n_rows": 2, - "levels_back": 2, - "primitives": (cgp.Sub, cgp.Mul), - }, + {"n_inputs": 1, "n_outputs": 1, "n_hidden_units": 4, "primitives": (cgp.Add, cgp.Mul),}, + {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 4, "primitives": (cgp.Sub, cgp.Mul),}, ] evolve_params = {"max_generations": 2000, "termination_fitness": -1e-12} diff --git a/test/test_individual.py b/test/test_individual.py index b98eebf3..675985cf 100644 --- a/test/test_individual.py +++ b/test/test_individual.py @@ -12,13 +12,7 @@ Params = namedtuple("Params", ["genome_params", "primitives", "dna", "target_function"]) params_list = [ Params( - genome_params={ - "n_inputs": 1, - "n_outputs": 1, - "n_columns": 2, - "n_rows": 1, - "levels_back": 2, - }, + genome_params={"n_inputs": 1, "n_outputs": 1, "n_hidden_units": 2,}, primitives=(cgp.Add, cgp.Parameter), dna=[ ID_INPUT_NODE, @@ -43,7 +37,7 @@ def _create_genome(genome_params, primitives, dna): - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) genome.dna = dna return genome @@ -85,7 +79,7 @@ def _unpack_genome(individual, individual_type="SingleGenome"): def test_pickle_individual(individual_type): primitives = (cgp.Add,) - genome = cgp.Genome(1, 1, 1, 1, primitives) + genome = cgp.Genome(1, 1, 1, primitives) individual = _create_individual(genome, individual_type=individual_type) with open("individual.pkl", "wb") as f: @@ -167,7 +161,7 @@ def test_individual_with_parameter_numpy(individual_type, params, graph_input_va def test_to_and_from_torch_plus_backprop(individual_type, rng_torch): torch = pytest.importorskip("torch") primitives = (cgp.Mul, cgp.Parameter) - genome = cgp.Genome(1, 1, 2, 2, primitives, 1) + genome = cgp.Genome(1, 1, 4, primitives) # f(x) = c * x genome.dna = [ ID_INPUT_NODE, @@ -233,7 +227,7 @@ def f_target(x): def test_update_parameters_from_torch_class_resets_fitness(individual_type): pytest.importorskip("torch") primitives = (cgp.Mul, cgp.Parameter) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(1, 1, 2, primitives) # f(x) = c * x genome.dna = [ ID_INPUT_NODE, @@ -271,7 +265,7 @@ def test_update_parameters_from_torch_class_does_not_reset_fitness_for_unused_pa ): pytest.importorskip("torch") primitives = (cgp.Mul, cgp.Parameter) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(1, 1, 2, primitives) # f(x) = x ** 2 genome.dna = [ ID_INPUT_NODE, @@ -304,7 +298,7 @@ def test_update_parameters_from_torch_class_does_not_reset_fitness_for_unused_pa @pytest.mark.parametrize("individual_type", ["SingleGenome", "MultiGenome"]) def test_individual_randomize_genome(individual_type, rng): primitives = (cgp.Add, cgp.Mul) - genome = cgp.Genome(1, 1, 2, 1, primitives, 1) + genome = cgp.Genome(1, 1, 2, primitives) genome.randomize(rng) dna_old = list(genome.dna) diff --git a/test/test_local_search.py b/test/test_local_search.py index a7d3b2d5..8721df09 100644 --- a/test/test_local_search.py +++ b/test/test_local_search.py @@ -8,7 +8,7 @@ def test_gradient_based_step_towards_maximum(): torch = pytest.importorskip("torch") primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 1, 1, 1, primitives) + genome = cgp.Genome(1, 1, 1, primitives) # f(x) = c genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] ind = cgp.individual.IndividualSingleGenome(genome) @@ -38,7 +38,7 @@ def test_gradient_based_step_towards_maximum_multi_genome(): torch = pytest.importorskip("torch") primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 1, 1, 1, primitives) + genome = cgp.Genome(1, 1, 1, primitives) # f(x) = c genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] genome2 = genome.clone() diff --git a/test/test_ls_evolution_strategies.py b/test/test_ls_evolution_strategies.py index f1d4cd84..ba9b69cb 100644 --- a/test/test_ls_evolution_strategies.py +++ b/test/test_ls_evolution_strategies.py @@ -7,7 +7,7 @@ def test_step_towards_maximum(rng_seed): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 2, 2, 1, primitives) + genome = cgp.Genome(1, 2, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, @@ -58,7 +58,7 @@ def _objective_convergence_to_maximum(ind): def test_convergence_to_maximum(rng_seed): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 2, 2, 1, primitives) + genome = cgp.Genome(1, 2, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, @@ -88,7 +88,7 @@ def test_convergence_to_maximum(rng_seed): def test_step_towards_maximum_multi_genome(rng_seed): primitives = (cgp.Parameter,) - genome = cgp.Genome(1, 2, 2, 1, primitives) + genome = cgp.Genome(1, 2, 2, primitives) # [f0(x), f1(x)] = [c1, c2] genome.dna = [ ID_INPUT_NODE, diff --git a/test/test_node.py b/test/test_node.py index 8c1d20f5..b35a1ee0 100644 --- a/test/test_node.py +++ b/test/test_node.py @@ -70,11 +70,11 @@ def _test_to_sympy(genome, x, y_target): def test_add(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Add,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) # f(x) = x[0] + x[1] genome.dna = [ @@ -99,11 +99,11 @@ def test_add(): def test_sub(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Sub,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) # f(x) = x[0] - x[1] genome.dna = [ @@ -128,11 +128,11 @@ def test_sub(): def test_mul(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Mul,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) # f(x) = x[0] * x[1] genome.dna = [ @@ -157,11 +157,11 @@ def test_mul(): def test_div(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Div,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) # f(x) = x[0] / x[1] genome.dna = [ @@ -186,11 +186,11 @@ def test_div(): def test_pow(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.Pow,) genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) # f(x) = x[0] ** x[1] genome.dna = [ @@ -215,12 +215,12 @@ def test_pow(): def test_constant_float(): - params = {"n_inputs": 2, "n_outputs": 1, "n_columns": 1, "n_rows": 1} + params = {"n_inputs": 2, "n_outputs": 1, "n_hidden_units": 1} primitives = (cgp.ConstantFloat,) # f(x) = c genome = cgp.Genome( - params["n_inputs"], params["n_outputs"], params["n_columns"], params["n_rows"], primitives, + params["n_inputs"], params["n_outputs"], params["n_hidden_units"], primitives ) genome.dna = [ ID_INPUT_NODE, @@ -243,11 +243,10 @@ def test_parameter(): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (cgp.Parameter,) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = c genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] @@ -266,11 +265,10 @@ class CustomParameter(cgp.Parameter): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (CustomParameter,) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = c genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] @@ -284,11 +282,10 @@ def test_parameter_two_nodes(): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 3, - "n_rows": 1, + "n_hidden_units": 3, } primitives = (cgp.Parameter, cgp.Add) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = c1 + c2 genome.dna = [ ID_INPUT_NODE, @@ -327,11 +324,10 @@ class CustomParameter(cgp.Parameter): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (CustomParameter,) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = c genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] f = cgp.CartesianGraph(genome).to_func() @@ -357,11 +353,10 @@ class DoubleParameter(cgp.OperatorNode): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (DoubleParameter,) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = p + q genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] f = cgp.CartesianGraph(genome).to_func() @@ -377,11 +372,10 @@ class CustomParameter(cgp.Parameter): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (CustomParameter, CustomParameter) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x) = p genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1] genome._parameter_names_to_values[""] = 1.0 @@ -409,11 +403,10 @@ def test_if_else_operator(): genome_params = { "n_inputs": 3, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, + "n_hidden_units": 1, } primitives = (cgp.IfElse,) - genome = cgp.Genome(**genome_params, primitives=primitives) + genome = cgp.Genome(primitives=primitives, **genome_params) # f(x_0, x_1, x_2) = {x_1 if x_0 >= 0, x_2 otherwise} genome.dna = [ @@ -461,7 +454,7 @@ class CustomAdd(cgp.OperatorNode): def test_raise_broken_def_numpy_output(): - with pytest.raises(ValueError): + with pytest.raises(TypeError): class CustomAdd(cgp.OperatorNode): _arity = 2 @@ -519,9 +512,7 @@ class MyScaledAdd(cgp.node.OperatorNode): params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, - "levels_back": 1, + "n_hidden_units": 1, "primitives": primitives, } @@ -563,9 +554,7 @@ class MyScaledAdd(cgp.node.OperatorNode): params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, - "levels_back": 1, + "n_hidden_units": 1, "primitives": primitives, } @@ -609,9 +598,7 @@ class MyScaledAdd(cgp.node.OperatorNode): params = { "n_inputs": 2, "n_outputs": 1, - "n_columns": 1, - "n_rows": 1, - "levels_back": 1, + "n_hidden_units": 1, "primitives": primitives, } diff --git a/test/test_population.py b/test/test_population.py index 729b5b83..8a2e0bbd 100644 --- a/test/test_population.py +++ b/test/test_population.py @@ -81,9 +81,7 @@ def individual_init(ind): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 3, - "n_rows": 1, - "levels_back": None, + "n_hidden_units": 3, "primitives": (cgp.Add, cgp.Sub, cgp.ConstantFloat), } @@ -112,8 +110,7 @@ def test_ncolumns_zero(population_params): genome_params = { "n_inputs": 1, "n_outputs": 1, - "n_columns": 0, - "n_rows": 1, + "n_hidden_units": 0, "primitives": (cgp.Mul, cgp.Sub, cgp.Add, cgp.ConstantFloat), } pop = cgp.Population(**population_params, genome_params=genome_params) diff --git a/test/test_utils.py b/test/test_utils.py index 2b7ae5c8..5fcb306a 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -157,9 +157,7 @@ def test_fec_cache_decorator_with_multiple_inputs_multiple_outputs(genome_params genome_params = { "n_inputs": 2, "n_outputs": 2, - "n_columns": 1, - "n_rows": 1, - "levels_back": None, + "n_hidden_units": 1, "primitives": (cgp.Add, cgp.Sub), } @@ -424,14 +422,14 @@ def test_custom_compute_key_for_disk_cache(individual, rng): tempfile.mkstemp()[1], compute_key=cgp.utils.compute_key_from_numpy_evaluation_and_args ) def inner_objective(ind): - return ind.to_func()(1.0, 2.0) + return ind.to_func()(2.0, 2.0) def my_compute_key(ind): return 0 @cgp.utils.disk_cache(tempfile.mkstemp()[1], compute_key=my_compute_key) def inner_objective_custom_compute_key(ind): - return ind.to_func()(1.0, 2.0) + return ind.to_func()(2.0, 2.0) individual0 = individual.clone() individual0.genome.randomize(rng)