/home/coin/SVN-release/OS-1.0.0/OS/src/OSModelInterfaces/OSnl2osil.cpp

Go to the documentation of this file.
00001 
00017 /*
00018 Using AMLP with nl2fml.  Here is the sequence of AMPL commands
00019 with the parinc problem:
00020 //
00021 model parinc.mod;    
00022 data parinc.dat;
00023 option solver nl2osil;
00024 option nl2osil_oopt g; 
00025 option nl2osil_solver lindo; 
00026 sovle;
00027 
00028 Alternatively, if you want to name the file and not use the AMPL randomly 
00029 generate file name, do the following:
00030 
00031    model hs71.mod;
00032    option solver amplclient;
00033    option amplclient_options "solver lindo";
00034    option lindo_options "<<any options for the lindo solver>>";
00035    write gtestfile;
00036    solve;
00037         
00038 of course, replacing gtestfile with btestfile generates a binary nl file. 
00039 // glpk is the default -- replace lindo with clp for that solver
00040 // on the Mac it wants the nl file to be text and not binary 
00041 solve;
00042 display x;
00043 //
00044 you should get x1 = 540, x2 = 252
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" /* for N_OPS */
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         //Initialize the AMPL library
00079         asl = ASL_alloc(ASL_read_fg);
00080         stub = &nlfilename[ 0];
00081         //cout << "READING FILE " << stub << endl;
00082         //Initialize the nl file reading
00083         nl = jac0dim(stub, (fint)strlen(stub));
00084         //Prepare *columnwise* parsing of nl file
00085         A_vals = (real *)Malloc(nzc*sizeof(real)); 
00086         //read nl file as a linear program
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         //cout << "objective function type" << *objtype << endl;
00095         #endif
00096         #ifdef AMPLDEBUG 
00097                 cout << "Start f_read()" << endl;
00098         #endif
00099 
00100         //fg_read(nl, 0);
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         //Printf ("op %d  optype %d  ", opnum, optype[opnum]);
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                                 //nlNodePoint = new OSnLNodePower();
00205                                 //nlNodePoint->m_mChildren[0] = walkTree (e->L.e);
00206                                 //nlNodeNumberPoint = new OSnLNodeNumber();
00207                                 //nlNodeNumberPoint->value = 2;
00208                                 //nlNodePoint->m_mChildren[1] = nlNodeNumberPoint;
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                 }//end switch   
00280         }//end try
00281         catch(const ErrorClass& eclass){
00282                 throw;
00283         }
00284 }//walkTree
00285 
00286 
00287 bool OSnl2osil::createOSInstance(){
00288         osinstance = new OSInstance();  
00289         int i, j;
00290         // put in instanceHeader information 
00291         // 
00292         osinstance->setInstanceDescription("Generated from AMPL nl file");
00293         //
00294         // put in instanceData information
00295         //
00296         // get the variable information
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         //(expr_v *)e;
00317         //
00318         //
00319         // now create the objective function
00320         //      
00321         double objWeight = 1.0;
00322         //      char    *objtype;       /* object type array: 0 == min, 1 == max */
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         //delete objectiveCoefficients; // delete the temporary sparse vector
00342         //objectiveCoefficients = NULL;
00343         //
00344         // now fill in row information
00345         //
00346         osinstance->setConstraintNumber( n_con);
00347         // kipp -- important  -- figure out where the nl file stores a rhs constant
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         // if A_vals has only zeros don't generate a linearConstraints section
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         // Kipp: can AMPL identify QPs???
00379         //osinstance->setQuadraticTerms(numberOfQPTerms, VarOneIdx, VarTwoIdx, Coeff, begin, end);
00380         //loop over each row with a nonlinear term
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                 //std::cout << "WALK THE TREE FOR NONLINEAR CONSTRAINT TERMS" << std::endl;
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                                 //std::cout << m_treeRoot->getNonlinearExpressionInXML() << std::endl;
00399                         }
00400                 }
00401                 //std::cout << "WALK THE TREE FOR NONLINEAR OBJECTIVE TERMS" << std::endl;
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                                 //std::cout << m_treeRoot->getNonlinearExpressionInXML() << std::endl;
00412                         }
00413                 }
00414                 //std::cout << "DONE WALKING THE TREE FOR NONLINEAR OBJECTIVE TERMS" << std::endl;
00415 
00416         }
00417         //
00418         // end loop of nonlinear rows
00419         //    
00420         //OSiLWriter osilwriter;
00421         //std::cout << "WRITE THE INSTANCE" << std::endl;
00422         //std::cout << osilwriter.writeOSiL( osinstance) << std::endl;
00423         //std::cout << "DONE WRITE THE INSTANCE" << std::endl;
00424         return true;
00425 }

Generated on Thu May 15 22:15:05 2008 by  doxygen 1.4.7