00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <iostream>
00050 #include "OSiLWriter.h"
00051 #include "OSnl2osil.h"
00052 #include "ErrorClass.h"
00053
00054
00055 #include "nlp.h"
00056 #include "getstub.h"
00057 #include "r_opn.hd"
00058 #include "opcode.hd"
00059
00060 #define R_OPS ((ASL_fg*)asl)->I.r_ops_
00061 #define OBJ_DE ((ASL_fg*)asl)->I.obj_de_
00062 #define CON_DE ((ASL_fg*)asl)->I.con_de_
00063
00064 efunc *r_ops_int[N_OPS];
00065
00066 #include <asl.h>
00067
00068 using std::cerr;
00069 using std::cout;
00070 using std::endl;
00071
00072
00073
00074
00075
00076
00077 OSnl2osil::OSnl2osil(std::string nlfilename){
00078
00079 asl = ASL_alloc(ASL_read_fg);
00080 stub = &nlfilename[ 0];
00081
00082
00083 nl = jac0dim(stub, (fint)strlen(stub));
00084
00085 A_vals = (real *)Malloc(nzc*sizeof(real));
00086
00087 #ifdef AMPLDEBUG
00088 cout << "number of nonzeros = " << nzc << endl;
00089 cout << "number of variable = " << n_var << endl;
00090 cout << "number of constraints = " << n_con << endl;
00091 cout << "number of objs = " << n_obj << endl;
00092 cout << "number of ranges = " << nranges << endl;
00093 cout << "number of equations = " << n_eqn << endl;
00094
00095 #endif
00096 #ifdef AMPLDEBUG
00097 cout << "Start f_read()" << endl;
00098 #endif
00099
00100
00101 X0 = (real *)Malloc( n_var*sizeof(real));
00102 cout << "N_OPS = " << N_OPS << endl;
00103 if(N_OPS > 0){
00104 for(int i = 0; i < N_OPS; i++){
00105 r_ops_int[i] = (efunc*)(unsigned long)i;
00106
00107 }
00108 R_OPS = r_ops_int;
00109 want_derivs = 0;
00110 fg_read(nl, 0);
00111 R_OPS = 0;
00112 }
00113 }
00114
00115 OSnl2osil::~OSnl2osil(){
00116 delete osinstance;
00117 osinstance = NULL;
00118 }
00119
00120 OSnLNode* OSnl2osil::walkTree (expr *e){
00121 OSnLNode *nlNodePoint;
00122 OSnLNodeVariable *nlNodeVariablePoint;
00123 OSnLNodeNumber *nlNodeNumberPoint;
00124 efunc *op;
00125 expr **ep;
00126 int opnum;
00127 int i;
00128 op = e->op;
00129 opnum = Intcast op;
00130
00131 try{
00132 switch( opnum) {
00133 case OPPLUS:
00134 cout << "FOUND PLUS NODE" << endl;
00135 nlNodePoint = new OSnLNodePlus();
00136 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00137 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00138 return nlNodePoint;
00139
00140 case OPSUMLIST:
00141 i = 0;
00142 cout << "INSIDE SUM OPERATOR" << endl;
00143 nlNodePoint = new OSnLNodeSum();
00144 nlNodePoint->inumberOfChildren = e->R.ep - e->L.ep;
00145 nlNodePoint->m_mChildren = new OSnLNode*[ e->R.ep - e->L.ep];
00146 for (ep = e->L.ep; ep < e->R.ep; *ep++)
00147 nlNodePoint->m_mChildren[i++] = walkTree ( *ep);
00148 return nlNodePoint;
00149
00150 case MAXLIST:
00151 i = 0;
00152 cout << "INSIDE MAX OPERATOR" << endl;
00153 nlNodePoint = new OSnLNodeMax();
00154 nlNodePoint->inumberOfChildren = e->R.ep - e->L.ep;
00155 nlNodePoint->m_mChildren = new OSnLNode*[ e->R.ep - e->L.ep];
00156 for (ep = e->L.ep; ep < e->R.ep; *ep++)
00157 nlNodePoint->m_mChildren[i++] = walkTree ( *ep);
00158 return nlNodePoint;
00159
00160 case OPMINUS:
00161 nlNodePoint = new OSnLNodeMinus();
00162 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00163 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00164 return nlNodePoint;
00165
00166 case OPUMINUS:
00167 nlNodePoint = new OSnLNodeNegate();
00168 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00169 return nlNodePoint;
00170
00171 case OPMULT:
00172 cout << "FOUND MULT NODE" << endl;
00173 nlNodePoint = new OSnLNodeTimes();
00174 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00175 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00176 return nlNodePoint;
00177
00178 case OPDIV:
00179 nlNodePoint = new OSnLNodeDivide();
00180 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00181 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00182 return nlNodePoint;
00183
00184 case OPPOW:
00185 cout << "FOUND OPPOW NODE" << endl;
00186 nlNodePoint = new OSnLNodePower();
00187 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00188 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00189 return nlNodePoint;
00190
00191
00192 case OP1POW:
00193 cout << "FOUND OP1POW NODE" << endl;
00194 cout << "OP1POW EXPONENT = " << e->R.en->v<< endl;
00195 nlNodePoint = new OSnLNodePower();
00196 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00197 nlNodeNumberPoint = new OSnLNodeNumber();
00198 nlNodeNumberPoint->value = e->R.en->v;
00199 nlNodePoint->m_mChildren[1] = nlNodeNumberPoint;
00200 return nlNodePoint;
00201
00202 case OP2POW:
00203 cout << "FOUND OP2POW NODE" << endl;
00204
00205
00206
00207
00208
00209 nlNodePoint = new OSnLNodeSquare();
00210 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00211 return nlNodePoint;
00212
00213 case OPCPOW:
00214 cout << "FOUND OPCPOW NODE" << endl;
00215 cout << "OPCPOW EXPONENT = " << e->R.en->v<< endl;
00216 nlNodePoint = new OSnLNodePower();
00217 nlNodeNumberPoint = new OSnLNodeNumber();
00218 nlNodeNumberPoint->value = e->L.en->v;
00219 nlNodePoint->m_mChildren[0] = nlNodeNumberPoint;
00220 nlNodePoint->m_mChildren[1] = walkTree (e->R.e);
00221 return nlNodePoint;
00222
00223 case OP_log:
00224 nlNodePoint = new OSnLNodeLn();
00225 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00226 return nlNodePoint;
00227
00228 case OP_sqrt:
00229 nlNodePoint = new OSnLNodeSqrt();
00230 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00231 return nlNodePoint;
00232
00233 case OP_cos:
00234 nlNodePoint = new OSnLNodeCos();
00235 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00236 return nlNodePoint;
00237
00238 case OP_sin:
00239 nlNodePoint = new OSnLNodeSin();
00240 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00241 return nlNodePoint;
00242
00243 case OP_exp:
00244 nlNodePoint = new OSnLNodeExp();
00245 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00246 return nlNodePoint;
00247
00248 case ABS:
00249 nlNodePoint = new OSnLNodeAbs();
00250 nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00251 return nlNodePoint;
00252
00253 case OPNUM:
00254 cout << "found a number node" << endl;
00255 nlNodeNumberPoint = new OSnLNodeNumber;
00256 cout << "THE NUMBER" << (double) ((expr_n*)e)->v << endl;
00257 nlNodeNumberPoint->value = (double) ((expr_n*)e)->v;
00258 return nlNodeNumberPoint;
00259
00260 case OPVARVAL:
00261 cout << "found a variable node" << endl;
00262 if(e->a >= osinstance->getVariableNumber() ) throw ErrorClass("OS cannot handle AMPL user defined variables, please reformulate");
00263 nlNodeVariablePoint = new OSnLNodeVariable;
00264 nlNodeVariablePoint->idx = e->a;
00265 nlNodeVariablePoint->coef = 1.0;
00266 return nlNodeVariablePoint;
00267
00268 default:
00269 std::ostringstream outStr;
00270 std::string error;
00271 outStr << endl;
00272 outStr << endl;
00273 error = "ERROR: An unsupported operator found, AMPL operator number = " ;
00274 outStr << error;
00275 outStr << opnum;
00276 outStr << endl;
00277 error = outStr.str();
00278 throw ErrorClass( error );
00279 }
00280 }
00281 catch(const ErrorClass& eclass){
00282 throw;
00283 }
00284 }
00285
00286
00287 bool OSnl2osil::createOSInstance(){
00288 osinstance = new OSInstance();
00289 int i, j;
00290
00291
00292 osinstance->setInstanceDescription("Generated from AMPL nl file");
00293
00294
00295
00296
00297
00298 std::string initString;
00299 std::string colName;
00300 double init = OSNAN;
00301 char vartype = 'C';
00302 osinstance->setVariableNumber( n_var);
00303 int firstBinaryVar = n_var - nbv - niv;
00304 int firstIntegerVar = n_var - niv;
00305 for(i = 0; i < n_var; i++){
00306 if(i >= firstBinaryVar) vartype = 'B';
00307 if(i >= firstIntegerVar) vartype = 'I';
00308 if(X0 != NULL) init = X0[ i];
00309 osinstance->addVariable(i, var_name(i),
00310 LUv[2*i] > -OSINFINITY ? LUv[2*i] : -OSINFINITY,
00311 LUv[2*i+1] < OSINFINITY ? LUv[2*i+1] : OSINFINITY,
00312 vartype, init, initString);
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 double objWeight = 1.0;
00322
00323 std::string objName="";
00324 SparseVector* objectiveCoefficients = NULL;
00325 objectiveCoefficients = new SparseVector( n_var);
00326 for(i = 0; i < n_var; i++){
00327 objectiveCoefficients->indexes[i] = i;
00328 }
00329 osinstance->setObjectiveNumber( n_obj) ;
00330 for(i = 0; i < n_obj; i++){
00331 for(j = 0; j < n_var; j++){
00332 objectiveCoefficients->values[j] = 0;
00333 }
00334 for(og = Ograd[i]; og; og = og->next){
00335 objectiveCoefficients->values[og->varno] = og->coef;
00336 }
00337 osinstance->addObjective(-n_obj + i, objName,
00338 (objtype[i] == 1)?"max":"min",
00339 objconst( i), objWeight, objectiveCoefficients) ;
00340 }
00341
00342
00343
00344
00345
00346 osinstance->setConstraintNumber( n_con);
00347
00348 double constant = 0.0;
00349 std::string rowName;
00350 for(i = 0; i < n_con; i++)
00351 {
00352 osinstance->addConstraint(i, con_name(i),
00353 LUrhs[2*i] > -OSINFINITY ? LUrhs[2*i] : -OSINFINITY,
00354 LUrhs[2*i+1] < OSINFINITY ? LUrhs[2*i+1] : OSINFINITY,
00355 constant);
00356 }
00357 int valuesBegin = 0;
00358 int valuesEnd = A_colstarts[ n_var] - 1;
00359 int startsBegin = 0;
00360 int indexesBegin = 0;
00361 int indexesEnd = A_colstarts[n_var] - 1;
00362
00363
00364 bool bNumAvalsIsPositive = false;
00365 i = valuesBegin;
00366 while( (i < valuesEnd) && (bNumAvalsIsPositive == false) ){
00367 if(A_vals[ i] != 0) bNumAvalsIsPositive = true;
00368 i++;
00369 }
00370 if(bNumAvalsIsPositive == true){
00371 osinstance->setLinearConstraintCoefficients(nzc, true,
00372 A_vals, valuesBegin, valuesEnd,
00373 A_rownos, indexesBegin, indexesEnd,
00374 A_colstarts, startsBegin, n_var);
00375 }
00376
00377
00378
00379
00380
00381
00382 if((nlc + nlo) > 0){
00383 OSnLNode* m_treeRoot;
00384 cout << nlc << endl;
00385 cout << nlo << endl;
00386 osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions = nlc + nlo;
00387 osinstance->instanceData->nonlinearExpressions->nl = new Nl*[ nlc + nlo ];
00388 int iNLidx = 0;
00389
00390 if(nlc > 0){
00391 while (iNLidx < nlc) {
00392 m_treeRoot = walkTree ((CON_DE + iNLidx)->e);
00393 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx] = new Nl();
00394 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->idx = iNLidx;
00395 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->osExpressionTree = new OSExpressionTree();
00396 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->osExpressionTree->m_treeRoot = m_treeRoot;
00397 iNLidx++;
00398
00399 }
00400 }
00401
00402 if(nlo > 0){
00403 while ( iNLidx < nlc + nlo){
00404 m_treeRoot = walkTree ((OBJ_DE + iNLidx - nlc)->e);
00405 std::cout << "CREATING A NEW NONLINEAR TERM IN THE OBJECTIVE" << std::endl;
00406 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx] = new Nl();
00407 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->idx = -1 - (iNLidx - nlc);
00408 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->osExpressionTree = new OSExpressionTree();
00409 osinstance->instanceData->nonlinearExpressions->nl[ iNLidx]->osExpressionTree->m_treeRoot = m_treeRoot;
00410 iNLidx++;
00411
00412 }
00413 }
00414
00415
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 return true;
00425 }