Skip to content

Commit

Permalink
add maxFractionalComponent, and CTAD for clang16
Browse files Browse the repository at this point in the history
  • Loading branch information
chriselrod committed Sep 12, 2023
1 parent 76041b7 commit 346f5f1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
39 changes: 25 additions & 14 deletions include/Math/BoxOpt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ constexpr double EXTREME = 8.0;

class BoxTransformView {
public:
constexpr BoxTransformView(double *f, int32_t *i, unsigned ntotal,
unsigned nunfixed)
: f64{f}, i32{i}, Ntotal{ntotal}, Nunfixed{nunfixed} {}
constexpr BoxTransformView(double *f, int32_t *i, unsigned ntotal)
: f64{f}, i32{i}, Ntotal{ntotal} {}
[[nodiscard]] constexpr auto size() const -> unsigned { return Ntotal; }
[[nodiscard]] constexpr auto numUnfixed() const -> unsigned {
return Nunfixed;
}
constexpr auto operator()(const AbstractVector auto &x, ptrdiff_t i) const
-> utils::eltype_t<decltype(x)> {
invariant(i < Ntotal);
Expand All @@ -38,6 +34,24 @@ class BoxTransformView {
[[nodiscard]] constexpr auto getUpperBounds() -> MutPtrVector<int32_t> {
return {i32 + ptrdiff_t(2) * Ntotal, Ntotal};
}
// gives max fractional ind on the transformed scale
template <bool Relative = true>
constexpr auto maxFractionalComponent(MutPtrVector<double> x) -> ptrdiff_t {
double max = 0.0;
ptrdiff_t k = -1;
for (ptrdiff_t i = 0, j = 0; i < Ntotal; ++i) {
double s = scales()[i];
if (s == 0.0) continue;
double a = s * sigmoid(x[j++]) + offs()[i];
double d = a - std::floor(a);
d = (d > 0.5) ? 1.0 - d : d;
if constexpr (Relative) d /= a;
if (d <= max) continue;
max = d;
k = i;
}
return k;
}

protected:
/// Ntotal offsets
Expand All @@ -48,7 +62,6 @@ class BoxTransformView {
/// Ntotal upper bounds
int32_t *i32;
unsigned Ntotal;
unsigned Nunfixed;

[[nodiscard]] constexpr auto getInds() const -> PtrVector<int32_t> {
return {i32, Ntotal};
Expand Down Expand Up @@ -95,7 +108,7 @@ class BoxTransform : public BoxTransformView {
public:
constexpr BoxTransform(unsigned ntotal, int32_t lb, int32_t ub)
: BoxTransformView{new double[long(2) * ntotal],
new int32_t[long(3) * ntotal], ntotal, ntotal} {
new int32_t[long(3) * ntotal], ntotal} {
invariant(lb < ub);
auto [s, o] = scaleOff(lb, ub);
for (int32_t i = 0; i < int32_t(ntotal); ++i) {
Expand All @@ -115,7 +128,6 @@ class BoxTransform : public BoxTransformView {
getLowerBounds()[idx] = lb;
double newScale, newOff;
if (lb == ub) {
--Nunfixed;
untrf.erase(getInds()[idx]);
getInds()[idx] = -1;
// we remove a fixed, so we must now decrement all following inds
Expand All @@ -138,7 +150,6 @@ class BoxTransform : public BoxTransformView {
getUpperBounds()[idx] = ub;
double newScale, newOff;
if (lb == ub) {
--Nunfixed;
untrf.erase(getInds()[idx]);
getInds()[idx] = -1;
// we remove a fixed, so we must now decrement all following inds
Expand All @@ -161,14 +172,13 @@ class BoxTransform : public BoxTransformView {
delete[] i32;
}
constexpr BoxTransform(BoxTransform &&other) noexcept
: BoxTransformView{other.f64, other.i32, other.Ntotal, other.Nunfixed} {
: BoxTransformView{other.f64, other.i32, other.Ntotal} {
other.f64 = nullptr;
other.i32 = nullptr;
}
constexpr BoxTransform(const BoxTransform &other)
: BoxTransformView{new double[long(2) * other.Ntotal],
new int32_t[long(3) * other.Ntotal], other.Ntotal,
other.Ntotal} {
new int32_t[long(3) * other.Ntotal], other.Ntotal} {
std::copy_n(other.f64, 2 * Ntotal, f64);
std::copy_n(other.i32, 3 * Ntotal, i32);
}
Expand All @@ -188,6 +198,8 @@ template <AbstractVector V> struct BoxTransformVector {
return *this;
}
};
template <AbstractVector V>
BoxTransformVector(V, BoxTransformView) -> BoxTransformVector<V>;

static_assert(AbstractVector<BoxTransformVector<PtrVector<double>>>);

Expand All @@ -196,7 +208,6 @@ template <typename F> struct BoxCall {
BoxTransformView transform;
constexpr auto operator()(const AbstractVector auto &x) const
-> utils::eltype_t<decltype(x)> {
invariant(x.size() == transform.numUnfixed());
return f(BoxTransformVector{x.view(), transform});
}
};
Expand Down
11 changes: 9 additions & 2 deletions include/Math/BoxOptInt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ namespace poly::math {

// recursive branch and bound
constexpr auto branchandbound(utils::Arena<> *alloc, MutPtrVector<double> x,
BoxTransformView trf, double lower, double upper,
const auto &f) -> double {}
BoxTransform &trf, double lower, double upper,
const auto &f) -> double {
ptrdiff_t j = trf.maxFractionalComponent<>(x);
if (j < 0) return lower; // was an integer solution
// if j >= 0, then `x[trf.getInds()[j]]` is the largest fractional component
// we'll thus split `trf` on it, creating two new boxes `trf1` and `trf2`
// and two new vectors `x1` and `x2`
// e.g., 3.4 -> two trfs with new bounds <=3 and >=4
}
// set floor and ceil
// Assumes that integer floor of values is optimal
constexpr auto minimizeIntSol(utils::Arena<> *alloc, MutPtrVector<int32_t> r,
Expand Down

0 comments on commit 346f5f1

Please sign in to comment.