-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parameter Set Constraints #8
Comments
What your are looking for looks like a CSP solver With Python, there is
I don't know if there is project like this written in Julia. I also wonder if https://github.com/JuliaOpt/JuMP.jl have such feature (or more generally https://github.com/JuliaOpt ) See http://nbviewer.jupyter.org/github/JuliaOpt/juliaopt-notebooks/tree/master/notebooks/ for some sample notebooks python-constraint is "only" 1500 lines of code |
A simpler approach with with parameter_generator() = Channel(ctype=Tuple{Int,Int}) do c
for short in 1:10
for long in 1:10
if short < long
push!(c, (short, long))
end
end
end
end
for (i, param) in enumerate(parameter_generator())
short, long = param
println("i=$i short=$short long=$long")
end or with parameter_generator() = Channel(ctype=Dict{String,Int}) do c
for short in 1:10
for long in 1:10
if short < long
push!(c, Dict("short"=>short, "long"=>long))
end
end
end
end
for (i, param) in enumerate(parameter_generator())
short = param["short"]
long = param["long"]
println("i=$i short=$short long=$long")
end it displays:
Using NamedTuples could also be considered |
Code updated with NamedTuples (from https://github.com/JuliaData/NamedTuples.jl ) mutable struct ParameterSet
arg_names::Vector{Symbol}
arg_defaults::Vector
arg_ranges::Vector
arg_types::Vector{<:Type}
n_args::Int
constraints::Vector{Function}
function ParameterSet(arg_names::Vector{Symbol},
arg_defaults::Vector,
arg_ranges::Vector=[x:x for x in arg_defaults],
constraints=Vector{Function}())
@assert length(arg_names) == length(arg_defaults) == length(arg_ranges)
@assert eltype.(arg_defaults) == eltype.(arg_ranges)
arg_types::Vector{<:Type} = eltype.(arg_defaults)
return new(arg_names, arg_defaults, arg_ranges, arg_types, length(arg_names), constraints)
end
end
import Base: length
length(ps::ParameterSet) = mapreduce(length, *, 1, ps.arg_ranges) # inspired by IterTools.jl length(p::Product)
abstract type ParameterIteration end
struct CartesianProductIteration <: ParameterIteration
end
using IterTools
using NamedTuples: make_tuple
function get_iterator(ps::ParameterSet, method::CartesianProductIteration)
itr = IterTools.product(ps.arg_ranges...)
itr = map(t->make_tuple(ps.arg_names)(t...), itr)
#itr = map(t->NamedTuple{Tuple(ps.arg_names)}(t...), itr) # see https://github.com/JuliaData/NamedTuples.jl/issues/53
for constraint in ps.constraints
itr = Iterators.filter(constraint, itr)
end
itr
end
using Base.Test
# write your own tests here
@testset "Main tests" begin
arg_names = [:real1, :real2]
arg_defaults = [0.5, 0.05]
arg_ranges = [0.01:0.01:0.99, 0.01:0.01:0.99]
#constraints = [
# p -> p[1] + p[2] < 1.0,
# p -> p[1] + p[2] > 0.5
#]
constraints = [
p -> p.real1 + p.real2 < 1.0,
p -> p.real1 + p.real2 > 0.5
]
ps = ParameterSet(arg_names, arg_defaults, arg_ranges, constraints)
@test length(ps) == 9801 # 99*99
itr_method = CartesianProductIteration()
#itr_method = RandomIteration()
itr = get_iterator(ps, itr_method)
#for p in itr
# println(p)
#end
v = collect(itr)
#println(v)
@test length(v) == 3626
end
@testset "Other test" begin
arg_names = [:short, :long]
arg_defaults = [1, 1]
arg_ranges = [1:10, 1:10]
#constraints = [
# p -> p[1] < p[2]
#]
constraints = [
p -> p.short < p.long
]
ps = ParameterSet(arg_names, arg_defaults, arg_ranges, constraints)
@test length(ps) == 100 # 10*10
itr_method = CartesianProductIteration()
#itr_method = RandomIteration()
itr = get_iterator(ps, itr_method)
v = collect(itr)
@test length(v) == 45
end |
When defining a
ParameterSet
object with ranges corresponding to each of its variables (i.e. thearg_ranges
member), currently there isn't any way to constrain the parameter space using the relationships between the variables.There should be logic to support these kinds of inter-variable relationship constraints. For example, take a simple strategy using two moving averages, one with a short lookback period and one with a long lookback period. Suppose our rule is to go long when the short MA crosses over the long MA, and we want to simulate this strategy over a bunch of pairs of lookback windows. There should be logic to constrain the simulation such that the short MA's lookback must be less than the long MA's lookback.
The text was updated successfully, but these errors were encountered: