Commit 930ffb7e authored by Brice Videau's avatar Brice Videau

Multidimensional distrib

parent 3ba7aa30
import ctypes as ct
from .base import Object, Error, ccs_error, _ccs_get_function, ccs_context, ccs_hyperparameter, ccs_configuration_space, ccs_configuration, ccs_rng, ccs_distribution, ccs_expression, ccs_datum
from .context import Context
from .distribution import Distribution
from .hyperparameter import Hyperparameter
from .expression import Expression
from .expression_parser import ccs_parser
......@@ -12,6 +13,8 @@ ccs_configuration_space_set_rng = _ccs_get_function("ccs_configuration_space_set
ccs_configuration_space_get_rng = _ccs_get_function("ccs_configuration_space_get_rng", [ccs_configuration_space, ct.POINTER(ccs_rng)])
ccs_configuration_space_add_hyperparameter = _ccs_get_function("ccs_configuration_space_add_hyperparameter", [ccs_configuration_space, ccs_hyperparameter, ccs_distribution])
ccs_configuration_space_add_hyperparameters = _ccs_get_function("ccs_configuration_space_add_hyperparameters", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_hyperparameter), ct.POINTER(ccs_distribution)])
ccs_configuration_space_set_distribution = _ccs_get_function("ccs_configuration_space_set_distribution", [ccs_configuration_space, ccs_distribution, ct.POINTER(ct.c_size_t)])
ccs_configuration_space_get_hyperparameter_distribution = _ccs_get_function("ccs_configuration_space_get_hyperparameter_distribution", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_distribution), ct.POINTER(ct.c_size_t)])
ccs_configuration_space_set_condition = _ccs_get_function("ccs_configuration_space_set_condition", [ccs_configuration_space, ct.c_size_t, ccs_expression])
ccs_configuration_space_get_condition = _ccs_get_function("ccs_configuration_space_get_condition", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression)])
ccs_configuration_space_get_conditions = _ccs_get_function("ccs_configuration_space_get_conditions", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression), ct.POINTER(ct.c_size_t)])
......@@ -71,6 +74,33 @@ class ConfigurationSpace(Context):
res = ccs_configuration_space_add_hyperparameters(self.handle, count, hypers, distribs)
Error.check(res)
def set_distribution(self, distribution, hyperparameters):
count = distribution.dimension
if count != len(hyperparameters):
raise Error(ccs_error(ccs_error.INVALID_VALUE))
hyps = []
for h in hyperparameters:
if isinstance(h, Hyperparameter):
hyps.append(self.hyperparameter_index(h))
elif isinstance(h, str):
hyps.append(self.hyperparameter_index_by_name(h))
else:
hyps.append(h)
v = (ct.c_size_t * count)(*hyps)
res = ccs_configuration_space_set_distribution(self.handle, distribution.handle, v)
Error.check(res)
def get_hyperparameter_distribution(self, hyperparameter):
if isinstance(hyperparameter, Hyperparameter):
hyperparameter = self.hyperparameter_index(hyperparameter)
elif isinstance(hyperparameter, str):
hyperparameter = self.hyperparameter_index_by_name(hyperparameter)
v1 = ccs_distribution()
v2 = ct.c_size_t()
res = ccs_configuration_space_get_hyperparameter_distribution(self.handle, hyperparameter, ct.byref(v1), ct.byref(v2))
Error.check(res)
return [Distribution.from_handle(v1), v2.value]
def set_condition(self, hyperparameter, expression):
if isinstance(expression, str):
expression = ccs_parser.parse(expression, context = PContext(extra=self))
......
......@@ -34,6 +34,31 @@ class TestConfigurationSpace(unittest.TestCase):
for c in cs.samples(100):
cs.check(c)
def test_set_distribution(self):
cs = ccs.ConfigurationSpace(name = "space")
h1 = ccs.NumericalHyperparameter()
h2 = ccs.NumericalHyperparameter()
h3 = ccs.NumericalHyperparameter()
cs.add_hyperparameters([h1, h2, h3])
distributions = [ ccs.UniformDistribution.float(lower = 0.1, upper = 0.3),
ccs.UniformDistribution.float(lower = 0.2, upper = 0.6) ]
d = ccs.MultivariateDistribution(distributions = distributions)
cs.set_distribution(d, [h1, h2])
(dist, indx) = cs.get_hyperparameter_distribution(h1)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 0, indx )
(dist, indx) = cs.get_hyperparameter_distribution(h2)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 1, indx )
cs.set_distribution(d, [h3, h1])
(dist, indx) = cs.get_hyperparameter_distribution(h1)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 1, indx )
(dist, indx) = cs.get_hyperparameter_distribution(h3)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 0, indx )
def test_conditions(self):
h1 = ccs.NumericalHyperparameter(lower = -1.0, upper = 1.0, default = 0.0)
h2 = ccs.NumericalHyperparameter(lower = -1.0, upper = 1.0)
......
......@@ -169,6 +169,39 @@ class TestDistribution(unittest.TestCase):
for v in a:
self.assertTrue( i.include(v) )
def test_create_mixture(self):
distributions = [ ccs.UniformDistribution.float(lower = -5.0, upper = 0.0),
ccs.UniformDistribution.float(lower = 0.0, upper = 2.0) ]
d = ccs.MixtureDistribution(distributions = distributions)
self.assertEqual( d.object_type, ccs.DISTRIBUTION )
self.assertEqual( d.type, ccs.MIXTURE )
self.assertEqual( d.data_types, [ccs.NUM_FLOAT] )
self.assertEqual( d.weights, [0.5, 0.5] )
self.assertEqual( [x.handle.value for x in d.distributions], [x.handle.value for x in distributions] )
d2 = ccs.Object.from_handle(d.handle)
self.assertEqual( d.__class__, d2.__class__ )
def test_create_multivariate(self):
distributions = [ ccs.UniformDistribution.float(lower = -5.0, upper = 0.0),
ccs.UniformDistribution.int(lower = 0, upper = 2) ]
d = ccs.MultivariateDistribution(distributions = distributions)
self.assertEqual( d.object_type, ccs.DISTRIBUTION )
self.assertEqual( d.type, ccs.MULTIVARIATE )
self.assertEqual( d.data_types, [ccs.NUM_FLOAT, ccs.NUM_INTEGER] )
self.assertEqual( [x.handle.value for x in d.distributions], [x.handle.value for x in distributions] )
d2 = ccs.Object.from_handle(d.handle)
self.assertEqual( d.__class__, d2.__class__ )
def test_mixture_multidim(self):
distributions = [ ccs.UniformDistribution.float(lower = -5.0, upper = 0.0),
ccs.UniformDistribution.int(lower = 0, upper = 2) ]
d = ccs.MultivariateDistribution(distributions = distributions)
d2 = ccs.MixtureDistribution(distributions = [d, d])
self.assertEqual( d2.object_type, ccs.DISTRIBUTION )
self.assertEqual( d2.type, ccs.MIXTURE )
self.assertEqual( d2.data_types, [ccs.NUM_FLOAT, ccs.NUM_INTEGER] )
self.assertEqual( d2.weights, [0.5, 0.5] )
if __name__ == '__main__':
unittest.main()
......@@ -35,9 +35,11 @@ module CCS
class MemoryPointer
alias read_ccs_float_t read_double
alias get_ccs_float_t get_double
alias read_array_of_ccs_float_t read_array_of_double
alias write_array_of_ccs_float_t write_array_of_double
alias read_ccs_int_t read_int64
alias get_ccs_int_t get_int64
alias read_array_of_ccs_int_t read_array_of_int64
alias write_array_of_ccs_int_t write_array_of_int64
alias read_ccs_bool_t read_int32
......@@ -45,8 +47,12 @@ module CCS
alias read_ccs_hash_t read_uint32
if FFI.find_type(:size_t).size == 8
alias read_size_t read_uint64
alias write_size_t write_uint64
alias write_array_of_size_t write_array_of_uint64
else
alias read_size_t read_uint32
alias write_size_t write_uint32
alias write_array_of_size_t write_array_of_uint32
end
end
......
......@@ -4,6 +4,8 @@ module CCS
attach_function :ccs_configuration_space_get_rng, [:ccs_configuration_space_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_add_hyperparameter, [:ccs_configuration_space_t, :ccs_hyperparameter_t, :ccs_distribution_t], :ccs_result_t
attach_function :ccs_configuration_space_add_hyperparameters, [:ccs_configuration_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_set_distribution, [:ccs_configuration_space_t, :ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_get_hyperparameter_distribution, [:ccs_configuration_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_set_condition, [:ccs_configuration_space_t, :size_t, :ccs_expression_t], :ccs_result_t
attach_function :ccs_configuration_space_get_condition, [:ccs_configuration_space_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_get_conditions, [:ccs_configuration_space_t, :size_t, :pointer, :pointer], :ccs_result_t
......@@ -53,6 +55,40 @@ module CCS
self
end
def set_distribution(distribution, hyperparameters )
count = distribution.dimension
raise CCSError, :CCS_INVALID_VALUE if count != hyperparameters.size
hyperparameters = hyperparameters.collect { |h|
case h
when Hyperparameter
hyperparameter_index(h)
when String
hyperparameter_index_by_name(hyperparameter)
else
h
end
}
p_hypers = MemoryPointer::new(:size_t, count)
p_hypers.write_array_of_size_t(hyperparameters)
res = CCS.ccs_configuration_space_set_distribution(@handle, distribution, p_hypers)
CCS.error_check(res)
self
end
def get_hyperparameter_distribution(hyperparameter)
case hyperparameter
when Hyperparameter
hyperparameter = hyperparameter_index(hyperparameter);
when String
hyperparameter = hyperparameter_index_by_name(hyperparameter);
end
p_distribution = MemoryPointer::new(:ccs_distribution_t)
p_indx = MemoryPointer::new(:size_t)
res = CCS.ccs_configuration_space_get_hyperparameter_distribution(@handle, hyperparameter, p_distribution, p_indx)
CCS.error_check(res)
[CCS::Distribution.from_handle(p_distribution.read_ccs_distribution_t), p_indx.read_size_t]
end
def add_hyperparameters(hyperparameters, distributions: nil)
count = hyperparameters.size
return self if count == 0
......
......@@ -3,7 +3,9 @@ module CCS
DistributionType = enum FFI::Type::INT32, :ccs_distribution_type_t, [
:CCS_UNIFORM,
:CCS_NORMAL,
:CCS_ROULETTE
:CCS_ROULETTE,
:CCS_MIXTURE,
:CCS_MULTIVARIATE
]
class MemoryPointer
def read_ccs_distribution_type_t
......@@ -22,7 +24,7 @@ module CCS
end
attach_function :ccs_distribution_get_type, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_distribution_get_data_type, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_distribution_get_data_types, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_distribution_get_dimension, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_distribution_get_bounds, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_distribution_check_oversampling, [:ccs_distribution_t, Interval.by_ref, :pointer], :ccs_result_t
......@@ -31,7 +33,6 @@ module CCS
class Distribution < Object
add_property :type, :ccs_distribution_type_t, :ccs_distribution_get_type, memoize: true
add_property :data_type, :ccs_numeric_type_t, :ccs_distribution_get_data_type, memoize: true
add_property :dimension, :size_t, :ccs_distribution_get_dimension, memoize: true
def self.from_handle(handle)
......@@ -45,11 +46,24 @@ module CCS
NormalDistribution::new(handle, retain: true)
when :CCS_ROULETTE
RouletteDistribution::new(handle, retain: true)
when :CCS_MIXTURE
MixtureDistribution::new(handle, retain: true)
when :CCS_MULTIVARIATE
MultivariateDistribution::new(handle, retain: true)
else
raise CCSError, :CCS_INVALID_DISTRIBUTION
end
end
def data_types
@data_types ||= begin
ptr = MemoryPointer::new(:ccs_numeric_type_t, dimension)
res = CCS.ccs_distribution_get_data_types(@handle, ptr)
CCS.error_check(res)
ptr.read_array_of_int64(dimension).collect { |i| NumericType.from_native(i, nil) }
end
end
def bounds
@bounds ||= begin
interval = Interval::new(type: :CCS_NUM_FLOAT)
......@@ -67,25 +81,50 @@ module CCS
end
def sample(rng)
ptr = MemoryPointer::new(:ccs_numeric_t)
dim = dimension
ptr = MemoryPointer::new(:ccs_numeric_t, dim)
res = CCS.ccs_distribution_sample(@handle, rng, ptr)
CCS.error_check(res)
if data_type == :CCS_NUM_FLOAT
ptr.read_ccs_float_t
if dim == 1
if data_types.first == :CCS_NUM_FLOAT
ptr.read_ccs_float_t
else
ptr.read_ccs_int_t
end
else
ptr.read_ccs_int_t
data_types.each_with_index.collect { |t, i|
if t == :CCS_NUM_FLOAT
ptr.get_ccs_float_t(i*8)
else
ptr.get_ccs_int_t(i*8)
end
}
end
end
def samples(rng, count)
return [] if count == 0
ptr = MemoryPointer::new(:ccs_numeric_t, count)
dim = dimension
ptr = MemoryPointer::new(:ccs_numeric_t, count*dim)
res = CCS.ccs_distribution_samples(@handle, rng, count, ptr)
CCS.error_check(res)
if data_type == :CCS_NUM_FLOAT
ptr.read_array_of_ccs_float_t(count)
if dim == 1
if data_types.first == :CCS_NUM_FLOAT
ptr.read_array_of_ccs_float_t(count)
else
ptr.read_array_of_ccs_int_t(count)
end
else
ptr.read_array_of_ccs_int_t(count)
sz = CCS.find_type(:ccs_numeric_t).size
count.times.collect { |j|
data_types.each_with_index.collect { |t, i|
if t == :CCS_NUM_FLOAT
ptr.get_ccs_float_t((j*dim + i)*sz)
else
ptr.get_ccs_int_t((j*dim + i)*sz)
end
}
}
end
end
......@@ -120,6 +159,10 @@ module CCS
self.new(nil, data_type: :CCS_NUM_FLOAT, lower: lower, upper: upper, scale: scale, quantization: quantization)
end
def data_type
@data_type ||= data_types.first
end
def lower
@lower ||= begin
ptr = MemoryPointer::new(:ccs_numeric_t)
......@@ -197,6 +240,10 @@ module CCS
self::new(nil, retain: false, data_type: :CCS_NUM_FLOAT, mu: mu, sigma: sigma, scale: scale, quantization: quantization)
end
def data_type
@data_type ||= data_types.first
end
def mu
@mu ||= begin
ptr = MemoryPointer::new(:ccs_numeric_t)
......@@ -256,6 +303,10 @@ module CCS
end
end
def data_type
@data_type ||= data_types.first
end
def areas
@areas ||= begin
count = num_areas
......@@ -266,4 +317,81 @@ module CCS
end
end
end
attach_function :ccs_create_mixture_distribution, [:size_t, :pointer, :pointer, :pointer], :ccs_result_t
attach_function :ccs_mixture_distribution_get_num_distributions, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_mixture_distribution_get_distributions, [:ccs_distribution_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_mixture_distribution_get_weights, [:ccs_distribution_t, :size_t, :pointer, :pointer], :ccs_result_t
class MixtureDistribution < Distribution
add_property :num_distributions, :size_t, :ccs_mixture_distribution_get_num_distributions, memoize: true
def initialize(handle = nil, retain: false, distributions: [], weights: nil)
if handle
super(handle, retain: retain)
else
ptr = MemoryPointer::new(:ccs_distribution_t)
p_distributions = MemoryPointer::new(:ccs_distribution_t, distributions.length)
if weights
raise CCSError, :CCS_INVALID_VALUE if distributions.length != weights.length
else
weights = [1.0]*distributions.length
end
p_weights = MemoryPointer::new(:ccs_float_t, weights.length)
p_distributions.write_array_of_pointer(distributions.collect(&:handle))
p_weights.write_array_of_ccs_float_t(weights)
res = CCS.ccs_create_mixture_distribution(distributions.length, p_distributions, p_weights, ptr)
CCS.error_check(res)
super(ptr.read_pointer, retain: false)
end
end
def weights
@weights ||= begin
count = num_distributions
ptr = MemoryPointer::new(:ccs_float_t, count)
res = CCS.ccs_mixture_distribution_get_weights(@handle, count, ptr, nil)
CCS.error_check(res)
ptr.read_array_of_ccs_float_t(count)
end
end
def distributions
@distributions ||= begin
count = num_distributions
ptr = MemoryPointer::new(:ccs_distribution_t, count)
res = CCS.ccs_mixture_distribution_get_distributions(@handle, count, ptr, nil)
CCS.error_check(res)
count.times.collect { |i| Distribution.from_handle(ptr[i].read_pointer) }
end
end
end
attach_function :ccs_create_multivariate_distribution, [:size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_multivariate_distribution_get_num_distributions, [:ccs_distribution_t, :pointer], :ccs_result_t
attach_function :ccs_multivariate_distribution_get_distributions, [:ccs_distribution_t, :size_t, :pointer, :pointer], :ccs_result_t
class MultivariateDistribution < Distribution
add_property :num_distributions, :size_t, :ccs_multivariate_distribution_get_num_distributions, memoize: true
def initialize(handle = nil, retain: false, distributions: [])
if handle
super(handle, retain: retain)
else
ptr = MemoryPointer::new(:ccs_distribution_t)
p_distributions = MemoryPointer::new(:ccs_distribution_t, distributions.length)
p_distributions.write_array_of_pointer(distributions.collect(&:handle))
res = CCS.ccs_create_multivariate_distribution(distributions.length, p_distributions, ptr)
CCS.error_check(res)
super(ptr.read_pointer, retain: false)
end
end
def distributions
@distributions ||= begin
count = num_distributions
ptr = MemoryPointer::new(:ccs_distribution_t, count)
res = CCS.ccs_multivariate_distribution_get_distributions(@handle, count, ptr, nil)
CCS.error_check(res)
count.times.collect { |i| Distribution.from_handle(ptr[i].read_pointer) }
end
end
end
end
......@@ -36,6 +36,30 @@ class CConfigSpaceTestConfigurationSpace < Minitest::Test
}
end
def test_set_distribution
cs = CCS::ConfigurationSpace::new(name: "space")
h1 = CCS::NumericalHyperparameter::new
h2 = CCS::NumericalHyperparameter::new
h3 = CCS::NumericalHyperparameter::new
cs.add_hyperparameters([h1, h2, h3])
distributions = [ CCS::UniformDistribution::float(lower: 0.1, upper: 0.3), CCS::UniformDistribution::float(lower: 0.2, upper: 0.6) ]
d = CCS::MultivariateDistribution::new(distributions: distributions)
cs.set_distribution(d, [h1, h2])
dist, indx = cs.get_hyperparameter_distribution(h1)
assert_equal( d.handle, dist.handle )
assert_equal( 0, indx )
dist, indx = cs.get_hyperparameter_distribution(h2)
assert_equal( d.handle, dist.handle )
assert_equal( 1, indx )
cs.set_distribution(d, [h3, h1])
dist, indx = cs.get_hyperparameter_distribution(h1)
assert_equal( d.handle, dist.handle )
assert_equal( 1, indx )
dist, indx = cs.get_hyperparameter_distribution(h3)
assert_equal( d.handle, dist.handle )
assert_equal( 0, indx )
end
def test_conditions
h1 = CCS::NumericalHyperparameter::new(lower: -1.0, upper: 1.0, default: 0.0)
h2 = CCS::NumericalHyperparameter::new(lower: -1.0, upper: 1.0)
......
......@@ -181,4 +181,37 @@ class CConfigSpaceTestDistribution < Minitest::Test
assert( i.include?(w) )
}
end
def test_create_mixture
distributions = [ CCS::UniformDistribution::float(lower: -5.0, upper: 0.0), CCS::UniformDistribution::float(lower: 0.0, upper: 2.0) ]
d = CCS::MixtureDistribution::new(distributions: distributions)
assert( d.object_type == :CCS_DISTRIBUTION )
assert( d.type == :CCS_MIXTURE )
assert( d.data_types == [:CCS_NUM_FLOAT] )
assert( d.weights == [0.5, 0.5] )
assert( d.distributions.collect(&:handle) == distributions.collect(&:handle) )
d2 = CCS::Object::from_handle(d)
assert_equal( d.class, d2.class )
end
def test_create_multivariate
distributions = [ CCS::UniformDistribution::float(lower: -5.0, upper: 0.0), CCS::UniformDistribution::int(lower: 0, upper: 2) ]
d = CCS::MultivariateDistribution::new(distributions: distributions)
assert( d.object_type == :CCS_DISTRIBUTION )
assert( d.type == :CCS_MULTIVARIATE )
assert( d.data_types == [:CCS_NUM_FLOAT, :CCS_NUM_INTEGER] )
assert( d.distributions.collect(&:handle) == distributions.collect(&:handle) )
d2 = CCS::Object::from_handle(d)
assert_equal( d.class, d2.class )
end
def test_mixture_multidim
distributions = [ CCS::UniformDistribution::float(lower: -5.0, upper: 0.0), CCS::UniformDistribution::int(lower: 0, upper: 2) ]
d = CCS::MultivariateDistribution::new(distributions: distributions)
d2 = CCS::MixtureDistribution::new(distributions: [d, d])
assert( d2.object_type == :CCS_DISTRIBUTION )
assert( d2.type == :CCS_MIXTURE )
assert( d2.data_types == [:CCS_NUM_FLOAT, :CCS_NUM_INTEGER] )
assert( d2.weights == [0.5, 0.5] )
end
end
......@@ -42,6 +42,11 @@ ccs_configuration_space_add_hyperparameters(ccs_configuration_space_t configura
ccs_hyperparameter_t *hyperparameters,
ccs_distribution_t *distributions);
extern ccs_result_t
ccs_configuration_space_set_distribution(ccs_configuration_space_t configuration_space,
ccs_distribution_t distribution,
size_t *indexes);
extern ccs_result_t
ccs_configuration_space_get_num_hyperparameters(ccs_configuration_space_t configuration_space,
size_t *num_hyperparameters_ret);
......@@ -51,6 +56,13 @@ ccs_configuration_space_get_hyperparameter(ccs_configuration_space_t configurat
size_t index,
ccs_hyperparameter_t *hyperparameter_ret);
extern ccs_result_t
ccs_configuration_space_get_hyperparameter_distribution(
ccs_configuration_space_t configuration_space,
size_t index,
ccs_distribution_t *distribution_ret,
size_t *index_ret);
extern ccs_result_t
ccs_configuration_space_get_hyperparameter_by_name(
ccs_configuration_space_t configuration_space,
......
......@@ -9,6 +9,8 @@ enum ccs_distribution_type_e {
CCS_UNIFORM,
CCS_NORMAL,
CCS_ROULETTE,
CCS_MIXTURE,
CCS_MULTIVARIATE,
CCS_DISTRIBUTION_TYPE_MAX,
CCS_DISTRIBUTION_TYPE_FORCE_32BIT = INT_MAX
};
......@@ -95,8 +97,8 @@ ccs_distribution_get_dimension(ccs_distribution_t distribution,
size_t *dimension);
extern ccs_result_t
ccs_distribution_get_data_type(ccs_distribution_t distribution,
ccs_numeric_type_t *data_type_ret);
ccs_distribution_get_data_types(ccs_distribution_t distribution,
ccs_numeric_type_t *data_types_ret);
extern ccs_result_t
ccs_distribution_get_bounds(ccs_distribution_t distribution,
......@@ -104,8 +106,8 @@ ccs_distribution_get_bounds(ccs_distribution_t distribution,
extern ccs_result_t
ccs_distribution_check_oversampling(ccs_distribution_t distribution,
ccs_interval_t *interval,
ccs_bool_t *oversampling_ret);
ccs_interval_t *intervals,
ccs_bool_t *oversamplings);
extern ccs_result_t
ccs_normal_distribution_get_parameters(ccs_distribution_t distribution,
......@@ -131,6 +133,32 @@ ccs_roulette_distribution_get_areas(ccs_distribution_t distribution,
ccs_float_t *areas,
size_t *num_areas_ret);
extern ccs_result_t
ccs_mixture_distribution_get_num_distributions(ccs_distribution_t distribution,
size_t *num_distributions_ret);
extern ccs_result_t
ccs_mixture_distribution_get_distributions(ccs_distribution_t distribution,
size_t num_distributions,
ccs_distribution_t *distributions,
size_t *num_distributions_ret);
extern ccs_result_t
ccs_mixture_distribution_get_weights(ccs_distribution_t distribution,
size_t num_weights,
ccs_float_t *weights,
size_t *num_weights_ret);
extern ccs_result_t
ccs_multivariate_distribution_get_num_distributions(ccs_distribution_t distribution,
size_t *num_distributions_ret);
extern ccs_result_t
ccs_multivariate_distribution_get_distributions(ccs_distribution_t distribution,
size_t num_distributions,
ccs_distribution_t *distributions,
size_t *num_distributions_ret);
// Sampling Interface
extern ccs_result_t
ccs_distribution_sample(ccs_distribution_t distribution,
......@@ -153,6 +181,25 @@ ccs_distribution_strided_samples(ccs_distribution_t distribution,
size_t stride,
ccs_numeric_t *values);
extern ccs_result_t
ccs_distribution_soa_samples(ccs_distribution_t distribution,
ccs_rng_t rng,
size_t num_values,
ccs_numeric_t **values);
extern ccs_result_t
ccs_distribution_hyperparameters_samples(ccs_distribution_t distribution,
ccs_rng_t rng,
ccs_hyperparameter_t *hyperparameters,
size_t num_values,
ccs_datum_t *values);
extern ccs_result_t
ccs_distribution_hyperparameters_sample(ccs_distribution_t distribution,
ccs_rng_t rng,
ccs_hyperparameter_t *hyperparameters,
ccs_datum_t *values);
#ifdef __cplusplus
}
#endif
......
......@@ -116,6 +116,13 @@ ccs_hyperparameter_check_values(ccs_hyperparameter_t hyperparameter,
const ccs_datum_t *values,
ccs_bool_t *results);
extern ccs_result_t
ccs_hyperparameter_convert_samples(ccs_hyperparameter_t hyperparameter,
ccs_bool_t oversampling,
size_t num_values,
const ccs_numeric_t *values,
ccs_datum_t *results);
// Sampling Interface
extern ccs_result_t
ccs_hyperparameter_sample(ccs_hyperparameter_t hyperparameter,
......@@ -130,6 +137,9 @@ ccs_hyperparameter_samples(ccs_hyperparameter_t hyperparameter,
size_t num_values,
ccs_datum_t *values);
extern ccs_result_t
ccs_hyperparameter_sampling_interval(ccs_hyperparameter_t hyperparameter,
ccs_interval_t *interval_ret);
#ifdef __cplusplus
}
#endif
......
......@@ -15,6 +15,8 @@ libcconfigspace_la_SOURCES = \
distribution_uniform.c \
distribution_normal.c \
distribution_roulette.c \
distribution_mixture.c \
distribution_multivariate.c \
hyperparameter.c \
hyperparameter_internal.h \
hyperparameter_numerical.c \
......
......@@ -265,6 +265,161 @@ error:
#undef utarray_oom
#define utarray_oom() exit(-1)
ccs_result_t
ccs_configuration_space_set_distribution(ccs_configuration_space_t configuration_space,
ccs_distribution_t distribution,
size_t *indexes) {
CCS_CHECK_OBJ(configuration_space, CCS_CONFIGURATION_SPACE);
CCS_CHECK_OBJ(distribution, CCS_DISTRIBUTION);
CCS_CHECK_PTR(indexes);
_ccs_distribution_wrapper_t *dwrapper;
_ccs_hyperparameter_wrapper_cs_t *hwrapper;
ccs_result_t err;
UT_array *hyperparameters = configuration_space->data->hyperparameters;
size_t num_hyperparameters = utarray_len(hyperparameters);
size_t dim;
err = ccs_distribution_get_dimension(distribution, &dim);
if (err)
return err;
for (size_t i = 0; i < dim; i++) {
if (indexes[i] >= num_hyperparameters)
return -CCS_INVALID_VALUE;
// Check duplicate entries
for (size_t j = 0; j < i; j++)
if (indexes[i] == indexes[j])
return -CCS_INVALID_VALUE;