Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:ampl/mp into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mapgccv committed Nov 29, 2023
2 parents 1cc94cb + 5983dee commit 35e5f1c
Show file tree
Hide file tree
Showing 39 changed files with 570 additions and 156 deletions.
4 changes: 2 additions & 2 deletions doc/source/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,14 @@ NL Writer APIs
- **NL Writer C++ API** is provided by classes
`mp::NLSOL`, `mp::NLFeeder2`, `mp::SOLHandler2`.
See
`example </~https://github.com/ampl/mp/blob/develop/nl-writer2/examples/cpp/nlsol_ex.cc>`_
`C++ API example </~https://github.com/ampl/mp/blob/develop/nl-writer2/examples/cpp/nlsol_ex.cc>`_
solving a small non-linear model.

- **NL Writer C API** is provided by structs
`NLW2_NLSOL_C`, `NLW2_NLFeeder2_C`, `NLW2_SOLHandler2_C`.
*Currently only linear models are supported.*
See
`example </~https://github.com/ampl/mp/blob/develop/nl-writer2/examples/c/nlsol_ex_c.c>`_
`C API example </~https://github.com/ampl/mp/blob/develop/nl-writer2/examples/c/nlsol_ex_c.c>`_
solving a small linear model.


Expand Down
3 changes: 0 additions & 3 deletions include/mp/ampls-cpp-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ extern "C" {
/// This function is not for the user.
///
/// @param p_be: GurobiBackend etc.
/// @param slv_opt: a string of solver options
/// (normally provided in the <solver>_options variable).
/// Can be \a nullptr.
/// @return slv on success, otherwise NULL and use AMPLSGetMessages()
/// (well they can contain warnings in any case).
AMPLS_MP_Solver* AMPLS__internal__Open(std::unique_ptr<mp::BasicBackend> p_be,
Expand Down
4 changes: 1 addition & 3 deletions include/mp/backend-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ class BasicBackend : public BasicSolver {
}

/// Parse solver options such as "outlev=1" from env and argv.
/// @param filename_no_ext: basname of the .nl file
/// (or whatever should be the basename of an output .sol file)
/// @param argv: (remaining part of) vector of cmdline strings
/// @param flags: 0 or \a Solver::NO_OPTION_ECHO
virtual
Expand All @@ -58,7 +56,7 @@ class BasicBackend : public BasicSolver {
/// Read NL.
/// This is also used by the AMPLS C API.
/// @param opts: 0-terminated list of extra options,
/// to be read after the <solver>_options nev var.
/// to be read after the [solver]_options nev var.
/// All model-related options should be here
/// (obj:.../objno/multiobj, cvt:..., acc:...),
/// they are not effective after NL input.
Expand Down
4 changes: 2 additions & 2 deletions include/mp/backend-std.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class StdBackend :
* No API to overload,
* Impl should check:
* - feasrelax() returns feasrelax mode
* - feasrelax().<methods> give the API
* - feasrelax().(methods) give the API
**/
DEFINE_STD_FEATURE(FEAS_RELAX)
ALLOW_STD_FEATURE(FEAS_RELAX, false)
Expand Down Expand Up @@ -233,7 +233,7 @@ class StdBackend :

/// Read NL.
/// @param opts: extra options
/// (to be read after <solver>_options env var).
/// (to be read after the [solver]_options env var).
/// All model-related options should be here
/// (obj:.../objno/multiobj, cvt:..., acc:...).
void ReadNL(const std::string& nl_filename,
Expand Down
2 changes: 1 addition & 1 deletion include/mp/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ class BasicExprFactory : private Alloc {
exprs_.push_back(0);
typedef typename ExprType::Impl Impl;
/// The following cannot overflow.
/// Using ::new due to #174
/// Using `~new` due to #174
Impl *impl = (Impl*) new char* [sizeof(Impl) + extra_bytes];
impl->kind_ = kind;
exprs_.back() = impl;
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_general.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ using SOS2Constraint = SOS_1or2_Constraint<2>;

////////////////////////////////////////////////////////////////////////
/// Complementarity constraint.
/// <Expr> complements a variable.
/// \a Expr complements a variable.
/// @param Expr: an affine or quadratic functional expression
template <class Expr>
class ComplementarityConstraint : public BasicConstraint {
Expand Down
2 changes: 1 addition & 1 deletion include/mp/flat/constr_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ using VarInfoStatic = VarInfoImpl<VarVecStatic>;
/// Solution check data
struct SolCheck {
/// Construct.
/// @param chkmode: can be subset of 1+2+4+8+16
/// @param chk_mode: can be subset of 1+2+4+8+16
SolCheck(ArrayRef<double> x,
const pre::ValueMapDbl& , //duals,
ArrayRef<double> obj,
Expand Down
6 changes: 4 additions & 2 deletions include/mp/flat/constr_prepro.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ class ConstraintPreprocessors {
}
con.GetArguments() = arg1;
}
IntegrateNested(con); // flatten nested
if (MPCD( IfPreproNestedAndsOrs() ))
IntegrateNested(con); // flatten nested
}

template <class PreprocessInfo>
Expand All @@ -362,7 +363,8 @@ class ConstraintPreprocessors {
}
con.GetArguments() = arg1;
}
IntegrateNested(con); // flatten nested
if (MPCD( IfPreproNestedAndsOrs() ))
IntegrateNested(con); // flatten nested
}

/// Count N fixed binary vars
Expand Down
4 changes: 2 additions & 2 deletions include/mp/flat/constr_prop_down.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ class ConstraintPropagatorsDown {
}

/// Context of the condition in IfThen.
/// @args: [condition, then, else] result variables
/// @ctx: context of the overall expression
/// @param args: [condition, then, else] result variables
/// @param ctx: context of the overall expression
template <class Array3>
void PropagateIfThenResultIntoCondition(Array3 args, Context ctx) {
Context ctx_cond = Context::CTX_MIX;
Expand Down
8 changes: 4 additions & 4 deletions include/mp/flat/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ namespace mp {

/// Expression context
///
/// <result> <-> <Expression>
/// CTX_POS: expression is implied by the boolean result
/// CTX_NEG: expression's negation is implied by the neg result
/// CTX_MIX: expression is equivalent to the result variable
/// Considering the relation (result) <-> (Expression):
/// - CTX_POS: expression is implied by the boolean result
/// - CTX_NEG: expression's negation is implied by the neg result
/// - CTX_MIX: expression is equivalent to the result variable
class Context {
public:
/// Possible values
Expand Down
10 changes: 10 additions & 0 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ class FlatConverter :
int preprocessAnything_ = 1;
int preprocessEqualityResultBounds_ = 1;
int preprocessEqualityBvar_ = 1;
int preproNestedAndOrs_ = 1;

int passQuadObj_ = ModelAPIAcceptsQuadObj();
int passQuadCon_ = ModelAPIAcceptsQC();
Expand Down Expand Up @@ -987,6 +988,10 @@ class FlatConverter :
GetEnv().AddOption("cvt:pre:eqbinary",
"0/1*: Preprocess reified equality comparison with a binary variable.",
options_.preprocessEqualityBvar_, 0, 1);
GetEnv().AddOption("cvt:pre:unnest",
"0/1*: Inline nested expressions, currently Ands/Ors.",
options_.preproNestedAndOrs_, 0, 1);

GetEnv().AddOption("cvt:quadobj passquadobj",
ModelAPIAcceptsQuadObj() ?
"0/1*: Multiply out and pass quadratic objective terms to the solver, "
Expand Down Expand Up @@ -1091,6 +1096,11 @@ class FlatConverter :
bool IfPreproEqBinVar() const
{ return MPCD( CanPreprocess(options_.preprocessEqualityBvar_) ); }

/// Whether inline nested forall, exists
bool IfPreproNestedAndsOrs() const
{ return MPCD( CanPreprocess(options_.preproNestedAndOrs_) ); }


/// Whether we pass quad obj terms to the solver without linearization
bool IfPassQuadObj() const { return options_.passQuadObj_; }

Expand Down
4 changes: 2 additions & 2 deletions include/mp/flat/redef/MIP/cond_ineq.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Cond_LE_LT_GT_GE_Converter_MIP :
static constexpr int kind_input = AlgCon::kind();

/// Convert in positive context:
/// resvar==1 --> <body> (cmp) <rhs>
/// resvar==1 --> (body) (cmp) (rhs)
void ConvertCtxPos(const ItemType& cc, int ) {
constexpr auto kind_output = // output comparison is <= or >=
( kind_input>0 ) ? 1 : -1; // even for < or >
Expand All @@ -44,7 +44,7 @@ class Cond_LE_LT_GT_GE_Converter_MIP :
}

/// Convert in negative context:
/// resvar==0 --> (body) (!cmp) <rhs>
/// resvar==0 --> (body) (!cmp) (rhs)
void ConvertCtxNeg(const ItemType& cc, int ) {
constexpr auto kind_output = // output comparison is <= or >=
( kind_input>0 ) ? -1 : 1; // even for < or >
Expand Down
21 changes: 19 additions & 2 deletions include/mp/flat/redef/MIP/converter_mip.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef MP2MIP_H
#define MP2MIP_H

#include <climits>

#include "mp/flat/converter.h"
#include "mp/flat/redef/MIP/redefs_mip_std.h"
#include "mp/flat/redef/encodings.h"
Expand Down Expand Up @@ -267,7 +269,7 @@ class MIPFlatConverter
/// @return true if don't need UEnc for var
bool DontNeedEqEncForVar(int var, const SingleVarEqConstMap& map) {
double dom_rng = MPCD(ub(var))-MPCD(lb(var))+1;
if (3 * map.size() // Use UEnc if we have >1/3 of the domain values
if (options_.NoUEncPosCtxRatio_ * map.size() // Use UEnc if >
> dom_rng)
return false;
int nNegCtx = 0;
Expand All @@ -279,7 +281,7 @@ class MIPFlatConverter
} // When up to 1 value in negative ctx, allow indicators.
// Example:
// x==5 ==> ...
return nNegCtx <= 1;
return nNegCtx <= options_.NoUEncNegCtxMax_;
}

/// Manually convert all comparisons for this variable
Expand Down Expand Up @@ -356,6 +358,8 @@ class MIPFlatConverter
double bigM_default_ { -1 };
double PLApproxRelTol_ { 1e-2 };
double PLApproxDomain_ { 1e6 };
double NoUEncPosCtxRatio_ { 0.0 };
int NoUEncNegCtxMax_ { 1 };
};
Options options_;

Expand All @@ -379,6 +383,19 @@ class MIPFlatConverter
"For piecewise-linear approximated functions, both arguments and result "
"are bounded to +-[pladomain]. Default 1e6.",
options_.PLApproxDomain_, 0.0, 1e100);
this->GetEnv().AddOption("cvt:uenc:ratio uenc:ratio",
"Min ratio (ub-lb)/Nvalues to skip unary encoding "
"for a variable x, where Nvalues is the number of constants "
"used in conditional comparisons x==const. Instead, "
"indicator constraints (or big-Ms) are used, if "
"uenc:negctx also applies. Default 0.",
options_.NoUEncPosCtxRatio_, 0.0, 1e100);
this->GetEnv().AddOption("cvt:uenc:negctx:max uenc:negctx:max uenc:negctx",
"If cvt:uenc:ratio applies, max number of constants "
"in comparisons x==const in negative context "
"(equivalently, x!=const in positive context) to skip "
"UEnc(x). Default 1.",
options_.NoUEncNegCtxMax_, 0, INT_MAX);
}
};

Expand Down
2 changes: 0 additions & 2 deletions include/mp/flat/redef/conic/cones.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ class Convert1QC : public MCKeeper<MCType> {
/// Considering const>=0.
/// Accept non-(+-1) coefficients.
///
/// @param body: linear constraint body.
/// @param sens: -1 for <=, 1 for >=.
/// @param rhs: constraint's rhs.
///
Expand Down Expand Up @@ -680,7 +679,6 @@ class Convert1ExpC : public MCKeeper<MCType> {
///
/// Accept non-(+-1) coefficients.
///
/// @param body: linear constraint body.
/// @param sens: -1 for <=, 1 for >=.
/// @param rhs: constraint's rhs.
///
Expand Down
2 changes: 1 addition & 1 deletion include/mp/nl-header-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ typedef struct NLHeader_C {


/// Default NLHeader_C
NLHeader_C MakeNLHeader_C_Default();
NLHeader_C MakeNLHeader_C_Default(void);


#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion include/mp/solver-opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ class SolverOptionManager {
};


/// Stored option <bool>.
/// Stored option &lt;bool&gt;.
/// Can only be set to True.
template <>
class SolverOptionManager::StoredOption<bool>
Expand Down
4 changes: 2 additions & 2 deletions include/mp/valcvt-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ Array CreateArray(Param ) { return Array{}; }
/// When IsSingleKey(), the map only has a single array (at key 0),
/// accessible via ().
///
/// @param Array: the type of array stored (std::vector<int> / <double>),
/// @param Array: the type of array stored (std::vector(int) / (double)),
/// or ValueNode.
/// @param Param: type of parameter to call CreateArray<Array>(Param)
/// @param Param: type of parameter to call CreateArray &lt; Array &gt; (Param)
/// when we need to create a mapped value.
template <class Array, class Param=int>
class ValueMap {
Expand Down
21 changes: 19 additions & 2 deletions nl-writer2/examples/c/nlsol_ex_c_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "nlsol_ex_c_model.h"

CAPIExample MakeCAPIExample_Linear_01() {
CAPIExample MakeCAPIExample_Linear_01(void) {
/// Variables.
/// Put y first because continuous variables
/// come before integer ones.
Expand Down Expand Up @@ -38,6 +38,17 @@ CAPIExample MakeCAPIExample_Linear_01() {
static const SparseEntry obj_linpart[]
= { {0, 13}, {1, 1.0} };

static const double ini_x[] = {30.15, 15.11};
static const double ini_y[] = {-10, -120};

static const SparseEntry suf_val[] = {{0, 5.3}};

static int n_suf = 1;
static const Suffix suf[] = {
{"zork", 1+4, // constraints, float-valued
1, suf_val}
};

/// Solution
static double sol_dual[] = {NAN, NAN};
static double sol_primal[] = {NAN, NAN};
Expand Down Expand Up @@ -66,6 +77,12 @@ CAPIExample MakeCAPIExample_Linear_01() {
.n_obj_nz = 2,
.obj_name = "TotalSum",

.ini_x = ini_x,
.ini_y = ini_y,

.n_suf = n_suf,
.suf = suf,

.binary_nl = 1,

.sol_dual_ = sol_dual,
Expand Down Expand Up @@ -98,5 +115,5 @@ void PrintSolution_C(CAPIExample* pex, const char* stub) {
pex->var_name[i], pex->sol_primal_[i]);

printf("\nObjno used: %d, solve_result_num: %d\n",
pex->objno_, pex->solve_code_);
pex->objno_+1, pex->solve_code_);
}
30 changes: 26 additions & 4 deletions nl-writer2/examples/c/nlsol_ex_c_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ subj to C3:
22*x + 14536*y <= 3e5;
## Initial guess
let x := 1.5;
let y := 0.11;
let x := 30.15;
let y := 15.11;
## Dual initial guess
let C2 := -10;
let C3 := -120;
## A suffix
suffix zork;
let C2.zork := 5;
let C2.zork := 5.3;
*
*/
Expand All @@ -44,6 +48,15 @@ typedef struct SparseEntry {
} SparseEntry;


/// Suffix
typedef struct Suffix {
const char* name_;
int kind_;
int n_val_;
const SparseEntry* values_; // store double's always
} Suffix;


/// C API example data
typedef struct CAPIExample {
const int n_var;
Expand Down Expand Up @@ -97,6 +110,15 @@ typedef struct CAPIExample {
int n_obj_nz;
const char* obj_name;

/// Primal initial guess (dense vector).
const double* ini_x;
/// Primal dual guess (dense vector).
const double* ini_y;

/// Suffixes.
int n_suf;
const Suffix* suf;

/// Some technical stuff
int binary_nl;

Expand All @@ -109,7 +131,7 @@ typedef struct CAPIExample {
} CAPIExample;

/// Create linear example data
CAPIExample MakeCAPIExample_Linear_01();
CAPIExample MakeCAPIExample_Linear_01(void);

/// Destroy linear example data
void DestroyCAPIExample_Linear_01(CAPIExample* );
Expand Down
Loading

0 comments on commit 35e5f1c

Please sign in to comment.