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:
@@ -26,17 +26,70 @@ enum RelationalOperator
|
|||||||
OP_EQ
|
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:
|
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() = default;
|
||||||
|
|
||||||
Constraint(const Expression &expr,
|
Constraint(const Expression &expr,
|
||||||
RelationalOperator op,
|
RelationalOperator op,
|
||||||
double strength = strength::required) : m_data(new ConstraintData(expr, op, strength)) {}
|
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;
|
Constraint(const Constraint &) = default;
|
||||||
|
|
||||||
@@ -44,32 +97,10 @@ public:
|
|||||||
|
|
||||||
~Constraint() = default;
|
~Constraint() = default;
|
||||||
|
|
||||||
const Expression &expression() const
|
const Expression &expression() const { return m_data->expression(); }
|
||||||
{
|
RelationalOperator op() const { return m_data->op(); }
|
||||||
return m_data->m_expression;
|
double strength() const { return m_data->strength(); }
|
||||||
}
|
bool violated() const { return m_data->violated(); }
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!() const
|
bool operator!() const
|
||||||
{
|
{
|
||||||
@@ -81,45 +112,9 @@ public:
|
|||||||
Constraint& operator=(Constraint &&) noexcept = default;
|
Constraint& operator=(Constraint &&) noexcept = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Expression reduce(const Expression &expr)
|
SharedDataPtr<ConstraintData> m_data;
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
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)
|
friend bool operator<(const Constraint &lhs, const Constraint &rhs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,63 +13,55 @@
|
|||||||
namespace kiwi
|
namespace kiwi
|
||||||
{
|
{
|
||||||
|
|
||||||
class Variable
|
class VariableData : public SharedData
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
VariableData(std::string name) : SharedData(),
|
||||||
|
m_name(std::move(name)),
|
||||||
|
m_value(0.0) {}
|
||||||
|
|
||||||
public:
|
VariableData(const char *name) : SharedData(),
|
||||||
class Context
|
m_name(name),
|
||||||
{
|
m_value(0.0) {}
|
||||||
public:
|
|
||||||
Context() = default;
|
~VariableData() = default;
|
||||||
virtual ~Context() {} // LCOV_EXCL_LINE
|
|
||||||
|
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() : m_data(new VariableData("")) {}
|
||||||
|
|
||||||
Variable(const char *name, Context *context = 0) : m_data(new VariableData(name, context)) {}
|
|
||||||
|
|
||||||
|
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(const Variable&) = default;
|
||||||
|
|
||||||
Variable(Variable&&) noexcept = default;
|
Variable(Variable&&) noexcept = default;
|
||||||
|
|
||||||
~Variable() = default;
|
~Variable() = default;
|
||||||
|
|
||||||
const std::string &name() const
|
const std::string &name() const { return m_data->name(); }
|
||||||
{
|
void setName(const char *name) { m_data->setName(name); }
|
||||||
return m_data->m_name;
|
void setName(const std::string &name) { m_data->setName(name); }
|
||||||
}
|
|
||||||
|
|
||||||
void setName(const char *name)
|
double value() const { return m_data->value(); }
|
||||||
{
|
void setValue(double value) { m_data->setValue(value); }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// operator== is used for symbolics
|
// operator== is used for symbolics
|
||||||
bool equals(const Variable &other)
|
bool equals(const Variable &other)
|
||||||
@@ -82,32 +74,6 @@ public:
|
|||||||
Variable& operator=(Variable&&) noexcept = default;
|
Variable& operator=(Variable&&) noexcept = default;
|
||||||
|
|
||||||
private:
|
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;
|
SharedDataPtr<VariableData> m_data;
|
||||||
|
|
||||||
friend bool operator<(const Variable &lhs, const Variable &rhs)
|
friend bool operator<(const Variable &lhs, const Variable &rhs)
|
||||||
|
|||||||
Reference in New Issue
Block a user