source: trunk/Clp/src/Clp_C_Interface.cpp @ 2441

Last change on this file since 2441 was 2441, checked in by stefan, 7 months ago

add Clp_writeMps, Clp_setRowName, Clp_setColumnName from patch provided by @framlingham in #101

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 38.4 KB
Line 
1// $Id: Clp_C_Interface.cpp 2441 2019-04-05 06:39:14Z stefan $
2// Copyright (C) 2003, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include "CoinPragma.hpp"
7
8#include <cmath>
9#include <cstring>
10
11#include "CoinHelperFunctions.hpp"
12#include "ClpConfig.h"
13#include "ClpSimplex.hpp"
14#include "ClpInterior.hpp"
15#ifndef SLIM_CLP
16#include "Idiot.hpp"
17#endif
18#include <cfloat>
19// Get C stuff but with extern C
20#define CLP_EXTERN_C
21#include "Coin_C_defines.h"
22
23/// To allow call backs
24class CMessageHandler : public CoinMessageHandler {
25
26public:
27  /**@name Overrides */
28  //@{
29  virtual int print();
30  //@}
31  /**@name set and get */
32  //@{
33  /// Model
34  const Clp_Simplex *model() const;
35  void setModel(Clp_Simplex *model);
36  /// Call back
37  void setCallBack(clp_callback callback);
38  //@}
39
40  /**@name Constructors, destructor */
41  //@{
42  /** Default constructor. */
43  CMessageHandler();
44  /// Constructor with pointer to model
45  CMessageHandler(Clp_Simplex *model,
46    FILE *userPointer = NULL);
47  /** Destructor */
48  virtual ~CMessageHandler();
49  //@}
50
51  /**@name Copy method */
52  //@{
53  /** The copy constructor. */
54  CMessageHandler(const CMessageHandler &);
55  /** The copy constructor from an CoinSimplexMessageHandler. */
56  CMessageHandler(const CoinMessageHandler &);
57
58  CMessageHandler &operator=(const CMessageHandler &);
59  /// Clone
60  virtual CoinMessageHandler *clone() const;
61  //@}
62
63protected:
64  /**@name Data members
65        The data members are protected to allow access for derived classes. */
66  //@{
67  /// Pointer back to model
68  Clp_Simplex *model_;
69  /// call back
70  clp_callback callback_;
71  //@}
72};
73
74//-------------------------------------------------------------------
75// Default Constructor
76//-------------------------------------------------------------------
77CMessageHandler::CMessageHandler()
78  : CoinMessageHandler()
79  , model_(NULL)
80  , callback_(NULL)
81{
82}
83
84//-------------------------------------------------------------------
85// Copy constructor
86//-------------------------------------------------------------------
87CMessageHandler::CMessageHandler(const CMessageHandler &rhs)
88  : CoinMessageHandler(rhs)
89  , model_(rhs.model_)
90  , callback_(rhs.callback_)
91{
92}
93
94CMessageHandler::CMessageHandler(const CoinMessageHandler &rhs)
95  : CoinMessageHandler(rhs)
96  , model_(NULL)
97  , callback_(NULL)
98{
99}
100
101// Constructor with pointer to model
102CMessageHandler::CMessageHandler(Clp_Simplex *model,
103  FILE *)
104  : CoinMessageHandler()
105  , model_(model)
106  , callback_(NULL)
107{
108}
109
110//-------------------------------------------------------------------
111// Destructor
112//-------------------------------------------------------------------
113CMessageHandler::~CMessageHandler()
114{
115}
116
117//----------------------------------------------------------------
118// Assignment operator
119//-------------------------------------------------------------------
120CMessageHandler &
121CMessageHandler::operator=(const CMessageHandler &rhs)
122{
123  if (this != &rhs) {
124    CoinMessageHandler::operator=(rhs);
125    model_ = rhs.model_;
126    callback_ = rhs.callback_;
127  }
128  return *this;
129}
130//-------------------------------------------------------------------
131// Clone
132//-------------------------------------------------------------------
133CoinMessageHandler *CMessageHandler::clone() const
134{
135  return new CMessageHandler(*this);
136}
137
138int CMessageHandler::print()
139{
140  if (callback_) {
141    int messageNumber = currentMessage().externalNumber();
142    if (currentSource() != "Clp")
143      messageNumber += 1000000;
144    int i;
145    int nDouble = numberDoubleFields();
146    assert(nDouble <= 10);
147    double vDouble[10];
148    for (i = 0; i < nDouble; i++)
149      vDouble[i] = doubleValue(i);
150    int nInt = numberIntFields();
151    assert(nInt <= 10);
152    CoinBigIndex vInt[10];
153    for (i = 0; i < nInt; i++)
154      vInt[i] = intValue(i);
155    int nString = numberStringFields();
156    assert(nString <= 10);
157    char *vString[10];
158    for (i = 0; i < nString; i++) {
159      std::string value = stringValue(i);
160      vString[i] = CoinStrdup(value.c_str());
161    }
162    callback_(model_, messageNumber,
163      nDouble, vDouble,
164      nInt, vInt,
165      nString, vString);
166    for (i = 0; i < nString; i++)
167      free(vString[i]);
168  }
169  return CoinMessageHandler::print();
170}
171const Clp_Simplex *
172CMessageHandler::model() const
173{
174  return model_;
175}
176void CMessageHandler::setModel(Clp_Simplex *model)
177{
178  model_ = model;
179}
180// Call back
181void CMessageHandler::setCallBack(clp_callback callback)
182{
183  callback_ = callback;
184}
185
186#include "Clp_C_Interface.h"
187#include <string>
188#include <stdio.h>
189#include <iostream>
190
191#if defined(__MWERKS__)
192#pragma export on
193#endif
194
195COINLIBAPI const char *COINLINKAGE
196Clp_Version(void)
197{
198  return CLP_VERSION;
199}
200COINLIBAPI int COINLINKAGE
201Clp_VersionMajor(void)
202{
203  return CLP_VERSION_MAJOR;
204}
205COINLIBAPI int COINLINKAGE Clp_VersionMinor(void)
206{
207  return CLP_VERSION_MINOR;
208}
209COINLIBAPI int COINLINKAGE Clp_VersionRelease(void)
210{
211  return CLP_VERSION_RELEASE;
212}
213
214/* Default constructor */
215COINLIBAPI Clp_Simplex *COINLINKAGE
216Clp_newModel()
217{
218  Clp_Simplex *model = new Clp_Simplex;
219  model->model_ = new ClpSimplex();
220  model->handler_ = NULL;
221  return model;
222}
223/* Destructor */
224COINLIBAPI void COINLINKAGE
225Clp_deleteModel(Clp_Simplex *model)
226{
227  delete model->model_;
228  delete model->handler_;
229  delete model;
230}
231
232/* Loads a problem (the constraints on the
233    rows are given by lower and upper bounds). If a pointer is NULL then the
234    following values are the default:
235    <ul>
236    <li> <code>colub</code>: all columns have upper bound infinity
237    <li> <code>collb</code>: all columns have lower bound 0
238    <li> <code>rowub</code>: all rows have upper bound infinity
239    <li> <code>rowlb</code>: all rows have lower bound -infinity
240    <li> <code>obj</code>: all variables have 0 objective coefficient
241    </ul>
242*/
243/* Just like the other loadProblem() method except that the matrix is
244   given in a standard column major ordered format (without gaps). */
245COINLIBAPI void COINLINKAGE
246Clp_loadProblem(Clp_Simplex *model, const int numcols, const int numrows,
247  const CoinBigIndex *start, const int *index,
248  const double *value,
249  const double *collb, const double *colub,
250  const double *obj,
251  const double *rowlb, const double *rowub)
252{
253  const char prefix[] = "Clp_c_Interface::Clp_loadProblem(): ";
254  const int verbose = 0;
255  if (verbose > 1) {
256    printf("%s numcols = %i, numrows = %i\n",
257      prefix, numcols, numrows);
258    printf("%s model = %p, start = %p, index = %p, value = %p\n",
259      prefix, reinterpret_cast< const void * >(model), reinterpret_cast< const void * >(start), reinterpret_cast< const void * >(index), reinterpret_cast< const void * >(value));
260    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
261      prefix, reinterpret_cast< const void * >(collb), reinterpret_cast< const void * >(colub), reinterpret_cast< const void * >(obj), reinterpret_cast< const void * >(rowlb), reinterpret_cast< const void * >(rowub));
262  }
263  model->model_->loadProblem(numcols, numrows, start, index, value,
264    collb, colub, obj, rowlb, rowub);
265}
266
267/* read quadratic part of the objective (the matrix part) */
268COINLIBAPI void COINLINKAGE
269Clp_loadQuadraticObjective(Clp_Simplex *model,
270  const int numberColumns,
271  const CoinBigIndex *start,
272  const int *column,
273  const double *element)
274{
275
276  model->model_->loadQuadraticObjective(numberColumns,
277    start, column, element);
278}
279/* Read an mps file from the given filename */
280COINLIBAPI int COINLINKAGE
281Clp_readMps(Clp_Simplex *model, const char *filename,
282  int keepNames,
283  int ignoreErrors)
284{
285  return model->model_->readMps(filename, keepNames != 0, ignoreErrors != 0);
286}
287/* Write an MPS file to the given filename */
288COINLIBAPI int COINLINKAGE
289Clp_writeMps(Clp_Simplex *model, const char *filename,
290  int formatType,
291  int numberAcross,
292  double objSense)
293{
294  return model->model_->writeMps(filename, formatType, numberAcross, objSense);
295}
296/* Copy in integer informations */
297COINLIBAPI void COINLINKAGE
298Clp_copyInIntegerInformation(Clp_Simplex *model, const char *information)
299{
300  model->model_->copyInIntegerInformation(information);
301}
302/* Drop integer informations */
303COINLIBAPI void COINLINKAGE
304Clp_deleteIntegerInformation(Clp_Simplex *model)
305{
306  model->model_->deleteIntegerInformation();
307}
308/* Resizes rim part of model  */
309COINLIBAPI void COINLINKAGE
310Clp_resize(Clp_Simplex *model, int newNumberRows, int newNumberColumns)
311{
312  model->model_->resize(newNumberRows, newNumberColumns);
313}
314/* Deletes rows */
315COINLIBAPI void COINLINKAGE
316Clp_deleteRows(Clp_Simplex *model, int number, const int *which)
317{
318  model->model_->deleteRows(number, which);
319}
320/* Add rows */
321COINLIBAPI void COINLINKAGE
322Clp_addRows(Clp_Simplex *model, int number, const double *rowLower,
323  const double *rowUpper,
324  const CoinBigIndex *rowStarts, const int *columns,
325  const double *elements)
326{
327  model->model_->addRows(number, rowLower, rowUpper, rowStarts, columns, elements);
328}
329
330/* Deletes columns */
331COINLIBAPI void COINLINKAGE
332Clp_deleteColumns(Clp_Simplex *model, int number, const int *which)
333{
334  model->model_->deleteColumns(number, which);
335}
336/* Add columns */
337COINLIBAPI void COINLINKAGE
338Clp_addColumns(Clp_Simplex *model, int number, const double *columnLower,
339  const double *columnUpper,
340  const double *objective,
341  const CoinBigIndex *columnStarts, const int *rows,
342  const double *elements)
343{
344  model->model_->addColumns(number, columnLower, columnUpper, objective,
345    columnStarts, rows, elements);
346}
347/* Change row lower bounds */
348COINLIBAPI void COINLINKAGE
349Clp_chgRowLower(Clp_Simplex *model, const double *rowLower)
350{
351  model->model_->chgRowLower(rowLower);
352}
353/* Change row upper bounds */
354COINLIBAPI void COINLINKAGE
355Clp_chgRowUpper(Clp_Simplex *model, const double *rowUpper)
356{
357  model->model_->chgRowUpper(rowUpper);
358}
359/* Change column lower bounds */
360COINLIBAPI void COINLINKAGE
361Clp_chgColumnLower(Clp_Simplex *model, const double *columnLower)
362{
363  model->model_->chgColumnLower(columnLower);
364}
365/* Change column upper bounds */
366COINLIBAPI void COINLINKAGE
367Clp_chgColumnUpper(Clp_Simplex *model, const double *columnUpper)
368{
369  model->model_->chgColumnUpper(columnUpper);
370}
371/* Change objective coefficients */
372COINLIBAPI void COINLINKAGE
373Clp_chgObjCoefficients(Clp_Simplex *model, const double *objIn)
374{
375  model->model_->chgObjCoefficients(objIn);
376}
377/* Drops names - makes lengthnames 0 and names empty */
378COINLIBAPI void COINLINKAGE
379Clp_dropNames(Clp_Simplex *model)
380{
381  model->model_->dropNames();
382}
383/* Copies in names */
384COINLIBAPI void COINLINKAGE
385Clp_copyNames(Clp_Simplex *model, const char *const *rowNamesIn,
386  const char *const *columnNamesIn)
387{
388  int iRow;
389  std::vector< std::string > rowNames;
390  int numberRows = model->model_->numberRows();
391  rowNames.reserve(numberRows);
392  for (iRow = 0; iRow < numberRows; iRow++) {
393    rowNames.push_back(rowNamesIn[iRow]);
394  }
395
396  int iColumn;
397  std::vector< std::string > columnNames;
398  int numberColumns = model->model_->numberColumns();
399  columnNames.reserve(numberColumns);
400  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
401    columnNames.push_back(columnNamesIn[iColumn]);
402  }
403  model->model_->copyNames(rowNames, columnNames);
404}
405
406/* Number of rows */
407COINLIBAPI int COINLINKAGE
408Clp_numberRows(Clp_Simplex *model)
409{
410  return model->model_->numberRows();
411}
412/* Number of columns */
413COINLIBAPI int COINLINKAGE
414Clp_numberColumns(Clp_Simplex *model)
415{
416  return model->model_->numberColumns();
417}
418/* Primal tolerance to use */
419COINLIBAPI double COINLINKAGE
420Clp_primalTolerance(Clp_Simplex *model)
421{
422  return model->model_->primalTolerance();
423}
424COINLIBAPI void COINLINKAGE
425Clp_setPrimalTolerance(Clp_Simplex *model, double value)
426{
427  model->model_->setPrimalTolerance(value);
428}
429/* Dual tolerance to use */
430COINLIBAPI double COINLINKAGE
431Clp_dualTolerance(Clp_Simplex *model)
432{
433  return model->model_->dualTolerance();
434}
435COINLIBAPI void COINLINKAGE
436Clp_setDualTolerance(Clp_Simplex *model, double value)
437{
438  model->model_->setDualTolerance(value);
439}
440/* Dual objective limit */
441COINLIBAPI double COINLINKAGE
442Clp_dualObjectiveLimit(Clp_Simplex *model)
443{
444  return model->model_->dualObjectiveLimit();
445}
446COINLIBAPI void COINLINKAGE
447Clp_setDualObjectiveLimit(Clp_Simplex *model, double value)
448{
449  model->model_->setDualObjectiveLimit(value);
450}
451/* Objective offset */
452COINLIBAPI double COINLINKAGE
453Clp_objectiveOffset(Clp_Simplex *model)
454{
455  return model->model_->objectiveOffset();
456}
457COINLIBAPI void COINLINKAGE
458Clp_setObjectiveOffset(Clp_Simplex *model, double value)
459{
460  model->model_->setObjectiveOffset(value);
461}
462/* Fills in array with problem name  */
463COINLIBAPI void COINLINKAGE
464Clp_problemName(Clp_Simplex *model, int maxNumberCharacters, char *array)
465{
466  std::string name = model->model_->problemName();
467  maxNumberCharacters = CoinMin(maxNumberCharacters,
468    ((int)strlen(name.c_str())) + 1);
469  strncpy(array, name.c_str(), maxNumberCharacters - 1);
470  array[maxNumberCharacters - 1] = '\0';
471}
472/* Sets problem name.  Must have \0 at end.  */
473COINLIBAPI int COINLINKAGE
474Clp_setProblemName(Clp_Simplex *model, int /*maxNumberCharacters*/, char *array)
475{
476  return model->model_->setStrParam(ClpProbName, array);
477}
478/* Number of iterations */
479COINLIBAPI int COINLINKAGE
480Clp_numberIterations(Clp_Simplex *model)
481{
482  return model->model_->numberIterations();
483}
484COINLIBAPI void COINLINKAGE
485Clp_setNumberIterations(Clp_Simplex *model, int numberIterations)
486{
487  model->model_->setNumberIterations(numberIterations);
488}
489/* Maximum number of iterations */
490COINLIBAPI int maximumIterations(Clp_Simplex *model)
491{
492  return model->model_->maximumIterations();
493}
494COINLIBAPI void COINLINKAGE
495Clp_setMaximumIterations(Clp_Simplex *model, int value)
496{
497  model->model_->setMaximumIterations(value);
498}
499/* Maximum time in seconds (from when set called) */
500COINLIBAPI double COINLINKAGE
501Clp_maximumSeconds(Clp_Simplex *model)
502{
503  return model->model_->maximumSeconds();
504}
505COINLIBAPI void COINLINKAGE
506Clp_setMaximumSeconds(Clp_Simplex *model, double value)
507{
508  model->model_->setMaximumSeconds(value);
509}
510/* Returns true if hit maximum iteratio`ns (or time) */
511COINLIBAPI int COINLINKAGE
512Clp_hitMaximumIterations(Clp_Simplex *model)
513{
514  return model->model_->hitMaximumIterations() ? 1 : 0;
515}
516/* Status of problem:
517   0 - optimal
518   1 - primal infeasible
519   2 - dual infeasible
520   3 - stopped on iterations etc
521   4 - stopped due to errors
522*/
523COINLIBAPI int COINLINKAGE
524Clp_status(Clp_Simplex *model)
525{
526  return model->model_->status();
527}
528/* Set problem status */
529COINLIBAPI void COINLINKAGE
530Clp_setProblemStatus(Clp_Simplex *model, int problemStatus)
531{
532  model->model_->setProblemStatus(problemStatus);
533}
534/* Secondary status of problem - may get extended
535   0 - none
536   1 - primal infeasible because dual limit reached
537   2 - scaled problem optimal - unscaled has primal infeasibilities
538   3 - scaled problem optimal - unscaled has dual infeasibilities
539   4 - scaled problem optimal - unscaled has both dual and primal infeasibilities
540*/
541COINLIBAPI int COINLINKAGE
542Clp_secondaryStatus(Clp_Simplex *model)
543{
544  return model->model_->secondaryStatus();
545}
546COINLIBAPI void COINLINKAGE
547Clp_setSecondaryStatus(Clp_Simplex *model, int status)
548{
549  model->model_->setSecondaryStatus(status);
550}
551/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
552COINLIBAPI double COINLINKAGE
553Clp_optimizationDirection(Clp_Simplex *model)
554{
555  return model->model_->optimizationDirection();
556}
557COINLIBAPI void COINLINKAGE
558Clp_setOptimizationDirection(Clp_Simplex *model, double value)
559{
560  model->model_->setOptimizationDirection(value);
561}
562/* Primal row solution */
563COINLIBAPI double *COINLINKAGE
564Clp_primalRowSolution(Clp_Simplex *model)
565{
566  return model->model_->primalRowSolution();
567}
568/* Primal column solution */
569COINLIBAPI double *COINLINKAGE
570Clp_primalColumnSolution(Clp_Simplex *model)
571{
572  return model->model_->primalColumnSolution();
573}
574/* Dual row solution */
575COINLIBAPI double *COINLINKAGE
576Clp_dualRowSolution(Clp_Simplex *model)
577{
578  return model->model_->dualRowSolution();
579}
580/* Reduced costs */
581COINLIBAPI double *COINLINKAGE
582Clp_dualColumnSolution(Clp_Simplex *model)
583{
584  return model->model_->dualColumnSolution();
585}
586/* Row lower */
587COINLIBAPI double *COINLINKAGE
588Clp_rowLower(Clp_Simplex *model)
589{
590  return model->model_->rowLower();
591}
592/* Row upper  */
593COINLIBAPI double *COINLINKAGE
594Clp_rowUpper(Clp_Simplex *model)
595{
596  return model->model_->rowUpper();
597}
598/* Objective */
599COINLIBAPI double *COINLINKAGE
600Clp_objective(Clp_Simplex *model)
601{
602  return model->model_->objective();
603}
604/* Column Lower */
605COINLIBAPI double *COINLINKAGE
606Clp_columnLower(Clp_Simplex *model)
607{
608  return model->model_->columnLower();
609}
610/* Column Upper */
611COINLIBAPI double *COINLINKAGE
612Clp_columnUpper(Clp_Simplex *model)
613{
614  return model->model_->columnUpper();
615}
616/* Number of elements in matrix */
617COINLIBAPI CoinBigIndex COINLINKAGE
618Clp_getNumElements(Clp_Simplex *model)
619{
620  return model->model_->getNumElements();
621}
622// Column starts in matrix
623COINLIBAPI const CoinBigIndex *COINLINKAGE Clp_getVectorStarts(Clp_Simplex *model)
624{
625  CoinPackedMatrix *matrix;
626  matrix = model->model_->matrix();
627  return (matrix == NULL) ? NULL : matrix->getVectorStarts();
628}
629
630// Row indices in matrix
631COINLIBAPI const int *COINLINKAGE Clp_getIndices(Clp_Simplex *model)
632{
633  CoinPackedMatrix *matrix = model->model_->matrix();
634  return (matrix == NULL) ? NULL : matrix->getIndices();
635}
636
637// Column vector lengths in matrix
638COINLIBAPI const int *COINLINKAGE Clp_getVectorLengths(Clp_Simplex *model)
639{
640  CoinPackedMatrix *matrix = model->model_->matrix();
641  return (matrix == NULL) ? NULL : matrix->getVectorLengths();
642}
643
644// Element values in matrix
645COINLIBAPI const double *COINLINKAGE Clp_getElements(Clp_Simplex *model)
646{
647  CoinPackedMatrix *matrix = model->model_->matrix();
648  return (matrix == NULL) ? NULL : matrix->getElements();
649}
650/* Objective value */
651COINLIBAPI double COINLINKAGE
652Clp_objectiveValue(Clp_Simplex *model)
653{
654  return model->model_->objectiveValue();
655}
656/* Integer information */
657COINLIBAPI char *COINLINKAGE
658Clp_integerInformation(Clp_Simplex *model)
659{
660  return model->model_->integerInformation();
661}
662/* Infeasibility/unbounded ray (NULL returned if none/wrong)
663   Up to user to use free() on these arrays.  */
664COINLIBAPI double *COINLINKAGE
665Clp_infeasibilityRay(Clp_Simplex *model)
666{
667  const double *ray = model->model_->internalRay();
668  double *array = NULL;
669  int numberRows = model->model_->numberRows();
670  int status = model->model_->status();
671  if (status == 1 && ray) {
672    array = static_cast< double * >(malloc(numberRows * sizeof(double)));
673    memcpy(array, ray, numberRows * sizeof(double));
674#ifdef PRINT_RAY_METHOD
675    printf("Infeasibility ray obtained by algorithm %s\n", model->model_->algorithm() > 0 ? "primal" : "dual");
676#endif
677  }
678  return array;
679}
680COINLIBAPI double *COINLINKAGE
681Clp_unboundedRay(Clp_Simplex *model)
682{
683  const double *ray = model->model_->internalRay();
684  double *array = NULL;
685  int numberColumns = model->model_->numberColumns();
686  int status = model->model_->status();
687  if (status == 2 && ray) {
688    array = static_cast< double * >(malloc(numberColumns * sizeof(double)));
689    memcpy(array, ray, numberColumns * sizeof(double));
690  }
691  return array;
692}
693COINLIBAPI void COINLINKAGE
694Clp_freeRay(Clp_Simplex *model, double *ray)
695{
696  free(ray);
697}
698/* See if status array exists (partly for OsiClp) */
699COINLIBAPI int COINLINKAGE
700Clp_statusExists(Clp_Simplex *model)
701{
702  return model->model_->statusExists() ? 1 : 0;
703}
704/* Return address of status array (char[numberRows+numberColumns]) */
705COINLIBAPI unsigned char *COINLINKAGE
706Clp_statusArray(Clp_Simplex *model)
707{
708  return model->model_->statusArray();
709}
710/* Copy in status vector */
711COINLIBAPI void COINLINKAGE
712Clp_copyinStatus(Clp_Simplex *model, const unsigned char *statusArray)
713{
714  model->model_->copyinStatus(statusArray);
715}
716
717/* User pointer for whatever reason */
718COINLIBAPI void COINLINKAGE
719Clp_setUserPointer(Clp_Simplex *model, void *pointer)
720{
721  model->model_->setUserPointer(pointer);
722}
723COINLIBAPI void *COINLINKAGE
724Clp_getUserPointer(Clp_Simplex *model)
725{
726  return model->model_->getUserPointer();
727}
728/* Pass in Callback function */
729COINLIBAPI void COINLINKAGE
730Clp_registerCallBack(Clp_Simplex *model,
731  clp_callback userCallBack)
732{
733  // Will be copy of users one
734  delete model->handler_;
735  model->handler_ = new CMessageHandler(*(model->model_->messageHandler()));
736  model->handler_->setCallBack(userCallBack);
737  model->handler_->setModel(model);
738  model->model_->passInMessageHandler(model->handler_);
739}
740/* Unset Callback function */
741COINLIBAPI void COINLINKAGE
742Clp_clearCallBack(Clp_Simplex *model)
743{
744  delete model->handler_;
745  model->handler_ = NULL;
746}
747/* Amount of print out:
748   0 - none
749   1 - just final
750   2 - just factorizations
751   3 - as 2 plus a bit more
752   4 - verbose
753   above that 8,16,32 etc just for selective debug
754*/
755COINLIBAPI void COINLINKAGE
756Clp_setLogLevel(Clp_Simplex *model, int value)
757{
758  model->model_->setLogLevel(value);
759}
760COINLIBAPI int COINLINKAGE
761Clp_logLevel(Clp_Simplex *model)
762{
763  return model->model_->logLevel();
764}
765/* length of names (0 means no names0 */
766COINLIBAPI int COINLINKAGE
767Clp_lengthNames(Clp_Simplex *model)
768{
769  return model->model_->lengthNames();
770}
771/* Fill in array (at least lengthNames+1 long) with a row name */
772COINLIBAPI void COINLINKAGE
773Clp_rowName(Clp_Simplex *model, int iRow, char *name)
774{
775  std::string rowName = model->model_->rowName(iRow);
776  strcpy(name, rowName.c_str());
777}
778/* Fill in array (at least lengthNames+1 long) with a column name */
779COINLIBAPI void COINLINKAGE
780Clp_columnName(Clp_Simplex *model, int iColumn, char *name)
781{
782  std::string columnName = model->model_->columnName(iColumn);
783  strcpy(name, columnName.c_str());
784}
785
786/** Set row name - Nice if they are short - 8 chars or less I think */
787COINLIBAPI void COINLINKAGE Clp_setRowName(Clp_Simplex *model, int iRow, char *name)
788{
789  std::string sName = name; // Copies the memory AFAIK
790  model->model_->setRowName(iRow, sName);
791}
792/** Set column name - Nice if they are short - 8 chars or less I think */
793COINLIBAPI void COINLINKAGE Clp_setColumnName(Clp_Simplex *model, int iColumn, char *name)
794{
795  std::string sName = name; // Copies the memory AFAIK
796  model->model_->setColumnName(iColumn, sName);
797}
798
799/* General solve algorithm which can do presolve.
800   See  ClpSolve.hpp for options
801*/
802COINLIBAPI int COINLINKAGE
803Clp_initialSolve(Clp_Simplex *model)
804{
805  return model->model_->initialSolve();
806}
807/* Pass solve options. (Exception to direct analogue rule) */
808COINLIBAPI int COINLINKAGE
809Clp_initialSolveWithOptions(Clp_Simplex *model, Clp_Solve *s)
810{
811  return model->model_->initialSolve(s->options);
812}
813/* Barrier initial solve */
814COINLIBAPI int COINLINKAGE
815Clp_initialBarrierSolve(Clp_Simplex *model0)
816{
817  ClpSimplex *model = model0->model_;
818
819  return model->initialBarrierSolve();
820}
821/* Barrier initial solve */
822COINLIBAPI int COINLINKAGE
823Clp_initialBarrierNoCrossSolve(Clp_Simplex *model0)
824{
825  ClpSimplex *model = model0->model_;
826
827  return model->initialBarrierNoCrossSolve();
828}
829/* Dual initial solve */
830COINLIBAPI int COINLINKAGE
831Clp_initialDualSolve(Clp_Simplex *model)
832{
833  return model->model_->initialDualSolve();
834}
835/* Primal initial solve */
836COINLIBAPI int COINLINKAGE
837Clp_initialPrimalSolve(Clp_Simplex *model)
838{
839  return model->model_->initialPrimalSolve();
840}
841/* Dual algorithm - see ClpSimplexDual.hpp for method */
842COINLIBAPI int COINLINKAGE
843Clp_dual(Clp_Simplex *model, int ifValuesPass)
844{
845  return model->model_->dual(ifValuesPass);
846}
847/* Primal algorithm - see ClpSimplexPrimal.hpp for method */
848COINLIBAPI int COINLINKAGE
849Clp_primal(Clp_Simplex *model, int ifValuesPass)
850{
851  return model->model_->primal(ifValuesPass);
852}
853/* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */
854COINLIBAPI void COINLINKAGE
855Clp_scaling(Clp_Simplex *model, int mode)
856{
857  model->model_->scaling(mode);
858}
859/* Gets scalingFlag */
860COINLIBAPI int COINLINKAGE
861Clp_scalingFlag(Clp_Simplex *model)
862{
863  return model->model_->scalingFlag();
864}
865/* Crash - at present just aimed at dual, returns
866   -2 if dual preferred and crash basis created
867   -1 if dual preferred and all slack basis preferred
868   0 if basis going in was not all slack
869   1 if primal preferred and all slack basis preferred
870   2 if primal preferred and crash basis created.
871
872   if gap between bounds <="gap" variables can be flipped
873
874   If "pivot" is
875   0 No pivoting (so will just be choice of algorithm)
876   1 Simple pivoting e.g. gub
877   2 Mini iterations
878*/
879COINLIBAPI int COINLINKAGE
880Clp_crash(Clp_Simplex *model, double gap, int pivot)
881{
882  return model->model_->crash(gap, pivot);
883}
884/* If problem is primal feasible */
885COINLIBAPI int COINLINKAGE
886Clp_primalFeasible(Clp_Simplex *model)
887{
888  return model->model_->primalFeasible() ? 1 : 0;
889}
890/* If problem is dual feasible */
891COINLIBAPI int COINLINKAGE
892Clp_dualFeasible(Clp_Simplex *model)
893{
894  return model->model_->dualFeasible() ? 1 : 0;
895}
896/* Dual bound */
897COINLIBAPI double COINLINKAGE
898Clp_dualBound(Clp_Simplex *model)
899{
900  return model->model_->dualBound();
901}
902COINLIBAPI void COINLINKAGE
903Clp_setDualBound(Clp_Simplex *model, double value)
904{
905  model->model_->setDualBound(value);
906}
907/* Infeasibility cost */
908COINLIBAPI double COINLINKAGE
909Clp_infeasibilityCost(Clp_Simplex *model)
910{
911  return model->model_->infeasibilityCost();
912}
913COINLIBAPI void COINLINKAGE
914Clp_setInfeasibilityCost(Clp_Simplex *model, double value)
915{
916  model->model_->setInfeasibilityCost(value);
917}
918/* Perturbation:
919   50  - switch on perturbation
920   100 - auto perturb if takes too long (1.0e-6 largest nonzero)
921   101 - we are perturbed
922   102 - don't try perturbing again
923   default is 100
924   others are for playing
925*/
926COINLIBAPI int COINLINKAGE
927Clp_perturbation(Clp_Simplex *model)
928{
929  return model->model_->perturbation();
930}
931COINLIBAPI void COINLINKAGE
932Clp_setPerturbation(Clp_Simplex *model, int value)
933{
934  model->model_->setPerturbation(value);
935}
936/* Current (or last) algorithm */
937COINLIBAPI int COINLINKAGE
938Clp_algorithm(Clp_Simplex *model)
939{
940  return model->model_->algorithm();
941}
942/* Set algorithm */
943COINLIBAPI void COINLINKAGE
944Clp_setAlgorithm(Clp_Simplex *model, int value)
945{
946  model->model_->setAlgorithm(value);
947}
948/* Sum of dual infeasibilities */
949COINLIBAPI double COINLINKAGE
950Clp_sumDualInfeasibilities(Clp_Simplex *model)
951{
952  return model->model_->sumDualInfeasibilities();
953}
954/* Number of dual infeasibilities */
955COINLIBAPI int COINLINKAGE
956Clp_numberDualInfeasibilities(Clp_Simplex *model)
957{
958  return model->model_->numberDualInfeasibilities();
959}
960/* Sum of primal infeasibilities */
961COINLIBAPI double COINLINKAGE
962Clp_sumPrimalInfeasibilities(Clp_Simplex *model)
963{
964  return model->model_->sumPrimalInfeasibilities();
965}
966/* Number of primal infeasibilities */
967COINLIBAPI int COINLINKAGE
968Clp_numberPrimalInfeasibilities(Clp_Simplex *model)
969{
970  return model->model_->numberPrimalInfeasibilities();
971}
972/* Save model to file, returns 0 if success.  This is designed for
973   use outside algorithms so does not save iterating arrays etc.
974   It does not save any messaging information.
975   Does not save scaling values.
976   It does not know about all types of virtual functions.
977*/
978COINLIBAPI int COINLINKAGE
979Clp_saveModel(Clp_Simplex *model, const char *fileName)
980{
981  return model->model_->saveModel(fileName);
982}
983/* Restore model from file, returns 0 if success,
984   deletes current model */
985COINLIBAPI int COINLINKAGE
986Clp_restoreModel(Clp_Simplex *model, const char *fileName)
987{
988  return model->model_->restoreModel(fileName);
989}
990
991/* Just check solution (for external use) - sets sum of
992   infeasibilities etc */
993COINLIBAPI void COINLINKAGE
994Clp_checkSolution(Clp_Simplex *model)
995{
996  model->model_->checkSolution();
997}
998/* Number of rows */
999COINLIBAPI int COINLINKAGE
1000Clp_getNumRows(Clp_Simplex *model)
1001{
1002  return model->model_->getNumRows();
1003}
1004/* Number of columns */
1005COINLIBAPI int COINLINKAGE
1006Clp_getNumCols(Clp_Simplex *model)
1007{
1008  return model->model_->getNumCols();
1009}
1010/* Number of iterations */
1011COINLIBAPI int COINLINKAGE
1012Clp_getIterationCount(Clp_Simplex *model)
1013{
1014  return model->model_->getIterationCount();
1015}
1016/* Are there a numerical difficulties? */
1017COINLIBAPI int COINLINKAGE
1018Clp_isAbandoned(Clp_Simplex *model)
1019{
1020  return model->model_->isAbandoned() ? 1 : 0;
1021}
1022/* Is optimality proven? */
1023COINLIBAPI int COINLINKAGE
1024Clp_isProvenOptimal(Clp_Simplex *model)
1025{
1026  return model->model_->isProvenOptimal() ? 1 : 0;
1027}
1028/* Is primal infeasiblity proven? */
1029COINLIBAPI int COINLINKAGE
1030Clp_isProvenPrimalInfeasible(Clp_Simplex *model)
1031{
1032  return model->model_->isProvenPrimalInfeasible() ? 1 : 0;
1033}
1034/* Is dual infeasiblity proven? */
1035COINLIBAPI int COINLINKAGE
1036Clp_isProvenDualInfeasible(Clp_Simplex *model)
1037{
1038  return model->model_->isProvenDualInfeasible() ? 1 : 0;
1039}
1040/* Is the given primal objective limit reached? */
1041COINLIBAPI int COINLINKAGE
1042Clp_isPrimalObjectiveLimitReached(Clp_Simplex *model)
1043{
1044  return model->model_->isPrimalObjectiveLimitReached() ? 1 : 0;
1045}
1046/* Is the given dual objective limit reached? */
1047COINLIBAPI int COINLINKAGE
1048Clp_isDualObjectiveLimitReached(Clp_Simplex *model)
1049{
1050  return model->model_->isDualObjectiveLimitReached() ? 1 : 0;
1051}
1052/* Iteration limit reached? */
1053COINLIBAPI int COINLINKAGE
1054Clp_isIterationLimitReached(Clp_Simplex *model)
1055{
1056  return model->model_->isIterationLimitReached() ? 1 : 0;
1057}
1058/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
1059COINLIBAPI double COINLINKAGE
1060Clp_getObjSense(Clp_Simplex *model)
1061{
1062  return model->model_->getObjSense();
1063}
1064/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
1065COINLIBAPI void COINLINKAGE
1066Clp_setObjSense(Clp_Simplex *model, double objsen)
1067{
1068  model->model_->setOptimizationDirection(objsen);
1069}
1070/* Primal row solution */
1071COINLIBAPI const double *COINLINKAGE
1072Clp_getRowActivity(Clp_Simplex *model)
1073{
1074  return model->model_->getRowActivity();
1075}
1076/* Primal column solution */
1077COINLIBAPI const double *COINLINKAGE
1078Clp_getColSolution(Clp_Simplex *model)
1079{
1080  return model->model_->getColSolution();
1081}
1082COINLIBAPI void COINLINKAGE
1083Clp_setColSolution(Clp_Simplex *model, const double *input)
1084{
1085  model->model_->setColSolution(input);
1086}
1087/* Dual row solution */
1088COINLIBAPI const double *COINLINKAGE
1089Clp_getRowPrice(Clp_Simplex *model)
1090{
1091  return model->model_->getRowPrice();
1092}
1093/* Reduced costs */
1094COINLIBAPI const double *COINLINKAGE
1095Clp_getReducedCost(Clp_Simplex *model)
1096{
1097  return model->model_->getReducedCost();
1098}
1099/* Row lower */
1100COINLIBAPI const double *COINLINKAGE
1101Clp_getRowLower(Clp_Simplex *model)
1102{
1103  return model->model_->getRowLower();
1104}
1105/* Row upper  */
1106COINLIBAPI const double *COINLINKAGE
1107Clp_getRowUpper(Clp_Simplex *model)
1108{
1109  return model->model_->getRowUpper();
1110}
1111/* Objective */
1112COINLIBAPI const double *COINLINKAGE
1113Clp_getObjCoefficients(Clp_Simplex *model)
1114{
1115  return model->model_->getObjCoefficients();
1116}
1117/* Column Lower */
1118COINLIBAPI const double *COINLINKAGE
1119Clp_getColLower(Clp_Simplex *model)
1120{
1121  return model->model_->getColLower();
1122}
1123/* Column Upper */
1124COINLIBAPI const double *COINLINKAGE
1125Clp_getColUpper(Clp_Simplex *model)
1126{
1127  return model->model_->getColUpper();
1128}
1129/* Objective value */
1130COINLIBAPI double COINLINKAGE
1131Clp_getObjValue(Clp_Simplex *model)
1132{
1133  return model->model_->getObjValue();
1134}
1135/* Get variable basis info */
1136COINLIBAPI int COINLINKAGE
1137Clp_getColumnStatus(Clp_Simplex *model, int sequence)
1138{
1139  return (int)model->model_->getColumnStatus(sequence);
1140}
1141/* Get row basis info */
1142COINLIBAPI int COINLINKAGE
1143Clp_getRowStatus(Clp_Simplex *model, int sequence)
1144{
1145  return (int)model->model_->getRowStatus(sequence);
1146}
1147/* Set variable basis info */
1148COINLIBAPI void COINLINKAGE
1149Clp_setColumnStatus(Clp_Simplex *model, int sequence, int value)
1150{
1151  if (value >= 0 && value <= 5) {
1152    model->model_->setColumnStatus(sequence, (ClpSimplex::Status)value);
1153    if (value == 3 || value == 5)
1154      model->model_->primalColumnSolution()[sequence] = model->model_->columnLower()[sequence];
1155    else if (value == 2)
1156      model->model_->primalColumnSolution()[sequence] = model->model_->columnUpper()[sequence];
1157  }
1158}
1159/* Set row basis info */
1160COINLIBAPI void COINLINKAGE
1161Clp_setRowStatus(Clp_Simplex *model, int sequence, int value)
1162{
1163  if (value >= 0 && value <= 5) {
1164    model->model_->setRowStatus(sequence, (ClpSimplex::Status)value);
1165    if (value == 3 || value == 5)
1166      model->model_->primalRowSolution()[sequence] = model->model_->rowLower()[sequence];
1167    else if (value == 2)
1168      model->model_->primalRowSolution()[sequence] = model->model_->rowUpper()[sequence];
1169  }
1170}
1171/* Small element value - elements less than this set to zero,
1172   default is 1.0e-20 */
1173COINLIBAPI double COINLINKAGE
1174Clp_getSmallElementValue(Clp_Simplex *model)
1175{
1176  return model->model_->getSmallElementValue();
1177}
1178COINLIBAPI void COINLINKAGE
1179Clp_setSmallElementValue(Clp_Simplex *model, double value)
1180{
1181  model->model_->setSmallElementValue(value);
1182}
1183/* Print model */
1184COINLIBAPI void COINLINKAGE
1185Clp_printModel(Clp_Simplex *model, const char *prefix)
1186{
1187  ClpSimplex *clp_simplex = model->model_;
1188  int numrows = clp_simplex->numberRows();
1189  int numcols = clp_simplex->numberColumns();
1190  CoinBigIndex numelem = clp_simplex->getNumElements();
1191  const CoinBigIndex *start = clp_simplex->matrix()->getVectorStarts();
1192  const int *length = clp_simplex->matrix()->getVectorLengths();
1193  const int *index = clp_simplex->matrix()->getIndices();
1194  const double *value = clp_simplex->matrix()->getElements();
1195  const double *collb = model->model_->columnLower();
1196  const double *colub = model->model_->columnUpper();
1197  const double *obj = model->model_->objective();
1198  const double *rowlb = model->model_->rowLower();
1199  const double *rowub = model->model_->rowUpper();
1200  printf("%s numcols = %i, numrows = %i, numelem = %i\n",
1201    prefix, numcols, numrows, numelem);
1202  printf("%s model = %p, start = %p, index = %p, value = %p\n",
1203    prefix, reinterpret_cast< const void * >(model), reinterpret_cast< const void * >(start), reinterpret_cast< const void * >(index), reinterpret_cast< const void * >(value));
1204  clp_simplex->matrix()->dumpMatrix(NULL);
1205  {
1206    int i;
1207    for (i = 0; i <= numcols; i++)
1208      printf("%s start[%i] = %i\n", prefix, i, start[i]);
1209    // may be gaps
1210    for (i = 0; i < numcols; i++) {
1211      for (CoinBigIndex j = start[i]; j < start[i] + length[i]; j++)
1212        printf("%s index[%i] = %i, value[%i] = %g\n",
1213          prefix, j, index[j], j, value[j]);
1214    }
1215  }
1216
1217  printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
1218    prefix, reinterpret_cast< const void * >(collb), reinterpret_cast< const void * >(colub), reinterpret_cast< const void * >(obj), reinterpret_cast< const void * >(rowlb), reinterpret_cast< const void * >(rowub));
1219  printf("%s optimization direction = %g\n", prefix, Clp_optimizationDirection(model));
1220  printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
1221  {
1222    int i;
1223    for (i = 0; i < numcols; i++)
1224      printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
1225        prefix, i, collb[i], i, colub[i], i, obj[i]);
1226    for (i = 0; i < numrows; i++)
1227      printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
1228        prefix, i, rowlb[i], i, rowub[i]);
1229  }
1230}
1231
1232#ifndef SLIM_CLP
1233/** Solve the problem with the idiot code */
1234/* tryhard values:
1235   tryhard & 7:
1236      0: NOT lightweight, 105 iterations within a pass (when mu stays fixed)
1237      1: lightweight, but focus more on optimality (mu is high)
1238         (23 iters in a pass)
1239      2: lightweight, but focus more on feasibility (11 iters in a pass)
1240      3: lightweight, but focus more on feasibility (23 iters in a pass, so it
1241         goes closer to opt than option 2)
1242   tryhard >> 3:
1243      number of passes, the larger the number the closer it gets to optimality
1244*/
1245COINLIBAPI void COINLINKAGE
1246Clp_idiot(Clp_Simplex *model, int tryhard)
1247{
1248  ClpSimplex *clp = model->model_;
1249  Idiot info(*clp);
1250  int numberpass = tryhard >> 3;
1251  int lightweight = tryhard & 7;
1252  info.setLightweight(lightweight);
1253  info.crash(numberpass, clp->messageHandler(), clp->messagesPointer(), false);
1254}
1255#endif
1256
1257COINLIBAPI Clp_Solve *COINLINKAGE
1258ClpSolve_new()
1259{
1260  return new Clp_Solve();
1261}
1262
1263COINLIBAPI void COINLINKAGE
1264ClpSolve_delete(Clp_Solve *solve)
1265{
1266  delete solve;
1267}
1268
1269// space- and error-saving macros
1270#define ClpSolveGetIntProperty(prop) \
1271  COINLIBAPI int COINLINKAGE         \
1272    ClpSolve_##prop(Clp_Solve *s)    \
1273  {                                  \
1274    return s->options.prop();        \
1275  }
1276
1277#define ClpSolveSetIntProperty(prop)       \
1278  COINLIBAPI void COINLINKAGE              \
1279    ClpSolve_##prop(Clp_Solve *s, int val) \
1280  {                                        \
1281    s->options.prop(val);                  \
1282  }
1283
1284COINLIBAPI void COINLINKAGE
1285ClpSolve_setSpecialOption(Clp_Solve *s, int which, int value, int extraInfo)
1286{
1287  s->options.setSpecialOption(which, value, extraInfo);
1288}
1289
1290COINLIBAPI int COINLINKAGE
1291ClpSolve_getSpecialOption(Clp_Solve *s, int which)
1292{
1293  return s->options.getSpecialOption(which);
1294}
1295
1296COINLIBAPI void COINLINKAGE
1297ClpSolve_setSolveType(Clp_Solve *s, int method, int extraInfo)
1298{
1299  s->options.setSolveType(static_cast< ClpSolve::SolveType >(method), extraInfo);
1300}
1301
1302ClpSolveGetIntProperty(getSolveType)
1303
1304  COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve *s, int amount, int extraInfo)
1305{
1306  s->options.setPresolveType(static_cast< ClpSolve::PresolveType >(amount), extraInfo);
1307}
1308
1309ClpSolveGetIntProperty(getPresolveType)
1310
1311  ClpSolveGetIntProperty(getPresolvePasses)
1312
1313    COINLIBAPI int COINLINKAGE
1314  ClpSolve_getExtraInfo(Clp_Solve *s, int which)
1315{
1316  return s->options.getExtraInfo(which);
1317}
1318
1319ClpSolveSetIntProperty(setInfeasibleReturn)
1320  ClpSolveGetIntProperty(infeasibleReturn)
1321
1322    ClpSolveGetIntProperty(doDual)
1323      ClpSolveSetIntProperty(setDoDual)
1324
1325        ClpSolveGetIntProperty(doSingleton)
1326          ClpSolveSetIntProperty(setDoSingleton)
1327
1328            ClpSolveGetIntProperty(doDoubleton)
1329              ClpSolveSetIntProperty(setDoDoubleton)
1330
1331                ClpSolveGetIntProperty(doTripleton)
1332                  ClpSolveSetIntProperty(setDoTripleton)
1333
1334                    ClpSolveGetIntProperty(doTighten)
1335                      ClpSolveSetIntProperty(setDoTighten)
1336
1337                        ClpSolveGetIntProperty(doForcing)
1338                          ClpSolveSetIntProperty(setDoForcing)
1339
1340                            ClpSolveGetIntProperty(doImpliedFree)
1341                              ClpSolveSetIntProperty(setDoImpliedFree)
1342
1343                                ClpSolveGetIntProperty(doDupcol)
1344                                  ClpSolveSetIntProperty(setDoDupcol)
1345
1346                                    ClpSolveGetIntProperty(doDuprow)
1347                                      ClpSolveSetIntProperty(setDoDuprow)
1348
1349                                        ClpSolveGetIntProperty(doSingletonColumn)
1350                                          ClpSolveSetIntProperty(setDoSingletonColumn)
1351
1352                                            ClpSolveGetIntProperty(presolveActions)
1353                                              ClpSolveSetIntProperty(setPresolveActions)
1354
1355                                                ClpSolveGetIntProperty(substitution)
1356                                                  ClpSolveSetIntProperty(setSubstitution)
1357
1358#if defined(__MWERKS__)
1359#pragma export off
1360#endif
1361
1362  /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1363*/
Note: See TracBrowser for help on using the repository browser.