Skip to content

Commit

Permalink
SOCP with Sqrt() #192
Browse files Browse the repository at this point in the history
Recognize quadratic cones in std form x >= sqrt( ||.||^2 )

This required reference counting #201 for defined variables
  • Loading branch information
glebbelov committed Mar 1, 2023
1 parent 1f8ac18 commit 6ff2deb
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 28 deletions.
7 changes: 6 additions & 1 deletion include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ class BasicConstraintKeeper {
virtual void SetChosenAcceptanceLevel(
ConstraintAcceptanceLevel acc) { acceptance_level_ = acc;}

/// Mark as deleted, use index only
virtual void MarkAsDeleted(int i) = 0;


protected:
int& GetAccLevRef() { return acceptance_level_; }
Expand Down Expand Up @@ -218,10 +221,12 @@ struct ConstraintLocationHelper {
int index_ = 0; // constraint index
};


/// Without constraint type
using AbstractConstraintLocation =
ConstraintLocationHelper<BasicConstraintKeeper>;


/// Converters handling custom constraints should derive from
class BasicFlatConverter {
public:
Expand Down Expand Up @@ -470,7 +475,7 @@ class ConstraintKeeper : public BasicConstraintKeeper {

public:
/// Mark as deleted, use index only
void MarkAsDeleted(int i) {
void MarkAsDeleted(int i) override {
MarkAsDeleted(cons_.at(i), i);
}

Expand Down
10 changes: 7 additions & 3 deletions include/mp/flat/convert_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class BasicFCC {
SetResultVar(GetConverter().
template GetConstraint<Constraint>(i).
GetResultVar());
if (GetConverter().DoingAutoLinking()) { // Autolink known targets
GetConverter().IncrementVarUsage(GetResultVar());
if (GetConverter().DoingAutoLinking()) { // Autolink known targets
auto& varvn = GetConverter().GetVarValueNode();
GetConverter().AutoLink( varvn.Select(GetResultVar()) );
auto& ck = GetConverter().GetConstraintKeeper(
Expand All @@ -46,7 +47,9 @@ class BasicFCC {
}
int GetResultVar() const { return prepro_.get_result_var(); }
protected:
void SetResultVar(int r) { prepro_.set_result_var(r); }
void SetResultVar(int r) {
prepro_.set_result_var(r);
}
public:
BasicFCC(Converter& cvt, Constraint&& fc) noexcept :
converter_(cvt), constr_(std::move(fc)) { }
Expand Down Expand Up @@ -93,7 +96,8 @@ class BasicFCC {
auto r = GetConverter().AddVar(lb(), ub(), type());
SetResultVar( r );
GetConstraint().SetResultVar( r );
}
GetConverter().IncrementVarUsage(r);
}
void AddConstraint() {
GetConverter().AddConstraint( std::move(GetConstraint()) );
}
Expand Down
93 changes: 82 additions & 11 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class FlatConverter :
AssignResult2Args(FuncConstraint&& fc) {
auto fcc = MakeFuncConstrConverter<Impl, FuncConstraint>(
*this, std::forward<FuncConstraint>(fc));
return fcc.Convert();
return fcc.Convert();
}

/// Same, but always return a variable
Expand All @@ -149,19 +149,67 @@ class FlatConverter :
return vc.get_var();
}

/// Replace functional expression defining a given variable
/// Typedef ConInfo; constraint location
using ConInfo = AbstractConstraintLocation;

/// Replace functional expression defining a given variable.
template <class FuncConstraint>
void RedefineVariable(int res_var, FuncConstraint&& fc) {
assert( MPD( HasInitExpression(res_var) ) );
auto ci_old = MPD( GetInitExpression(res_var) );
fc.SetResultVar(res_var);
auto i = MPD( AddConstraint(std::move(fc) ) );
auto& ck = GET_CONSTRAINT_KEEPER( FuncConstraint );
// If this expression exists, use it.
// TODO make sure any new context is re-converted
// if necessary.
auto i = MPD( MapFind(fc) );
if (i<0)
i = MPD( AddConstraint(std::move(fc)) );
auto& ck = GET_CONSTRAINT_KEEPER( FuncConstraint );
ConInfo ci{&ck, i};
ReplaceInitExpression(res_var, ci);
MarkAsDeleted(ci_old);
}


/// Variables' reference counting ///////////////////////////////////
/// Currently only for defined variables ////////////////////////////

/// Use "+1" a variable
void IncrementVarUsage(int v) {
++VarUsageRef(v);
}

/// Unuse result variable.
/// Throw if already not used.
void DecrementVarUsage(int v) {
assert(VarUsageRef(v)>0);
if (! (--VarUsageRef(v))) {
if (HasInitExpression(v))
MarkAsDeleted(GetInitExpression(v));
}
}

/// Fix unused defined vars.
/// Normally should delete them.
void FixUnusedDefinedVars() {
for (auto i=num_vars(); i--; ) {
if (HasInitExpression(i) &&
! VarUsageRef(i))
set_var_ub(i, lb(i));
}
}


protected:
int& VarUsageRef(int i) {
assert(i>=0 && i<num_vars());
if (i>=refcnt_vars_.size())
refcnt_vars_.resize(
std::max((size_t)num_vars(),
(size_t)(refcnt_vars_.size()*1.4)));
return refcnt_vars_[i];
}

//////////////////////////// CUSTOM CONSTRAINTS CONVERSION ////////////////////////////
///
//////////////////////////// THE CONVERSION LOOP: BREADTH-FIRST ///////////////////////
Expand Down Expand Up @@ -369,11 +417,25 @@ class FlatConverter :
return AddConstraint( std::move(con) );
}

/// Retrieve constraint of specified type at location \a ci.
template <class Constraint>
const Constraint& GetConstraint(int i) const {
return GET_CONST_CONSTRAINT_KEEPER(Constraint).GetConstraint(i);
const Constraint& GetConstraint(const ConInfo& ci) const {
assert(MPCD(template IsConInfoType<Constraint>(ci) ));
return GET_CONST_CONSTRAINT_KEEPER(Constraint).
GetConstraint(ci.GetIndex());
}

/// Retrieve constraint of specified type at index \a i.
template <class Constraint>
const Constraint& GetConstraint(int i) const {
return GET_CONST_CONSTRAINT_KEEPER(Constraint).GetConstraint(i);
}

/// Delete constraint
void MarkAsDeleted(const ConInfo& ci) {
ci.GetCK()->MarkAsDeleted(ci.GetIndex());
}

protected:
USE_BASE_MAP_FINDERS( BaseConverter )

Expand Down Expand Up @@ -413,6 +475,7 @@ class FlatConverter :
MPD( ConvertModel() );
if (relax())
GetModel().RelaxIntegrality();
FixUnusedDefinedVars(); // Until we have proper var deletion
GetModel().PushModelTo(GetModelAPI());
MPD( CloseGraphExporter() );
if (value_presolver_.GetExport())
Expand Down Expand Up @@ -495,6 +558,8 @@ class FlatConverter :


public:
/// Shortcut num_vars()
int num_vars() const { return MPCD(GetModel()).num_vars(); }
/// Shortcut lb(var)
double lb(int var) const { return this->GetModel().lb(var); }
/// Shortcut ub(var)
Expand Down Expand Up @@ -554,9 +619,6 @@ class FlatConverter :
return MP_DISPATCH( Convert2Var(std::move(ae)) );
}

/// Typedef ConInfo
using ConInfo = AbstractConstraintLocation;

/// Add vector of variables. Type: var::CONTINUOUS by default
/// @return vector of the Ids of the new vars
std::vector<int> AddVars_returnIds(std::size_t nvars,
Expand Down Expand Up @@ -605,10 +667,17 @@ class FlatConverter :

/// Get the init expr
const ConInfo& GetInitExpression(int var) const {
assert(HasInitExpression(var));
return var_info_[var];
return var_info_.at(var);
}

/// Check if the constraint location points to the
/// constraint keeper used for this ConType.
template <class ConType>
bool IsConInfoType(const ConInfo& ci) const {
return &(BasicConstraintKeeper&)
(GET_CONST_CONSTRAINT_KEEPER(ConType))
== ci.GetCK();
}

/////////////////////// AUTO LINKING ////////////////////////////

Expand Down Expand Up @@ -832,6 +901,8 @@ class FlatConverter :

ConicConverter<Impl> conic_cvt_ { *static_cast<Impl*>(this) };

std::vector<int> refcnt_vars_;


protected:
/////////////////////// CONSTRAINT KEEPERS /////////////////////////
Expand Down
Loading

0 comments on commit 6ff2deb

Please sign in to comment.