gpp_domain¶
Contents:
gpp_domain.hpp¶
This file contains “DomainType” classes that specify different kinds of domains (e.g., TensorProduct, Simplex). These are currently used to describe domain limits for optimizers (defined in gpp_optimization, used by gpp_math, gpp_model_selection).
Currently, we only support domains with planar (linear) boundaries.
Each domain provides functions to describe the set of boundary planes, check whether a point is inside/outside, generate random points inside, and limit updates (from optimizers) so that a path stays inside the domain.
See gpp_geometry.hpp for how to specify a plane.
namespace optimal_learning
Macro to allow restrict as a keyword for C++ compilation and CUDA/nvcc compilation. See related entry in gpp_common.hpp for more details.
EnumsDomainTypes enum
Enumerating domains for convenience. Useful for selecting which tests to run and also used by the Python interface to communicate domain type to C++.
Values:
- kTensorProduct = = 0 -
- kSimplex = = 1 -
class DummyDomain
A dummy domain; commonly paired with the NullOptimizer. Use when domain is irrelevant.
It does not track any member data and claims all points are inside.
Public FunctionsPublic Static Attributesbool CheckPointInside(double const *restrict OL_UNUSED)Always returns true: DummyDomain contains all points.
- Parameters:
point[dim]: point to check - Returns:
- true if point is inside the domain or on its boundary, false otherwise
constexpr char const * kName
string name of this domain for logging
class RepeatedDomain
A generic domain type for simultaneously manipulating num_repeats points in a “regular” domain (the kernel).
Note
Comments in this class are copied to RepeatedDomain in optimal_learning/python/repated_domain.py.
Note
the kernel domain is not copied. Instead, the kernel functions are called num_repeats times in a loop. In some cases, data reordering is also necessary to preserve the output properties (e.g., uniform distribution).
For some use cases (e.g., q,p-EI optimization with q > 1), we need to simultaneously manipulate several points within the same domain. To support this use case, we have the RepeatedDomain, a light-weight wrapper around any DomainType object that kernalizes that object’s functionality.
In general, kernel domain operations need be performed num_repeats times, once for each point. This class hides the looping logic so that use cases like various Optimizer implementations (gpp_optimization.hpp) do not need to be explicitly aware of whether they are optimizing 1 point or 50 points. Instead, an optimizable Evaluator/State pair provides GetProblemSize() and appropriately sized gradient information. Coupled with RepeatedDomain, Optimizers can remain oblivious.
In simpler terms, say we want to solve 5,0-EI in a parameter-space of dimension 3. So we would have 5 points moving around in a 3D space. The 3D space, whatever it is, is the kernel domain. We “repeat” the kernel 5 times; in practice this mostly amounts to simple loops around kernel functions and sometimes data reordering is also needed.
Note
this operation is more complex than just working in a higher dimensional space. 3 points in a 2D simplex is not the same as 1 point in a 6D simplex; e.g., [(0.5, 0.5), (0.5, 0.5), (0.5, 0.5)] is valid in the first scenario but not in the second.
Where the member domain takes kernel_input, this class’s members take an array with of num_repeats data with the same size as kernel_input, ordered sequentially. So if we have kernel_input[dim][num_points], we now have repeated_input[dim][num_points][num_repeats]. The same is true for outputs.
For example, CheckPointInside() calls the kernel domain’s CheckPointInside() function num_repeats times, returning True only if all num_repeats input points are inside the kernel domain.
Public TypePublic Functionstypedef DomainType_ DomainType
Private MembersRepeatedDomain()RepeatedDomain(const DomainType & domain, int num_repeats_in)Construct a RepeatedDomain object, which kernalizes and repeats an input DomainType object.
Note
this class maintains a pointer to the input domain. Do not let the domain object go out of scope before this object goes out of scope.
- Parameters:
domain: the domain to repeat num_repeats: number of times to repeat the input domain int dim()int num_repeats()bool CheckPointInside(double const *restrict point)Check if a point is inside the domain/on its domain or outside
- Parameters:
point[dim][num_repeats]: point to check - Returns:
- true if point is inside the domain or on its boundary, false otherwise
bool GeneratePointInDomain(UniformRandomGenerator * uniform_generator, double *restrict random_point)Generates “point” such that CheckPointInside(point) returns true.
May use rejection sampling so point generation may fail.
- Parameters:
uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_point[dim][num_repeats]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_point[dim][num_repeats]: point with coordinates inside the domain (left in invalid state if fcn returns false) - Returns:
- true if point generation succeeded
int GenerateUniformPointsInDomain(int num_points, UniformRandomGenerator * uniform_generator, double *restrict random_points)Generates AT MOST num_points points in the domain (i.e., such that CheckPointInside(point) returns true). The points will be uniformly distributed.
May use rejection sampling so we are not guaranteed to generate num_points samples.
- Parameters:
num_points: number of random points to generate uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_points[dim][num_repeats][num_points]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_points[dim][num_repeats][num_points]: point with coordinates inside the domain - Returns:
- number of points actually generated
void LimitUpdate(double max_relative_change, double const *restrict current_point, double *restrict update_vector)Changes update_vector so that:
point_new = point + update_vectorhas coordinates such that CheckPointInside(point_new) returns true.
update_vector is UNMODIFIED if point_new is already inside the domain.
Note
we modify update_vector (instead of returning point_new) so that further update limiting/testing may be performed.
- Parameters:
max_relative_change: max change allowed per update (as a relative fraction of current distance to boundary) current_point[dim][num_repeats]: starting point update_vector[dim][num_repeats]: proposed update - Outputs:
update_vector[dim][num_repeats]: modified update so that the final point remains inside the domain int num_repeats_
number of times to repeat the input domain
const DomainType *restrict domain_
pointer to the domain to repeat
class SimplexIntersectTensorProductDomain
Domain class for the intersection of the unit simplex with an arbitrary tensor product domain. To that end, this object has a TensorProductDomain object as a data member and uses its functions when possible.
See TensorProductDomain for what that means. The unit d-simplex is defined as the set of x_i such that:
- x_i >= 0 \forall i (i ranging over dimension)
- \sum_i x_i <= 1
(Implying that x_i <= 1 \forall i)
ASSUMPTION: most of the volume of the tensor product region lies inside the simplex region.
Public FunctionsPublic Static AttributesSimplexIntersectTensorProductDomain()SimplexIntersectTensorProductDomain(ClosedInterval const *restrict domain, int dim_in)Constructs a SimplexIntersectTensorProductDomain. The bounds of the tensor product region are specified through the “domain” input, just as with TensorProductDomain.
- Parameters:
domain[dim]: array of ClosedInterval specifying the boundaries of a dim-dimensional tensor-product domain. dim_in: number of spatial dimensions int dim()int GetMaxNumberOfBoundaryPlanes()Maximum number of planes that define the boundary of this domain. Used for testing.
This result is NOT exact.
- Returns:
- max number of planes defining the boundary of this domain
void GetBoundaryPlanes(Plane *restrict planes)Fills an input array with all bounding planes of this domain. See struct Plane in gpp_geometry.hpp for how to specify a plane. Used for testing.
Let max_num_bound = GetMaxNumberOfBoundaryPlanes()
- Parameters:
planes[max_num_bound]: properly allocated space: max_num_bound Plane objects in dim spatial dimensions - Outputs:
planes[max_num_bound]: array of planes of this domain bool CheckPointInside(double const *restrict point)Check if a point is inside the domain/on its domain or outside
- Parameters:
point[dim]: point to check - Returns:
- true if point is inside the domain or on its boundary, false otherwise
bool GeneratePointInDomain(UniformRandomGenerator * uniform_generator, double *restrict random_point)Generates “point” such that CheckPointInside(point) returns true.
Uses rejection sampling so point generation may fail.
- Parameters:
uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_point[dim]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_point[dim]: point with coordinates inside the domain (left in invalid state if fcn returns false) - Returns:
- true if point generation succeeded
int GenerateUniformPointsInDomain(int num_points, UniformRandomGenerator * uniform_generator, double *restrict random_points)Generates AT MOST num_points points in the domain (i.e., such that CheckPointInside(point) returns true). The points will be uniformly distributed.
Uses rejection sampling so we are not guaranteed to generate num_points samples.
- Parameters:
num_points: number of random points to generate uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_points[dim][num_points]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_points[dim][num_points]: point with coordinates inside the domain - Returns:
- number of points actually generated
void LimitUpdate(double max_relative_change, double const *restrict current_point, double *restrict update_vector)Changes update_vector so that:
point_new = point + update_vectorhas coordinates such that CheckPointInside(point_new) returns true.
update_vector is UNMODIFIED if point_new is already inside the domain.
Note
we modify update_vector (instead of returning point_new) so that further update limiting/testing may be performed.
- Parameters:
max_relative_change: max change allowed per update (as a relative fraction of current distance to boundary) current_point[dim]: starting point update_vector[dim]: proposed update - Outputs:
update_vector[dim]: modified update so that the final point remains inside the domain Private Membersconstexpr char const * kName
string name of this domain for logging
Private Static Attributesint dim_
the number of spatial dimensions of this domain
TensorProductDomain tensor_product_domain_
the tensor product domain to intersect with
Plane simplex_plane_
the plane defining the simplex
constexpr double kPointGenerationRatio
GenerateUniformPointsInDomain() is happy if ratio*requested_points number of points is generated.
constexpr double kValidPointRatioFloor
in GenerateUniformPointsInDomain(), if the ratio of valid points is > this, we retry requesting 1/ratio points. otherwise we retry with 5x the points (i.e., flooring ratio at 5)
constexpr int kMaxPointRatioGrowth
1/kValidPointRatioFloor; the most we’ll increase the number of requested points on a retry
constexpr double kInvalidStepScaleFactor
attempt to scale down the step-size (or distance to wall) by this factor when a domain-exiting (i.e., invalid) step is requested
constexpr double kRelativeChangeEpsilonTweak
small tweak to relative_change (to prevent max_relative_change == 1.0 exactly; see LimitUpdate comments)
class TensorProductDomain
Domain type for a tensor product domain.
A d-dimensional tensor product domain is D = [x_0_{min}, x_0_{max}] X [x_1_{min}, x_1_{max}] X ... X [x_d_{min}, x_d_{max}]
Public FunctionsPublic Static AttributesTensorProductDomain()TensorProductDomain(ClosedInterval const *restrict domain, int dim_in)Constructs a TensorProductDomain.
- Parameters:
domain[dim]: array of ClosedInterval specifying the boundaries of a dim-dimensional tensor-product domain. dim_in: number of spatial dimensions int dim()void SetDomain(ClosedInterval const *restrict domain)Explicitly set the domain boundaries. Assumes specified domain is non-empty.
- Parameters:
domain[dim]: array of ClosedInterval specifying the boundaries of a dim-dimensional tensor-product domain. int GetMaxNumberOfBoundaryPlanes()Maximum number of planes that define the boundary of this domain. Used for testing.
This result is exact.
- Returns:
- max number of planes defining the boundary of this domain
void GetBoundaryPlanes(Plane *restrict planes)Fills an input array with all bounding planes of this domain. See struct Plane in gpp_geometry.hpp for how to specify a plane. Used for testing.
Let max_num_bound = GetMaxNumberOfBoundaryPlanes()
- Parameters:
planes[max_num_bound]: properly allocated space: max_num_bound Plane objects in dim spatial dimensions - Outputs:
planes[max_num_bound]: array of planes of this domain bool CheckPointInside(double const *restrict point)Check if a point is inside the domain/on its boundary or outside.
- Parameters:
point[dim]: point to check - Returns:
- true if point is inside the domain or on its boundary, false otherwise
bool GeneratePointInDomain(UniformRandomGenerator * uniform_generator, double *restrict random_point)Generates “point” such that CheckPointInside(point) returns true.
- Parameters:
uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_point[dim]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_point[dim]: point with coordinates inside the domain (left in invalid state if fcn returns false) - Returns:
- true if point generation succeeded
int GenerateUniformPointsInDomain(int num_points, UniformRandomGenerator * uniform_generator, double *restrict random_points)Generates num_points points in the domain (i.e., such that CheckPointInside(point) returns true). The points will be uniformly distributed.
- Parameters:
num_points: number of random points to generate uniform_generator[1]: a UniformRandomGenerator object providing the random engine for uniform random numbers random_points[dim][num_points]: properly sized array - Outputs:
uniform_generator[1]: UniformRandomGenerator object will have its state changed due to random draws random_points[dim][num_points]: point with coordinates inside the domain - Returns:
- number of points generated (always num_points; ok to not use this result)
void LimitUpdate(double max_relative_change, double const *restrict current_point, double *restrict update_vector)Changes update_vector so that:
point_new = point + update_vectorhas coordinates such that CheckPointInside(point_new) returns true.
update_vector is UNMODIFIED if point_new is already inside the domain.
Note
we modify update_vector (instead of returning point_new) so that further update limiting/testing may be performed.
- Parameters:
max_relative_change: max change allowed per update (as a relative fraction of current distance to boundary) current_point[dim]: starting point update_vector[dim]: proposed update - Outputs:
update_vector[dim]: modified update so that the final point remains inside the domain Private Membersconstexpr char const * kName
string name of this domain for logging
Private Static Attributesint dim_
the number of spatial dimensions of this domain
std::vector< ClosedInterval > domain_
the list of ClosedInterval that define the boundaries of this tensor product domain
constexpr double kInvalidStepScaleFactor
attempt to scale down the step-size (or distance to wall) by this factor when a domain-exiting (i.e., invalid) step is requested
gpp_domain.cpp¶
This file contains definitions for constructors and member functions of the various domain classes in gpp_domain.hpp.
namespace optimal_learning
Macro to allow restrict as a keyword for C++ compilation and CUDA/nvcc compilation. See related entry in gpp_common.hpp for more details.