/home/coin/SVN-release/OS-2.4.1/OS/src/OSModelInterfaces/OSgams2osil.cpp

Go to the documentation of this file.
00001 // Copyright (C) GAMS Development and others 2007-2009
00002 // All Rights Reserved.
00003 // This code is published under the Eclipse Public License.
00004 //
00005 // $Id: OSgams2osil.cpp 4292 2011-09-21 05:47:18Z kmartin $
00006 //
00007 // Author: Stefan Vigerske
00008 
00009 #include "OSgams2osil.hpp"
00010 #include "GAMSlinksConfig.h"
00011 #include "GamsNLinstr.h"
00012 
00013 #include "OSInstance.h"
00014 #include "CoinHelperFunctions.hpp"
00015 
00016 #include "gmomcc.h"
00017 #include "gevmcc.h"
00018 
00019 #include <sstream>
00020 
00021 OSgams2osil::OSgams2osil(gmoHandle_t gmo_)
00022     : gev(gmo_ ? (gevHandle_t)gmoEnvironment(gmo_) : NULL), gmo(gmo_), osinstance(NULL)
00023 {
00024     //assert(gev_ == NULL); // TODO better
00025     assert(gmo_ == NULL); // TODO better
00026 }
00027 
00028 OSgams2osil::OSgams2osil(std::string gamsControlFile)
00029     : gev(NULL), gmo(NULL), osinstance(NULL)
00030 {
00031     initGMO( gamsControlFile.c_str() ) ;
00032 }
00033 
00034 OSgams2osil::~OSgams2osil()
00035 {
00036     delete osinstance;
00037 
00038     //close output channels
00039 //      gmoCloseGms(gmo);
00040     gmoFree(&gmo);
00041     gevFree(&gev);
00042     gmoLibraryUnload();
00043     gevLibraryUnload();
00044 }
00045 
00046 bool OSgams2osil::initGMO(const char* datfile)
00047 {
00048     assert(gmo == NULL);
00049     assert(gev == NULL);
00050 
00051     char msg[1024];
00052     int rc;
00053 
00054     //if (!gmoCreate(&gmo, msg, sizeof(msg))) {
00055     //          fprintf(stderr, "%s\n",msg);
00056     //          return false;
00057     //  }
00058 
00059 
00060 //      if (!gmoCreateD(&gmo, GAMSIO_PATH, msg, sizeof(msg))) {
00061     if (!gmoCreate(&gmo, msg, sizeof(msg)))
00062     {
00063         fprintf(stderr, "%s\n",msg);
00064         return false;
00065     }
00066 //      }
00067 
00068     if (!gevCreate(&gev, msg, sizeof(msg)))
00069     {
00070         fprintf(stderr, "%s\n",msg);
00071         return EXIT_FAILURE;
00072     }
00073 
00074 
00075     gmoIdentSet(gmo, "OS link object");
00076 
00077     // load control file
00078     if ((rc = gevInitEnvironmentLegacy(gev, datfile)))
00079     {
00080         fprintf(stderr, "Could not init gams environment: %s Rc = %d\n", datfile, rc);
00081         gmoFree(&gmo);
00082         gevFree(&gev);
00083         return false;
00084     }
00085 
00086     if ((rc = gmoRegisterEnvironment(gmo, gev, msg)))
00087     {
00088         gevLogStat(gev, "Could not register environment.");
00089         gmoFree(&gmo);
00090         gevFree(&gev);
00091         return false;
00092     }
00093 
00094     // setup GAMS output channels
00095 //      if ((rc = gmoOpenGms( gmo))) {
00096 //              fprintf(stderr, "Could not open GAMS environment. Rc = %d\n", rc);
00097 //              gmoFree(&gmo);
00098 //              return false;
00099 //      }
00100 
00101     if ((rc = gmoLoadDataLegacy(gmo, msg)))
00102     {
00103         gevLogStat(gev, "Could not load model data.");
00104 //              gmoCloseGms(gmo);
00105         gmoFree(&gmo);
00106         gevFree(&gev);
00107         return false;
00108     }
00109 
00110     gmoMinfSet(gmo, -OSDBL_MAX);
00111     gmoPinfSet(gmo,  OSDBL_MAX);
00112     gmoObjReformSet(gmo, 1);
00113     gmoObjStyleSet(gmo, ObjType_Fun);
00114     gmoIndexBaseSet(gmo, 0);
00115 
00116     return true;
00117 }
00118 
00119 bool OSgams2osil::createOSInstance()
00120 {
00121     assert(gmo != NULL);
00122     assert(gev != NULL);
00123 
00124     osinstance = new OSInstance();
00125     int i, j;
00126     char buffer[255];
00127 
00128     // unfortunately, we do not know the model name
00129     osinstance->setInstanceDescription("Generated from GAMS modeling object");
00130     osinstance->setVariableNumber(gmoN(gmo));
00131 
00132     char*        vartypes = new char[gmoN(gmo)];
00133     std::string* varnames = new std::string[gmoN(gmo)];
00134     for(i = 0; i < gmoN(gmo); ++i)
00135     {
00136         switch (gmoGetVarTypeOne(gmo, i))
00137         {
00138         case var_X:
00139             vartypes[i] = 'C';
00140             break;
00141         case var_B:
00142             vartypes[i] = 'B';
00143             break;
00144         case var_I:
00145             vartypes[i] = 'I';
00146             break;
00147         default :
00148         {
00149             // TODO: how to represent semicontinuous var. and SOS in OSiL ?
00150             gevLogStat(gev, "Error: Unsupported variable type.");
00151             return false;
00152         }
00153         }
00154         gmoGetVarNameOne(gmo, i, buffer);
00155         varnames[i] = buffer;
00156     }
00157 
00158     double* varlow = new double[gmoN(gmo)];
00159     double* varup  = new double[gmoN(gmo)];
00160     gmoGetVarLower(gmo, varlow);
00161     gmoGetVarUpper(gmo, varup);
00162 
00163     if (!osinstance->setVariables(gmoN(gmo), varnames, varlow, varup, vartypes))
00164         return false;
00165 
00166     delete[] vartypes;
00167     delete[] varnames;
00168     delete[] varlow;
00169     delete[] varup;
00170 
00171     if (gmoModelType(gmo) == Proc_cns)   // no objective in constraint satisfaction models
00172     {
00173         osinstance->setObjectiveNumber(0);
00174     }
00175     else     // setup objective
00176     {
00177         osinstance->setObjectiveNumber(1);
00178 
00179         SparseVector* objectiveCoefficients = new SparseVector(gmoObjNZ(gmo) - gmoObjNLNZ(gmo));
00180 
00181         int* colidx = new int[gmoObjNZ(gmo)];
00182         double* val = new double[gmoObjNZ(gmo)];
00183         int* nlflag = new int[gmoObjNZ(gmo)];
00184         int* dummy  = new int[gmoObjNZ(gmo)];
00185 
00186         if (gmoObjNZ(gmo)) nlflag[0] = 0; // workaround for gmo bug
00187         gmoGetObjSparse(gmo, colidx, val, nlflag, dummy, dummy);
00188         for (i = 0, j = 0; i < gmoObjNZ(gmo); ++i)
00189         {
00190             if (nlflag[i]) continue;
00191             objectiveCoefficients->indexes[j] = colidx[i];
00192             objectiveCoefficients->values[j]  = val[i];
00193             j++;
00194             assert(j <= gmoObjNZ(gmo) - gmoObjNLNZ(gmo));
00195         }
00196         assert(j == gmoObjNZ(gmo) - gmoObjNLNZ(gmo));
00197 
00198         delete[] colidx;
00199         delete[] val;
00200         delete[] nlflag;
00201         delete[] dummy;
00202 
00203         std::string objname = "objective"; //TODO
00204 //              if (dict.haveNames() && dict.getObjName(buffer, 256))
00205 //                      objname = buffer;
00206 //              std::cout << "gmo obj con: " << gmoObjConst(gmo) << std::endl;
00207         if (!osinstance->addObjective(-1, objname, gmoSense(gmo) == Obj_Min ? "min" : "max", gmoObjConst(gmo), 1., objectiveCoefficients))
00208         {
00209             delete objectiveCoefficients;
00210             return false;
00211         }
00212         delete objectiveCoefficients;
00213     }
00214 
00215     osinstance->setConstraintNumber(gmoM(gmo));
00216 
00217     double lb, ub;
00218     for (i = 0;  i < gmoM(gmo);  ++i)
00219     {
00220         switch (gmoGetEquTypeOne(gmo, i))
00221         {
00222         case equ_E:
00223             lb = ub = gmoGetRhsOne(gmo, i);
00224             break;
00225         case equ_L:
00226             lb = -OSDBL_MAX;
00227             ub =  gmoGetRhsOne(gmo, i);
00228             break;
00229         case equ_G:
00230             lb = gmoGetRhsOne(gmo, i);
00231             ub = OSDBL_MAX;
00232             break;
00233         case equ_N:
00234             lb = -OSDBL_MAX;
00235             ub =  OSDBL_MAX;
00236             break;
00237         default:
00238             gevLogStat(gev, "Error: Unknown row type. Exiting ...");
00239             return false;
00240         }
00241         std::string conname;
00242         gmoGetEquNameOne(gmo, i, buffer);
00243         conname = buffer;
00244         if (!osinstance->addConstraint(i, conname, lb, ub, 0.))
00245             return false;
00246     }
00247 
00248     int nz = gmoNZ(gmo);
00249     double* values  = new double[nz];
00250     int* colstarts  = new int[gmoN(gmo)+1];
00251     int* rowindexes = new int[nz];
00252     int* nlflags    = new int[nz];
00253 
00254     gmoGetMatrixCol(gmo, colstarts, rowindexes, values, nlflags);
00255 //      for (i = 0; i < gmoNZ(gmo); ++i)
00256 //              if (nlflags[i]) values[i] = 0.;
00257     colstarts[gmoN(gmo)] = nz;
00258 
00259     int shift = 0;
00260     for (int col = 0; col < gmoN(gmo); ++col)
00261     {
00262         colstarts[col+1] -= shift;
00263         int k = colstarts[col];
00264         while (k < colstarts[col+1])
00265         {
00266             values[k] = values[k+shift];
00267             rowindexes[k] = rowindexes[k+shift];
00268             if (nlflags[k+shift])
00269             {
00270                 ++shift;
00271                 --colstarts[col+1];
00272             }
00273             else
00274             {
00275                 ++k;
00276             }
00277         }
00278     }
00279     nz -= shift;
00280 
00281     if (!osinstance->setLinearConstraintCoefficients(nz, true,
00282             values, 0, nz-1,
00283             rowindexes, 0, nz-1,
00284             colstarts, 0, gmoN(gmo)))
00285     {
00286         delete[] nlflags;
00287         return false;
00288     }
00289 
00290     // values, colstarts, rowindexes are deleted by OSInstance
00291     delete[] nlflags;
00292 
00293     if (!gmoObjNLNZ(gmo) && !gmoNLNZ(gmo)) // everything linear -> finished
00294         return true;
00295 
00296     osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions = gmoNLM(gmo) + (gmoObjNLNZ(gmo) ? 1 : 0);
00297     osinstance->instanceData->nonlinearExpressions->nl = CoinCopyOfArrayOrZero((Nl**)NULL, osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions);
00298     int iNLidx = 0;
00299 
00300     int* opcodes = new int[gmoMaxSingleFNL(gmo)+1];
00301     int* fields  = new int[gmoMaxSingleFNL(gmo)+1];
00302     int constantlen = gmoNLConst(gmo);
00303     double* constants = (double*)gmoPPool(gmo);
00304     int codelen;
00305 
00306     OSnLNode* nl;
00307     if (gmoObjNLNZ(gmo))
00308     {
00309         std::clog << "parsing nonlinear objective instructions" << std::endl;
00310         gmoDirtyGetObjFNLInstr(gmo, &codelen, opcodes, fields);
00311 
00312         nl = parseGamsInstructions(codelen, opcodes, fields, constantlen, constants);
00313         if (!nl) return false;
00314 
00315         double objjacval = gmoObjJacVal(gmo);
00316         std::clog << "obj jac val: " << objjacval << std::endl;
00317         if (objjacval == 1.)   // scale by -1/objjacval = negate
00318         {
00319             OSnLNode* negnode = new OSnLNodeNegate;
00320             negnode->m_mChildren[0] = nl;
00321             nl = negnode;
00322         }
00323         else if (objjacval != -1.)     // scale by -1/objjacval
00324         {
00325             OSnLNodeNumber* numbernode = new OSnLNodeNumber();
00326             numbernode->value = -1/objjacval;
00327             OSnLNodeTimes* timesnode = new OSnLNodeTimes();
00328             timesnode->m_mChildren[0] = nl;
00329             timesnode->m_mChildren[1] = numbernode;
00330             nl = timesnode;
00331         }
00332         assert(iNLidx < osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions);
00333         osinstance->instanceData->nonlinearExpressions->nl[iNLidx] = new Nl();
00334         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->idx = -1;
00335         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->osExpressionTree = new OSExpressionTree();
00336         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->osExpressionTree->m_treeRoot = nl;
00337         ++iNLidx;
00338     }
00339 
00340     for (i = 0; i < gmoM(gmo); ++i)
00341     {
00342         if (gmoDirtyGetRowFNLInstr(gmo, i, &codelen, opcodes, fields))
00343         {
00344             std::clog << "got nonzero return at constraint " << i << std::endl;
00345         }
00346         if (!codelen) continue;
00347         std::clog << "parsing " << codelen << " nonlinear instructions of constraint " << osinstance->getConstraintNames()[i] << std::endl;
00348         nl = parseGamsInstructions(codelen, opcodes, fields, constantlen, constants);
00349         if (!nl) return false;
00350         assert(iNLidx < osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions);
00351         osinstance->instanceData->nonlinearExpressions->nl[iNLidx] = new Nl();
00352         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->idx = i; // correct that this is the con. number?
00353         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->osExpressionTree = new OSExpressionTree();
00354         osinstance->instanceData->nonlinearExpressions->nl[iNLidx]->osExpressionTree->m_treeRoot = nl;
00355         ++iNLidx;
00356     }
00357     assert(iNLidx == osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions);
00358 
00359     return true;
00360 }
00361 
00362 OSInstance* OSgams2osil::takeOverOSInstance()
00363 {
00364     OSInstance* osinst = osinstance;
00365     osinstance = NULL;
00366     return osinst;
00367 }
00368 
00369 OSnLNode* OSgams2osil::parseGamsInstructions(int codelen, int* opcodes, int* fields, int constantlen, double* constants)
00370 {
00371     std::vector<OSnLNode*> nlNodeVec;
00372 
00373     const bool debugoutput = false;
00374 
00375 //      for (int i=0; i<codelen; ++i)
00376 //              std::clog << i << '\t' << GamsOpCodeName[opcodes[i+1]] << '\t' << fields[i+1] << std::endl;
00377 
00378     nlNodeVec.reserve(codelen);
00379 
00380     for (int i=0; i<codelen; ++i)
00381     {
00382         GamsOpCode opcode = (GamsOpCode)opcodes[i];
00383         int address = fields[i]-1;
00384 
00385         if (debugoutput) std::clog << '\t' << GamsOpCodeName[opcode] << ": ";
00386 //              if (opcode == nlStore) {
00387 //                      std::clog << "stop" << std::endl;
00388 //                      break;
00389 //              }
00390         switch(opcode)
00391         {
00392         case nlNoOp :   // no operation
00393         {
00394             if (debugoutput) std::clog << "ignored" << std::endl;
00395         }
00396         break;
00397         case nlPushV :   // push variable
00398         {
00399             address = gmoGetjSolver(gmo, address);
00400             if (debugoutput) std::clog << "push variable " << osinstance->getVariableNames()[address] << std::endl;
00401             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00402             nlNode->idx=address;
00403             nlNodeVec.push_back( nlNode );
00404         }
00405         break;
00406         case nlPushI :   // push constant
00407         {
00408             if (debugoutput) std::clog << "push constant " << constants[address] << std::endl;
00409             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00410             nlNode->value = constants[address];
00411             nlNodeVec.push_back( nlNode );
00412         }
00413         break;
00414         case nlStore:   // store row
00415         {
00416             if (debugoutput) std::clog << "ignored" << std::endl;
00417         }
00418         break;
00419         case nlAdd :   // add
00420         {
00421             if (debugoutput) std::clog << "add" << std::endl;
00422             nlNodeVec.push_back( new OSnLNodePlus() );
00423         }
00424         break;
00425         case nlAddV:   // add variable
00426         {
00427             address = gmoGetjSolver(gmo, address);
00428             if (debugoutput) std::clog << "add variable " << osinstance->getVariableNames()[address] << std::endl;
00429             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00430             nlNode->idx=address;
00431             nlNodeVec.push_back( nlNode );
00432             nlNodeVec.push_back( new OSnLNodePlus() );
00433         }
00434         break;
00435         case nlAddI:   // add immediate
00436         {
00437             if (debugoutput) std::clog << "add constant " << constants[address] << std::endl;
00438             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00439             nlNode->value = constants[address];
00440             nlNodeVec.push_back( nlNode );
00441             nlNodeVec.push_back( new OSnLNodePlus() );
00442         }
00443         break;
00444         case nlSub:   // minus
00445         {
00446             if (debugoutput) std::clog << "minus" << std::endl;
00447             nlNodeVec.push_back( new OSnLNodeMinus() );
00448         }
00449         break;
00450         case nlSubV:   // subtract variable
00451         {
00452             address = gmoGetjSolver(gmo, address);
00453             if (debugoutput) std::clog << "substract variable " << osinstance->getVariableNames()[address] << std::endl;
00454             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00455             nlNode->idx=address;
00456             nlNodeVec.push_back( nlNode );
00457             nlNodeVec.push_back( new OSnLNodeMinus() );
00458         }
00459         break;
00460         case nlSubI:   // subtract immediate
00461         {
00462             if (debugoutput) std::clog << "substract constant " << constants[address] << std::endl;
00463             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00464             nlNode->value = constants[address];
00465             nlNodeVec.push_back( nlNode );
00466             nlNodeVec.push_back( new OSnLNodeMinus() );
00467         }
00468         break;
00469         case nlMul:   // multiply
00470         {
00471             if (debugoutput) std::clog << "multiply" << std::endl;
00472             nlNodeVec.push_back( new OSnLNodeTimes() );
00473         }
00474         break;
00475         case nlMulV:   // multiply variable
00476         {
00477             address = gmoGetjSolver(gmo, address);
00478             if (debugoutput) std::clog << "multiply variable " << osinstance->getVariableNames()[address] << std::endl;
00479             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00480             nlNode->idx=address;
00481             nlNodeVec.push_back( nlNode );
00482             nlNodeVec.push_back( new OSnLNodeTimes() );
00483         }
00484         break;
00485         case nlMulI:   // multiply immediate
00486         {
00487             if (debugoutput) std::clog << "multiply constant " << constants[address] << std::endl;
00488             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00489             nlNode->value = constants[address];
00490             nlNodeVec.push_back( nlNode );
00491             nlNodeVec.push_back( new OSnLNodeTimes() );
00492         }
00493         break;
00494         case nlDiv:   // divide
00495         {
00496             if (debugoutput) std::clog << "divide" << std::endl;
00497             nlNodeVec.push_back( new OSnLNodeDivide() );
00498         }
00499         break;
00500         case nlDivV:   // divide variable
00501         {
00502             address = gmoGetjSolver(gmo, address);
00503             if (debugoutput) std::clog << "divide variable " << osinstance->getVariableNames()[address] << std::endl;
00504             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00505             nlNode->idx=address;
00506             nlNodeVec.push_back( nlNode );
00507             nlNodeVec.push_back( new OSnLNodeDivide() );
00508         }
00509         break;
00510         case nlDivI:   // divide immediate
00511         {
00512             if (debugoutput) std::clog << "divide constant " << constants[address] << std::endl;
00513             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00514             nlNode->value = constants[address];
00515             nlNodeVec.push_back( nlNode );
00516             nlNodeVec.push_back( new OSnLNodeDivide() );
00517         }
00518         break;
00519         case nlUMin:   // unary minus
00520         {
00521             if (debugoutput) std::clog << "negate" << std::endl;
00522             nlNodeVec.push_back( new OSnLNodeNegate() );
00523         }
00524         break;
00525         case nlUMinV:   // unary minus variable
00526         {
00527             address = gmoGetjSolver(gmo, address);
00528             if (debugoutput) std::clog << "push negated variable " << osinstance->getVariableNames()[address] << std::endl;
00529             OSnLNodeVariable *nlNode = new OSnLNodeVariable();
00530             nlNode->idx = address;
00531             nlNode->coef = -1.;
00532             nlNodeVec.push_back( nlNode );
00533         }
00534         break;
00535         case nlCallArg1 :
00536         case nlCallArg2 :
00537         case nlCallArgN :
00538         {
00539             if (debugoutput) std::clog << "call function ";
00540             GamsFuncCode func = GamsFuncCode(address+1); // here the shift by one was not a good idea
00541             switch (func)
00542             {
00543             case fnmin :
00544             {
00545                 if (debugoutput) std::clog << "min" << std::endl;
00546                 nlNodeVec.push_back( new OSnLNodeMin() );
00547             }
00548             break;
00549             case fnmax :
00550             {
00551                 if (debugoutput) std::clog << "max" << std::endl;
00552                 nlNodeVec.push_back( new OSnLNodeMax() );
00553             }
00554             break;
00555             case fnsqr :
00556             {
00557                 if (debugoutput) std::clog << "square" << std::endl;
00558                 nlNodeVec.push_back( new OSnLNodeSquare() );
00559             }
00560             break;
00561             case fnexp:
00562             case fnslexp:
00563             case fnsqexp:
00564             {
00565                 if (debugoutput) std::clog << "exp" << std::endl;
00566                 nlNodeVec.push_back( new OSnLNodeExp() );
00567             }
00568             break;
00569             case fnlog :
00570             {
00571                 if (debugoutput) std::clog << "ln" << std::endl;
00572                 nlNodeVec.push_back( new OSnLNodeLn() );
00573             }
00574             break;
00575             case fnlog10:
00576             case fnsllog10:
00577             case fnsqlog10:
00578             {
00579                 if (debugoutput) std::clog << "log10 = ln * 1/ln(10)" << std::endl;
00580                 nlNodeVec.push_back( new OSnLNodeLn() );
00581                 OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00582                 nlNode->value = 1./log(10.);
00583                 nlNodeVec.push_back( nlNode );
00584                 nlNodeVec.push_back( new OSnLNodeTimes() );
00585             }
00586             break;
00587             case fnlog2 :
00588             {
00589                 if (debugoutput) std::clog << "log2 = ln * 1/ln(2)" << std::endl;
00590                 nlNodeVec.push_back( new OSnLNodeLn() );
00591                 OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00592                 nlNode->value = 1./log(2.);
00593                 nlNodeVec.push_back( nlNode );
00594                 nlNodeVec.push_back( new OSnLNodeTimes() );
00595             }
00596             break;
00597             case fnsqrt:
00598             {
00599                 if (debugoutput) std::clog << "sqrt" << std::endl;
00600                 nlNodeVec.push_back( new OSnLNodeSqrt() );
00601             }
00602             break;
00603             case fnabs:
00604             {
00605                 if (debugoutput) std::clog << "abs" << std::endl;
00606                 nlNodeVec.push_back( new OSnLNodeAbs() );
00607             }
00608             break;
00609             case fncos:
00610             {
00611                 if (debugoutput) std::clog << "cos" << std::endl;
00612                 nlNodeVec.push_back( new OSnLNodeCos() );
00613             }
00614             break;
00615             case fnsin:
00616             {
00617                 if (debugoutput) std::clog << "sin" << std::endl;
00618                 nlNodeVec.push_back( new OSnLNodeSin() );
00619             }
00620             break;
00621             case fnpower:
00622             case fnrpower: // x ^ y
00623             case fncvpower: // constant ^ x
00624             case fnvcpower:   // x ^ constant {
00625             {
00626                 if (debugoutput) std::clog << "power" << std::endl;
00627                 nlNodeVec.push_back( new OSnLNodePower() );
00628             }
00629             break;
00630             case fnpi:
00631             {
00632                 if (debugoutput) std::clog << "pi" << std::endl;
00633                 nlNodeVec.push_back( new OSnLNodePI() );
00634             }
00635             break;
00636             case fndiv:
00637             case fndiv0:
00638             {
00639                 nlNodeVec.push_back( new OSnLNodeDivide() );
00640             }
00641             break;
00642             case fnslrec: // 1/x
00643             case fnsqrec:   // 1/x
00644             {
00645                 if (debugoutput) std::clog << "divide" << std::endl;
00646                 nlNodeVec.push_back( new OSnLNodeLn() );
00647                 OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00648                 nlNode->value = 1.;
00649                 nlNodeVec.push_back( nlNode );
00650                 nlNodeVec.push_back( new OSnLNodeDivide() );
00651             }
00652             break;
00653             case fnceil:
00654             case fnfloor:
00655             case fnround:
00656             case fnmod:
00657             case fntrunc:
00658             case fnsign:
00659             case fnarctan:
00660             case fnerrf:
00661             case fndunfm:
00662             case fndnorm:
00663             case fnerror:
00664             case fnfrac:
00665             case fnerrorl:
00666             case fnfact /* factorial */:
00667             case fnunfmi /* uniform random number */:
00668             case fnncpf /* fischer: sqrt(x1^2+x2^2+2*x3) */:
00669             case fnncpcm /* chen-mangasarian: x1-x3*ln(1+exp((x1-x2)/x3))*/:
00670             case fnentropy /* x*ln(x) */:
00671             case fnsigmoid /* 1/(1+exp(-x)) */:
00672             case fnboolnot:
00673             case fnbooland:
00674             case fnboolor:
00675             case fnboolxor:
00676             case fnboolimp:
00677             case fnbooleqv:
00678             case fnrelopeq:
00679             case fnrelopgt:
00680             case fnrelopge:
00681             case fnreloplt:
00682             case fnrelople:
00683             case fnrelopne:
00684             case fnifthen:
00685             case fnedist /* euclidian distance */:
00686             case fncentropy /* x*ln((x+d)/(y+d))*/:
00687             case fngamma:
00688             case fnloggamma:
00689             case fnbeta:
00690             case fnlogbeta:
00691             case fngammareg:
00692             case fnbetareg:
00693             case fnsinh:
00694             case fncosh:
00695             case fntanh:
00696             case fnsignpower /* sign(x)*abs(x)^c */:
00697             case fnncpvusin /* veelken-ulbrich */:
00698             case fnncpvupow /* veelken-ulbrich */:
00699             case fnbinomial:
00700             case fntan:
00701             case fnarccos:
00702             case fnarcsin:
00703             case fnarctan2 /* arctan(x2/x1) */:
00704             case fnpoly: /* simple polynomial */
00705             default :
00706             {
00707                 if (debugoutput) std::cerr << "nr. " << func << " - unsuppored. Error." << std::endl;
00708                 return NULL;
00709             }
00710             }
00711         }
00712         break;
00713         case nlMulIAdd:
00714         {
00715             if (debugoutput) std::clog << "multiply constant " << constants[address] << " and add " << std::endl;
00716             OSnLNodeNumber *nlNode = new OSnLNodeNumber();
00717             nlNode->value = constants[address];
00718             nlNodeVec.push_back( nlNode );
00719             nlNodeVec.push_back( new OSnLNodeTimes() );
00720             nlNodeVec.push_back( new OSnLNodePlus() );
00721         }
00722         break;
00723         case nlFuncArgN :
00724         {
00725             if (debugoutput) std::clog << "ignored" << std::endl;
00726         }
00727         break;
00728         case nlArg:
00729         {
00730             if (debugoutput) std::clog << "ignored" << std::endl;
00731         }
00732         break;
00733         case nlHeader:   // header
00734         {
00735             if (debugoutput) std::clog << "ignored" << std::endl;
00736         }
00737         break;
00738         case nlPushZero:
00739         {
00740             if (debugoutput) std::clog << "push constant zero" << std::endl;
00741             nlNodeVec.push_back( new OSnLNodeNumber() );
00742         }
00743         break;
00744         case nlStoreS:   // store scaled row
00745         {
00746             if (debugoutput) std::clog << "ignored" << std::endl;
00747         }
00748         break;
00749         // the following three should have been taken out by reorderInstr above; the remaining ones seem to be unused by now
00750         case nlPushS: // duplicate value from address levels down on top of stack
00751         case nlPopup: // duplicate value from this level to at address levels down and pop entries in between
00752         case nlSwap: // swap two positions on top of stack
00753         case nlAddL: // add local
00754         case nlSubL: // subtract local
00755         case nlMulL: // multiply local
00756         case nlDivL: // divide local
00757         case nlPushL: // push local
00758         case nlPopL: // pop local
00759         case nlPopDeriv: // pop derivative
00760         case nlUMinL: // push umin local
00761         case nlPopDerivS: // store scaled gradient
00762         case nlEquScale: // equation scale
00763         case nlEnd: // end of instruction list
00764         default:
00765         {
00766             std::cerr << "not supported - Error." << std::endl;
00767             return NULL;
00768         }
00769         }
00770     }
00771 
00772     if (!nlNodeVec.size()) return NULL;
00773     // the vector is in postfix format - create expression tree and return it
00774     return nlNodeVec[0]->createExpressionTreeFromPostfix(nlNodeVec);
00775 }

Generated on Thu Nov 10 03:05:49 2011 by  doxygen 1.4.7