Changeset 587 for branches/devel/Cbc/src


Ignore:
Timestamp:
Mar 30, 2007 9:08:00 AM (13 years ago)
Author:
forrest
Message:

for lou and callable cbcmain

Location:
branches/devel/Cbc/src
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • branches/devel/Cbc/src/CbcModel.cpp

    r583 r587  
    15961596  counts for these new cuts.
    15971597
    1598   TODO: (lh) I'm confused. We create a nodeInfo without checking whether we
    1599         have a solution or not. Then we use numberUnsatisfied() to decide
    1600         whether to stash the cuts and bump reference counts. Other places we
    1601         use variable() (i.e., presence of a branching variable). Equivalent?
     1598  This next test can be problematic if we've discovered an
     1599  alternate equivalent answer and subsequently fathom the solution
     1600  known to the row cut debugger due to bounds.
    16021601*/
    16031602        if (onOptimalPath) {
    1604           if (!feasible) {
     1603          bool objLim = solver_->isDualObjectiveLimitReached() ;
     1604          if (!feasible && !objLim) {
    16051605            printf("infeas2\n");
    16061606            solver_->writeMps("infeas");
     
    16131613            assert (!solver_->isProvenOptimal());
    16141614          }
    1615           assert (feasible);
     1615          assert (feasible || objLim);
    16161616        }
    16171617        bool checkingNode=false;
     
    47574757    }
    47584758  }
    4759   // Reduced cost fix at end
    4760   if (solver_->isProvenOptimal())
     4759/*
     4760  Reduced cost fix at end. Must also check feasible, in case we've popped out
     4761  because a generator indicated we're infeasible.
     4762*/
     4763  if (feasible && solver_->isProvenOptimal())
    47614764    reducedCostFix();
    47624765  // If at root node do heuristics
     
    86588661  if (anyAction >= 0) {
    86598662    if (resolved) {
    8660       bool needValidSolution = (newNode->branchingObject() == NULL) ;
     8663/*
     8664  Used to be that when the node was not fathomed (branching object present)
     8665  the solution was not needed. But that's no longer the case --- heuristics
     8666  are applied, and they may want the solution.
     8667*/
     8668      // bool needValidSolution = (newNode->branchingObject() == NULL) ;
     8669      bool needValidSolution = true ;
    86618670      takeOffCuts(cuts,needValidSolution,NULL) ;
    86628671#             ifdef CHECK_CUT_COUNTS
  • branches/devel/Cbc/src/CbcModel.hpp

    r539 r587  
    3131class CbcEventHandler ;
    3232class CglPreProcess;
     33
     34// #define CBC_CHECK_BASIS 1
    3335
    3436//#############################################################################
     
    13951397    */
    13961398    void assignSolver(OsiSolverInterface *&solver,bool deleteSolver=true);
     1399
     1400    /** \brief Set ownership of solver
     1401
     1402      A parameter of false tells CbcModel it does not own the solver and
     1403      should not delete it. Once you claim ownership of the solver, you're
     1404      responsible for eventually deleting it. Note that CbcModel clones
     1405      solvers with abandon.  Unless you have a deep understanding of the
     1406      workings of CbcModel, the only time you want to claim ownership is when
     1407      you're about to delete the CbcModel object but want the solver to
     1408      continue to exist (as, for example, when branchAndBound has finished
     1409      and you want to hang on to the answer).
     1410    */
     1411    inline void setModelOwnsSolver (bool ourSolver)
     1412    { ourSolver_ = ourSolver ; } ;
     1413
     1414    /*! \brief Get ownership of solver
     1415   
     1416      A return value of true means that CbcModel owns the solver and will
     1417      take responsibility for deleting it when that becomes necessary.
     1418    */
     1419    inline bool modelOwnsSolver () { return (ourSolver_) ; } ;
    13971420 
    13981421    /** Copy constructor .
     
    17901813  */
    17911814  int numberStrong_;
    1792   /** The number of branches before pseudo costs believed
    1793       in dynamic strong branching. (0 off) */
     1815  /** \brief The number of branches before pseudo costs believed
     1816             in dynamic strong branching.
     1817     
     1818    A value of 0 is  off.
     1819  */
    17941820  int numberBeforeTrust_;
    1795   /** The number of variable sfor which to compute penalties
    1796       in dynamic strong branching. (0 off) */
     1821  /** \brief The number of variables for which to compute penalties
     1822             in dynamic strong branching.
     1823  */
    17971824  int numberPenalties_;
    17981825  /** Scale factor to make penalties match strong.
     
    19241951void getIntegerInformation(const OsiObject * object, double & originalLower,
    19251952                           double & originalUpper) ;
     1953// So we can call from other programs
     1954// Real main program
     1955class OsiClpSolverInterface;
     1956int CbcMain (int argc, const char *argv[],OsiClpSolverInterface & solver,CbcModel ** babSolver);
     1957// four ways of calling
     1958int callCbc(const char * input2, OsiClpSolverInterface& solver1);
     1959int callCbc(const char * input2);
     1960int callCbc(const std::string input2, OsiClpSolverInterface& solver1);
     1961int callCbc(const std::string input2) ;
    19261962#endif
  • branches/devel/Cbc/src/CbcNode.cpp

    r574 r587  
    730730}
    731731
     732#define CBC_NEW_CREATEINFO
     733#ifdef CBC_NEW_CREATEINFO
     734
     735/*
     736  New createInfo, with basis manipulation hidden inside mergeBasis. Allows
     737  solvers to override and carry over all information from one basis to
     738  another.
     739*/
     740
     741void
     742CbcNode::createInfo (CbcModel *model,
     743                     CbcNode *lastNode,
     744                     const CoinWarmStartBasis *lastws,
     745                     const double *lastLower, const double *lastUpper,
     746                     int numberOldActiveCuts, int numberNewCuts)
     747
     748{ OsiSolverInterface *solver = model->solver();
     749  CbcStrategy *strategy = model->strategy();
     750/*
     751  The root --- no parent. Create full basis and bounds information.
     752*/
     753  if (!lastNode)
     754  {
     755    if (!strategy)
     756      nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
     757    else
     758      nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
     759  } else {
     760/*
     761  Not the root. Create an edit from the parent's basis & bound information.
     762  This is not quite as straightforward as it seems. We need to reintroduce
     763  cuts we may have dropped out of the basis, in the correct position, because
     764  this whole process is strictly positional. Start by grabbing the current
     765  basis.
     766*/
     767    const CoinWarmStartBasis *ws =
     768      dynamic_cast<const CoinWarmStartBasis*>(solver->getWarmStart());
     769    assert(ws!=NULL); // make sure not volume
     770    //int numberArtificials = lastws->getNumArtificial();
     771    int numberColumns = solver->getNumCols();
     772    int numberRowsAtContinuous = model->numberRowsAtContinuous();
     773    int currentNumberCuts = model->currentNumberCuts();
     774#   ifdef CBC_CHECK_BASIS
     775    std::cout
     776      << "Before expansion: orig " << numberRowsAtContinuous
     777      << ", old " << numberOldActiveCuts
     778      << ", new " << numberNewCuts
     779      << ", current " << currentNumberCuts << "." << std::endl ;
     780    ws->print();
     781#   endif
     782/*
     783  Clone the basis and resize it to hold the structural constraints, plus
     784  all the cuts: old cuts, both active and inactive (currentNumberCuts),
     785  and new cuts (numberNewCuts). This will become the expanded basis.
     786*/
     787    CoinWarmStartBasis *expanded =
     788      dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
     789    int iCompact = numberRowsAtContinuous+numberOldActiveCuts+numberNewCuts ;
     790    // int nPartial = numberRowsAtContinuous+currentNumberCuts;
     791    int iFull = numberRowsAtContinuous+currentNumberCuts+numberNewCuts;
     792    // int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
     793    // printf("l %d full %d\n",maxBasisLength,iFull);
     794    expanded->resize(iFull,numberColumns);
     795#   ifdef CBC_CHECK_BASIS
     796    std::cout
     797      << "\tFull basis " << iFull << " rows, "
     798      << numberColumns << " columns; compact "
     799      << iCompact << " rows." << std::endl ;
     800#   endif
     801/*
     802  Now flesh out the expanded basis. The clone already has the
     803  correct status information for the variables and for the structural
     804  (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
     805  cuts created while processing this node --- they can be copied en bloc
     806  into the correct position in the expanded basis. The space reserved for
     807  xferRows is a gross overestimate.
     808*/
     809    CoinWarmStartBasis::XferVec xferRows ;
     810    xferRows.reserve(iFull-numberRowsAtContinuous+1) ;
     811    if (numberNewCuts) {
     812      xferRows.push_back(
     813          CoinWarmStartBasis::XferEntry(iCompact-numberNewCuts,
     814                                        iFull-numberNewCuts,numberNewCuts)) ;
     815    }
     816/*
     817  From nPartial down, record the entries we want to copy from the current
     818  basis (the entries for the active cuts; non-zero in the list returned
     819  by addedCuts). Fill the expanded basis with entries showing a status of
     820  basic for the deactivated (loose) cuts.
     821*/
     822    CbcCountRowCut **cut = model->addedCuts();
     823    iFull -= (numberNewCuts+1) ;
     824    iCompact -= (numberNewCuts+1) ;
     825    int runLen = 0 ;
     826    CoinWarmStartBasis::XferEntry entry(-1,-1,-1) ;
     827    while (iFull >= numberRowsAtContinuous) {
     828      for ( ; iFull >= numberRowsAtContinuous &&
     829              cut[iFull-numberRowsAtContinuous] ; iFull--)
     830        runLen++ ;
     831      if (runLen) {
     832        iCompact -= runLen ;
     833        entry.first = iCompact+1 ;
     834        entry.second = iFull+1 ;
     835        entry.third = runLen ;
     836        runLen = 0 ;
     837        xferRows.push_back(entry) ;
     838      }
     839      for ( ; iFull >= numberRowsAtContinuous &&
     840              !cut[iFull-numberRowsAtContinuous] ; iFull--)
     841        expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
     842    }
     843/*
     844  Finally, call mergeBasis to copy over entries from the current basis to
     845  the expanded basis. Since we cloned the expanded basis from the active basis
     846  and haven't changed the number of variables, only row status entries need
     847  to be copied.
     848*/
     849    expanded->mergeBasis(ws,&xferRows,0) ;
     850
     851#ifdef CBC_CHECK_BASIS
     852    std::cout << "Expanded basis:" << std::endl ;
     853    expanded->print() ;
     854    std::cout << "Diffing against:" << std::endl ;
     855    lastws->print() ;
     856#endif   
     857
     858/*
     859  Now that we have two bases in proper positional correspondence, creating
     860  the actual diff is dead easy.
     861
     862  Note that we're going to compare the expanded basis here to the stripped
     863  basis (lastws) produced by addCuts. It doesn't affect the correctness (the
     864  diff process has no knowledge of the meaning of an entry) but it does
     865  mean that we'll always generate a whack of diff entries because the expanded
     866  basis is considerably larger than the stripped basis.
     867*/
     868    CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
     869/*
     870  Diff the bound vectors. It's assumed the number of structural variables
     871  is not changing. For branching objects that change bounds on integer
     872  variables, we should see at least one bound change as a consequence
     873  of applying the branch that generated this subproblem from its parent.
     874  This need not hold for other types of branching objects (hyperplane
     875  branches, for example).
     876*/
     877    const double * lower = solver->getColLower();
     878    const double * upper = solver->getColUpper();
     879
     880    double *boundChanges = new double [2*numberColumns] ;
     881    int *variables = new int [2*numberColumns] ;
     882    int numberChangedBounds=0;
     883   
     884    int i;
     885    for (i=0;i<numberColumns;i++) {
     886      if (lower[i]!=lastLower[i]) {
     887        variables[numberChangedBounds]=i;
     888        boundChanges[numberChangedBounds++]=lower[i];
     889      }
     890      if (upper[i]!=lastUpper[i]) {
     891        variables[numberChangedBounds]=i|0x80000000;
     892        boundChanges[numberChangedBounds++]=upper[i];
     893      }
     894#ifdef CBC_DEBUG
     895      if (lower[i] != lastLower[i]) {
     896        std::cout
     897          << "lower on " << i << " changed from "
     898          << lastLower[i] << " to " << lower[i] << std::endl ;
     899      }
     900      if (upper[i] != lastUpper[i]) {
     901        std::cout
     902          << "upper on " << i << " changed from "
     903          << lastUpper[i] << " to " << upper[i] << std::endl ;
     904      }
     905#endif
     906    }
     907#ifdef CBC_DEBUG
     908    std::cout << numberChangedBounds << " changed bounds." << std::endl ;
     909#endif
     910    //if (lastNode->branchingObject()->boundBranch())
     911    //assert (numberChangedBounds);
     912/*
     913  Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
     914  return.
     915*/
     916    if (!strategy)
     917      nodeInfo_ =
     918        new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
     919                               variables,boundChanges,basisDiff) ;
     920    else
     921      nodeInfo_ =
     922        strategy->partialNodeInfo(model,lastNode->nodeInfo_,this,
     923                                  numberChangedBounds,variables,boundChanges,
     924                                  basisDiff) ;
     925    delete basisDiff ;
     926    delete [] boundChanges;
     927    delete [] variables;
     928    delete expanded ;
     929    delete ws;
     930  }
     931  // Set node number
     932  nodeInfo_->setNodeNumber(model->getNodeCount2());
     933}
     934
     935#else   // CBC_NEW_CREATEINFO
     936
     937/*
     938  Original createInfo, with bare manipulation of basis vectors. Fails if solver
     939  maintains additional information in basis.
     940*/
    732941
    733942void
     
    9021111  nodeInfo_->setNodeNumber(model->getNodeCount2());
    9031112}
     1113
     1114#endif  // CBC_NEW_CREATEINFO
    9041115
    9051116/*
  • branches/devel/Cbc/src/Cbc_ampl.cpp

    r529 r587  
    2323THIS SOFTWARE.
    2424****************************************************************/
     25#ifdef COIN_HAS_ASL
    2526
    2627#include "CbcConfig.h"
     
    3637#include "CoinFloatEqual.hpp"
    3738
     39#include "Cbc_ampl.h"
    3840extern "C" {
    3941# include "getstub.h"
    40 }
    41 
    42 #include "Cbc_ampl.h"
     42# include "asl_pfgh.h"
     43}
     44
    4345#include <string>
    4446#include <cassert>
     
    144146        { "sosno", 0, ASL_Sufkind_var | ASL_Sufkind_real },
    145147        { "sosref", 0, ASL_Sufkind_var | ASL_Sufkind_real },
     148        { "special", 0, ASL_Sufkind_var },
     149        /*{ "special", 0, ASL_Sufkind_con },*/
    146150        { strdup("sstatus"), 0, ASL_Sufkind_var, 0 },
    147151        { strdup("sstatus"), 0, ASL_Sufkind_con, 0 },
     
    164168  double *pseudoUp, *pseudoDown;
    165169  int *priority, *direction;
    166   // To label cuts
     170  // To label cuts (there will be other uses for special)
    167171  int *cut;
    168   SufDesc *dpup, *dpdown, *dpri, *ddir, *dcut;
     172  // To label special variables - at present 1= must be >= 1 or <= -1
     173  int * special;
     174  SufDesc *dpup, *dpdown, *dpri, *ddir, *dcut, *dspecial;
    169175 
    170176  ddir = suf_get("direction", ASL_Sufkind_var);
     
    172178  dpri = suf_get("priority", ASL_Sufkind_var);
    173179  priority = dpri->u.i;
     180  dcut = suf_get("special", ASL_Sufkind_con);
    174181  dcut = suf_get("cut", ASL_Sufkind_con);
    175182  cut = dcut->u.i;
     183  dspecial = suf_get("special", ASL_Sufkind_var);
     184  special = dspecial->u.i;
    176185  dpdown = suf_get("downPseudocost", ASL_Sufkind_var);
    177186  pseudoDown = dpdown->u.r;
     
    211220              "Treating %d negative .priority values as 0\n",
    212221              badpri);
     222  }
     223  if (special) {
     224    int badspecial=0;
     225    saveInfo->special= (int *) malloc(numberColumns*sizeof(int));
     226    for (i=0;i<numberColumns;i++) {
     227      int value = special[i];
     228      if (value<0) {
     229        badspecial++;
     230        value=0;
     231      }
     232      saveInfo->special[i]=value;
     233    }
     234    if (badspecial)
     235      fprintf(Stderr,
     236              "Treating %d negative special values as 0\n",
     237              badspecial);
    213238  }
    214239  int numberRows = saveInfo->numberRows;
     
    725750}
    726751#endif
     752// stolen from IPopt with changes
     753typedef struct {
     754  double obj_sign_;
     755  ASL_pfgh * asl_;
     756  double * non_const_x_;
     757  int nz_h_full_; // number of nonzeros in hessian
     758  int nerror_;
     759  bool objval_called_with_current_x_;
     760  bool conval_called_with_current_x_;
     761} CbcAmplInfo;
     762
     763static bool get_nlp_info(void * amplInfo,int & n, int & m, int & nnz_jac_g,
     764                              int & nnz_h_lag)
     765{
     766  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     767  ASL_pfgh* asl = info->asl_;
     768 
     769  n = n_var; // # of variables
     770  m = n_con; // # of constraints
     771  nnz_jac_g = nzc; // # of non-zeros in the jacobian
     772  nnz_h_lag = info->nz_h_full_; // # of non-zeros in the hessian
     773 
     774  return true;
     775}
     776
     777static bool get_bounds_info(void * amplInfo,int  n, double * x_l,
     778                            double * x_u, int  m, double * g_l, double * g_u)
     779{
     780  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     781  ASL_pfgh* asl = info->asl_;
     782  assert(n == n_var);
     783  assert(m == n_con);
     784  int i;
     785  for (i=0; i<n; i++) {
     786    x_l[i] = LUv[2*i];
     787    x_u[i] = LUv[2*i+1];
     788  }
     789 
     790  for (i=0; i<m; i++) {
     791    g_l[i] = LUrhs[2*i];
     792    g_u[i] = LUrhs[2*i+1];
     793  }
     794  return true;
     795}
     796
     797
     798bool get_constraints_linearity(void * amplInfo,int  n,
     799      int * const_types)
     800{
     801  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     802  ASL_pfgh* asl = info->asl_;
     803  //check that n is good
     804  assert(n == n_con);
     805  // check that there are no network constraints
     806  assert(nlnc == 0 && lnc == 0);
     807  //the first nlc constraints are non linear the rest is linear
     808  int i;
     809  for (i=0; i<nlc; i++) {
     810    const_types[i]=1;
     811  }
     812  // the rest is linear
     813  for (i=nlc; i<n_con; i++)
     814    const_types[i]=0;
     815  return true;
     816}
     817#if 0
     818bool get_starting_point(int  n, bool init_x, double * x, bool init_z,
     819                        double * z_L, double * z_U, int  m, bool init_lambda, double * lambda)
     820{
     821  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     822  ASL_pfgh* asl = info->asl_;
     823  assert(n == n_var);
     824  assert(m == n_con);
     825  int i;
     826 
     827  if (init_x) {
     828    for (i=0; i<n; i++) {
     829      if (havex0[i]) {
     830        x[i] = X0[i];
     831      }
     832      else {
     833        x[i] = 0.0;
     834      }
     835    }
     836  }
     837 
     838  if (init_z) {
     839    for (i=0; i<n; i++) {
     840      z_L[i] = z_U[i] = 1.0;
     841    }
     842  }
     843 
     844  if (init_lambda) {
     845    for (i=0; i<m; i++) {
     846      if (havepi0[i]) {
     847        lambda[i] = pi0[i];
     848      }
     849      else {
     850        lambda[i] = 0.0;
     851      }
     852    }
     853  }
     854 
     855  return true;
     856}
     857#endif
     858static bool internal_objval(CbcAmplInfo * info ,double & obj_val)
     859{
     860  ASL_pfgh* asl = info->asl_;
     861  info->objval_called_with_current_x_ = false; // in case the call below fails
     862
     863  if (n_obj==0) {
     864    obj_val = 0;
     865    info->objval_called_with_current_x_ = true;
     866    return true;
     867  }  else {
     868    double  retval = objval(0, info->non_const_x_, (fint*)info->nerror_);
     869    if (!info->nerror_) {
     870      obj_val = info->obj_sign_*retval;
     871      info->objval_called_with_current_x_ = true;
     872      return true;
     873    } else {
     874      abort();
     875    }
     876  }
     877 
     878  return false;
     879}
     880
     881static bool internal_conval(CbcAmplInfo * info ,int  m, double * g)
     882{
     883  ASL_pfgh* asl = info->asl_;
     884  info->conval_called_with_current_x_ = false; // in case the call below fails
     885 
     886  bool allocated = false;
     887  if (!g) {
     888    g = new double[m];
     889    allocated = true;
     890  }
     891 
     892  conval(info->non_const_x_, g, (fint*)info->nerror_);
     893
     894  if (allocated) {
     895    delete [] g;
     896    g = NULL;
     897  }
     898 
     899  if (!info->nerror_) {
     900    info->conval_called_with_current_x_ = true;
     901    return true;
     902  } else {
     903    abort();
     904  }
     905  return false;
     906}
     907
     908
     909static bool apply_new_x(CbcAmplInfo * info  ,bool new_x, int  n, const double * x)
     910{
     911  ASL_pfgh* asl = info->asl_;
     912 
     913  if (new_x) {
     914    // update the flags so these methods are called
     915    // before evaluating the hessian
     916    info->conval_called_with_current_x_ = false;
     917    info->objval_called_with_current_x_ = false;
     918
     919    //copy the data to the non_const_x_
     920    if (!info->non_const_x_) {
     921      info->non_const_x_ = new double [n];
     922    }
     923
     924    for (int  i=0; i<n; i++) {
     925      info->non_const_x_[i] = x[i];
     926    }
     927   
     928    // tell ampl that we have a new x
     929    xknowne(info->non_const_x_, (fint*)info->nerror_);
     930    return info->nerror_ ? false : true;
     931  }
     932 
     933  return true;
     934}
     935bool eval_f(void * amplInfo,int  n, const double * x, bool new_x, double & obj_value)
     936{
     937  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     938  if (!apply_new_x(info,new_x, n, x)) {
     939    return false;
     940  }
     941 
     942  return internal_objval(info,obj_value);
     943}
     944
     945bool eval_grad_f(void * amplInfo,int  n, const double * x, bool new_x, double * grad_f)
     946{
     947  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     948  ASL_pfgh* asl = info->asl_;
     949  if (!apply_new_x(info,new_x, n, x)) {
     950    return false;
     951  }
     952  int i;
     953 
     954  if (n_obj==0) {
     955    for (i=0; i<n; i++) {
     956      grad_f[i] = 0.;
     957    }
     958  }
     959  else {
     960    objgrd(0, info->non_const_x_, grad_f, (fint*)info->nerror_);
     961    if (info->nerror_) {
     962      return false;
     963    }
     964   
     965    if (info->obj_sign_==-1) {
     966      for (i=0; i<n; i++) {
     967        grad_f[i] = -grad_f[i];
     968      }
     969    }
     970  }
     971  return true;
     972}
     973
     974bool eval_g(void * amplInfo,int  n, const double * x, bool new_x, int  m, double * g)
     975{
     976  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     977  ASL_pfgh* asl = info->asl_;
     978  assert(n == n_var);
     979  assert(m == n_con);
     980 
     981  if (!apply_new_x(info,new_x, n, x)) {
     982    return false;
     983  }
     984 
     985  return internal_conval(info,m, g);
     986}
     987
     988bool eval_jac_g(void * amplInfo,int  n, const double * x, bool new_x,
     989                int  m, int  nele_jac, int * iRow,
     990                int  *jCol, double * values)
     991{
     992  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     993  ASL_pfgh* asl = info->asl_;
     994  assert(n == n_var);
     995  assert(m == n_con);
     996  int i;
     997 
     998  if (iRow && jCol && !values) {
     999    // setup the structure
     1000    int  current_nz = 0;
     1001    for (i=0; i<n_con; i++) {
     1002      for (cgrad* cg=Cgrad[i]; cg; cg = cg->next) {
     1003        //iRow[cg->goff] = i + 1;
     1004        iRow[cg->goff] = i ;
     1005        jCol[cg->goff] = cg->varno + 1;
     1006        //                              iRow[current_nz] = i + 1;
     1007        //                              jCol[current_nz] = cg->varno+1;
     1008        current_nz++;
     1009      }
     1010    }
     1011    assert(current_nz == nele_jac);
     1012    return true;
     1013  }
     1014  else if (!iRow && !jCol && values) {
     1015    if (!apply_new_x(info,new_x, n, x)) {
     1016      return false;
     1017    }
     1018   
     1019    jacval(info->non_const_x_, values, (fint*)info->nerror_);
     1020    if (!info->nerror_) {
     1021      return true;
     1022    } else {
     1023      abort();
     1024    }
     1025  }
     1026  else {
     1027    assert(false && "Invalid combination of iRow, jCol, and values pointers");
     1028  }
     1029 
     1030  return false;
     1031}
     1032
     1033bool eval_h(void * amplInfo,int  n, const double * x, bool new_x,
     1034            double  obj_factor, int  m, const double * lambda,
     1035            bool new_lambda, int  nele_hess, int * iRow,
     1036            int * jCol, double * values)
     1037{
     1038  CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
     1039  ASL_pfgh* asl = info->asl_;
     1040  assert(n == n_var);
     1041  assert(m == n_con);
     1042  int i;
     1043 
     1044  if (iRow && jCol && !values) {
     1045    // setup the structure
     1046    int k=0;
     1047    for (int i=0; i<n; i++) {
     1048      for (int j=sputinfo->hcolstarts[i]; j<sputinfo->hcolstarts[i+1]; j++) {
     1049        //iRow[k] = i + 1;
     1050        iRow[k] = i;
     1051        jCol[k] = sputinfo->hrownos[j]+1;
     1052        k++;
     1053      }
     1054    }
     1055    assert(k==nele_hess);
     1056    return true;
     1057  }
     1058  else if (!iRow & !jCol && values) {
     1059    if (!apply_new_x(info,new_x, n, x)) {
     1060      return false;
     1061    }
     1062    if (!info->objval_called_with_current_x_) {
     1063      double  dummy;
     1064      internal_objval(info,dummy);
     1065      internal_conval(info,m,NULL);
     1066    }
     1067    if (!info->conval_called_with_current_x_) {
     1068      internal_conval(info,m,NULL);
     1069    }
     1070    // copy lambda to non_const_lambda - note, we do not store a copy like
     1071    // we do with x since lambda is only used here and not in other calls
     1072    double * non_const_lambda = new double [m];
     1073    for (i=0; i<m; i++) {
     1074      non_const_lambda[i] = lambda[i];
     1075    }
     1076   
     1077    real ow=info->obj_sign_*obj_factor;
     1078    sphes(values, -1, &ow, non_const_lambda);
     1079   
     1080    delete [] non_const_lambda;
     1081    return true;
     1082  }
     1083  else {
     1084    assert(false && "Invalid combination of iRow, jCol, and values pointers");
     1085  }
     1086 
     1087  return false;
     1088}
    7271089void
    7281090CoinModel::gdb( int nonLinear, const char * fileName,const void * info)
     
    9551317        column[k]=cg->varno;
    9561318        element[k++]=cg->coef;
     1319      }
     1320      matrixByRow.appendRow(k,column,element);
     1321    }
     1322    delete [] column;
     1323    delete [] element;
     1324    numberRows=n_con;
     1325    numberColumns=n_var;
     1326    numberElements=nzc;;
     1327    numberBinary=nbv;
     1328    numberIntegers=niv;
     1329    numberAllNonLinearBoth=nlvb;
     1330    numberIntegerNonLinearBoth=nlvbi;
     1331    numberAllNonLinearConstraints=nlvc;
     1332    numberIntegerNonLinearConstraints=nlvci;
     1333    numberAllNonLinearObjective=nlvo;
     1334    numberIntegerNonLinearObjective=nlvoi;
     1335    /* say we want primal solution */
     1336    want_xpi0=1;
     1337    //double * dualSolution=NULL;
     1338    // save asl
     1339    // Fix memory leak one day
     1340    CbcAmplInfo * info = new CbcAmplInfo;
     1341    amplGamsData_ = info;
     1342    info->asl_=NULL; // as wrong form asl;
     1343    info->nz_h_full_=-1; // number of nonzeros in hessian
     1344    info->objval_called_with_current_x_=false;
     1345    info->nerror_=0;
     1346    info->obj_sign_=direction;
     1347    info->conval_called_with_current_x_=false;
     1348    info->non_const_x_=NULL;
     1349  } else if (nonLinear==2) {
     1350    // General nonlinear!
     1351    ASL_pfgh* asl = (ASL_pfgh*)ASL_alloc(ASL_read_pfgh);
     1352    // was asl = ASL_alloc(ASL_read_fg);
     1353    nl = jac0dim(stub, (long) strlen(stub));
     1354    free(stub);
     1355    suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl));
     1356    /* read  model*/
     1357    X0 = (double*) malloc(n_var*sizeof(double));
     1358    CoinZeroN(X0,n_var);
     1359    // code stolen from Ipopt
     1360    int retcode = pfgh_read(nl, ASL_return_read_err | ASL_findgroups);
     1361
     1362    switch (retcode) {
     1363      case ASL_readerr_none : {}
     1364      break;
     1365      case ASL_readerr_nofile : {
     1366        printf( "Cannot open .nl file\n");
     1367        exit(-1);
     1368      }
     1369      break;
     1370      case ASL_readerr_nonlin : {
     1371        assert(false); // this better not be an error!
     1372        printf( "model involves nonlinearities (ed0read)\n");
     1373        exit(-1);
     1374      }
     1375      break;
     1376      case  ASL_readerr_argerr : {
     1377        printf( "user-defined function with bad args\n");
     1378        exit(-1);
     1379      }
     1380      break;
     1381      case ASL_readerr_unavail : {
     1382        printf( "user-defined function not available\n");
     1383        exit(-1);
     1384      }
     1385      break;
     1386      case ASL_readerr_corrupt : {
     1387        printf( "corrupt .nl file\n");
     1388        exit(-1);
     1389      }
     1390      break;
     1391      case ASL_readerr_bug : {
     1392        printf( "bug in .nl reader\n");
     1393        exit(-1);
     1394      }
     1395      break;
     1396      case ASL_readerr_CLP : {
     1397        printf( "ASL error message: \"solver cannot handle CLP extensions\"\n");
     1398        exit(-1);
     1399      }
     1400      break;
     1401      default: {
     1402        printf( "Unknown error in stub file read. retcode = %d\n", retcode);
     1403        exit(-1);
     1404      }
     1405      break;
     1406    }
     1407
     1408    // see "changes" in solvers directory of ampl code...
     1409    hesset(1,0,1,0,nlc);
     1410
     1411    assert (n_obj==1);
     1412    // find the nonzero structure for the hessian
     1413    // parameters to sphsetup:
     1414    int coeff_obj = 1; // coefficient of the objective fn ???
     1415    int mult_supplied = 1; // multipliers will be supplied
     1416    int uptri = 1; // only need the upper triangular part
     1417    // save asl
     1418    // Fix memory leak one day
     1419    CbcAmplInfo * info = new CbcAmplInfo;
     1420    amplGamsData_ = info;
     1421    info->asl_=asl;
     1422    // This is not easy to get from ampl so save
     1423    info->nz_h_full_= sphsetup(-1, coeff_obj, mult_supplied, uptri);
     1424    info->objval_called_with_current_x_=false;
     1425    info->nerror_=0;
     1426    info->obj_sign_=direction;
     1427    info->conval_called_with_current_x_=false;
     1428    info->non_const_x_=NULL;
     1429    /* objective*/
     1430    objective = (double *) malloc(n_var*sizeof(double));
     1431    for (i=0;i<n_var;i++)
     1432      objective[i]=0.0;;
     1433    if (n_obj) {
     1434      for (og = Ograd[0];og;og = og->next)
     1435        objective[og->varno] = og->coef;
     1436    }
     1437    if (objtype[0])
     1438      direction=-1.0;
     1439    else
     1440      direction=1.0;
     1441    objectiveOffset_=objconst(0);
     1442    /* Column bounds*/
     1443    columnLower = (double *) malloc(n_var*sizeof(double));
     1444    columnUpper = (double *) malloc(n_var*sizeof(double));
     1445    for (i=0;i<n_var;i++) {
     1446      columnLower[i]=LUv[2*i];
     1447      if (columnLower[i]<= negInfinity)
     1448        columnLower[i]=-COIN_DBL_MAX;
     1449      columnUpper[i]=LUv[2*i+1];
     1450      if (columnUpper[i]>= Infinity)
     1451        columnUpper[i]=COIN_DBL_MAX;
     1452    }
     1453    // Build by row from scratch
     1454    //matrixByRow.reserve(n_var,nzc,true);
     1455    // say row orderded
     1456    matrixByRow.transpose();
     1457    /* Row bounds*/
     1458    rowLower = (double *) malloc(n_con*sizeof(double));
     1459    rowUpper = (double *) malloc(n_con*sizeof(double));
     1460    int * column = new int [n_var];
     1461    double * element = new double [n_var];
     1462    for (i=0;i<n_con;i++) {
     1463      rowLower[i]=LUrhs[2*i];
     1464      if (rowLower[i]<= negInfinity)
     1465        rowLower[i]=-COIN_DBL_MAX;
     1466      rowUpper[i]=LUrhs[2*i+1];
     1467      if (rowUpper[i]>= Infinity)
     1468        rowUpper[i]=COIN_DBL_MAX;
     1469      int k=0;
     1470      for(cgrad * cg = Cgrad[i]; cg; cg = cg->next) {
     1471        column[k]=cg->varno;
     1472        double value = cg->coef;
     1473        if (!value)
     1474          value = -1.2345e-29;
     1475        element[k++]=value;
    9571476      }
    9581477      matrixByRow.appendRow(k,column,element);
     
    11871706  }
    11881707}
     1708#else
     1709#include "Cbc_ampl.h"
     1710int
     1711readAmpl(ampl_info * info, int argc, char **argv, void ** coinModel)
     1712{
     1713  return 0;
     1714}
     1715void freeArrays1(ampl_info * info)
     1716{
     1717}
     1718void freeArrays2(ampl_info * info)
     1719{
     1720}
     1721void freeArgs(ampl_info * info)
     1722{
     1723}
     1724int ampl_obj_prec()
     1725{
     1726  return 0;
     1727}
     1728void writeAmpl(ampl_info * info)
     1729{
     1730}
     1731#endif
  • branches/devel/Cbc/src/Cbc_ampl.h

    r532 r587  
    3838  double * sosReference;
    3939  int * cut;
     40  int * special;
    4041  char ** arguments;
    4142  char buffer[300];
  • branches/devel/Cbc/src/Makefile.am

    r526 r587  
    4242        CbcModel.cpp CbcModel.hpp \
    4343        CbcNode.cpp CbcNode.hpp \
     44        CbcSolver.cpp CbcCbcParam.cpp \
    4445        CbcStatistics.cpp CbcStatistics.hpp \
    4546        CbcStrategy.cpp CbcStrategy.hpp \
     
    4950## If we have the Ampl solver library, we need to add additional things
    5051## also see lower down
    51 #if COIN_HAS_ASL
    52 #libCbc_la_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
    53 #endif
     52## new idea is to add in source code anyway
     53libCbc_la_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
    5454
    5555# This is for libtool (on Windows)
     
    6868        CbcMain.cpp \
    6969        CbcParam.cpp CbcParam.hpp \
    70         CbcCbcParam.cpp \
    7170        unitTest.cpp
    7271
     
    182181cbc_SOURCES = \
    183182        CoinSolve.cpp \
    184         CbcCbcParam.cpp \
    185183        unitTestClp.cpp
    186184
     
    200198# If we have the Ampl solver library, we need to add additional things
    201199if COIN_HAS_ASL
    202 cbc_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
     200#cbc_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
    203201cbc_LDADD += $(ASLLIB)
    204202AM_CPPFLAGS += $(ASL_CPPFLAGS)
  • branches/devel/Cbc/src/Makefile.in

    r526 r587  
    119119
    120120# If we have the Ampl solver library, we need to add additional things
    121 @COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__append_28 = Cbc_ampl.cpp Cbc_ampl.h
    122 @COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__append_29 = $(ASLLIB)
    123 @COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__append_30 = $(ASL_CPPFLAGS)
     121#cbc_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
     122@COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__append_28 = $(ASLLIB)
     123@COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__append_29 = $(ASL_CPPFLAGS)
    124124subdir = src
    125125DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
     
    151151        CbcHeuristicFPump.lo CbcHeuristicGreedy.lo \
    152152        CbcHeuristicLocal.lo CbcHeuristicRINS.lo CbcMessage.lo \
    153         CbcModel.lo CbcNode.lo CbcStatistics.lo CbcStrategy.lo \
    154         CbcTree.lo CbcLinked.lo CbcTreeLocal.lo
     153        CbcModel.lo CbcNode.lo CbcSolver.lo CbcCbcParam.lo \
     154        CbcStatistics.lo CbcStrategy.lo CbcTree.lo CbcLinked.lo \
     155        CbcTreeLocal.lo Cbc_ampl.lo
    155156libCbc_la_OBJECTS = $(am_libCbc_la_OBJECTS)
    156157@COIN_HAS_CLP_TRUE@am__EXEEXT_1 = cbc$(EXEEXT)
    157158binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
    158159PROGRAMS = $(bin_PROGRAMS)
    159 am__cbc_SOURCES_DIST = CoinSolve.cpp CbcCbcParam.cpp unitTestClp.cpp \
    160         Cbc_ampl.cpp Cbc_ampl.h
    161 @COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@am__objects_1 =  \
    162 @COIN_HAS_ASL_TRUE@@COIN_HAS_CLP_TRUE@  Cbc_ampl.$(OBJEXT)
     160am__cbc_SOURCES_DIST = CoinSolve.cpp unitTestClp.cpp
    163161@COIN_HAS_CLP_TRUE@am_cbc_OBJECTS = CoinSolve.$(OBJEXT) \
    164 @COIN_HAS_CLP_TRUE@     CbcCbcParam.$(OBJEXT) unitTestClp.$(OBJEXT) \
    165 @COIN_HAS_CLP_TRUE@     $(am__objects_1)
     162@COIN_HAS_CLP_TRUE@     unitTestClp.$(OBJEXT)
    166163cbc_OBJECTS = $(am_cbc_OBJECTS)
    167164am__DEPENDENCIES_1 =
     
    176173@COIN_HAS_CLP_TRUE@     $(am__DEPENDENCIES_2)
    177174am_cbc_generic_OBJECTS = CbcMain.$(OBJEXT) CbcParam.$(OBJEXT) \
    178         CbcCbcParam.$(OBJEXT) unitTest.$(OBJEXT)
     175        unitTest.$(OBJEXT)
    179176cbc_generic_OBJECTS = $(am_cbc_generic_OBJECTS)
    180177@COIN_HAS_CLP_TRUE@am__DEPENDENCIES_3 =  \
     
    447444
    448445# List all source files for this library, including headers
    449 libCbc_la_SOURCES = \
    450         Cbc_C_Interface.cpp Cbc_C_Interface.h \
    451         CbcConfig.h \
    452         CbcBranchActual.cpp CbcBranchActual.hpp \
    453         CbcBranchBase.cpp CbcBranchBase.hpp \
    454         CbcBranchCut.cpp CbcBranchCut.hpp \
    455         CbcBranchDynamic.cpp CbcBranchDynamic.hpp \
    456         CbcBranchLotsize.cpp CbcBranchLotsize.hpp \
    457         CbcCompareActual.cpp CbcCompareActual.hpp \
    458         CbcCompareBase.hpp \
    459         CbcCountRowCut.cpp CbcCountRowCut.hpp \
    460         CbcCutGenerator.cpp CbcCutGenerator.hpp \
    461         CbcEventHandler.cpp CbcEventHandler.hpp \
    462         CbcFathom.cpp CbcFathom.hpp \
    463         CbcFathomDynamicProgramming.cpp CbcFathomDynamicProgramming.hpp \
    464         CbcFeasibilityBase.hpp \
    465         CbcHeuristic.cpp CbcHeuristic.hpp \
    466         CbcHeuristicFPump.cpp CbcHeuristicFPump.hpp \
    467         CbcHeuristicGreedy.cpp CbcHeuristicGreedy.hpp \
    468         CbcHeuristicLocal.cpp CbcHeuristicLocal.hpp \
    469         CbcHeuristicRINS.cpp CbcHeuristicRINS.hpp \
    470         CbcMessage.cpp CbcMessage.hpp \
    471         CbcModel.cpp CbcModel.hpp \
    472         CbcNode.cpp CbcNode.hpp \
    473         CbcStatistics.cpp CbcStatistics.hpp \
    474         CbcStrategy.cpp CbcStrategy.hpp \
    475         CbcTree.cpp CbcTree.hpp \
    476         CbcLinked.cpp CbcLinked.hpp \
    477         CbcTreeLocal.cpp CbcTreeLocal.hpp
    478 
    479 #if COIN_HAS_ASL
    480 #libCbc_la_SOURCES += Cbc_ampl.cpp Cbc_ampl.h
    481 #endif
     446libCbc_la_SOURCES = Cbc_C_Interface.cpp Cbc_C_Interface.h CbcConfig.h \
     447        CbcBranchActual.cpp CbcBranchActual.hpp CbcBranchBase.cpp \
     448        CbcBranchBase.hpp CbcBranchCut.cpp CbcBranchCut.hpp \
     449        CbcBranchDynamic.cpp CbcBranchDynamic.hpp CbcBranchLotsize.cpp \
     450        CbcBranchLotsize.hpp CbcCompareActual.cpp CbcCompareActual.hpp \
     451        CbcCompareBase.hpp CbcCountRowCut.cpp CbcCountRowCut.hpp \
     452        CbcCutGenerator.cpp CbcCutGenerator.hpp CbcEventHandler.cpp \
     453        CbcEventHandler.hpp CbcFathom.cpp CbcFathom.hpp \
     454        CbcFathomDynamicProgramming.cpp \
     455        CbcFathomDynamicProgramming.hpp CbcFeasibilityBase.hpp \
     456        CbcHeuristic.cpp CbcHeuristic.hpp CbcHeuristicFPump.cpp \
     457        CbcHeuristicFPump.hpp CbcHeuristicGreedy.cpp \
     458        CbcHeuristicGreedy.hpp CbcHeuristicLocal.cpp \
     459        CbcHeuristicLocal.hpp CbcHeuristicRINS.cpp \
     460        CbcHeuristicRINS.hpp CbcMessage.cpp CbcMessage.hpp \
     461        CbcModel.cpp CbcModel.hpp CbcNode.cpp CbcNode.hpp \
     462        CbcSolver.cpp CbcCbcParam.cpp CbcStatistics.cpp \
     463        CbcStatistics.hpp CbcStrategy.cpp CbcStrategy.hpp CbcTree.cpp \
     464        CbcTree.hpp CbcLinked.cpp CbcLinked.hpp CbcTreeLocal.cpp \
     465        CbcTreeLocal.hpp Cbc_ampl.cpp Cbc_ampl.h
    482466
    483467# This is for libtool (on Windows)
     
    488472        CbcMain.cpp \
    489473        CbcParam.cpp CbcParam.hpp \
    490         CbcCbcParam.cpp \
    491474        unitTest.cpp
    492475
     
    515498        $(am__append_11) $(am__append_13) $(am__append_15) \
    516499        $(am__append_17) $(am__append_19) $(am__append_22) \
    517         $(am__append_25) $(am__append_30) -I`$(CYGPATH_W) \
     500        $(am__append_25) $(am__append_29) -I`$(CYGPATH_W) \
    518501        $(CGLSRCDIR)/src` -I`$(CYGPATH_W) $(CGLSRCDIR)/src/CglClique` \
    519502        -I`$(CYGPATH_W) $(CGLSRCDIR)/src/CglDuplicateRow` \
     
    540523
    541524# List all source files for this executable, including headers
    542 @COIN_HAS_CLP_TRUE@cbc_SOURCES = CoinSolve.cpp CbcCbcParam.cpp \
    543 @COIN_HAS_CLP_TRUE@     unitTestClp.cpp $(am__append_28)
     525@COIN_HAS_CLP_TRUE@cbc_SOURCES = \
     526@COIN_HAS_CLP_TRUE@     CoinSolve.cpp \
     527@COIN_HAS_CLP_TRUE@     unitTestClp.cpp
     528
    544529
    545530# Additional COIN libraries
     
    549534@COIN_HAS_CLP_TRUE@     $(CLPOBJDIR)/src/libClp.la \
    550535@COIN_HAS_CLP_TRUE@     $(COINUTILSOBJDIR)/src/libCoinUtils.la \
    551 @COIN_HAS_CLP_TRUE@     $(am__append_29)
     536@COIN_HAS_CLP_TRUE@     $(am__append_28)
    552537
    553538# Finally, the -rpath flag is used by libtool to make sure that the shared
     
    707692@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcBranchDynamic.Plo@am__quote@
    708693@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcBranchLotsize.Plo@am__quote@
    709 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCbcParam.Po@am__quote@
     694@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCbcParam.Plo@am__quote@
    710695@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCompareActual.Plo@am__quote@
    711696@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCountRowCut.Plo@am__quote@
     
    725710@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcNode.Plo@am__quote@
    726711@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcParam.Po@am__quote@
     712@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcSolver.Plo@am__quote@
    727713@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcStatistics.Plo@am__quote@
    728714@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcStrategy.Plo@am__quote@
     
    730716@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcTreeLocal.Plo@am__quote@
    731717@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cbc_C_Interface.Plo@am__quote@
    732 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cbc_ampl.Po@am__quote@
     718@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cbc_ampl.Plo@am__quote@
    733719@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CoinSolve.Po@am__quote@
    734720@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unitTest.Po@am__quote@
Note: See TracChangeset for help on using the changeset viewer.