11 #include "OsiSolverInterface.hpp"
13 #include "CoinPackedMatrix.hpp"
19 using namespace Ipopt;
24 SepaTMINLP2OsiLP::extract(OsiSolverInterface *si,
25 const double *
x,
bool getObj)
32 TNLP::IndexStyleEnum index_style;
34 model_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
37 model_->eval_jac_g(n, x, 1, m, nnz_jac_g, NULL, NULL, value_());
41 model_->eval_g(n, x, 1, m,
g());
48 const double * rowLower = model_->g_l();
49 const double * rowUpper = model_->g_u();
50 const double * colLower = model_->x_l();
51 const double * colUpper = model_->x_u();
53 double nlp_infty = si->getInfinity();
54 double infty = DBL_MAX;
56 for(
int i = 0 ; i <
m ; i++) {
57 if(const_types_[i] == Ipopt::TNLP::NON_LINEAR) {
58 if(rowLower[i] > - nlp_infty){
59 rowLow[i] = (rowLower[i] - g[i]) - 1
e-07;
63 if(rowUpper[i] < nlp_infty)
64 rowUp[i] = (rowUpper[i] - g[i]) + 1
e-07;
69 if(rowLower[i] > -nlp_infty){
70 rowLow[i] = (rowLower[i]);
74 if(rowUpper[i] < nlp_infty){
75 rowUp[i] = (rowUpper[i]);
86 for(
int i = 0 ; i < nnz_jac_g ; i++) {
89 cleanNnz(value_[i],colLower[jCol_[i]], colUpper[jCol_[i]],
90 rowLower[iRow_[i]], rowUpper[iRow_[i]],
93 rowUp[iRow_[i]], tiny_, very_tiny_)) {
94 if(rowLow[iRow_[i]] > -infty)
95 rowLow[iRow_[i]] += value_[i] * x[jCol_[i]];
96 if(rowUp[iRow_[i]] < infty)
97 rowUp[iRow_[i]] += value_[i] *x[jCol_[i]];
101 CoinPackedMatrix mat(
true, iRow_(), jCol_(), value_(), nnz_jac_g);
102 mat.setDimensions(m,n);
105 vector<double> act(m);
107 for(
int j = 0 ;
j <
m ;
j++){
108 if(
j==10 && fabs(x[0] - 4.73032) < 1
e-4)
109 assert(act[
j] + 1
e-5 > rowLow[
j] && act[
j] - 1
e-5 < rowUp[
j] + g[
j]);
114 for(
int i = 0 ; i <
n; i++)
118 si->loadProblem(mat, colLower, colUpper, obj(), rowLow(), rowUp());
119 for(
int i = 0 ; i <
n ; i++) {
124 if(model_->hasLinearObjective()){
127 model_->eval_f(n,
x0(), 1, zero);
128 si->setDblParam(OsiObjOffset, -zero);
130 model_->eval_grad_f(n, x, 1,obj());
131 si->setObjective(obj());
140 get_oas(cs, x, 0, 1);
147 SepaTMINLP2OsiLP::get_oas(OsiCuts &cs,
const double *
x,
bool getObj,
bool global)
const {
149 int n,
m, nnz_jac_g, nnz_h_lag;
150 TNLP::IndexStyleEnum index_style;
151 model_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
155 model_->eval_jac_g(n, x, 1, m, nnz_jac_g, NULL, NULL, value_());
156 model_->eval_g(n,x,0,m,
g());
164 std::vector<int> cut2rowIdx;
168 const double * rowLower = model_->g_l();
169 const double * rowUpper = model_->g_u();
170 const double * colLower = model_->x_l();
171 const double * colUpper = model_->x_u();
172 double nlp_infty = infty_;
173 double infty = DBL_MAX;
175 for(
int rowIdx = 0; rowIdx <
m ; rowIdx++) {
176 if(const_types_[rowIdx] == TNLP::NON_LINEAR) {
177 row2cutIdx[rowIdx] = numCuts;
178 cut2rowIdx.push_back(rowIdx);
179 if(rowLower[rowIdx] > - nlp_infty)
180 lb[numCuts] = rowLower[rowIdx] - g[rowIdx];
182 lb[numCuts] = -
infty;
183 if(rowUpper[rowIdx] < nlp_infty)
184 ub[numCuts] = rowUpper[rowIdx] - g[rowIdx];
196 for(
int i = 0 ; i < nnz_jac_g ; i++) {
197 const int &rowIdx = iRow_[i];
198 const int & cutIdx = row2cutIdx[ rowIdx ];
200 const int &colIdx = jCol_[i];
202 if(
cleanNnz(value_[i],colLower[colIdx], colUpper[colIdx],
203 rowLower[rowIdx], rowUpper[rowIdx],
206 ub[cutIdx], tiny_, very_tiny_)) {
207 if(fabs(value_[i]) > 1e15) {
208 printf(
"Not generating cut because of big coefficient %g col %i x[%i] = %g\n", value_[i], colIdx, colIdx, x[colIdx]);
211 cuts[cutIdx].insert(colIdx,value_[i]);
212 if(lb[cutIdx] > - infty)
213 lb[cutIdx] += value_[i] * x[colIdx];
214 if(ub[cutIdx] < infty)
215 ub[cutIdx] += value_[i] * x[colIdx];
220 for(
int cutIdx = 0; cutIdx < numCuts; cutIdx++) {
223 newCut.setGloballyValidAsInteger(1);
225 const int* ids = model_->get_const_xtra_id();
227 int binary_id = (ids == NULL) ? -1 : ids[cut2rowIdx[cutIdx]];
230 if (lb[cutIdx] > -infty) {
231 cuts[cutIdx].insert(binary_id, -lb[cutIdx]);
233 newCut.setUb(ub[cutIdx]);
236 if (ub[cutIdx] < infty) {
237 cuts[cutIdx].insert(binary_id, -ub[cutIdx]);
238 newCut.setLb(lb[cutIdx]);
244 newCut.setLb(lb[cutIdx]);
245 newCut.setUb(ub[cutIdx]);
248 newCut.setRow(cuts[cutIdx]);
251 printf(
"++++++++ I have generated %i cuts +++++++++\n", numCuts);
259 SepaTMINLP2OsiLP::get_oa(
int rowIdx, OsiCuts &cs,
const double *
x,
bool getObj,
bool global)
const {
261 int n,
m, nnz_jac_g, nnz_h_lag;
262 TNLP::IndexStyleEnum index_style;
263 model_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
266 model_->eval_gi(n,x,1, rowIdx,gi);
269 model_->eval_grad_gi(n, x, 0, rowIdx, nnz, jCol(), NULL);
270 model_->eval_grad_gi(n, x, 0, rowIdx, nnz, NULL, value_());
277 const double * rowLower = model_->g_l();
278 const double * rowUpper = model_->g_u();
279 const double * colLower = model_->x_l();
280 const double * colUpper = model_->x_u();
281 double nlp_infty = infty_;
282 double infty = DBL_MAX;
284 if (rowLower[rowIdx] > -nlp_infty)
285 lb = rowLower[rowIdx] - gi;
288 if (rowUpper[rowIdx] < nlp_infty)
289 ub = rowUpper[rowIdx] - gi;
293 CoinPackedVector cut;
296 for(
int i = 0 ; i <
nnz ; i++) {
297 if(index_style == Ipopt::TNLP::FORTRAN_STYLE) jCol[i]--;
298 const int &colIdx = jCol[i];
300 if(
cleanNnz(value_[i],colLower[colIdx], colUpper[colIdx],
301 rowLower[rowIdx], rowUpper[rowIdx],
304 ub, tiny_, very_tiny_)) {
305 if(fabs(value_[i]) > 1e15) {
306 printf(
"Not generating cut because of big coefficient %g col %i x[%i] = %g\n", value_[i], colIdx, colIdx, x[colIdx]);
309 cut.insert(colIdx,value_[i]);
311 lb += value_[i] * x[colIdx];
313 ub += value_[i] * x[colIdx];
319 newCut.setGloballyValidAsInteger(1);
321 const int* ids = model_->get_const_xtra_id();
323 int binary_id = (ids == NULL) ? -1 : ids[rowIdx];
327 cut.insert(binary_id, -lb);
333 cut.insert(binary_id, -ub);
349 SepaTMINLP2OsiLP::get_refined_oa(OsiCuts & cs)
const{
356 Ipopt::TNLP::IndexStyleEnum index_style;
358 model_->get_nlp_info(n, m, nnz_jac_g, nnz_h_lag, index_style);
362 const double * colLower = model_->x_l();
363 const double * colUpper = model_->x_u();
366 model_->get_variables_linearity(n, varTypes());
370 double * p = CoinCopyOfArray(colLower, n);
371 double * pp = CoinCopyOfArray(colLower, n);
372 double *
up = CoinCopyOfArray(colUpper, n);
374 std::vector<double> step(n);
377 for (
int i = 0; i <
n; i++) {
388 for (
int i = 0; i <
n; i++) {
392 p[i] = pp[i] = up[i] = 0;
395 step[i] = (up[i] - p[i]) / (num_approx_);
398 get_oas(cs, p, 0,
true);
399 for (
int j = 1;
j <= num_approx_;
j++) {
401 for (
int i = 0; i <
n; i++) {
405 get_oas(cs, pp, 0,
true);
409 get_oas(cs, up, 0,
true);
417 SepaTMINLP2OsiLP::add_outer_description_function_values(OsiSolverInterface &si) {
422 Ipopt::TNLP::IndexStyleEnum index_style;
424 model_->get_nlp_info(n, m, nnz_jac_g, nnz_h_lag, index_style);
428 const double * colLower = model_->x_l();
429 const double * colUpper = model_->x_u();
432 model_->get_variables_linearity(n, varTypes());
437 double * p = CoinCopyOfArray(colLower, n);
438 double * pp = CoinCopyOfArray(colLower, n);
439 double *
up = CoinCopyOfArray(colUpper, n);
440 double * low = CoinCopyOfArray(colLower, n);
446 for (
int i = 0; i <
n; i++) {
456 for (
int i = 0; i <
n; i++) {
460 low[i] = p[i] = pp[i] = up[i] = 0;
463 step[i] = (up[i] - low[i]) / (num_approx_*20);
466 get_oas(cs, low, 0,
true);
467 get_oas(cs, up, 0,
true);
470 model_->eval_g(n, low, 1, m, g_p());
471 model_->eval_g(n, up, 1, m, g_pp());
473 for (
int i = 0; (i <
m); i++) {
474 if(const_types_[i] != Ipopt::TNLP::NON_LINEAR)
continue;
475 double thresh = std::abs(g_pp[i] - g_p[i])/(num_approx_-1);
477 printf(
"Constraint %i threshold is %g lower val %g upper %g\n",i, thresh,
479 std::copy(low, low + n, p);
480 std::copy(low, low + n, pp);
481 double g_p_i, g_pp_i;
484 while (nbG[i] < num_approx_) {
487 for (
int j = 0;
j <
n;
j++) {
490 model_->eval_gi(n, pp, 1, i, g_pp_i);
492 if (std::abs(g_p_i - g_pp_i)>=thresh ) {
493 printf(
"Function value after %i steps %g\n", n_steps, g_pp_i);
494 get_oa(i, cs, pp, 0,
true);
495 for (
int j = 0;
j <
n;
j++) {
bool IsValid(const OSSmartPtr< U > &smart_ptr)
void fint fint fint real fint real real real real real real real real real * e
static bool cleanNnz(double &value, double colLower, double colUpper, double rowLower, double rowUpper, double colsol, double &lb, double &ub, double tiny, double veryTiny)
void fint fint fint real fint real real real real real real * g
int nnz
ATTENTION: Filter expect the jacobian to be ordered by row.
VariableType
Type of the variables.
void fint fint fint real fint real * x