Replace kiwi Constraint and Variable types

Going to replace these types since they are so stupid simple and
the originals are not conducive to integrating efficienctly outside
C++. We need a well defined way to get a pointer/reference to the
shared data. The proxy objects frustrate that, but they are
what is baked into the library. The public interface is not altered
except for the ability to access and construct from pointers.
This commit is contained in:
2024-02-24 22:56:33 -06:00
parent 70a9213c91
commit 359c31a0af
2 changed files with 99 additions and 138 deletions

View File

@@ -26,17 +26,70 @@ enum RelationalOperator
OP_EQ
};
class Constraint
class Constraint;
class ConstraintData : public SharedData
{
static Expression reduce(const Expression &expr)
{
std::map<Variable, double> vars;
for (const auto & term : expr.terms())
vars[term.variable()] += term.coefficient();
std::vector<Term> terms(vars.begin(), vars.end());
return Expression(std::move(terms), expr.constant());
}
public:
ConstraintData(const Expression &expr,
RelationalOperator op,
double strength) : SharedData(),
m_expression(reduce(expr)),
m_strength(strength::clip(strength)),
m_op(op) {}
ConstraintData(const ConstraintData &other, double strength) : SharedData(),
m_expression(other.m_expression),
m_strength(strength::clip(strength)),
m_op(other.m_op) {}
~ConstraintData() = default;
const Expression &expression() const { return m_expression; }
RelationalOperator op() const { return m_op; }
double strength() const { return m_strength; }
bool violated() const
{
switch (m_op)
{
case OP_EQ: return !impl::nearZero(m_expression.value());
case OP_GE: return m_expression.value() < 0.0;
case OP_LE: return m_expression.value() > 0.0;
}
std::abort();
}
private:
Expression m_expression;
double m_strength;
RelationalOperator m_op;
ConstraintData(const ConstraintData &other) = delete;
ConstraintData &operator=(const ConstraintData &other) = delete;
};
class Constraint
{
public:
explicit Constraint(ConstraintData *p) : m_data(p) {}
Constraint() = default;
Constraint(const Expression &expr,
RelationalOperator op,
double strength = strength::required) : m_data(new ConstraintData(expr, op, strength)) {}
Constraint(const Constraint &other, double strength) : m_data(new ConstraintData(other, strength)) {}
Constraint(const Constraint &other, double strength) : m_data(new ConstraintData(*other.m_data, strength)) {}
Constraint(const Constraint &) = default;
@@ -44,32 +97,10 @@ public:
~Constraint() = default;
const Expression &expression() const
{
return m_data->m_expression;
}
RelationalOperator op() const
{
return m_data->m_op;
}
double strength() const
{
return m_data->m_strength;
}
bool violated() const
{
switch (m_data->m_op)
{
case OP_EQ: return !impl::nearZero(m_data->m_expression.value());
case OP_GE: return m_data->m_expression.value() < 0.0;
case OP_LE: return m_data->m_expression.value() > 0.0;
}
std::abort();
}
const Expression &expression() const { return m_data->expression(); }
RelationalOperator op() const { return m_data->op(); }
double strength() const { return m_data->strength(); }
bool violated() const { return m_data->violated(); }
bool operator!() const
{
@@ -81,45 +112,9 @@ public:
Constraint& operator=(Constraint &&) noexcept = default;
private:
static Expression reduce(const Expression &expr)
{
std::map<Variable, double> vars;
for (const auto & term : expr.terms())
vars[term.variable()] += term.coefficient();
std::vector<Term> terms(vars.begin(), vars.end());
return Expression(std::move(terms), expr.constant());
}
class ConstraintData : public SharedData
{
SharedDataPtr<ConstraintData> m_data;
public:
ConstraintData(const Expression &expr,
RelationalOperator op,
double strength) : SharedData(),
m_expression(reduce(expr)),
m_strength(strength::clip(strength)),
m_op(op) {}
ConstraintData(const Constraint &other, double strength) : SharedData(),
m_expression(other.expression()),
m_strength(strength::clip(strength)),
m_op(other.op()) {}
~ConstraintData() = default;
Expression m_expression;
double m_strength;
RelationalOperator m_op;
private:
ConstraintData(const ConstraintData &other);
ConstraintData &operator=(const ConstraintData &other);
};
SharedDataPtr<ConstraintData> m_data;
friend bool operator<(const Constraint &lhs, const Constraint &rhs)
{

View File

@@ -13,63 +13,55 @@
namespace kiwi
{
class Variable
class VariableData : public SharedData
{
public:
VariableData(std::string name) : SharedData(),
m_name(std::move(name)),
m_value(0.0) {}
public:
class Context
{
public:
Context() = default;
virtual ~Context() {} // LCOV_EXCL_LINE
VariableData(const char *name) : SharedData(),
m_name(name),
m_value(0.0) {}
~VariableData() = default;
const std::string &name() const { return m_name; }
void setName(const char *name) { m_name = name; }
void setName(const std::string &name) { m_name = name; }
double value() const { return m_value; }
void setValue(double value) { m_value = value; }
private:
std::string m_name;
double m_value;
VariableData(const VariableData &other) = delete;
VariableData &operator=(const VariableData &other) = delete;
};
Variable(Context *context = 0) : m_data(new VariableData("", context)) {}
class Variable
{
public:
explicit Variable(VariableData *p) : m_data(p) {}
VariableData *ptr() { return m_data; }
Variable(std::string name, Context *context = 0) : m_data(new VariableData(std::move(name), context)) {}
Variable(const char *name, Context *context = 0) : m_data(new VariableData(name, context)) {}
Variable() : m_data(new VariableData("")) {}
Variable(std::string name) : m_data(new VariableData(std::move(name))) {}
Variable(const char *name) : m_data(new VariableData(name)) {}
Variable(const Variable&) = default;
Variable(Variable&&) noexcept = default;
~Variable() = default;
const std::string &name() const
{
return m_data->m_name;
}
const std::string &name() const { return m_data->name(); }
void setName(const char *name) { m_data->setName(name); }
void setName(const std::string &name) { m_data->setName(name); }
void setName(const char *name)
{
m_data->m_name = name;
}
void setName(const std::string &name)
{
m_data->m_name = name;
}
Context *context() const
{
return m_data->m_context.get();
}
void setContext(Context *context)
{
m_data->m_context.reset(context);
}
double value() const
{
return m_data->m_value;
}
void setValue(double value)
{
m_data->m_value = value;
}
double value() const { return m_data->value(); }
void setValue(double value) { m_data->setValue(value); }
// operator== is used for symbolics
bool equals(const Variable &other)
@@ -82,32 +74,6 @@ public:
Variable& operator=(Variable&&) noexcept = default;
private:
class VariableData : public SharedData
{
public:
VariableData(std::string name, Context *context) : SharedData(),
m_name(std::move(name)),
m_context(context),
m_value(0.0) {}
VariableData(const char *name, Context *context) : SharedData(),
m_name(name),
m_context(context),
m_value(0.0) {}
~VariableData() = default;
std::string m_name;
std::unique_ptr<Context> m_context;
double m_value;
private:
VariableData(const VariableData &other);
VariableData &operator=(const VariableData &other);
};
SharedDataPtr<VariableData> m_data;
friend bool operator<(const Variable &lhs, const Variable &rhs)