My Project
OSnl2OS.cpp
Go to the documentation of this file.
1/* $Id: OSnl2OS.cpp 4210 2011-06-28 09:44:54Z stefan $ */
22#include <iostream>
23#include "OSiLWriter.h"
24#include "OSoLWriter.h"
25#include "OSoLReader.h"
26#include "OSnl2OS.h"
27#include "OSOption.h"
28#include "OSOutput.h"
29#include "OSErrorClass.h"
30#include "OSMathUtil.h"
31
32#include "CoinHelperFunctions.hpp"
33
34
35#include "nlp.h"
36#include "getstub.h"
37#include "r_opn.hd" /* for N_OPS */
38#include "opcode.hd"
39
40#ifdef HAVE_CMATH
41# include <cmath>
42#else
43# ifdef HAVE_CMATH_H
44# include <cmath.h>
45# endif
46#endif
47
48#include <sstream>
49
50
51#define R_OPS ((ASL_fg*)asl)->I.r_ops_
52#define OBJ_DE ((ASL_fg*)asl)->I.obj_de_
53#define VAR_E ((ASL_fg*)asl)->I.var_e_
54#define CON_DE ((ASL_fg*)asl)->I.con_de_
55
56
57#include <asl.h>
58//#include "sufinfo.h"
59
60using std::endl;
61
62#ifdef HAVE_STDINT_H
63#include <stdint.h>
64#endif
65
66#ifdef HAVE_STDLIB_H
67#include <stdlib.h>
68#endif
69
70
72 : osolreader (NULL), osinstance(NULL), osoption(NULL), stub("")
73{
74 cw = ASL_alloc( ASL_read_fg);
75 rw = ASL_alloc( ASL_read_fg);
76 asl = cw;
77}
78
79OSnl2OS::OSnl2OS(ASL *cw, ASL *rw, ASL *asl)
80 : osolreader (NULL), osinstance(NULL), osoption(NULL), stub("")
81{
82 this->asl = asl;
83 this->cw = cw;
84 this->rw = rw;
85}
86
87ASL* OSnl2OS::getASL(std::string name)
88{
89 if (name == "asl")
90 return asl;
91 else if (name == "cw")
92 return cw;
93 else if (name == "rw")
94 return rw;
95 else
96 return NULL;
97}
98
99void OSnl2OS::setOsol(std::string osol)
100{
101 this->osol = osol;
102}
103
104void OSnl2OS::setJobID(std::string jobID)
105{
106 this->jobID = jobID;
107}
108
109bool OSnl2OS::readNl(std::string stub)
110{
111 std::ostringstream outStr;
112
113 try
114 {
115 efunc *r_ops_int[N_OPS];
116 FILE *nl;
117
118 //Initialize the AMPL library
119// asl = cw = ASL_alloc( ASL_read_fg);
120 asl = cw;
121
122 //Initialize the nl file reading
123 nl = jac0dim(const_cast<char*>(stub.c_str()), (fint)stub.length());
124
125 //Prepare *columnwise* parsing of nl file
126 A_vals = (real *)Malloc(nzc*sizeof(real));
127
128 // allocate initial values for primal and dual variables if available
129 want_xpi0 = 3;
130
131 // allocate space for initial values
132 X0 = new real[n_var];
133 havex0 = new char[n_var];
134 pi0 = new real[n_con];
135 havepi0 = new char[n_con];
136
137#ifndef NDEBUG
138 outStr.str("");
139 outStr.clear();
140 outStr << "number of nonzeros = " << nzc << endl;
141 outStr << "number of variables = " << n_var << endl;
142 outStr << "number of constraints = " << n_con << endl;
143 outStr << "number of objectives = " << n_obj << endl;
144 outStr << "number of ranges = " << nranges << endl;
145 outStr << "number of equations = " << n_eqn << endl;
147#endif
148 if(N_OPS > 0)
149 {
150 for(int i = 0; i < N_OPS; i++)
151 {
152 r_ops_int[i] = (efunc*)(unsigned long)i;
153 }
154 R_OPS = r_ops_int;
155 want_derivs = 0;
156 fg_read(nl, ASL_keep_all_suffixes);
157 R_OPS = 0;
158 }
159
160 // Now create row-wise version
161// asl = rw = ASL_alloc( ASL_read_fg);
162 asl = rw;
163 nl = jac0dim((char*)stub.c_str(), (fint)stub.length());
164 want_derivs = 0;
165 qp_read(nl, 0);
166
167 asl = cw;
168 numkount = 0;
169 return true;
170 }
171 catch(const ErrorClass& eclass)
172 {
173 return false;
174 }
175}
176
177
179{
180 if (osinstance != NULL) delete osinstance;
181 osinstance = NULL;
182
183 if (osolreader != NULL)
184 {
185 delete osolreader;
186 osolreader = NULL;
187 }
188 else
189 {
190 if (osoption != NULL) delete osoption;
191 osoption = NULL;
192 }
193
194 free( A_vals);
195 if (X0) delete [] X0; X0 = NULL;
196 if (havex0) delete [] havex0; havex0 = NULL;
197 if (pi0) delete [] pi0; pi0 = NULL;
198 if (havepi0) delete [] havepi0; havepi0 = NULL;
199 if (cw != NULL) ASL_free(&cw);
200 if (rw != NULL) ASL_free(&rw);
201 cw = NULL;
202 rw = NULL;
203 asl = NULL;
204}
205
207{
208 OSnLNode *nlNodePoint;
209 OSnLNodeVariable *nlNodeVariablePoint;
210 OSnLNodeNumber *nlNodeNumberPoint;
211 efunc *op;
212 expr **ep;
213 int opnum;
214 int i;
215 int j = ((expr_v *)e - VAR_E) - osinstance->getVariableNumber() ;
216 op = e->op;
217 opnum = Intcast op;
218 try
219 {
220 switch( opnum)
221 {
222 case OPPLUS:
223 nlNodePoint = new OSnLNodePlus();
224 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
225 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
226 op_type.push_back( "PLUS");
227 return nlNodePoint;
228
229 case OPSUMLIST:
230 i = 0;
231 nlNodePoint = new OSnLNodeSum();
232 nlNodePoint->inumberOfChildren = e->R.ep - e->L.ep;
233 nlNodePoint->m_mChildren = new OSnLNode*[ e->R.ep - e->L.ep];
234 for (ep = e->L.ep; ep < e->R.ep; *ep++)
235 nlNodePoint->m_mChildren[i++] = walkTree ( *ep);
236 return nlNodePoint;
237
238 case MAXLIST:
239 i = 0;
240 nlNodePoint = new OSnLNodeMax();
241 nlNodePoint->inumberOfChildren = e->R.ep - e->L.ep;
242 nlNodePoint->m_mChildren = new OSnLNode*[ e->R.ep - e->L.ep];
243 for (ep = e->L.ep; ep < e->R.ep; *ep++)
244 nlNodePoint->m_mChildren[i++] = walkTree ( *ep);
245 return nlNodePoint;
246
247 case OPMINUS:
248 nlNodePoint = new OSnLNodeMinus();
249
250 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
251 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
252 op_type.push_back( "MINUS");
253
254 return nlNodePoint;
255
256 case OPUMINUS:
257 nlNodePoint = new OSnLNodeNegate();
258 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
259 return nlNodePoint;
260
261 case OPMULT:
262 nlNodePoint = new OSnLNodeTimes();
263 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
264 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
265 op_type.push_back( "TIMES");
266 return nlNodePoint;
267
268 case OPDIV:
269 nlNodePoint = new OSnLNodeDivide();
270 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
271 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
272 return nlNodePoint;
273
274 case OPPOW:
275 nlNodePoint = new OSnLNodePower();
276 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
277 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
278 op_type.push_back( "POWER");
279 return nlNodePoint;
280
281
282 case OP1POW:
283 nlNodePoint = new OSnLNodePower();
284
285
286 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
287 nlNodeNumberPoint = new OSnLNodeNumber();
288 nlNodeNumberPoint->value = e->R.en->v;
289 nlNodePoint->m_mChildren[1] = nlNodeNumberPoint;
290
291 op_type.push_back( "NUMBER");
292 op_type.push_back( os_dtoa_format( numkount) );
293 operand.push_back( e->R.en->v );
294 numkount++;
295
296 op_type.push_back( "POWER");
297
298
299 return nlNodePoint;
300
301 case OP2POW:
302 nlNodePoint = new OSnLNodeSquare();
303
304 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
305 op_type.push_back( "SQUARE");
306 return nlNodePoint;
307
308 case OPCPOW:
309 nlNodePoint = new OSnLNodePower();
310 nlNodeNumberPoint = new OSnLNodeNumber();
311 nlNodeNumberPoint->value = e->L.en->v;
312 nlNodePoint->m_mChildren[0] = nlNodeNumberPoint;
313 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
314 return nlNodePoint;
315
316 case OP_log:
317 nlNodePoint = new OSnLNodeLn();
318 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
319 op_type.push_back( "LOG");
320 return nlNodePoint;
321
322 case OP_sqrt:
323 nlNodePoint = new OSnLNodeSqrt();
324 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
325 return nlNodePoint;
326
327 case OP_cos:
328 nlNodePoint = new OSnLNodeCos();
329 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
330 return nlNodePoint;
331
332 case OP_sin:
333 nlNodePoint = new OSnLNodeSin();
334 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
335 return nlNodePoint;
336
337 case OP_exp:
338 nlNodePoint = new OSnLNodeExp();
339 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
340 return nlNodePoint;
341
342 case ABS:
343 nlNodePoint = new OSnLNodeAbs();
344 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
345 return nlNodePoint;
346
347 case OPNUM:
348 nlNodeNumberPoint = new OSnLNodeNumber;
349 nlNodeNumberPoint->value = (double) ((expr_n*)e)->v;
350 op_type.push_back( "NUMBER");
351 op_type.push_back( os_dtoa_format( numkount ) );
352
353 operand.push_back( (double) ((expr_n*)e)->v );
354 numkount++;
355
356
357 return nlNodeNumberPoint;
358
359 case OPVARVAL:
360 // treat the common expression or defined variables
361 if( j >= 0 )
362 {
363
364 // Orban: http://www.gerad.ca/~orban/drampl/def-vars.html
365 if(j < ncom0)
366 {
367 struct cexp *common = ((const ASL_fg *) asl) -> I.cexps_ + j ;
368 //walk the tree for the non-linear stuff
369
370 // now add the linear terms
371 int nlin = common -> nlin;
372
373 if( nlin > 0)
374 {
375 nlNodePoint = new OSnLNodeSum();
376 nlNodePoint->inumberOfChildren = nlin + 1;
377 nlNodePoint->m_mChildren = new OSnLNode*[ nlin + 1];
378 // we have linear variables
379 // get the index and coefficient
380 linpart *L = common -> L;
381 for(int kj = 0; kj < nlin; kj++)
382 {
383 // add an OSnLSumNode with the linear terms
384 nlNodePoint->m_mChildren[ kj] = new OSnLNodeVariable;
385 nlNodeVariablePoint = (OSnLNodeVariable*)nlNodePoint->m_mChildren[ kj];
386 nlNodeVariablePoint->coef = L [kj]. fac;
387 nlNodeVariablePoint->idx = ((uintptr_t) (L [kj].v.rp) - (uintptr_t) VAR_E) / sizeof (expr_v);
388 }
389 nlNodePoint->m_mChildren[ nlin] = walkTree( common->e);
390 return nlNodePoint;
391 }
392 else return walkTree( common->e);
393 }
394 else
395 {
396 struct cexp1 *common = ((const ASL_fg *) asl) -> I.cexps1_ + (j - ncom0);
397 //walk the tree for the non-linear stuff
398
399 // now add the linear terms
400 int nlin = common -> nlin;
401
402 if( nlin > 0)
403 {
404 nlNodePoint = new OSnLNodeSum();
405 nlNodePoint->inumberOfChildren = nlin + 1;
406 nlNodePoint->m_mChildren = new OSnLNode*[ nlin + 1];
407 // we have linear variables
408 // get the index and coefficient
409 linpart *L = common -> L;
410 for(int kj = 0; kj < nlin; kj++)
411 {
412 // add an OSnLSumNode with the linear terms
413 nlNodePoint->m_mChildren[ kj] = new OSnLNodeVariable;
414 nlNodeVariablePoint = (OSnLNodeVariable*)nlNodePoint->m_mChildren[ kj];
415 nlNodeVariablePoint->coef = L [kj]. fac;
416 nlNodeVariablePoint->idx = ((uintptr_t) (L [kj].v.rp) - (uintptr_t) VAR_E) / sizeof (expr_v);
417 }
418 nlNodePoint->m_mChildren[ nlin] = walkTree( common->e);
419 return nlNodePoint;
420 }
421 else return walkTree( common->e);
422 }
423 }
424 //if(e->a > osinstance->getVariableNumber() ) throw ErrorClass("OS cannot handle AMPL user defined variables, please reformulate");
425 nlNodeVariablePoint = new OSnLNodeVariable;
426 nlNodeVariablePoint->idx = e->a;
427 nlNodeVariablePoint->coef = 1.0;
428
429 op_type.push_back( "VARIABLE");
430 op_type.push_back( os_dtoa_format( e->a ) );
431
432
433 return nlNodeVariablePoint;
434 break;
435 default:
436 std::ostringstream outStr;
437 std::string error;
438 outStr << endl;
439 outStr << endl;
440 error = "ERROR: An unsupported operator found, AMPL operator number = " ;
441 outStr << error;
442 outStr << opnum;
443 outStr << endl;
444 error = outStr.str();
445 throw ErrorClass( error );
446 }//end switch
447 }//end try
448 catch(const ErrorClass& eclass)
449 {
450 throw;
451 }
452}//walkTree
453
454static inline char integerOrBinary(real upper, real lower)
455{
456 if (lower > -1.0 + OS_EPS && upper < 2.0 - OS_EPS)
457 return 'B';
458 return 'I';
459}
460
461void OSnl2OS::setVar(OSInstance *osinstance, int lower, int upper, char vartype)
462{
463 std::ostringstream outStr;
464 int i;
465#ifndef NDEBUG
466 outStr.str("");
467 outStr.clear();
468 outStr << "LOWER = " << lower << std::endl;
469 outStr << "UPPER = " << upper << std::endl;
471#endif
472 for(i = lower; i < upper; i++)
473 {
474 osinstance->addVariable(i, var_name(i),
475 LUv[2*i] > -OSDBL_MAX ? LUv[2*i] : -OSDBL_MAX,
476 LUv[2*i+1] < OSDBL_MAX ? LUv[2*i+1] : OSDBL_MAX,
477 vartype);
478 }
479}
480
481void OSnl2OS::setIBVar(OSInstance *osinstance, int lower, int upper)
482{
483 std::ostringstream outStr;
484 int i;
485#ifndef NDEBUG
486 outStr.str("");
487 outStr.clear();
488 outStr << "LOWER = " << lower << std::endl;
489 outStr << "UPPER = " << upper << std::endl;
491#endif
492 for(i = lower; i < upper; i++)
493 {
494 if (LUv[2*i] > -1.0 + OS_EPS && LUv[2*i+1] < 2.0 - OS_EPS)
495 osinstance->addVariable(i, var_name(i),0,1,'B');
496 else
497 osinstance->addVariable(i, var_name(i),
498 LUv[2*i] > -OSDBL_MAX ? LUv[2*i] : -OSDBL_MAX,
499 LUv[2*i+1] < OSDBL_MAX ? LUv[2*i+1] : OSDBL_MAX,
500 'I');
501 }
502}
503
505{
506 int *A_rowstarts = NULL;
507 int *A_colptr = NULL;
508 double *A_nzelem = NULL;
509 int i, j;
510 std::ostringstream outStr;
511
512 osinstance = new OSInstance();
513
514 // put in instanceHeader information
515 //
516 osinstance->setInstanceDescription("Generated from AMPL nl file");
517 //
518 // put in instanceData information
519 //
520 // get the variable information
521 //
522 std::string colName;
523// char vartype = 'C';
525
526 //first the nonlinear variables
527 setVar(osinstance,0,nlvb - nlvbi,'C'); // continuous in an objective and in a constraint
528 setIBVar(osinstance,nlvb - nlvbi,nlvb); // integer or binary in an objective and in a constraint
529 setVar(osinstance,nlvb,nlvc - nlvci,'C'); // continuous just in constraints
530 setIBVar(osinstance,nlvc - nlvci,nlvc); // integer or binary just in constraints
531 setVar(osinstance,nlvc,nlvo - nlvoi,'C'); // continuous just in objectives
532 setIBVar(osinstance,nlvo - nlvoi,nlvo); // integer or binary just in objectives
533
534 //now the other variables
535 setVar(osinstance,CoinMax(nlvc, nlvo),CoinMax(nlvc, nlvo) + nwv,'C'); // linear arc variables
536 setVar(osinstance,CoinMax(nlvc, nlvo) + nwv,n_var - niv - nbv, 'C'); // other linear
537 setVar(osinstance,n_var - niv - nbv, n_var - niv, 'B') ; // linear binary
538 setVar(osinstance,n_var - niv, n_var, 'I'); // linear integer
539
540
547 std::vector<int> fidxs, v1idxs, v2idxs;
548 std::vector<double> coeffs;
549 std::vector<Nl> nlExprs;
550 real* delsqp;
551 fint* colqp;
552 fint* rowqp;
553 int osNLIdx; // OS n.l. function index
554 int aNLIdx; // AMPL n.l. function index
555 cgrad *cg;
556
557 bool isQP = true;
558 bool fill_in = false;
559
560 if (nlvc > 0 || nlvo > 0)
561 {
562 //Switch to row-wise format.
563 asl = rw;
564
565 // Iterate from -nlo to nlc-1 so that the qterms are sorted by idx
566
567 // Process the objectives first, for which fill-in does not matter
568 for (osNLIdx = -nlo, aNLIdx = nlo-1; osNLIdx < 0; osNLIdx++, aNLIdx--)
569 {
570 if (nqpcheck(aNLIdx, &rowqp, &colqp, &delsqp) > 0) // quadratic
571 {
572 for (int v1 = 0; v1 < n_var; v1++)
573 {
574 for (int* psV2 = (int*)&rowqp[colqp[v1]]; psV2 < (int*)&rowqp[colqp[v1+1]]; psV2++, delsqp++)
575 {
576 if (std::abs(*delsqp) > OS_EPS) // Try to exclude terms introduced by rounding
577 {
578 fidxs.push_back(osNLIdx);
579 v1idxs.push_back(v1);
580 v2idxs.push_back(*psV2);
581 coeffs.push_back(0.5 * *delsqp);
582 }
583 }
584 }
585 }
586 else // Nonlinear or error in nqpcheck
587 {
588 Nl nl;
589 expr* e = aNLIdx < 0 ? CON_DE[osNLIdx].e : OBJ_DE[aNLIdx].e; // because osNLIdx = -aNLIdx-1
590 nl.idx = osNLIdx;
593 nl.m_bDeleteExpressionTree = false;
594 /*
595 * Note: If the copy operation of the Nl class is changed from shallow
596 * to deep, we will want to manage memory differently here.
597 */
598 nlExprs.push_back(nl);
599 }
600 }
601
602 int nqpchk;
603// cgrad *cg;
604
605 double* A_row_temp = new double[n_var];
606
607 for (osNLIdx = 0, aNLIdx = -1; osNLIdx < nlc; osNLIdx++, aNLIdx--)
608 {
609 if (isQP) // (No need to keep looking for quad terms once we found a non-quadratic term)
610 {
611 // check the nonzeroes before and after
612 if (!fill_in) // (once we know there will be fill-in, we can stop counting)
613 {
614 for(cg = Cgrad[osNLIdx]; cg; cg = cg->next)
615 {
616 if (cg->coef != 0) A_row_temp[cg->varno] = cg->coef;
617 }
618 }
619
620 nqpchk = nqpcheck(aNLIdx, &rowqp, &colqp, &delsqp);
621 if (nqpchk > 0) // there is a quadratic part
622 {
623 for (int v1 = 0; v1 < n_var; v1++)
624 {
625 for (int* psV2 = (int*)&rowqp[colqp[v1]]; psV2 < (int*)&rowqp[colqp[v1+1]]; psV2++, delsqp++)
626 {
627 if (std::abs(*delsqp) > OS_EPS) // Try to exclude terms introduced by rounding
628 {
629 fidxs.push_back(osNLIdx);
630 v1idxs.push_back(v1);
631 v2idxs.push_back(*psV2);
632 coeffs.push_back(0.5 * *delsqp);
633 }
634 }
635 }
636 if (!fill_in) // (once we know there will be fill-in we can stop counting)
637 {
638 for(cg = Cgrad[osNLIdx]; cg; cg = cg->next)
639 {
640 if (cg->coef != 0)
641 if (cg->coef != A_row_temp[cg->varno])
642 {
643 fill_in = true;
644 break;
645 }
646 }
647 }
648 continue;
649 }
650 if (nqpchk < 0) isQP = false;
651 }
652
653// Nonlinear or error in nqpcheck
654 {
655 Nl nl;
656 expr* e = aNLIdx < 0 ? CON_DE[osNLIdx].e : OBJ_DE[aNLIdx].e; // because osNLIdx = -aNLIdx-1
657 nl.idx = osNLIdx;
660 nl.m_bDeleteExpressionTree = false;
661 /*
662 * Note: If the copy operation of the Nl class is changed from shallow
663 * to deep, we will want to manage memory differently here.
664 */
665 nlExprs.push_back(nl);
666 }
667 }
668 delete [] A_row_temp;
669
670 if (nlExprs.size())
671 {
672 Nl** ppsNl = new Nl*[ nlExprs.size() ];
673 for (size_t k = 0; k < nlExprs.size(); k++)
674 {
675 ppsNl[k] = new Nl(nlExprs[k]); // See above note about shallow copy
676 ppsNl[k]->m_bDeleteExpressionTree = true;
677 }
682 }
683 if (fidxs.size())
684 {
685 osinstance->setQuadraticCoefficients((int)fidxs.size(), &fidxs[0], &v1idxs[0], &v2idxs[0], &coeffs[0], 0, (int)fidxs.size()-1);
686 }
687 // Note: if we intended to call objval, conval etc with asl == rw later we must call qp_opify here.
688
689 //
690 // end loop of nonlinear rows
691 //
692 }
693
694 // now create the objective function
695 // in the nl file, this is stored in dense form; convert to sparse.
696 //
697 double objWeight = 1.0;
698 // char *objtype; /* object type array: 0 == min, 1 == max */
699 SparseVector* objectiveCoefficients = NULL;
700
702 for(i = 0; i < n_obj; i++)
703 {
704 int n_obj_coef = 0;
705 for(og = Ograd[i]; og; og = og->next)
706 {
707 if (og->coef != 0) n_obj_coef++;
708 }
709 objectiveCoefficients = new SparseVector( n_obj_coef);
710 int i_obj_coef = -1;
711 for(og = Ograd[i]; og; og = og->next)
712 {
713 if (fabs(og->coef) > OS_EPS)
714 {
715 i_obj_coef++;
716 objectiveCoefficients->values[i_obj_coef] = og->coef;
717 objectiveCoefficients->indexes[i_obj_coef] = og->varno;
718 }
719 }
720 osinstance->addObjective(-i-1, obj_name(i),
721 (objtype[i] == 1)?"max":"min",
722 objconst( i), objWeight, objectiveCoefficients) ;
723 delete objectiveCoefficients; // delete the temporary sparse vector
724 objectiveCoefficients = NULL;
725 }
726
727 //
728 // now fill in row information
729 //
731 // kipp -- important -- figure out where the nl file stores a rhs constant
732 double constant = 0.0;
733 std::string rowName;
734 for(i = 0; i < n_con; i++)
735 {
736 osinstance->addConstraint(i, con_name(i),
737 LUrhs[2*i] > -OSDBL_MAX ? LUrhs[2*i] : -OSDBL_MAX,
738 LUrhs[2*i+1] < OSDBL_MAX ? LUrhs[2*i+1] : OSDBL_MAX,
739 constant);
740 }
741
742 //
743 // Now the A-matrix
744 // The treatment depends on whether there was fill-in during the QP check or not
745 //
746 if (fill_in) // store the matrix rowwise
747 {
748 int row_len;
749 A_rowstarts = new int[n_con+1];
750 A_rowstarts[0] = 0;
751 for (int i=0; i < n_con; i++)
752 {
753 row_len = 0;
754 for(cg = Cgrad[i]; cg; cg = cg->next)
755 {
756 if (cg->coef != 0) row_len++;
757 }
758 A_rowstarts[i+1] = A_rowstarts[i] + row_len;
759 }
760 A_colptr = new int[A_rowstarts[n_con]];
761 A_nzelem = new double[A_rowstarts[n_con]];
762 for (int i=0; i < n_con; i++)
763 {
764 row_len = 0;
765 for(cg = Cgrad[i]; cg; cg = cg->next)
766 {
767 if (cg->coef != 0)
768 {
769 A_colptr[A_rowstarts[i]+row_len] = cg->varno;
770 A_nzelem[A_rowstarts[i]+row_len] = cg->coef;
771 row_len++;
772 }
773 }
774 }
775
776 if(A_rowstarts[ n_con] > 0)
777 {
778 osinstance->setLinearConstraintCoefficients(A_rowstarts[ n_con], false,
779 A_nzelem, 0, A_rowstarts[n_con] - 1,
780 A_colptr, 0, A_rowstarts[n_con] - 1,
781 A_rowstarts, 0, n_con);
782// setLinearConstraintCoefficients does a soft copy, and unlike the column-wise representation,
783// this row-wise representation is not taken care of by the ASL_free method in the destructor
787 }
788
789
790#ifndef NDEBUG
791 outStr.str("");
792 outStr.clear();
793 outStr << "A-matrix elements: ";
794 for (int i = 0; i < A_rowstarts[ n_con]; i++)
795 outStr << A_nzelem[i] << " ";
796 outStr << endl;
797 outStr << "A-matrix col index: ";
798 for (int i = 0; i < A_rowstarts[ n_con]; i++)
799 outStr << A_colptr[i] << " ";
800 outStr << endl;
801 outStr << "A-matrix rowstart: ";
802 for (int i = 0; i <= n_con; i++)
803 outStr << A_rowstarts[i] << " ";
804 outStr << endl;
806#endif
807 }
808
809 else
810 {
811 asl=cw;
812 int colStart, colEnd, nCoefSqueezed;
813 nCoefSqueezed = 0;
814
815#ifndef NDEBUG
816 outStr.str("");
817 outStr.clear();
818 outStr << "A-matrix elements: ";
819 for (int i = 0; i < A_colstarts[ n_var]; i++)
820 outStr << A_vals[i] << " ";
821 outStr << endl;
822 outStr << "A-matrix rowinfo: ";
823 for (int i = 0; i < A_colstarts[ n_var]; i++)
824 outStr << A_rownos[i] << " ";
825 outStr << endl;
826 outStr << "A-matrix colstart: ";
827 for (int i = 0; i <= n_var; i++)
828 outStr << A_colstarts[i] << " ";
829 outStr << endl;
831#endif
832
833 colEnd = 0;
834 for (i = 0; i < n_var; i++)
835 {
836 colStart = colEnd;
837 colEnd = A_colstarts[i+1];
838#ifndef NDEBUG
839 outStr.str("");
840 outStr.clear();
841 outStr << "col " << i << " from " << colStart << " to " << colEnd - 1 << endl;
843#endif
844 for (j = colStart; j < colEnd; j++)
845 {
846 if (fabs(A_vals[ j]) > OS_EPS)
847 {
848 A_vals[ j-nCoefSqueezed] = A_vals[ j];
849 A_rownos[ j-nCoefSqueezed] = A_rownos[j];
850 }
851 else
852 {
853#ifndef NDEBUG
854 outStr.str("");
855 outStr.clear();
856 outStr << "squeeze out element " << j << endl;
858#endif
859 nCoefSqueezed++;
860 }
861 }
862 A_colstarts[i+1] = A_colstarts[i+1] - nCoefSqueezed;
863 }
864
865#ifndef NDEBUG
866 outStr.str("");
867 outStr.clear();
868 outStr << "A-matrix elements: ";
869 for (i = 0; i < A_colstarts[ n_var]; i++)
870 outStr << A_vals[i] << " ";
871 outStr << endl;
872 outStr << "A-matrix rowinfo: ";
873 for (i = 0; i < A_colstarts[ n_var]; i++)
874 outStr << A_rownos[i] << " ";
875 outStr << endl;
876 outStr << "A-matrix colstart: ";
877 for (i = 0; i <= n_var; i++)
878 outStr << A_colstarts[i] << " ";
879 outStr << endl;
880 outStr << "A-matrix nonzeroes: " << A_colstarts[ n_var] << "; nsqueezed: " << nCoefSqueezed << endl;
882#endif
883
884 if(A_colstarts[ n_var] > 0)
885 {
886 osinstance->setLinearConstraintCoefficients(A_colstarts[ n_var], true,
887 A_vals, 0, A_colstarts[n_var] - 1,
888 A_rownos, 0, A_colstarts[n_var] - 1,
889 A_colstarts, 0, n_var);
893// We are doing a shallow copy, so we must decouple the A matrix from the AMPL data structure
894 A_vals = NULL;
895 A_rownos = NULL;
896 A_colstarts = NULL;
897 }
898 }
899
900
908 SufDesc *d;
909 int suffixType, nOther, nOtherIdx;
910
911 asl = cw;
912
913 try
914 {
915 osolreader = new OSoLReader();
916
917 // check if there are any suffixes to deal with and read options if necessary
918 bool have_primal = false;
919 for (i=0; i < n_var; i++)
920 {
921 if (havex0[i] != 0)
922 {
923 have_primal = true;
924 break;
925 }
926 }
927
928 bool have_dual = false;
929 for (i=0; i < n_con; i++)
930 {
931 if (havepi0[i] != 0)
932 {
933 have_dual = true;
934 break;
935 }
936 }
937
938 //OSOption* osoption = NULL;
939
940 if ((asl->i.suffixes[ASL_Sufkind_var] != NULL) ||
941 (asl->i.suffixes[ASL_Sufkind_con] != NULL) ||
942 (asl->i.suffixes[ASL_Sufkind_obj] != NULL) ||
943 (asl->i.suffixes[ASL_Sufkind_prob] != NULL) ||
944 ( have_primal ) || ( have_dual ) )
945 {
946 OSOption* tmpoption = new OSOption();
947 tmpoption = osolreader->readOSoL(osol);
956 osoption = new OSOption();
957 osoption->deepCopyFrom(tmpoption);
958
959 //make sure to copy the jobID if it was set (from the command line)
960 if (jobID != "") osoption->setJobID(jobID);
961 }
962
963 bool found;
964 bool extend;
965 int nOther;
966 int nIndexes;
967 std::string *otherOptionNames = NULL;
968
969 // First the variable-indexed suffixes
970 suffixType = ASL_Sufkind_var;
971 if ( (asl->i.suffixes[suffixType] != NULL) )
972 {
973 // make a record of all <otherVariableOptions> present in the OSoL file
974 nOther = 0;
975 if (osoption != NULL &&
976 osoption->optimization != NULL &&
977 osoption->optimization->variables != NULL &&
979 {
980 otherOptionNames = new std::string[osoption->optimization->variables->numberOfOtherVariableOptions];
983 otherOptionNames[nOther++] = osoption->optimization->variables->other[i]->name;
984 }
985 OtherVariableOption* varopt;
986 for (d=asl->i.suffixes[suffixType]; d; d=d->next)
987 {
988#ifndef NDEBUG
989 outStr.str("");
990 outStr.clear();
991 outStr << "Detected suffix " << d->sufname << "; kind = " << d->kind << std::endl;
993#endif
994
995 // Deal with special cases: basis information, special ordered sets (?) and branching weights (?)
996 if (strcmp(d->sufname,"sstatus") == 0) //(d->sufname == "sstatus")
997 {
998 // note that AMPL uses different numeric values for representing basis status:
999 // 0 = no status assigned = ENUM_BASIS_STATUS_unknown
1000 // 1 = basic = ENUM_BASIS_STATUS_basic
1001 // 2 = superbasic = ENUM_BASIS_STATUS_superbasic
1002 // 3 = nonbasic <= (normally =) lower bound = ENUM_BASIS_STATUS_atLower
1003 // 4 = nonbasic >= (normally =) upper bound = ENUM_BASIS_STATUS_atUpper
1004 // 5 = nonbasic at equal lower and upper bounds = ENUM_BASIS_STATUS_atEquality
1005 // 6 = nonbasic between bounds = ENUM_BASIS_STATUS_isFree
1006
1015 };
1016 // allocate space
1017 int* IBS;
1018
1019#ifndef NDEBUG
1020 outStr.str("");
1021 outStr.clear();
1022 outStr << "Original basis (in AMPL codes):";
1023 for (int k=0; k<n_var; k++)
1024 outStr << " " << d->u.i[k];
1025 outStr << std::endl;
1027#endif
1028
1029 // if OSoL file has a basis, merge values by overwriting .nl file info
1030 if (osoption != NULL &&
1031 osoption->optimization != NULL &&
1032 osoption->optimization->variables != NULL &&
1034 {
1035 // retrieve basis and store into ASL data structure
1036 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1037 {
1039 if (nIndexes > 0)
1040 {
1041 IBS = new int[nIndexes];
1043
1044 for (int k=0; k < nIndexes; k++)
1045 d->u.i[IBS[k]] = i;
1046 delete[] IBS;
1047 }
1048#ifndef NDEBUG
1049 outStr.str("");
1050 outStr.clear();
1051 outStr << "After processing state " << i << ":";
1052 for (int k=0; k<n_var; k++)
1053 outStr << " " << d->u.i[k];
1054 outStr << std::endl;
1056#endif
1057 }
1058 }
1059#ifndef NDEBUG
1060 outStr.str("");
1061 outStr.clear();
1062 outStr << "Merged basis (in AMPL codes):";
1063 for (int k=0; k<n_var; k++)
1064 outStr << " " << d->u.i[k];
1065 outStr << std::endl;
1067#endif
1068
1069 // count the number of entries
1072 for (i=0; i<ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1073 {
1074 nidx[i] = 0;
1075 kidx[i] = 0;
1076 }
1077
1078 for (int k=0; k < n_var; k++)
1079 nidx[d->u.i[k]]++;
1080
1081 // allocate space
1082 int **IBS2;
1083 IBS2 = new int*[ENUM_BASIS_STATUS_NUMBER_OF_STATES];
1084 for (int i=0; i<ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1085 {
1086 IBS2[i] = new int[nidx[i]];
1087 }
1088
1089 // store basis info into class-oriented arrays
1090 for (int k=0; k < n_var; k++)
1091 {
1092 IBS2[d->u.i[k]][kidx[d->u.i[k]]++] = k;
1093 }
1094
1095 // store into <initialBasisStatus> element
1096 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1097 if (nidx[i] > 0)
1098 osoption->setInitBasisStatus(ENUM_PROBLEM_COMPONENT_variables, basCode[i], IBS2[i], nidx[i]);
1099
1100 // garbage collection
1101 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1102 delete [] IBS2[i];
1103 delete [] IBS2;
1104 }
1105
1106 else // not one of the special cases
1107 {
1108 // allocate space
1109 varopt = new OtherVariableOption();
1110
1111 varopt->name = d->sufname;
1112 varopt->numberOfEnumerations = 0;
1113 varopt->var = new OtherVarOption*[n_var];
1114
1115 // check if the option was present in the OSoL file
1116 found = false;
1117 int iopt;
1118 for (iopt=0; iopt < nOther; iopt++)
1119 {
1120 if (d->sufname == otherOptionNames[iopt])
1121 {
1122 found = true;
1123 break;
1124 }
1125 }
1126
1127 // merge values by overwriting .nl file info
1128 if (found)
1129 {
1130 OtherVariableOption* otherOption;
1131 otherOption = osoption->getOtherVariableOption(iopt);
1132 for (int i=0; i < otherOption->numberOfVar; i++)
1133 {
1134 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1135 {
1136 d->u.r[otherOption->var[i]->idx] = os_strtod(otherOption->var[i]->value.c_str(), NULL);
1137 }
1138 else
1139 d->u.i[otherOption->var[i]->idx] = (int)os_strtod(otherOption->var[i]->value.c_str(), NULL) + 0.1;
1140 }
1141 if (otherOption->description == "")
1142 varopt->description = "combined from osol and .nl data";
1143 else
1144 varopt->description = otherOption->description + "; merged with .nl data";
1145 }
1146 else
1147 varopt->description = "transferred from .nl file";
1148
1149 // count the number of entries
1150 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1151 {
1152 varopt->varType = "real";
1153 nOtherIdx = 0;
1154 for (int k=0; k < n_var; k++)
1155 {
1156 if (d->u.r[k] != 0)
1157 {
1158 varopt->var[nOtherIdx] = new OtherVarOption();
1159 varopt->var[nOtherIdx]->idx = k;
1160 varopt->var[nOtherIdx]->value = os_dtoa_format(d->u.r[k]);
1161 nOtherIdx++;
1162 }
1163 }
1164 }
1165 else // here the suffix values are integer
1166 {
1167 varopt->varType = "integer";
1168 nOtherIdx = 0;
1169 for (int k=0; k < n_var; k++)
1170 {
1171 if (d->u.i[k] != 0)
1172 {
1173 varopt->var[nOtherIdx] = new OtherVarOption();
1174 varopt->var[nOtherIdx]->idx = k;
1175 varopt->var[nOtherIdx]->value = os_dtoa_format((double)d->u.i[k]);
1176 nOtherIdx++;
1177 }
1178 }
1179 }
1180
1181 varopt->numberOfVar = nOtherIdx;
1182
1183 if (found)
1184 {
1185 // here we just replace the <var> element and update the numberOfVar
1186 for (int k=0; k < osoption->optimization->variables->other[iopt]->numberOfVar; k++)
1187 delete osoption->optimization->variables->other[iopt]->var[k];
1188 delete [] osoption->optimization->variables->other[iopt]->var;
1189 osoption->optimization->variables->other[iopt]->var = varopt->var;
1190 osoption->optimization->variables->other[iopt]->numberOfVar = nOtherIdx;
1191 varopt->var = NULL;
1193 }
1194 else
1195 {
1196 if (!osoption->setAnOtherVariableOption(varopt))
1197 throw ErrorClass( "OSnl2OS: Error transfering suffixes on variables" );
1198 }
1199
1200 delete varopt;
1201 varopt = NULL;
1202 }
1203 }
1204 delete [] otherOptionNames;
1205 otherOptionNames = NULL;
1206 }
1207
1208 // suffixes indexed over constraints and objectives work the same way
1209 suffixType = ASL_Sufkind_con;
1210 if ( (asl->i.suffixes[suffixType] != NULL) )
1211 {
1212 // make a record of all <otherConstraintOptions> present in the OSoL file
1213 nOther = 0;
1214 if (osoption != NULL &&
1215 osoption->optimization != NULL &&
1216 osoption->optimization->constraints != NULL &&
1218 {
1219 otherOptionNames = new std::string[osoption->optimization->constraints->numberOfOtherConstraintOptions];
1222 otherOptionNames[nOther++] = osoption->optimization->constraints->other[i]->name;
1223 }
1224 OtherConstraintOption* conopt;
1225 for (d=asl->i.suffixes[suffixType]; d; d=d->next)
1226 {
1227#ifndef NDEBUG
1228 outStr.str("");
1229 outStr.clear();
1230 outStr << "Detected suffix " << d->sufname << "; kind = " << d->kind << std::endl;
1232#endif
1233 // Deal with special cases first: basis information and branching weights
1234 if (strcmp(d->sufname,"sstatus") == 0) //(d->sufname == "sstatus")
1235 {
1236 // note that AMPL uses different numeric values for representing basis status:
1237 // 0 = no status assigned = ENUM_BASIS_STATUS_unknown
1238 // 1 = basic = ENUM_BASIS_STATUS_basic
1239 // 2 = superbasic = ENUM_BASIS_STATUS_superbasic
1240 // 3 = nonbasic <= (normally =) lower bound = ENUM_BASIS_STATUS_atLower
1241 // 4 = nonbasic >= (normally =) upper bound = ENUM_BASIS_STATUS_atUpper
1242 // 5 = nonbasic at equal lower and upper bounds = ENUM_BASIS_STATUS_atEquality
1243 // 6 = nonbasic between bounds = ENUM_BASIS_STATUS_isFree
1244
1253 };
1254
1255 // allocate space
1256 int* IBS;
1257
1258#ifndef NDEBUG
1259 outStr.str("");
1260 outStr.clear();
1261 outStr << "Original basis (in AMPL codes):";
1262 for (int k=0; k<n_con; k++)
1263 outStr << " " << d->u.i[k];
1264 outStr << std::endl;
1266#endif
1267 // if OSoL file has a basis, merge values by overwriting .nl file info
1268 if (osoption != NULL &&
1269 osoption->optimization != NULL &&
1270 osoption->optimization->constraints != NULL &&
1272 {
1273
1274 // retrieve basis and store into ASL data structure
1275 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1276 {
1278 if (nIndexes > 0)
1279 {
1280 IBS = new int[nIndexes];
1282
1283 for (int k=0; k < nIndexes; k++)
1284 d->u.i[IBS[k]] = i;
1285 delete[] IBS;
1286 }
1287#ifndef NDEBUG
1288 outStr.str("");
1289 outStr.clear();
1290 outStr << "After processing state " << i << ":";
1291 for (int k=0; k<n_con; k++)
1292 outStr << " " << d->u.i[k];
1293 outStr << std::endl;
1295#endif
1296 }
1297 }
1298#ifndef NDEBUG
1299 outStr.str("");
1300 outStr.clear();
1301 outStr << "Merged basis (in AMPL codes):";
1302 for (int k=0; k<n_con; k++)
1303 outStr << " " << d->u.i[k];
1304 outStr << std::endl;
1306#endif
1307
1308 // count the number of entries
1311 for (i=0; i<ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1312 {
1313 nidx[i] = 0;
1314 kidx[i] = 0;
1315 }
1316
1317 for (int k=0; k < n_con; k++)
1318 nidx[d->u.i[k]]++;
1319
1320 // allocate space
1321 int **IBS2;
1322 IBS2 = new int*[ENUM_BASIS_STATUS_NUMBER_OF_STATES];
1323 for (int i=0; i<ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1324 {
1325 IBS2[i] = new int[nidx[i]];
1326 }
1327
1328 // store basis info into class-oriented arrays
1329 for (int k=0; k < n_con; k++)
1330 {
1331 IBS2[d->u.i[k]][kidx[d->u.i[k]]++] = k;
1332 }
1333
1334 // store into <initialBasisStatus> element
1335 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1336 if (nidx[i] > 0)
1337 osoption->setInitBasisStatus(ENUM_PROBLEM_COMPONENT_constraints, basCode[i], IBS2[i], nidx[i]);
1338
1339 // garbage collection
1340 for (int i=0; i < ENUM_BASIS_STATUS_NUMBER_OF_STATES; i++)
1341 delete [] IBS2[i];
1342 delete [] IBS2;
1343 }
1344
1345 else // not one of the special cases
1346 {
1347 // allocate space
1348 conopt = new OtherConstraintOption();
1349
1350 conopt->name = d->sufname;
1351 conopt->numberOfEnumerations = 0;
1352 conopt->con = new OtherConOption*[n_con];
1353
1354 // check if the option was present in the OSoL file
1355 found = false;
1356 int iopt;
1357 for (iopt=0; iopt < nOther; iopt++)
1358 {
1359 if (d->sufname == otherOptionNames[iopt])
1360 {
1361 found = true;
1362 break;
1363 }
1364 }
1365
1366 // merge values by overwriting .nl file info
1367 if (found)
1368 {
1369 OtherConstraintOption* otherOption;
1370 otherOption = osoption->getOtherConstraintOption(iopt);
1371 for (int i=0; i < otherOption->numberOfCon; i++)
1372 {
1373 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1374 {
1375 d->u.r[otherOption->con[i]->idx] = os_strtod(otherOption->con[i]->value.c_str(), NULL);
1376 }
1377 else
1378 d->u.i[otherOption->con[i]->idx] = (int)os_strtod(otherOption->con[i]->value.c_str(), NULL) + 0.1;
1379 }
1380 if (otherOption->description == "")
1381 conopt->description = "combined from osol and .nl data";
1382 else
1383 conopt->description = otherOption->description + "; merged with .nl data";
1384 }
1385 else
1386 conopt->description = "transferred from .nl file";
1387
1388 // count the number of entries
1389 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1390 {
1391 conopt->conType = "real";
1392 nOtherIdx = 0;
1393 for (int k=0; k < n_con; k++)
1394 {
1395 if (d->u.r[k] != 0)
1396 {
1397 conopt->con[nOtherIdx] = new OtherConOption();
1398 conopt->con[nOtherIdx]->idx = k;
1399 conopt->con[nOtherIdx]->value = os_dtoa_format(d->u.r[k]);
1400 nOtherIdx++;
1401 }
1402 }
1403 }
1404 else // here the suffix values are integer
1405 {
1406 conopt->conType = "integer";
1407 nOtherIdx = 0;
1408 for (int k=0; k < n_con; k++)
1409 {
1410 if (d->u.i[k] != 0)
1411 {
1412 conopt->con[nOtherIdx] = new OtherConOption();
1413 conopt->con[nOtherIdx]->idx = k;
1414 conopt->con[nOtherIdx]->value = os_dtoa_format((double)d->u.i[k]);
1415 nOtherIdx++;
1416 }
1417 }
1418 }
1419
1420 conopt->numberOfCon = nOtherIdx;
1421
1422 if (found)
1423 {
1424 // here we just replace the <con> element and update the numberOfCon
1425 for (int k=0; k < osoption->optimization->constraints->other[iopt]->numberOfCon; k++)
1426 delete osoption->optimization->constraints->other[iopt]->con[k];
1427 delete [] osoption->optimization->constraints->other[iopt]->con;
1428 osoption->optimization->constraints->other[iopt]->con = conopt->con;
1429 osoption->optimization->constraints->other[iopt]->numberOfCon = nOtherIdx;
1430 conopt->con = NULL;
1432 }
1433 else
1434 {
1436 throw ErrorClass( "OSnl2OS: Error transfering suffixes on constraints" );
1437 }
1438
1439 delete conopt;
1440 conopt = NULL;
1441 }
1442 }
1443 delete [] otherOptionNames;
1444 otherOptionNames = NULL;
1445 }
1446
1447 // here we have suffixes indexed over objectives
1448 suffixType = ASL_Sufkind_obj;
1449 if ( (asl->i.suffixes[suffixType] != NULL) )
1450 {
1451 // make a record of all <otherObjectiveOptions> present in the OSoL file
1452 nOther = 0;
1453 if (osoption != NULL &&
1454 osoption->optimization != NULL &&
1455 osoption->optimization->objectives != NULL &&
1457 {
1458 otherOptionNames = new std::string[osoption->optimization->objectives->numberOfOtherObjectiveOptions];
1461 otherOptionNames[nOther++] = osoption->optimization->objectives->other[i]->name;
1462 }
1463 OtherObjectiveOption* objopt;
1464 for (d=asl->i.suffixes[suffixType]; d; d=d->next)
1465 {
1466#ifndef NDEBUG
1467 outStr.str("");
1468 outStr.clear();
1469 outStr << "Detected suffix " << d->sufname << "; kind = " << d->kind << std::endl;
1471#endif
1472
1473 // allocate space
1474 objopt = new OtherObjectiveOption();
1475
1476 objopt->name = d->sufname;
1477 objopt->numberOfEnumerations = 0;
1478 objopt->obj = new OtherObjOption*[n_obj];
1479
1480 // check if the option was present in the OSoL file
1481 found = false;
1482 int iopt;
1483 for (iopt=0; iopt < nOther; iopt++)
1484 {
1485 if (d->sufname == otherOptionNames[iopt])
1486 {
1487 found = true;
1488 break;
1489 }
1490 }
1491
1492 // merge values by overwriting .nl file info
1493 if (found)
1494 {
1495 OtherObjectiveOption* otherOption;
1496 otherOption = osoption->getOtherObjectiveOption(iopt);
1497#ifndef NDEBUG
1499#endif
1500 for (int i=0; i < otherOption->numberOfObj; i++)
1501 {
1502 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1503 {
1504 d->u.r[-1 - otherOption->obj[i]->idx] = os_strtod(otherOption->obj[i]->value.c_str(), NULL);
1505 }
1506 else
1507 d->u.i[-1 - otherOption->obj[i]->idx] = atoi(otherOption->obj[i]->value.c_str());
1508 }
1509 if (otherOption->description == "")
1510 objopt->description = "combined from osol and .nl data";
1511 else
1512 objopt->description = otherOption->description + "; merged with .nl data";
1513 }
1514 else
1515 objopt->description = "transferred from .nl file";
1516
1517 // count the number of entries
1518 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1519 {
1520 objopt->objType = "real";
1521 nOtherIdx = 0;
1522 for (int k=0; k < n_obj; k++)
1523 {
1524 if (d->u.r[k] != 0)
1525 {
1526 objopt->obj[nOtherIdx] = new OtherObjOption();
1527 objopt->obj[nOtherIdx]->idx = -1 - k;
1528 objopt->obj[nOtherIdx]->value = os_dtoa_format(d->u.r[k]);
1529 nOtherIdx++;
1530 }
1531 }
1532 }
1533 else // here the suffix values are integer
1534 {
1535 objopt->objType = "integer";
1536 nOtherIdx = 0;
1537 for (int k=0; k < n_obj; k++)
1538 {
1539 if (d->u.i[k] != 0)
1540 {
1541 objopt->obj[nOtherIdx] = new OtherObjOption();
1542 objopt->obj[nOtherIdx]->idx = -1 - k;
1543 objopt->obj[nOtherIdx]->value = os_dtoa_format((double)d->u.i[k]);
1544 nOtherIdx++;
1545 }
1546 }
1547 }
1548
1549 objopt->numberOfObj = nOtherIdx;
1550
1551 if (found)
1552 {
1553 // here we just replace the <obj> element and update the numberOfObj
1554 for (int k=0; k < osoption->optimization->objectives->other[iopt]->numberOfObj; k++)
1555 delete osoption->optimization->objectives->other[iopt]->obj[k];
1556 delete [] osoption->optimization->objectives->other[iopt]->obj;
1557 osoption->optimization->objectives->other[iopt]->obj = objopt->obj;
1558 osoption->optimization->objectives->other[iopt]->numberOfObj = nOtherIdx;
1559 objopt->obj = NULL;
1561 }
1562 else
1563 {
1564 if (!osoption->setAnOtherObjectiveOption(objopt))
1565 throw ErrorClass( "OSnl2OS: Error transfering suffixes on objectives" );
1566 }
1567
1568 delete objopt;
1569 objopt = NULL;
1570 }
1571 delete [] otherOptionNames;
1572 otherOptionNames = NULL;
1573 }
1574
1575
1576 //problem-indexed suffixes: Only the currently active problem is put into the .nl file, so this must be scalar
1577 suffixType = ASL_Sufkind_prob;
1578 if ( (asl->i.suffixes[suffixType] != NULL) )
1579 {
1580 std::string opttype, optvalue, optdesc;
1581 optdesc = "transferred from .nl file";
1582 for (d=asl->i.suffixes[suffixType]; d; d=d->next)
1583 {
1584#ifndef NDEBUG
1585 outStr.str("");
1586 outStr.clear();
1587 outStr << "Detected suffix " << d->sufname << "; kind = " << d->kind << std::endl;
1589#endif
1590
1591 if (d->kind & 4) // bit-wise mask to distinguish real from integer
1592 {
1593 opttype = "real";
1594 optvalue = os_dtoa_format(d->u.r[0]);
1595 }
1596 else // here the suffix values are integer
1597 {
1598 opttype = "integer";
1599 optvalue = os_dtoa_format((double)d->u.i[0]);
1600 }
1601
1602 if (!osoption->setAnotherSolverOption(d->sufname,optvalue,"","",opttype,optdesc))
1603 throw ErrorClass( "OSnl2OS: Error transfering problem-indexed suffixes" );
1604 }
1605 }
1606
1607 // process initial primal values and merge with data contained in OSoL file
1608 // .nl file has data in dense form, but we store in sparse form
1609 // OSoL data supersede .nl file, so we turn redundant .nl file info OFF
1610 if (osoption != NULL &&
1611 osoption->optimization != NULL &&
1612 osoption->optimization->variables != NULL &&
1615 {
1617 for (int i=0; i < n_prev; i++)
1619 }
1620
1621 // count the number of values (including those in the OSoL file)
1622 int n_x0 = 0;
1623 for (int i=0; i < n_var; i++)
1624 if (havex0[i] != 0) n_x0++;
1625
1626 if (n_x0 > 0)
1627 {
1628 // allocate space
1629 InitVarValue **x_init = new InitVarValue*[n_x0];
1630
1631 // pull info out of ASL data structure
1632 n_x0 = 0;
1633 for (int i=0; i < n_var; i++)
1634 {
1635 if (havex0[i] != 0)
1636 {
1637 x_init[n_x0] = new InitVarValue();
1638 x_init[n_x0]->idx = i;
1639 x_init[n_x0]->value = X0[i];
1640 n_x0++;
1641 }
1642 }
1643
1644 // store into osoption
1646 throw ErrorClass( "OSnl2OS: Error merging initial primal variable values" );
1647
1648 for (int i=0; i < n_x0; i++)
1649 delete x_init[i];
1650// x_init[i] = NULL;
1651 delete [] x_init;
1652 x_init = NULL;
1653 }
1654
1655 // process initial dual values and merge with data contained in OSoL file
1656 // .nl file has data in dense form, but we store in sparse form
1657 // OSoL data supersede .nl file, so we turn redundant .nl file info OFF
1658 if (osoption != NULL &&
1659 osoption->optimization != NULL &&
1660 osoption->optimization->constraints != NULL &&
1663 {
1665 for (int i=0; i < n_prev; i++)
1667 }
1668
1669 // count the number of values (including those in the OSoL file)
1670 int n_pi0 = 0;
1671 for (int i=0; i < n_con; i++)
1672 if (havepi0[i] != 0) n_pi0++;
1673
1674 if (n_pi0 > 0)
1675 {
1676 // allocate space
1677 InitDualVarValue **pi_init = new InitDualVarValue*[n_pi0];
1678
1679 // pull info out of ASL data structure
1680 n_pi0 = 0;
1681 for (int i=0; i < n_con; i++)
1682 {
1683 if (havepi0[i] != 0)
1684 {
1685 pi_init[n_pi0] = new InitDualVarValue();
1686 pi_init[n_pi0]->idx = i;
1687 pi_init[n_pi0]->lbDualValue = pi0[i];
1688 pi_init[n_pi0]->ubDualValue = pi0[i];
1689 n_pi0++;
1690 }
1691 }
1692
1693 // store into osoption
1695 throw ErrorClass( "OSnl2OS: Error merging initial dual variable values" );
1696
1697 for (int i=0; i < n_pi0; i++)
1698 delete pi_init[i];
1699// pi_init[i] = NULL;
1700 delete [] pi_init;
1701 pi_init = NULL;
1702 }
1703
1704 //still to do
1705 //special ordered sets, branching weights, branching group weights
1706 //initial objective values: .val
1707
1708#ifndef NDEBUG
1710 OSiLWriter* osilwriter = new OSiLWriter();
1711 std::string tmposil = osilwriter->writeOSiL(osinstance);
1713
1714 delete osilwriter;
1715 osilwriter = NULL;
1716
1717#endif
1718 }// end try
1719
1720 catch(const ErrorClass& eclass)
1721 {
1722 // garbage collection etc.
1723 }
1724
1725#ifndef NDEBUG
1726 OSiLWriter *osilwriter = new OSiLWriter();
1727 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSModelInterfaces, ENUM_OUTPUT_LEVEL_trace, "WRITE THE INSTANCE\n");
1728 osilwriter->m_bWhiteSpace = true;
1730 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSModelInterfaces, ENUM_OUTPUT_LEVEL_trace, "DONE WRITING THE INSTANCE\n");
1732 delete osilwriter;
1733 osilwriter = NULL;
1734
1735 OSoLWriter *osolwriter = new OSoLWriter();
1738 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSModelInterfaces, ENUM_OUTPUT_LEVEL_trace, "DONE WRITING THE OPTIONS\n");
1739 delete osolwriter;
1740 osolwriter = NULL;
1741#endif
1742
1743 return true;
1744}
1745
1746
const OSSmartPtr< OSOutput > osoutput
Definition OSOutput.cpp:39
std::string os_dtoa_format(double x)
void free(void *)
OSOption * osoption
double os_strtod(const char *s00, char **se)
Definition OSdtoa.cpp:2541
#define Intcast
Definition OSdtoa.cpp:38
#define R_OPS
Definition OSnl2OS.cpp:51
#define VAR_E
Definition OSnl2OS.cpp:53
#define CON_DE
Definition OSnl2OS.cpp:54
static char integerOrBinary(real upper, real lower)
Definition OSnl2OS.cpp:454
#define OBJ_DE
Definition OSnl2OS.cpp:52
InitDualVariableValues * initialDualValues
initial dual values for the constraints
Definition OSOption.h:3274
OtherConstraintOption ** other
other information about the constraints
Definition OSOption.h:3280
int numberOfOtherConstraintOptions
number of <other> child elements
Definition OSOption.h:3268
BasisStatus * initialBasisStatus
initial basis status for the slack variables
Definition OSOption.h:3277
bool bDeleteArrays
bDeleteArrays is true if we delete the arrays in garbage collection set to true by default
Definition OSGeneral.h:619
used for throwing exceptions.
OSnLNode ** m_mChildren
m_mChildren holds all the operands, that is, nodes that the current node operates on.
Definition OSnLNode.h:84
unsigned int inumberOfChildren
inumberOfChildren is the number of OSnLNode child elements If this number is not fixed,...
Definition OSnLNode.h:74
the InitDualVarValue class.
Definition OSOption.h:2925
int idx
constraint index
Definition OSOption.h:2929
double ubDualValue
initial upper bound
Definition OSOption.h:2938
double lbDualValue
initial lower bound
Definition OSOption.h:2935
int numberOfCon
number of <con> children
Definition OSOption.h:2992
InitDualVarValue ** con
initial dual values for each constraint
Definition OSOption.h:2995
the InitVarValue class.
Definition OSOption.h:1160
double value
initial value
Definition OSOption.h:1170
int idx
variable index
Definition OSOption.h:1164
InitVarValue ** var
initial value for each variable
Definition OSOption.h:1226
int numberOfVar
number of children
Definition OSOption.h:1223
NonlinearExpressions * nonlinearExpressions
nonlinearExpressions is a pointer to a NonlinearExpressions object
LinearConstraintCoefficients * linearConstraintCoefficients
linearConstraintCoefficients is a pointer to a LinearConstraintCoefficients object
bool bDeleteArrays
bDeleteArrays is true if we delete the arrays in garbage collection set to true by default
Definition OSGeneral.h:482
DoubleVector * value
a pointer to the array of nonzero values being stored
Definition OSInstance.h:315
IntVector * start
a pointer to the start of each row or column stored in sparse format
Definition OSInstance.h:306
IntVector * rowIdx
a pointer of row indices if the problem is stored by column
Definition OSInstance.h:309
IntVector * colIdx
a pointer of column indices if the problem is stored by row
Definition OSInstance.h:312
The in-memory representation of the <nl> element.
Definition OSInstance.h:411
int idx
idx holds the row index of the nonlinear expression
Definition OSInstance.h:414
ScalarExpressionTree * osExpressionTree
osExpressionTree contains the root of the ScalarExpressionTree
Definition OSInstance.h:430
bool m_bDeleteExpressionTree
m_bDeleteExpressionTree is true, if in garbage collection, we should delete the osExpression tree obj...
Definition OSInstance.h:427
The in-memory representation of the <nonlinearExpressions> element.
Definition OSInstance.h:453
int numberOfNonlinearExpressions
numberOfNonlinearExpressions is the number of <nl> elements in the <nonlinearExpressions> element.
Definition OSInstance.h:466
Nl ** nl
nl is pointer to an array of Nl object pointers
Definition OSInstance.h:469
The in-memory representation of an OSiL instance..
bool setConstraintNumber(int number)
set the number of constraints.
bool addVariable(int index, std::string name, double lowerBound, double upperBound, char type)
add a variable.
std::string printModel()
Print the infix representation of the problem.
bool addConstraint(int index, std::string name, double lowerBound, double upperBound, double constant)
add a constraint.
bool setQuadraticCoefficients(int number, int *rowIndexes, int *varOneIndexes, int *varTwoIndexes, double *coefficients, int begin, int end)
set quadratic coefficients into the QuadraticCoefficients->qTerm data structure
bool setLinearConstraintCoefficients(int numberOfValues, bool isColumnMajor, double *values, int valuesBegin, int valuesEnd, int *indexes, int indexesBegin, int indexesEnd, int *starts, int startsBegin, int startsEnd)
set linear constraint coefficients
InstanceData * instanceData
A pointer to an InstanceData object.
int getVariableNumber()
Get number of variables.
bool setInstanceDescription(std::string description)
set the instance description.
bool addObjective(int index, std::string name, std::string maxOrMin, double constant, double weight, SparseVector *objectiveCoefficients)
add an objective.
bool setObjectiveNumber(int number)
set the number of objectives.
bool setVariableNumber(int number)
set the number of variables.
The Option Class.
Definition OSOption.h:3565
bool setAnOtherConstraintOption(OtherConstraintOption *optionValue)
OptimizationOption * optimization
optimizationOption holds the fifth child of the OSOption specified by the OSoL Schema.
Definition OSOption.h:3596
bool setJobID(std::string jobID)
Set the job ID.
bool deepCopyFrom(OSOption *that)
A function to make a deep copy of an OSOption object.
OtherObjectiveOption * getOtherObjectiveOption(int optionNumber)
Get one particular <other> objective option from the array of options.
bool setInitDualVarValuesSparse(int numberOfCon, InitDualVarValue **con)
bool setAnOtherObjectiveOption(OtherObjectiveOption *objOption)
bool setInitBasisStatus(int object, int status, int *i, int ni)
int getNumberOfInitialBasisElements(int type, int status)
Get the number of initial basis elements for a particular variable type and basis status.
OtherConstraintOption * getOtherConstraintOption(int optionNumber)
Get one particular <other> constraint option from the array of options.
bool setAnOtherVariableOption(OtherVariableOption *varOption)
bool setAnotherSolverOption(std::string name, std::string value, std::string solver, std::string category, std::string type, std::string description)
bool setInitVarValuesSparse(int numberOfVar, InitVarValue **var)
bool getInitialBasisElements(int type, int status, int *elem)
Get the initial basis elements for a particular variable type and basis status.
OtherVariableOption * getOtherVariableOption(int optionNumber)
Get one particular <other> variable option from the array of options.
Take an OSInstance object and write a string that validates against the OSiL schema.
Definition OSiLWriter.h:30
std::string writeOSiL(const OSInstance *theosinstance)
create an osil string from an OSInstance object
bool m_bWhiteSpace
m_bWhiteSpace is set to true if we write white space in the file
Definition OSiLWriter.h:68
The OSnLNodeAbs Class.
Definition OSnLNode.h:1113
The OSnLNodeCos Class.
Definition OSnLNode.h:963
The OSnLNodeDivide Class.
Definition OSnLNode.h:669
The OSnLNodeExp Class.
Definition OSnLNode.h:1063
The OSnLNode Class for nonlinear expressions.
Definition OSnLNode.h:180
The OSnLNodeLn Class.
Definition OSnLNode.h:816
The OSnLNodeMax Class.
Definition OSnLNode.h:415
The OSnLNodeMinus Class.
Definition OSnLNode.h:516
The OSnLNodeNegate Class.
Definition OSnLNode.h:567
The OSnLNodeNumber Class.
Definition OSnLNode.h:1263
double value
value is the value of the number
Definition OSnLNode.h:1266
The OSnLNodePlus Class.
Definition OSnLNode.h:316
The OSnLNodePower Class.
Definition OSnLNode.h:718
The OSnLNodeSin Class.
Definition OSnLNode.h:1013
The OSnLNodeSqrt Class.
Definition OSnLNode.h:865
The OSnLNodeSquare Class.
Definition OSnLNode.h:913
The OSnLNodeSum Class.
Definition OSnLNode.h:366
The OSnLNodeTimes Class.
Definition OSnLNode.h:618
The OSnLNodeVariable Class.
Definition OSnLNode.h:1479
int idx
idx is the index of the variable
Definition OSnLNode.h:1488
double coef
coef is an option coefficient on the variable, the default value is 1.0
Definition OSnLNode.h:1485
~OSnl2OS()
the OSnl2OS class destructor
Definition OSnl2OS.cpp:178
std::vector< std::string > op_type
Definition OSnl2OS.h:191
void setJobID(std::string jobID)
set the job ID
Definition OSnl2OS.cpp:104
OSoLReader * osolreader
we may need to parse an OSoL file if there is suffix information indicated in the AMPL nl content
Definition OSnl2OS.h:160
ASL * cw
Pointers to AMPL data structures.
Definition OSnl2OS.h:207
ASL * getASL(std::string name)
return a pointer to an ASL object
Definition OSnl2OS.cpp:87
OSInstance * osinstance
osinstance is a pointer to the OSInstance object that gets created from the information in the nl fil...
Definition OSnl2OS.h:172
bool readNl(std::string stub)
read the nl file
Definition OSnl2OS.cpp:109
ASL * rw
Definition OSnl2OS.h:207
bool createOSObjects()
create an OSInstance and OSOption representation from the AMPL nl content (Some of the information in...
Definition OSnl2OS.cpp:504
std::vector< double > operand
Definition OSnl2OS.h:192
ograd * og
og is a pointer to the AMPL data structure holding the objective function coefficients
Definition OSnl2OS.h:200
OSOption * osoption
osoption is a pointer to the OSOption object that gets created from the information in the nl file (a...
Definition OSnl2OS.h:177
void setIBVar(OSInstance *osinstance, int lower, int upper)
special version of the previous method because AMPL makes no distinction between integer and binary v...
Definition OSnl2OS.cpp:481
std::string osol
osol is a string containing the content of the OS option file (it may be empty if no option file was ...
Definition OSnl2OS.h:183
int numkount
Definition OSnl2OS.h:193
void setOsol(std::string osol)
set the osol string
Definition OSnl2OS.cpp:99
std::string jobID
jobID is a string containing a jobID that may have been supplied on the command line (it may be empty...
Definition OSnl2OS.h:189
OSnl2OS()
the OSnl2OS class constructor
Definition OSnl2OS.cpp:71
void setVar(OSInstance *osinstance, int lower, int upper, char vartype)
store a number of variables into an OSInstance object
Definition OSnl2OS.cpp:461
ASL * asl
Definition OSnl2OS.h:207
std::string stub
stub is the name of the file with the nl instance
Definition OSnl2OS.h:211
OSnLNode * walkTree(expr *e)
parse an nl tree structure holding a nonlinear expression
Definition OSnl2OS.cpp:206
Used to read an OSoL string.
Definition OSoLReader.h:38
OSOption * readOSoL(const std::string &osol)
parse the OSoL solver options.
Take an OSOption object and write a string that validates against the OSoL schema.
Definition OSoLWriter.h:30
std::string writeOSoL(OSOption *theosoption)
create an osol string from an OSOption object
int numberOfOtherObjectiveOptions
number of <other> child elements
Definition OSOption.h:2686
OtherObjectiveOption ** other
other information about the objectives
Definition OSOption.h:2698
VariableOption * variables
the options for the variables
Definition OSOption.h:3509
ObjectiveOption * objectives
the options for the objectives
Definition OSOption.h:3512
ConstraintOption * constraints
the options for the constraints
Definition OSOption.h:3515
the OtherConOption class.
Definition OSOption.h:3092
int idx
variable index
Definition OSOption.h:3096
std::string value
value of the option
Definition OSOption.h:3102
the OtherConstraintOption class.
Definition OSOption.h:3157
std::string conType
type of the values in the con array
Definition OSOption.h:3188
std::string name
name of the option
Definition OSOption.h:3167
int numberOfCon
number of <con> children
Definition OSOption.h:3161
OtherConOption ** con
array of option values
Definition OSOption.h:3185
std::string description
description of the option
Definition OSOption.h:3182
int numberOfEnumerations
number of <enumeration> child elements
Definition OSOption.h:3164
the OtherObjOption class.
Definition OSOption.h:2510
int idx
variable index
Definition OSOption.h:2514
std::string value
value of the option
Definition OSOption.h:2520
the OtherObjectiveOption class.
Definition OSOption.h:2575
OtherObjOption ** obj
array of option values
Definition OSOption.h:2603
int numberOfObj
number of <obj> children
Definition OSOption.h:2579
std::string name
name of the option
Definition OSOption.h:2585
int numberOfEnumerations
number of <enumeration> child elements
Definition OSOption.h:2582
std::string objType
type of the values in the obj array
Definition OSOption.h:2606
std::string description
description of the option
Definition OSOption.h:2600
the OtherVarOption class.
Definition OSOption.h:1928
std::string value
value of the option
Definition OSOption.h:1938
int idx
variable index
Definition OSOption.h:1932
the OtherVariableOption class.
Definition OSOption.h:1990
int numberOfVar
number of child elements
Definition OSOption.h:1994
int numberOfEnumerations
number of <enumeration> child elements
Definition OSOption.h:1997
std::string name
name of the option
Definition OSOption.h:2000
OtherVarOption ** var
array of option values
Definition OSOption.h:2018
std::string description
description of the option
Definition OSOption.h:2015
std::string varType
type of the values in the var array
Definition OSOption.h:2021
Used to hold part of the instance in memory.
OSnLNode * m_treeRoot
m_treeRoot holds the root node (of OSnLNode type) of the expression tree.
a sparse vector data structure
Definition OSGeneral.h:123
double * values
values holds a double array of nonzero values.
Definition OSGeneral.h:164
int * indexes
indexes holds an integer array of indexes whose corresponding values are nonzero.
Definition OSGeneral.h:159
BasisStatus * initialBasisStatus
initial basis information
Definition OSOption.h:2110
int numberOfOtherVariableOptions
number of <other> child elements
Definition OSOption.h:2101
OtherVariableOption ** other
other variable options
Definition OSOption.h:2119
InitVariableValues * initialVariableValues
initial values for the variables
Definition OSOption.h:2104
#define OS_EPS
@ ENUM_COMBINE_ARRAYS_merge
@ ENUM_OUTPUT_LEVEL_detailed_trace
@ ENUM_OUTPUT_LEVEL_debug
@ ENUM_OUTPUT_LEVEL_trace
@ ENUM_BASIS_STATUS_isFree
@ ENUM_BASIS_STATUS_unknown
@ ENUM_BASIS_STATUS_basic
@ ENUM_BASIS_STATUS_NUMBER_OF_STATES
@ ENUM_BASIS_STATUS_atLower
@ ENUM_BASIS_STATUS_atEquality
@ ENUM_BASIS_STATUS_superbasic
@ ENUM_BASIS_STATUS_atUpper
@ ENUM_OUTPUT_AREA_OSModelInterfaces
@ ENUM_PROBLEM_COMPONENT_constraints
@ ENUM_PROBLEM_COMPONENT_variables
#define OSDBL_MAX