Skip to content

Commit

Permalink
Extracted dom_size and param value from icn construction (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
Azzaare authored Jan 13, 2021
1 parent f5f7665 commit 363f28b
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 98 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
48 changes: 26 additions & 22 deletions src/comparison.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 8 additions & 6 deletions src/genetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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))
Expand Down
18 changes: 9 additions & 9 deletions src/icn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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}}()
Expand Down Expand Up @@ -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

Expand All @@ -133,20 +133,20 @@ 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

"""
show_composition(icn)
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
Expand Down
21 changes: 10 additions & 11 deletions src/learn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand All @@ -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
Expand Down
60 changes: 30 additions & 30 deletions src/transformation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
_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)
_tr_count_eq_right(i, x)
_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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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,
Expand All @@ -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
Expand Down
Loading

0 comments on commit 363f28b

Please sign in to comment.