SetId Approximator::function_rhs_val(const Function& fun, SetId rhs, SetId val, Parity parity) const { POMAGMA_ASSERT1(rhs, "rhs is undefined"); POMAGMA_ASSERT1(val, "val is undefined"); POMAGMA_ASSERT1(parity == NABOVE or parity == NBELOW, "invalid parity"); const bool upward = (parity == NBELOW); const DenseSet& support = m_structure.carrier().support(); const DenseSet rhs_set = m_sets.load(rhs); // positive const DenseSet val_set = m_sets.load(val); // negative DenseSet lhs_set(m_item_dim); // negative for (auto iter = support.iter_diff(lhs_set); iter.ok(); iter.next()) { Ob lhs = *iter; if (unlikely(lhs_set.contains(lhs))) continue; // iterator latency for (auto iter = fun.get_Lx_set(lhs).iter_insn(rhs_set); iter.ok(); iter.next()) { Ob rhs = *iter; Ob val = fun.find(lhs, rhs); if (val_set.contains(val)) { convex_insert(lhs_set, lhs, upward); break; } } } return m_sets.store(std::move(lhs_set)); }
SetId Approximator::function_lhs_rhs(const Function& fun, SetId lhs, SetId rhs, Parity parity) const { POMAGMA_ASSERT1(lhs, "lhs is undefined"); POMAGMA_ASSERT1(rhs, "rhs is undefined"); POMAGMA_ASSERT1(parity == ABOVE or parity == BELOW, "invalid parity"); const bool upward = (parity == ABOVE); const DenseSet lhs_set = m_sets.load(lhs); // positive const DenseSet rhs_set = m_sets.load(rhs); // positive DenseSet val_set(m_item_dim); // positive const Ob optimum = upward ? m_top : m_bot; POMAGMA_ASSERT1(lhs_set.contains(optimum), "invalid lhs set"); POMAGMA_ASSERT1(rhs_set.contains(optimum), "invalid rhs set"); val_set.insert(optimum); DenseSet temp_set(m_item_dim); for (auto iter = lhs_set.iter(); iter.ok(); iter.next()) { Ob lhs = *iter; // optimize for constant functions if (Ob lhs_top = fun.find(lhs, m_top)) { if (Ob lhs_bot = fun.find(lhs, m_bot)) { if (lhs_top == lhs_bot) { convex_insert(val_set, lhs_top, upward); continue; } } } temp_set.set_insn(rhs_set, fun.get_Lx_set(lhs)); for (auto iter = temp_set.iter(); iter.ok(); iter.next()) { Ob rhs = *iter; Ob val = fun.find(lhs, rhs); convex_insert(val_set, val, upward); } } return m_sets.store(std::move(val_set)); }
bool contains(Ob ob) const { return m_support.contains(ob); }
inline void Approximator::convex_insert(DenseSet& set, Ob ob, bool upward) const { if (not set.contains(ob)) { set += upward ? m_less.get_Lx_set(ob) : m_less.get_Rx_set(ob); } }