Skip to content

Commit

Permalink
MP2NL: write MILP #237
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Sep 10, 2024
1 parent 507b489 commit c5c247f
Show file tree
Hide file tree
Showing 13 changed files with 2,155 additions and 115 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ if (BUILD_EXAMPLES OR NLW2_LIB)
set(NLW2_DOC_SRC ${NLW2_SRC})
# Export library target names
# for a calling CMake project
set(NLW2_LIB_NAME ${NLW2_LIB_NAME} PARENT_SCOPE)
set(NLW2_INCLUDE_PATH ${NLW2_INCLUDE_PATH} PARENT_SCOPE)
set(NLW2_LIB_NAME ${NLW2_LIB_NAME} PARENT_SCOPE)
set(NLW2_C_API_LIB_NAME ${NLW2_C_API_LIB_NAME} PARENT_SCOPE)
# Add to folders to better organize project in IDEs
add_to_folder(${MP_FOLDER_PREFIX}nlw nlw2 nlw2_c_api nl-writer-example-c nl-writer-example-cpp)
Expand Down
5 changes: 4 additions & 1 deletion include/mp/flat/converter_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ class FlatModel
/// Push variables
if (var_names_storage_.size() > 0) {
// Convert names to c-str if needed
var_names_.reserve(var_names_storage_.size());
for (const std::string& s : var_names_storage_)
var_names_.push_back(s.c_str());
backend.AddVariables({ var_lb_subm_, var_ub_subm_, var_type_, var_names_ });
Expand Down Expand Up @@ -436,7 +437,9 @@ class FlatModel
template <class Backend>
void SetObjectiveTo(
Backend& backend, int i, const QuadraticObjective& obj) const {
if (obj.GetQPTerms().size())
if (obj.HasExpr())
backend.SetNLObjective(i, obj);
else if (obj.GetQPTerms().size())
backend.SetQuadraticObjective(i, obj);
else
backend.SetLinearObjective(i, obj);
Expand Down
5 changes: 5 additions & 0 deletions include/mp/flat/model_api_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,15 @@ class BasicFlatModelAPI {
/// Whether accepts NLObjective (relevant in BasicExprModelAPI)
static int AcceptsNLObj() { return 0; }


/// Placeholder for SetQuadraticObjective()
void SetQuadraticObjective(int , const QuadraticObjective& ) {
MP_UNSUPPORTED("FlatModelAPI::SetQuadraticObjective()");
}
/// Placeholder for SetNLObjective()
void SetNLObjective(int , const NLObjective& ) {
MP_UNSUPPORTED("FlatModelAPI::SetNLObjective()");
}

/// Placeholder for AddConstraint<>()
template <class Constraint>
Expand Down
4 changes: 2 additions & 2 deletions nl-writer2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ set(NLW2_INC_FILES
${NLW2_INCLUDE_PATH}/mp/nl-model.h
${NLW2_INCLUDE_PATH}/mp/nl-solver.h
${NLW2_INCLUDE_PATH}/mp/nl-solver.hpp
${NLW2_INCLUDE_PATH}/mp/nl-feeder.h
${NLW2_INCLUDE_PATH}/mp/nl-writer2.h
${NLW2_INCLUDE_PATH}/mp/nl-feeder.h
${NLW2_INCLUDE_PATH}/mp/nl-writer2.h
${NLW2_INCLUDE_PATH}/mp/nl-writer2.hpp
${NLW2_INCLUDE_PATH}/mp/nl-writer2-misc.h
${NLW2_INCLUDE_PATH}/mp/nl-utils.h
Expand Down
8 changes: 5 additions & 3 deletions nl-writer2/include/mp/nl-feeder.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ namespace mp {
`~mp::NLFeeder` can be used as a base class for other feeders,
or just be an interface prototype.
**Subclassed examples:**
**Subclassed interfaces and examples:**
- Simplified (MI)QP interface via `~mp::NLModel`,
`~mp::NLFeeder_Easy`
- C API implementation class `~mp::NLW2_NLFeeder_C_Impl`
- Other examples/tests, e.g., see `ExampleNLFeeder`.
- Smaller examples/tests, e.g., see the example folder.
- MP2NL is a meta-driver interfacing the MP library
to external NL solvers.
@param: *Impl* is the final CRTP type
derived from `~mp::NLFeeder`.
derived from `~mp::NLFeeder`. Currently unused.
@param: *ExprType* is a type storing expressions from
methods such as `~mp::NLFeeder::FeedExpr`. If not used,
Expand Down
12 changes: 11 additions & 1 deletion nl-writer2/include/mp/nl-writer2.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ class NLWriter2 :
template <class Index, class Value>
class SparseVectorWriter {
public:
/// Index type
using index_type = Index;
/// Value type
using value_type = Value;
/// Construct
SparseVectorWriter() { }
/// Not construct(const&)
Expand Down Expand Up @@ -216,6 +220,12 @@ class NLWriter2 :
template <class Index, class Value>
class SingleSparseVecWrtFactory {
public:
/// Index type
using index_type = Index;
/// Value type
using value_type = Value;
/// Vector writer type
using writer_type = SparseVectorWriter<Index, Value>;
/// Construct.
/// @param fmt: format string for printf()
/// containing %d for the number of sparse elements
Expand Down Expand Up @@ -551,7 +561,7 @@ class NLWriter2 :
/// Start writing an int-valued suffix.
SuffixIntWriter StartIntSuffix(
const char* name, int kind, int nnz);
/// Start writing an dbl-valued suffix.
/// Start writing a dbl-valued suffix.
SuffixDblWriter StartDblSuffix(
const char* name, int kind, int nnz);

Expand Down
2 changes: 1 addition & 1 deletion nl-writer2/include/mp/sol-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace mp {
\rst
SOLHandler: reads solution details on request
via provided callback objects.
See the examples folder.
See the examples folder and the MP2NL driver.
`~mp::SOLHandler` can be used as a base class for other handlers,
or just be an interface prototype.
Expand Down
252 changes: 252 additions & 0 deletions nl-writer2/include/mp/unused/nl-feeder-abstract-defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
#ifndef NLFEEDERABSTRACTDEFS_H
#define NLFEEDERABSTRACTDEFS_H


namespace mp {

/// SparseVectorWriter<> interface
template <class T>
class BasicSparseVectorWriter {
public:
/// Virtual destruct
virtual ~BasicSparseVectorWriter() { }
/// Number of elements left to write
virtual int NLeft() const = 0;
/// Write entry
virtual void Write(int index, T value) = 0;
};

/// Typedef sparse int vec writer
using BasicSparseIntVecWriter = BasicSparseVectorWriter<int>;

/// Typedef sparse double vec writer
using BasicSparseDblVecWriter = BasicSparseVectorWriter<double>;


/// SparseVectorWriterFactory interface.
/// An implementation can be used once to produce a SparseVectorWriter<>.
template <class T>
class BasicSparseVectorWriterFactory {
public:
/// Virtual destruct
virtual ~BasicSparseVectorWriterFactory() { }
/// Make the SparseVectorWriter.
/// @note std::size_t without include:
/// https://stackoverflow.com/questions/36594569/which-header-should-i-include-for-size-t.
virtual BasicSparseVectorWriter<T>&
MakeVectorWriter(decltype(sizeof(int)) nnz) = 0;
};

/// Typedef sparse int vec writer factory
using BasicSparseIntVecWrtFactory = BasicSparseVectorWriterFactory<int>;

/// Typedef sparse double vec writer factory
using BasicSparseDblVecWrtFactory = BasicSparseVectorWriterFactory<double>;


/// NLExprWriter interface.
/// @note Store ExprArgWriter's as local objects.
template <class Expr>
class BasicNLExprWriter {
public:
/// Virtual destruct
virtual ~BasicNLExprWriter() { }

/// Write the next arg as Feeder's native expression.
/// This recursively calls Feeder::FeedExpr().
virtual void EPut(Expr e) = 0;

/** Write the next arg as 'variable reference'.
* 0 <= index < num_vars is a solver variable;
* index >= num_vars is a defined variable. */
virtual void VPut(int v, const char* descr="") = 0;

/** Write numeric constant expression. */
virtual void NPut(double x) = 0;

/** Write string constant expression. */
virtual void StrPut(const char* ) = 0;


/// typedef ExprArgWriter
/// @todo return temporary
using ExprArgWriter = int; // BasicNLExprWriter;

/** Write the next arg as function call expression. */
virtual ExprArgWriter FuncPut(
int index, int nArgs, const char* descr="") = 0;

/// Write the next arg as AMPL opcode for a unary op.
/// @return 1-arg writer.
virtual ExprArgWriter OPut1(int opcode, const char* descr="") = 0;
/// Write AMPL opcode for a binary op.
virtual ExprArgWriter OPut2(int opcode, const char* descr="") = 0;
/// Write AMPL opcode for a 3-arg op.
virtual ExprArgWriter OPut3(int opcode, const char* descr="") = 0;

/// Write AMPL opcode for an iterated op (min, exists, sum, etc).
/// For a piecewise-linear expression, \a nArgs should be
/// 2*(N slopes) and the arguments are:
/// break points, slopes, argument variable.
virtual ExprArgWriter OPutN(
int opcode, int nArgs, const char* descr="") = 0;

/// Shortcut: OPut1( struct Opcode )
template <class Opcode> ExprArgWriter OPut1(Opcode oc)
{ return OPut1(oc.code, oc.name); }
/// Shortcut: OPut2( struct Opcode )
template <class Opcode> ExprArgWriter OPut2(Opcode oc)
{ return OPut2(oc.code, oc.name); }
/// Shortcut: OPut3( struct Opcode )
template <class Opcode> ExprArgWriter OPut3(Opcode oc)
{ return OPut3(oc.code, oc.name); }
/// Shortcut: OPutN( struct Opcode, int nArgs )
template <class Opcode> ExprArgWriter OPutN(
Opcode oc, int nArgs)
{ return OPutN(oc.code, nArgs, oc.name); }
};


/** Interface: writer of a defined variable. */
template <class Expr>
class BasicNLDefVarWriter {
public:
/// Virtual destruct
virtual ~BasicNLDefVarWriter() { }

/// Write entries c*var[v] to the linear part
/// of the defining expression.
/// All nnz entries should be written before
/// the nonlinear expression.
/// This method can be called only once.
virtual BasicSparseDblVecWriter& GetLinExprWriter() = 0;

/// Retrieve the nonlinear expression writer.
/// Should be used after the linear expression.
virtual BasicNLExprWriter<Expr>& GetExprWriter() = 0;
};


/** Interface: BasicNLDefVarWriterFactory.
* Write a sequence of defined variables,
* for example, all such used in a certain constraint. */
template <class Expr>
class BasicNLDefVarWriterFactory {
public:
/// Virtual destruct.
virtual ~BasicNLDefVarWriterFactory() { }

/// Start writing a defined variable.
///
/// @param index: defined variable index, used to
/// reference it in subsequent expression graphs.
/// Thus, the index should be >= num_vars,
/// < num_vars+num_common_exprs.
/// Providing the index explicitly, because classical NL
/// likes special order of defined variables.
///
/// @param nnz: number of nonzeros in the linear part.
///
/// @param descr: meta-information - what is this variable,
/// for example, "nl(t[2])".
/// Providing it here because it's not
/// included in ColNames().
///
/// @return A callback object writing
/// a single defined variable.
virtual BasicNLDefVarWriter<Expr>& StartDefVar(
int index, int nnz, const char* descr="") = 0;
};


/** Interface: write \a num_vars variable bounds
* (all except defined variables). */
class BasicNLVarBndWriter {
public:
/// virtual destruct
virtual ~BasicNLVarBndWriter() { }
/// Write range for the next variable.
virtual void WriteLbUb(double lb, double ub) = 0;
};


/** Interface: write \a num_algebraic_cons constraint bounds. */
class BasicNLConBndWriter {
public:
/// Virtual destruct
virtual ~BasicNLConBndWriter() { }
/// Write range/complementarity for the next constraint.
virtual void WriteAlgConRange(
double L, double U,
int k, int cvar) = 0;
};


/// Interface: int suffix writer
using BasicNLSuffixIntWriter = BasicSparseIntVecWriter;

/// Interface: double-valued suffix writer
using BasicNLSuffixDblWriter = BasicSparseDblVecWriter;

/** Interface: suffixes. */
class BasicNLSuffixWriterFactory {
public:
/// Virtual destruct
virtual ~BasicNLSuffixWriterFactory() { }
/// Start writing an int-valued suffix.
virtual BasicNLSuffixIntWriter& StartIntSuffix(
const char* name, int kind, int nnz) = 0;
/// Start writing a dbl-valued suffix.
virtual BasicNLSuffixDblWriter& StartDblSuffix(
const char* name, int kind, int nnz) = 0;
};


/** Interface: PL-SOS constraints. */
class BasicPLSOSWriter {
public:
/// Virtual destruct.
virtual ~BasicPLSOSWriter() { }
/// .sos for variables
virtual BasicNLSuffixIntWriter& StartSOSVars(int nnz) = 0;
/// .sos for constraints
virtual BasicNLSuffixIntWriter& StartSOSCons(int nnz) = 0;
/// .sosref for variables
virtual BasicNLSuffixDblWriter& StartSOSREFVars(int nnz) = 0;
};


/** Interface: write num_vars+num_rand_vars-1
* column sizes */
class BasicNLColSizeWriter {
public:
/// Virtual destruct
virtual ~BasicNLColSizeWriter() { }

/// Write next col's size
virtual void Write(int s) = 0;
};


/// Interface: string file writer
class BasicNLNameFileWriter {
public:
/// Virtual destruct
virtual ~BasicNLNameFileWriter() { }

/// operator bool
virtual operator bool() const = 0;

/// Write 1 string
virtual void Write(const char* name) = 0;

/// Write 2 strings (name, comment)
virtual void Write(const char* name, const char* cmt) = 0;

/// Write 1 string, 1 double
virtual void Write(const char* name, double num) = 0;
};

} // namespace mp

#endif // NLFEEDERABSTRACTDEFS_H
Loading

0 comments on commit c5c247f

Please sign in to comment.