diff --git a/Project.toml b/Project.toml index 69fcdf4..87295f3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CompositionalNetworks" uuid = "4b67e4b5-442d-4ef5-b760-3f5df3a57537" authors = ["Jean-François Baffier"] -version = "0.1.0" +version = "0.1.1" [deps] ConstraintDomains = "5800fd60-8556-4464-8d61-84ebf7a0bedb" diff --git a/src/comparison.jl b/src/comparison.jl index be1dea8..a3c23f3 100644 --- a/src/comparison.jl +++ b/src/comparison.jl @@ -2,65 +2,69 @@ _co_identity(x::Number) Identity function. Already defined in Julia as `identity`, specialized for scalars in the `comparison` layer. """ -_co_identity(x) = identity(x) +_co_identity(x; param=nothing, dom_size=0, nvars=0) = identity(x) """ _co_abs_diff_val_param(x, param) Return the absolute difference between `x` and `param`. """ -_co_abs_diff_val_param(x, param) = abs(x - param) +_co_abs_diff_val_param(x; param, dom_size=0, nvars=0) = abs(x - param) """ _co_val_minus_param(x, param) _co_param_minus_val(x, param) Return the difference `x - param` (resp. `param - x`) if positive, `0.0` otherwise. """ -_co_val_minus_param(x, param) = max(0.0, x - param) -_co_param_minus_val(x, param) = max(0.0, param - x) +_co_val_minus_param(x; param, dom_size=0, nvars=0) = max(0.0, x - param) +_co_param_minus_val(x; param, dom_size=0, nvars=0) = max(0.0, param - x) """ _co_euclidian_param(x, param, ds) _co_euclidian(x, ds) Compute an euclidian norm with domain size `ds`, possibly weigthed by `param`, on a scalar. """ -_co_euclidian_param(x, param, ds) = x == param ? 0.0 : (1.0 + abs(x - param) \ ds) -_co_euclidian(x, ds) = _co_euclidian_param(x, 0.0, ds) +function _co_euclidian_param(x; param, dom_size, nvars=0) + return x == param ? 0.0 : (1.0 + abs(x - param) \ dom_size) +end +function _co_euclidian(x; param=nothing, dom_size, nvars=0) + return _co_euclidian_param(x; param=0.0, dom_size=dom_size) +end """ _co_abs_diff_val_vars(x, nvars) Return the absolute difference between `x` and the number of variables `nvars`. """ -_co_abs_diff_val_vars(x, nvars) = abs(x - nvars) +_co_abs_diff_val_vars(x; param=nothing, dom_size=0, nvars) = abs(x - nvars) """ _co_val_minus_vars(x, nvars) _co_vars_minus_val(x, nvars) Return the difference `x - nvars` (resp. `nvars - x`) if positive, `0.0` otherwise, where `nvars` denotes the numbers of variables. """ -_co_val_minus_vars(x, nvars) = _co_val_minus_param(x, nvars) -_co_vars_minus_val(x, nvars) = _co_param_minus_val(x, nvars) +_co_val_minus_vars(x; param=nothing, dom_size=0, nvars) = _co_val_minus_param(x; param=nvars) +_co_vars_minus_val(x; param=nothing, dom_size=0, nvars) = _co_param_minus_val(x; param=nvars) """ comparison_layer(nvars, dom_size, param = nothing) Generate the layer of transformations functions of the ICN. Iff `param` value is set, also includes all the parametric transformation with that value. """ -function comparison_layer(nvars, dom_size, param = nothing) - comparisons = LittleDict{Symbol, Function}( +function comparison_layer(param=false) + comparisons = LittleDict{Symbol,Function}( :identity => _co_identity, - :euclidian => (x -> _co_euclidian(x, dom_size)), - :abs_diff_val_vars => (x -> _co_abs_diff_val_vars(x, nvars)), - :val_minus_vars => (x -> _co_val_minus_vars(x, nvars)), - :vars_minus_val => (x -> _co_vars_minus_val(x, nvars)), + :euclidian => _co_euclidian, + :abs_diff_val_vars => _co_abs_diff_val_vars, + :val_minus_vars => _co_val_minus_vars, + :vars_minus_val => _co_vars_minus_val, ) - if !isnothing(param) - comparisons_param = LittleDict{Symbol, Function}( - :abs_diff_val_param => (x -> _co_abs_diff_val_param(x, param)), - :val_minus_param => (x -> _co_val_minus_param(x, param)), - :param_minus_val => (x -> _co_param_minus_val(x, param)), - :euclidian_param => (x -> _co_euclidian_param(x, param, dom_size)), + if param + comparisons_param = LittleDict{Symbol,Function}( + :abs_diff_val_param => _co_abs_diff_val_param, + :val_minus_param => _co_val_minus_param, + :param_minus_val => _co_param_minus_val, + :euclidian_param => _co_euclidian_param, ) - comparisons = LittleDict{Symbol, Function}(union(comparisons, comparisons_param)) + comparisons = LittleDict{Symbol,Function}(union(comparisons, comparisons_param)) end return Layer(comparisons, true) diff --git a/src/genetic.jl b/src/genetic.jl index ab7dc40..8da0038 100644 --- a/src/genetic.jl +++ b/src/genetic.jl @@ -12,17 +12,17 @@ end _loss(X, X_sols, icn, weigths, metric) Compute the loss of `icn`. """ -function _loss(X, X_sols, icn, weigths, metric) +function _loss(X, X_sols, icn, weigths, metric, dom_size, param) f = compose(icn, weigths) - return sum(x -> abs(f(x) - metric(x, X_sols)), X) + regularization(icn) + return (sum(x -> abs(f(x; param = param, dom_size = dom_size) - metric(x, X_sols)), X) + regularization(icn)) end """ _optimize!(icn, X, X_sols; metric = hamming, pop_size = 200) Optimize and set the weigths of an ICN with a given set of configuration `X` and solutions `X_sols`. """ -function _optimize!(icn, X, X_sols; metric=hamming, pop_size=200, iter=100) - fitness = weigths -> _loss(X, X_sols, icn, weigths, metric) +function _optimize!(icn, X, X_sols, dom_size, param=nothing; metric=hamming, pop_size=200, iter=100) + fitness = weigths -> _loss(X, X_sols, icn, weigths, metric, dom_size, param) _icn_ga = GA( populationSize=pop_size, @@ -44,12 +44,14 @@ end Optimize and set the weigths of an ICN with a given set of configuration `X` and solutions `X_sols`. The best weigths among `global_iter` will be set. """ -function optimize!(icn, X, X_sols, global_iter, local_iter; metric=hamming, popSize=100) +function optimize!(icn, X, X_sols, global_iter, local_iter, dom_size, param=nothing; metric=hamming, popSize=100) results = Dictionary{BitVector,Int}() @info "Starting optimization of weights" for i in 1:global_iter @info "Iteration $i" - _optimize!(icn, X, X_sols; iter = local_iter, metric = metric, pop_size = popSize) + _optimize!(icn, X, X_sols, dom_size, param; + iter=local_iter, metric=metric, pop_size=popSize + ) _incsert!(results, _weigths(icn)) end best = rand(findall(x -> x == maximum(results), results)) diff --git a/src/icn.jl b/src/icn.jl index b3dfb03..1eb5569 100644 --- a/src/icn.jl +++ b/src/icn.jl @@ -16,12 +16,12 @@ mutable struct ICN comparison::Layer weigths::BitVector - function ICN(; nvars, dom_size, - param=nothing, + function ICN(; + param=false, tr_layer=transformation_layer(param), ar_layer=arithmetic_layer(), ag_layer=aggregation_layer(), - co_layer=comparison_layer(nvars, dom_size, param), + co_layer=comparison_layer(param), ) w = _generate_weights([tr_layer, ar_layer, ag_layer, co_layer]) new(tr_layer, ar_layer, ag_layer, co_layer, w) @@ -91,7 +91,7 @@ _generate_weights(icn::ICN) = _generate_weights(_layers(icn)) Internal function called by `compose` and `show_composition`. """ function _compose(icn::ICN) - !_is_viable(icn) && (return (_ -> typemax(Float64)), []) + !_is_viable(icn) && (return ((x; param=nothing, dom_size=0) -> typemax(Float64)), []) funcs = Vector{Vector{Function}}() symbols = Vector{Vector{Symbol}}() @@ -124,7 +124,7 @@ function _compose(icn::ICN) end l = length(funcs[1]) - composition = x -> fill(x, l) .|> funcs[1] |> funcs[2][1] |> funcs[3][1] |> funcs[4][1] + composition = (x; param=nothing, dom_size) -> fill(x, l) .|> map(f -> (y -> f(y; param=param)), funcs[1]) |> funcs[2][1] |> funcs[3][1] |> (y -> funcs[4][1](y; param=param, dom_size=dom_size, nvars=length(x))) return composition, symbols end @@ -133,12 +133,12 @@ end compose(icn, weights) Return a function composed by some of the operations of a given ICN. Can be applied to any vector of variables. If `weights` are given, will assign to `icn`. """ -function compose(icn::ICN; action = :composition) +function compose(icn::ICN; action=:composition) return action == :symbols ? _compose(icn)[2] : _compose(icn)[1] end -function compose(icn, weigths; action = :composition) +function compose(icn, weigths; action=:composition) _weigths!(icn, weigths) - compose(icn; action = action) + compose(icn; action=action) end """ @@ -146,7 +146,7 @@ end Return the composition (weights) of an ICN. """ function show_composition(icn) - symbs = compose(icn, action = :symbols) + symbs = compose(icn, action=:symbols) aux = map(s -> _reduce_symbols(s, ", ", length(s) > 1), symbs) return _reduce_symbols(aux, " ∘ ", false) end diff --git a/src/learn.jl b/src/learn.jl index b709f05..0f006b9 100644 --- a/src/learn.jl +++ b/src/learn.jl @@ -37,12 +37,12 @@ end ) Create an ICN, optimize it, and return its composition. """ -function learn_compose(X, X_sols; nvars, dom_size, param=nothing, +function learn_compose(X, X_sols, dom_size, param=nothing; global_iter=10, local_iter=100, metric=hamming, popSize=200, action=:composition ) - icn = ICN(nvars=nvars, dom_size=dom_size, param=param) - optimize!(icn, X, X_sols, global_iter, local_iter; metric=metric, popSize=200) + icn = ICN(param=!isnothing(param)) + optimize!(icn, X, X_sols, global_iter, local_iter, dom_size, param; metric=metric, popSize=200) @info show_composition(icn) return compose(icn, action=action) @@ -52,13 +52,12 @@ function explore_learn_compose(concept; domains, param=nothing, search=:complete, global_iter=10, local_iter=100, metric=hamming, popSize=200, action=:composition, ) + dom_size = maximum(_length, domains) if search == :complete X_sols, X = _complete_search_space(domains, concept) union!(X, X_sols) - return learn_compose(X, X_sols; - nvars=length(domains), dom_size=maximum(_length, domains), - local_iter=local_iter, global_iter=global_iter, param=param, - action=action) + return learn_compose(X, X_sols, dom_size, param; + local_iter=local_iter, global_iter=global_iter, action=action) end end @@ -67,10 +66,10 @@ function _compose_to_string(symbols, name) tr_length = length(symbols[1]) CN = "CompositionalNetworks." - tr = _reduce_symbols(symbols[1], ", "; prefix = CN * "_tr_") - ar = _reduce_symbols(symbols[2], ", ", false; prefix = CN * "_ar_") - ag = _reduce_symbols(symbols[3], ", ", false; prefix = CN * "_ag_") - co = _reduce_symbols(symbols[4], ", ", false; prefix = CN * "_co_") + tr = _reduce_symbols(symbols[1], ", "; prefix=CN * "_tr_") + ar = _reduce_symbols(symbols[2], ", ", false; prefix=CN * "_ar_") + ag = _reduce_symbols(symbols[3], ", ", false; prefix=CN * "_ag_") + co = _reduce_symbols(symbols[4], ", ", false; prefix=CN * "_co_") julia_string = """ $name = x -> fill(x, $tr_length) .|> $tr |> $ar |> $ag |> $co diff --git a/src/transformation.jl b/src/transformation.jl index 85b3648..3b4265d 100644 --- a/src/transformation.jl +++ b/src/transformation.jl @@ -3,8 +3,8 @@ _tr_identity(x) Identity function. Already defined in Julia as `identity`, specialized for vectors and scalars. """ -_tr_identity(x) = identity(x) -_tr_identity(i, x) = identity(i) +_tr_identity(x; param=nothing) = identity(x) +_tr_identity(i, x; param=nothing) = identity(i) """ _tr_count_eq(i, x) @@ -12,9 +12,9 @@ _tr_identity(i, x) = identity(i) _tr_count_eq_left(i, x) Count the number of elements equal to `x[i]` (optionally to the right/left of `x[i]`). Extended method to vector `x` are generated. """ -_tr_count_eq(i, x) = count(y -> x[i] == y, x) - 1 -_tr_count_eq_right(i, x) = _tr_count_eq(1, @view x[i:end]) -_tr_count_eq_left(i, x) = _tr_count_eq(i, @view x[1:i]) +_tr_count_eq(i, x; param=nothing) = count(y -> x[i] == y, x) - 1 +_tr_count_eq_right(i, x; param=nothing) = _tr_count_eq(1, @view x[i:end]) +_tr_count_eq_left(i, x; param=nothing) = _tr_count_eq(i, @view x[1:i]) # Generating vetorized versions lazy(_tr_count_eq, _tr_count_eq_left, _tr_count_eq_right) @@ -28,12 +28,12 @@ lazy(_tr_count_eq, _tr_count_eq_left, _tr_count_eq_right) _tr_count_l_right(i, x) Count the number of elements greater/lesser than `x[i]` (optionally to the left/right of `x[i]`). Extended method to vector with sig `(x)` are generated. """ -_tr_count_greater(i, x) = count(y -> x[i] < y, x) -_tr_count_lesser(i, x) = count(y -> x[i] > y, x) -_tr_count_g_left(i, x) = _tr_count_greater(i, @view x[1:i]) -_tr_count_l_left(i, x) = _tr_count_lesser(i, @view x[1:i]) -_tr_count_g_right(i, x) = _tr_count_greater(1, @view x[i:end]) -_tr_count_l_right(i, x) = _tr_count_lesser(1, @view x[i:end]) +_tr_count_greater(i, x; param=nothing) = count(y -> x[i] < y, x) +_tr_count_lesser(i, x; param=nothing) = count(y -> x[i] > y, x) +_tr_count_g_left(i, x; param=nothing) = _tr_count_greater(i, @view x[1:i]) +_tr_count_l_left(i, x; param=nothing) = _tr_count_lesser(i, @view x[1:i]) +_tr_count_g_right(i, x; param=nothing) = _tr_count_greater(1, @view x[i:end]) +_tr_count_l_right(i, x; param=nothing) = _tr_count_lesser(1, @view x[i:end]) # Generating vetorized versions lazy(_tr_count_greater, _tr_count_g_left, _tr_count_g_right) @@ -45,9 +45,9 @@ lazy(_tr_count_lesser, _tr_count_l_left, _tr_count_l_right) _tr_count_g_param(i, x, param) Count the number of elements equal to (resp. lesser/greater than) `x[i] + param`. Extended method to vector with sig `(x, param)` are generated. """ -_tr_count_eq_param(i, x, param) = count(y -> y == x[i] + param, x) -_tr_count_l_param(i, x, param) = count(y -> y < x[i] + param, x) -_tr_count_g_param(i, x, param) = count(y -> y > x[i] + param, x) +_tr_count_eq_param(i, x; param) = count(y -> y == x[i] + param, x) +_tr_count_l_param(i, x; param) = count(y -> y < x[i] + param, x) +_tr_count_g_param(i, x; param) = count(y -> y > x[i] + param, x) # Generating vetorized versions lazy_param(_tr_count_eq_param, _tr_count_l_param, _tr_count_g_param) @@ -56,7 +56,7 @@ lazy_param(_tr_count_eq_param, _tr_count_l_param, _tr_count_g_param) _tr_count_bounding_param(i, x, param) Count the number of elements bounded (not strictly) by `x[i]` and `x[i] + param`. An extended method to vector with sig `(x, param)` is generated. """ -_tr_count_bounding_param(i, x, param) = count(y -> x[i] ≤ y ≤ x[i] + param, x) +_tr_count_bounding_param(i, x; param) = count(y -> x[i] ≤ y ≤ x[i] + param, x) # Generating vetorized versions lazy_param(_tr_count_bounding_param) @@ -66,8 +66,8 @@ lazy_param(_tr_count_bounding_param) _tr_param_minus_val(i, x, param) Return the difference `x[i] - param` (resp. `param - x[i]`) if positive, `0.0` otherwise. Extended method to vector with sig `(x, param)` are generated. """ -_tr_val_minus_param(i, x, param) = max(0, x[i] - param) -_tr_param_minus_val(i, x, param) = max(0, param - x[i]) +_tr_val_minus_param(i, x; param) = max(0, x[i] - param) +_tr_param_minus_val(i, x; param) = max(0, param - x[i]) # Generating vetorized versions lazy_param(_tr_val_minus_param, _tr_param_minus_val) @@ -77,9 +77,9 @@ lazy_param(_tr_val_minus_param, _tr_param_minus_val) _tr_contiguous_vals_minus_rev(i, x) Return the difference `x[i] - x[i + 1]` (resp. `x[i + 1] - x[i]`) if positive, `0.0` otherwise. Extended method to vector with sig `(x)` are generated. """ -_tr_contiguous_vals_minus(i, x) = length(x) == i ? 0 : _tr_val_minus_param(i, x, x[i + 1]) -function _tr_contiguous_vals_minus_rev(i, x) - return length(x) == i ? 0 : _tr_param_minus_val(i, x, x[i + 1]) +_tr_contiguous_vals_minus(i, x; param=nothing) = length(x) == i ? 0 : _tr_val_minus_param(i, x; param=x[i + 1]) +function _tr_contiguous_vals_minus_rev(i, x; param=nothing) + return length(x) == i ? 0 : _tr_param_minus_val(i, x; param=x[i + 1]) end # Generating vetorized versions lazy(_tr_contiguous_vals_minus, _tr_contiguous_vals_minus_rev) @@ -89,8 +89,8 @@ lazy(_tr_contiguous_vals_minus, _tr_contiguous_vals_minus_rev) transformation_layer(param = nothing) Generate the layer of transformations functions of the ICN. Iff `param` value is set, also includes all the parametric transformation with that value. """ -function transformation_layer(param = nothing) - transformations = LittleDict{Symbol, Function}( +function transformation_layer(param=false) + transformations = LittleDict{Symbol,Function}( :identity => _tr_identity, :count_eq => _tr_count_eq, :count_eq_left => _tr_count_eq_left, @@ -105,14 +105,14 @@ function transformation_layer(param = nothing) :contiguous_vals_minus_rev => _tr_contiguous_vals_minus_rev, ) - if !isnothing(param) - transformations_param = LittleDict{Symbol, Function}( - :count_eq_param => ((x...) -> _tr_count_eq_param(x..., param)), - :count_l_param => ((x...) -> _tr_count_l_param(x..., param)), - :count_g_param => ((x...) -> _tr_count_g_param(x..., param)), - :count_bounding_param => ((x...) -> _tr_count_bounding_param(x..., param)), - :val_minus_param => ((x...) -> _tr_val_minus_param(x..., param)), - :param_minus_val => ((x...) -> _tr_param_minus_val(x..., param)), + if param + transformations_param = LittleDict{Symbol,Function}( + :count_eq_param => _tr_count_eq_param, + :count_l_param => _tr_count_l_param, + :count_g_param => _tr_count_g_param, + :count_bounding_param => _tr_count_bounding_param, + :val_minus_param => _tr_val_minus_param, + :param_minus_val => _tr_param_minus_val, ) transformations = LittleDict(union(transformations, transformations_param)) end diff --git a/src/utils.jl b/src/utils.jl index 85c877a..9f2fd42 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,10 +1,8 @@ """ - _map_tr(f, x) _map_tr(f, x, param) -Return an anonymous function that applies `f` to all elements of `x`, with an optional parameter `param`. +Return an anonymous function that applies `f` to all elements of `x`, with a parameter `param` (which is set to `nothing` for function with no parameter). """ -_map_tr(f, x) = ((g, y) -> map(i -> g(i, y), 1:length(y)))(f, x) -_map_tr(f, x, param) = ((g, y, p) -> map(i -> g(i, y, p), 1:length(y)))(f, x, param) +_map_tr(f, x, p) = ((g, y; param) -> map(i -> g(i, y; param=param), 1:length(y)))(f, x, param=p) """ lazy(funcs::Function...) @@ -12,17 +10,20 @@ _map_tr(f, x, param) = ((g, y, p) -> map(i -> g(i, y, p), 1:length(y)))(f, x, pa Generate methods extended to a vector instead of one of its components. For `lazy` (resp. `lazy_param`) a function `f` should have the following signature: `f(i::Int, x::V)` (resp. `f(i::Int, x::V, param::T)`). """ function lazy(funcs::Function...) - foreach(f -> eval(:($f(x) = (y -> _map_tr($f, y))(x))), map(Symbol, funcs)) + foreach( + f -> eval(:($f(x; param=nothing) = _map_tr($f, x, param))), map(Symbol, funcs) + ) end + function lazy_param(funcs::Function...) - foreach(f -> eval(:($f(x, param) = (y -> _map_tr($f, y, param))(x))), map(Symbol, funcs)) + foreach(f -> eval(:($f(x; param) = _map_tr($f, x, param))), map(Symbol, funcs)) end """ _as_bitvector(n::Int, max_n::Int = n) Convert an Int to a BitVector of minimal size (relatively to `max_n`). """ -function _as_bitvector(n::Int, max_n::Int = n) +function _as_bitvector(n::Int, max_n::Int=n) nm1 = n - 1 v = falses(ceil(Int, log2(max_n))) i = 0 @@ -64,8 +65,8 @@ end _reduce_symbols(symbols, sep) Produce a formatted string that separates the symbols by `sep`. Used internally for `show_composition`. """ -function _reduce_symbols(symbols, sep, parenthesis = true; prefix = "") - str = reduce((x,y) -> "$y$sep$x", map(s -> "$prefix$s", symbols)) +function _reduce_symbols(symbols, sep, parenthesis=true; prefix="") + str = reduce((x, y) -> "$y$sep$x", map(s -> "$prefix$s", symbols)) return parenthesis ? "[$str]" : str end diff --git a/test/icn.jl b/test/icn.jl index 3f0eef5..628c415 100644 --- a/test/icn.jl +++ b/test/icn.jl @@ -1,5 +1,5 @@ # # Test with manually weighted ICN -icn = ICN(nvars=4, dom_size=4, param=2) +icn = ICN(param=true) show_layers(icn) icn.weigths = vcat(trues(18), falses(6)) @test CN._is_viable(icn) @@ -10,12 +10,12 @@ f = compose(icn) " contiguous_vals_minus_rev, contiguous_vals_minus, count_l_right, count_g_right" * ", count_l_left, count_g_left, count_lesser, count_greater, count_eq_right, " * "count_eq_left, count_eq, identity]" v = [1,2,4,3] -@test f(v) == 67 +@test f(v; param=2, dom_size=4) == 67 ## Test GA and exploration doms = [domain([1,2,3,4]) for i in 1:4] -err = explore_learn_compose(allunique, domains = doms) -@test err([1,2,3,3]) > 0.0 +err = explore_learn_compose(allunique, domains=doms) +@test err([1,2,3,3], dom_size = 4) > 0.0 ## Test export to file compose_to_file!(icn, "all_different", "test_dummy.jl") \ No newline at end of file diff --git a/test/layers.jl b/test/layers.jl index cc3f669..1b5e202 100644 --- a/test/layers.jl +++ b/test/layers.jl @@ -95,8 +95,8 @@ funcs_param = Dict( for (f, results) in funcs_param @info f for (key, vals) in enumerate(data) - @test f(vals.first, vals.second) == results[key] - foreach(i -> f(i, vals.first, vals.second), vals.first) + @test f(vals.first; param=vals.second) == results[key] + foreach(i -> f(i, vals.first; param=vals.second), vals.first) end end @@ -140,7 +140,7 @@ funcs_param = [ for (f, results) in funcs_param @info f for (key, vals) in enumerate(data) - @test f(vals.first, vals.second[1]) == results[key] + @test f(vals.first; param=vals.second[1]) == results[key] end end @@ -153,7 +153,7 @@ funcs_vars = [ for (f, results) in funcs_vars @info f for (key, vals) in enumerate(data) - @test f(vals.first, vals.second[2]) == results[key] + @test f(vals.first, nvars=vals.second[2]) == results[key] end end @@ -164,7 +164,7 @@ funcs_param_dom = [ for (f, results) in funcs_param_dom @info f for (key, vals) in enumerate(data) - @test f(vals.first, vals.second[1], vals.second[2]) ≈ results[key] + @test f(vals.first, param=vals.second[1], dom_size=vals.second[2]) ≈ results[key] end end @@ -175,6 +175,6 @@ funcs_dom = [ for (f, results) in funcs_dom @info f for (key, vals) in enumerate(data) - @test f(vals.first, vals.second[2]) ≈ results[key] + @test f(vals.first, dom_size=vals.second[2]) ≈ results[key] end end