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

Last change on this file since 2446 was 2446, checked in by stefan, 3 months ago

add Clp_modifyCoefficient to C interface

  • as suggested in #102
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 38.6 KB
Line 
1// $Id: Clp_C_Interface.cpp 2446 2019-04-07 04:56:40Z 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/* Change matrix coefficients */
378COINLIBAPI void COINLINKAGE
379Clp_modifyCoefficient(Clp_Simplex *model, int row, int column, double newElement,
380  bool keepZero)
381{
382  model->model_->modifyCoefficient(row, column, newElement, keepZero);
383}
384/* Drops names - makes lengthnames 0 and names empty */
385COINLIBAPI void COINLINKAGE
386Clp_dropNames(Clp_Simplex *model)
387{
388  model->model_->dropNames();
389}
390/* Copies in names */
391COINLIBAPI void COINLINKAGE
392Clp_copyNames(Clp_Simplex *model, const char *const *rowNamesIn,
393  const char *const *columnNamesIn)
394{
395  int iRow;
396  std::vector< std::string > rowNames;
397  int numberRows = model->model_->numberRows();
398  rowNames.reserve(numberRows);
399  for (iRow = 0; iRow < numberRows; iRow++) {
400    rowNames.push_back(rowNamesIn[iRow]);
401  }
402
403  int iColumn;
404  std::vector< std::string > columnNames;
405  int numberColumns = model->model_->numberColumns();
406  columnNames.reserve(numberColumns);
407  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
408    columnNames.push_back(columnNamesIn[iColumn]);
409  }
410  model->model_->copyNames(rowNames, columnNames);
411}
412
413/* Number of rows */
414COINLIBAPI int COINLINKAGE
415Clp_numberRows(Clp_Simplex *model)
416{
417  return model->model_->numberRows();
418}
419/* Number of columns */
420COINLIBAPI int COINLINKAGE
421Clp_numberColumns(Clp_Simplex *model)
422{
423  return model->model_->numberColumns();
424}
425/* Primal tolerance to use */
426COINLIBAPI double COINLINKAGE
427Clp_primalTolerance(Clp_Simplex *model)
428{
429  return model->model_->primalTolerance();
430}
431COINLIBAPI void COINLINKAGE
432Clp_setPrimalTolerance(Clp_Simplex *model, double value)
433{
434  model->model_->setPrimalTolerance(value);
435}
436/* Dual tolerance to use */
437COINLIBAPI double COINLINKAGE
438Clp_dualTolerance(Clp_Simplex *model)
439{
440  return model->model_->dualTolerance();
441}
442COINLIBAPI void COINLINKAGE
443Clp_setDualTolerance(Clp_Simplex *model, double value)
444{
445  model->model_->setDualTolerance(value);
446}
447/* Dual objective limit */
448COINLIBAPI double COINLINKAGE
449Clp_dualObjectiveLimit(Clp_Simplex *model)
450{
451  return model->model_->dualObjectiveLimit();
452}
453COINLIBAPI void COINLINKAGE
454Clp_setDualObjectiveLimit(Clp_Simplex *model, double value)
455{
456  model->model_->setDualObjectiveLimit(value);
457}
458/* Objective offset */
459COINLIBAPI double COINLINKAGE
460Clp_objectiveOffset(Clp_Simplex *model)
461{
462  return model->model_->objectiveOffset();
463}
464COINLIBAPI void COINLINKAGE
465Clp_setObjectiveOffset(Clp_Simplex *model, double value)
466{
467  model->model_->setObjectiveOffset(value);
468}
469/* Fills in array with problem name  */
470COINLIBAPI void COINLINKAGE
471Clp_problemName(Clp_Simplex *model, int maxNumberCharacters, char *array)
472{
473  std::string name = model->model_->problemName();
474  maxNumberCharacters = CoinMin(maxNumberCharacters,
475    ((int)strlen(name.c_str())) + 1);
476  strncpy(array, name.c_str(), maxNumberCharacters - 1);
477  array[maxNumberCharacters - 1] = '\0';
478}
479/* Sets problem name.  Must have \0 at end.  */
480COINLIBAPI int COINLINKAGE
481Clp_setProblemName(Clp_Simplex *model, int /*maxNumberCharacters*/, char *array)
482{
483  return model->model_->setStrParam(ClpProbName, array);
484}
485/* Number of iterations */
486COINLIBAPI int COINLINKAGE
487Clp_numberIterations(Clp_Simplex *model)
488{
489  return model->model_->numberIterations();
490}
491COINLIBAPI void COINLINKAGE
492Clp_setNumberIterations(Clp_Simplex *model, int numberIterations)
493{
494  model->model_->setNumberIterations(numberIterations);
495}
496/* Maximum number of iterations */
497COINLIBAPI int maximumIterations(Clp_Simplex *model)
498{
499  return model->model_->maximumIterations();
500}
501COINLIBAPI void COINLINKAGE
502Clp_setMaximumIterations(Clp_Simplex *model, int value)
503{
504  model->model_->setMaximumIterations(value);
505}
506/* Maximum time in seconds (from when set called) */
507COINLIBAPI double COINLINKAGE
508Clp_maximumSeconds(Clp_Simplex *model)
509{
510  return model->model_->maximumSeconds();
511}
512COINLIBAPI void COINLINKAGE
513Clp_setMaximumSeconds(Clp_Simplex *model, double value)
514{
515  model->model_->setMaximumSeconds(value);
516}
517/* Returns true if hit maximum iteratio`ns (or time) */
518COINLIBAPI int COINLINKAGE
519Clp_hitMaximumIterations(Clp_Simplex *model)
520{
521  return model->model_->hitMaximumIterations() ? 1 : 0;
522}
523/* Status of problem:
524   0 - optimal
525   1 - primal infeasible
526   2 - dual infeasible
527   3 - stopped on iterations etc
528   4 - stopped due to errors
529*/
530COINLIBAPI int COINLINKAGE
531Clp_status(Clp_Simplex *model)
532{
533  return model->model_->status();
534}
535/* Set problem status */
536COINLIBAPI void COINLINKAGE
537Clp_setProblemStatus(Clp_Simplex *model, int problemStatus)
538{
539  model->model_->setProblemStatus(problemStatus);
540}
541/* Secondary status of problem - may get extended
542   0 - none
543   1 - primal infeasible because dual limit reached
544   2 - scaled problem optimal - unscaled has primal infeasibilities
545   3 - scaled problem optimal - unscaled has dual infeasibilities
546   4 - scaled problem optimal - unscaled has both dual and primal infeasibilities
547*/
548COINLIBAPI int COINLINKAGE
549Clp_secondaryStatus(Clp_Simplex *model)
550{
551  return model->model_->secondaryStatus();
552}
553COINLIBAPI void COINLINKAGE
554Clp_setSecondaryStatus(Clp_Simplex *model, int status)
555{
556  model->model_->setSecondaryStatus(status);
557}
558/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
559COINLIBAPI double COINLINKAGE
560Clp_optimizationDirection(Clp_Simplex *model)
561{
562  return model->model_->optimizationDirection();
563}
564COINLIBAPI void COINLINKAGE
565Clp_setOptimizationDirection(Clp_Simplex *model, double value)
566{
567  model->model_->setOptimizationDirection(value);
568}
569/* Primal row solution */
570COINLIBAPI double *COINLINKAGE
571Clp_primalRowSolution(Clp_Simplex *model)
572{
573  return model->model_->primalRowSolution();
574}
575/* Primal column solution */
576COINLIBAPI double *COINLINKAGE
577Clp_primalColumnSolution(Clp_Simplex *model)
578{
579  return model->model_->primalColumnSolution();
580}
581/* Dual row solution */
582COINLIBAPI double *COINLINKAGE
583Clp_dualRowSolution(Clp_Simplex *model)
584{
585  return model->model_->dualRowSolution();
586}
587/* Reduced costs */
588COINLIBAPI double *COINLINKAGE
589Clp_dualColumnSolution(Clp_Simplex *model)
590{
591  return model->model_->dualColumnSolution();
592}
593/* Row lower */
594COINLIBAPI double *COINLINKAGE
595Clp_rowLower(Clp_Simplex *model)
596{
597  return model->model_->rowLower();
598}
599/* Row upper  */
600COINLIBAPI double *COINLINKAGE
601Clp_rowUpper(Clp_Simplex *model)
602{
603  return model->model_->rowUpper();
604}
605/* Objective */
606COINLIBAPI double *COINLINKAGE
607Clp_objective(Clp_Simplex *model)
608{
609  return model->model_->objective();
610}
611/* Column Lower */
612COINLIBAPI double *COINLINKAGE
613Clp_columnLower(Clp_Simplex *model)
614{
615  return model->model_->columnLower();
616}
617/* Column Upper */
618COINLIBAPI double *COINLINKAGE
619Clp_columnUpper(Clp_Simplex *model)
620{
621  return model->model_->columnUpper();
622}
623/* Number of elements in matrix */
624COINLIBAPI CoinBigIndex COINLINKAGE
625Clp_getNumElements(Clp_Simplex *model)
626{
627  return model->model_->getNumElements();
628}
629// Column starts in matrix
630COINLIBAPI const CoinBigIndex *COINLINKAGE Clp_getVectorStarts(Clp_Simplex *model)
631{
632  CoinPackedMatrix *matrix;
633  matrix = model->model_->matrix();
634  return (matrix == NULL) ? NULL : matrix->getVectorStarts();
635}
636
637// Row indices in matrix
638COINLIBAPI const int *COINLINKAGE Clp_getIndices(Clp_Simplex *model)
639{
640  CoinPackedMatrix *matrix = model->model_->matrix();
641  return (matrix == NULL) ? NULL : matrix->getIndices();
642}
643
644// Column vector lengths in matrix
645COINLIBAPI const int *COINLINKAGE Clp_getVectorLengths(Clp_Simplex *model)
646{
647  CoinPackedMatrix *matrix = model->model_->matrix();
648  return (matrix == NULL) ? NULL : matrix->getVectorLengths();
649}
650
651// Element values in matrix
652COINLIBAPI const double *COINLINKAGE Clp_getElements(Clp_Simplex *model)
653{
654  CoinPackedMatrix *matrix = model->model_->matrix();
655  return (matrix == NULL) ? NULL : matrix->getElements();
656}
657/* Objective value */
658COINLIBAPI double COINLINKAGE
659Clp_objectiveValue(Clp_Simplex *model)
660{
661  return model->model_->objectiveValue();
662}
663/* Integer information */
664COINLIBAPI char *COINLINKAGE
665Clp_integerInformation(Clp_Simplex *model)
666{
667  return model->model_->integerInformation();
668}
669/* Infeasibility/unbounded ray (NULL returned if none/wrong)
670   Up to user to use free() on these arrays.  */
671COINLIBAPI double *COINLINKAGE
672Clp_infeasibilityRay(Clp_Simplex *model)
673{
674  const double *ray = model->model_->internalRay();
675  double *array = NULL;
676  int numberRows = model->model_->numberRows();
677  int status = model->model_->status();
678  if (status == 1 && ray) {
679    array = static_cast< double * >(malloc(numberRows * sizeof(double)));
680    memcpy(array, ray, numberRows * sizeof(double));
681#ifdef PRINT_RAY_METHOD
682    printf("Infeasibility ray obtained by algorithm %s\n", model->model_->algorithm() > 0 ? "primal" : "dual");
683#endif
684  }
685  return array;
686}
687COINLIBAPI double *COINLINKAGE
688Clp_unboundedRay(Clp_Simplex *model)
689{
690  const double *ray = model->model_->internalRay();
691  double *array = NULL;
692  int numberColumns = model->model_->numberColumns();
693  int status = model->model_->status();
694  if (status == 2 && ray) {
695    array = static_cast< double * >(malloc(numberColumns * sizeof(double)));
696    memcpy(array, ray, numberColumns * sizeof(double));
697  }
698  return array;
699}
700COINLIBAPI void COINLINKAGE
701Clp_freeRay(Clp_Simplex *model, double *ray)
702{
703  free(ray);
704}
705/* See if status array exists (partly for OsiClp) */
706COINLIBAPI int COINLINKAGE
707Clp_statusExists(Clp_Simplex *model)
708{
709  return model->model_->statusExists() ? 1 : 0;
710}
711/* Return address of status array (char[numberRows+numberColumns]) */
712COINLIBAPI unsigned char *COINLINKAGE
713Clp_statusArray(Clp_Simplex *model)
714{
715  return model->model_->statusArray();
716}
717/* Copy in status vector */
718COINLIBAPI void COINLINKAGE
719Clp_copyinStatus(Clp_Simplex *model, const unsigned char *statusArray)
720{
721  model->model_->copyinStatus(statusArray);
722}
723
724/* User pointer for whatever reason */
725COINLIBAPI void COINLINKAGE
726Clp_setUserPointer(Clp_Simplex *model, void *pointer)
727{
728  model->model_->setUserPointer(pointer);
729}
730COINLIBAPI void *COINLINKAGE
731Clp_getUserPointer(Clp_Simplex *model)
732{
733  return model->model_->getUserPointer();
734}
735/* Pass in Callback function */
736COINLIBAPI void COINLINKAGE
737Clp_registerCallBack(Clp_Simplex *model,
738  clp_callback userCallBack)
739{
740  // Will be copy of users one
741  delete model->handler_;
742  model->handler_ = new CMessageHandler(*(model->model_->messageHandler()));
743  model->handler_->setCallBack(userCallBack);
744  model->handler_->setModel(model);
745  model->model_->passInMessageHandler(model->handler_);
746}
747/* Unset Callback function */
748COINLIBAPI void COINLINKAGE
749Clp_clearCallBack(Clp_Simplex *model)
750{
751  delete model->handler_;
752  model->handler_ = NULL;
753}
754/* Amount of print out:
755   0 - none
756   1 - just final
757   2 - just factorizations
758   3 - as 2 plus a bit more
759   4 - verbose
760   above that 8,16,32 etc just for selective debug
761*/
762COINLIBAPI void COINLINKAGE
763Clp_setLogLevel(Clp_Simplex *model, int value)
764{
765  model->model_->setLogLevel(value);
766}
767COINLIBAPI int COINLINKAGE
768Clp_logLevel(Clp_Simplex *model)
769{
770  return model->model_->logLevel();
771}
772/* length of names (0 means no names0 */
773COINLIBAPI int COINLINKAGE
774Clp_lengthNames(Clp_Simplex *model)
775{
776  return model->model_->lengthNames();
777}
778/* Fill in array (at least lengthNames+1 long) with a row name */
779COINLIBAPI void COINLINKAGE
780Clp_rowName(Clp_Simplex *model, int iRow, char *name)
781{
782  std::string rowName = model->model_->rowName(iRow);
783  strcpy(name, rowName.c_str());
784}
785/* Fill in array (at least lengthNames+1 long) with a column name */
786COINLIBAPI void COINLINKAGE
787Clp_columnName(Clp_Simplex *model, int iColumn, char *name)
788{
789  std::string columnName = model->model_->columnName(iColumn);
790  strcpy(name, columnName.c_str());
791}
792
793/** Set row name - Nice if they are short - 8 chars or less I think */
794COINLIBAPI void COINLINKAGE Clp_setRowName(Clp_Simplex *model, int iRow, char *name)
795{
796  std::string sName = name; // Copies the memory AFAIK
797  model->model_->setRowName(iRow, sName);
798}
799/** Set column name - Nice if they are short - 8 chars or less I think */
800COINLIBAPI void COINLINKAGE Clp_setColumnName(Clp_Simplex *model, int iColumn, char *name)
801{
802  std::string sName = name; // Copies the memory AFAIK
803  model->model_->setColumnName(iColumn, sName);
804}
805
806/* General solve algorithm which can do presolve.
807   See  ClpSolve.hpp for options
808*/
809COINLIBAPI int COINLINKAGE
810Clp_initialSolve(Clp_Simplex *model)
811{
812  return model->model_->initialSolve();
813}
814/* Pass solve options. (Exception to direct analogue rule) */
815COINLIBAPI int COINLINKAGE
816Clp_initialSolveWithOptions(Clp_Simplex *model, Clp_Solve *s)
817{
818  return model->model_->initialSolve(s->options);
819}
820/* Barrier initial solve */
821COINLIBAPI int COINLINKAGE
822Clp_initialBarrierSolve(Clp_Simplex *model0)
823{
824  ClpSimplex *model = model0->model_;
825
826  return model->initialBarrierSolve();
827}
828/* Barrier initial solve */
829COINLIBAPI int COINLINKAGE
830Clp_initialBarrierNoCrossSolve(Clp_Simplex *model0)
831{
832  ClpSimplex *model = model0->model_;
833
834  return model->initialBarrierNoCrossSolve();
835}
836/* Dual initial solve */
837COINLIBAPI int COINLINKAGE
838Clp_initialDualSolve(Clp_Simplex *model)
839{
840  return model->model_->initialDualSolve();
841}
842/* Primal initial solve */
843COINLIBAPI int COINLINKAGE
844Clp_initialPrimalSolve(Clp_Simplex *model)
845{
846  return model->model_->initialPrimalSolve();
847}
848/* Dual algorithm - see ClpSimplexDual.hpp for method */
849COINLIBAPI int COINLINKAGE
850Clp_dual(Clp_Simplex *model, int ifValuesPass)
851{
852  return model->model_->dual(ifValuesPass);
853}
854/* Primal algorithm - see ClpSimplexPrimal.hpp for method */
855COINLIBAPI int COINLINKAGE
856Clp_primal(Clp_Simplex *model, int ifValuesPass)
857{
858  return model->model_->primal(ifValuesPass);
859}
860/* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */
861COINLIBAPI void COINLINKAGE
862Clp_scaling(Clp_Simplex *model, int mode)
863{
864  model->model_->scaling(mode);
865}
866/* Gets scalingFlag */
867COINLIBAPI int COINLINKAGE
868Clp_scalingFlag(Clp_Simplex *model)
869{
870  return model->model_->scalingFlag();
871}
872/* Crash - at present just aimed at dual, returns
873   -2 if dual preferred and crash basis created
874   -1 if dual preferred and all slack basis preferred
875   0 if basis going in was not all slack
876   1 if primal preferred and all slack basis preferred
877   2 if primal preferred and crash basis created.
878
879   if gap between bounds <="gap" variables can be flipped
880
881   If "pivot" is
882   0 No pivoting (so will just be choice of algorithm)
883   1 Simple pivoting e.g. gub
884   2 Mini iterations
885*/
886COINLIBAPI int COINLINKAGE
887Clp_crash(Clp_Simplex *model, double gap, int pivot)
888{
889  return model->model_->crash(gap, pivot);
890}
891/* If problem is primal feasible */
892COINLIBAPI int COINLINKAGE
893Clp_primalFeasible(Clp_Simplex *model)
894{
895  return model->model_->primalFeasible() ? 1 : 0;
896}
897/* If problem is dual feasible */
898COINLIBAPI int COINLINKAGE
899Clp_dualFeasible(Clp_Simplex *model)
900{
901  return model->model_->dualFeasible() ? 1 : 0;
902}
903/* Dual bound */
904COINLIBAPI double COINLINKAGE
905Clp_dualBound(Clp_Simplex *model)
906{
907  return model->model_->dualBound();
908}
909COINLIBAPI void COINLINKAGE
910Clp_setDualBound(Clp_Simplex *model, double value)
911{
912  model->model_->setDualBound(value);
913}
914/* Infeasibility cost */
915COINLIBAPI double COINLINKAGE
916Clp_infeasibilityCost(Clp_Simplex *model)
917{
918  return model->model_->infeasibilityCost();
919}
920COINLIBAPI void COINLINKAGE
921Clp_setInfeasibilityCost(Clp_Simplex *model, double value)
922{
923  model->model_->setInfeasibilityCost(value);
924}
925/* Perturbation:
926   50  - switch on perturbation
927   100 - auto perturb if takes too long (1.0e-6 largest nonzero)
928   101 - we are perturbed
929   102 - don't try perturbing again
930   default is 100
931   others are for playing
932*/
933COINLIBAPI int COINLINKAGE
934Clp_perturbation(Clp_Simplex *model)
935{
936  return model->model_->perturbation();
937}
938COINLIBAPI void COINLINKAGE
939Clp_setPerturbation(Clp_Simplex *model, int value)
940{
941  model->model_->setPerturbation(value);
942}
943/* Current (or last) algorithm */
944COINLIBAPI int COINLINKAGE
945Clp_algorithm(Clp_Simplex *model)
946{
947  return model->model_->algorithm();
948}
949/* Set algorithm */
950COINLIBAPI void COINLINKAGE
951Clp_setAlgorithm(Clp_Simplex *model, int value)
952{
953  model->model_->setAlgorithm(value);
954}
955/* Sum of dual infeasibilities */
956COINLIBAPI double COINLINKAGE
957Clp_sumDualInfeasibilities(Clp_Simplex *model)
958{
959  return model->model_->sumDualInfeasibilities();
960}
961/* Number of dual infeasibilities */
962COINLIBAPI int COINLINKAGE
963Clp_numberDualInfeasibilities(Clp_Simplex *model)
964{
965  return model->model_->numberDualInfeasibilities();
966}
967/* Sum of primal infeasibilities */
968COINLIBAPI double COINLINKAGE
969Clp_sumPrimalInfeasibilities(Clp_Simplex *model)
970{
971  return model->model_->sumPrimalInfeasibilities();
972}
973/* Number of primal infeasibilities */
974COINLIBAPI int COINLINKAGE
975Clp_numberPrimalInfeasibilities(Clp_Simplex *model)
976{
977  return model->model_->numberPrimalInfeasibilities();
978}
979/* Save model to file, returns 0 if success.  This is designed for
980   use outside algorithms so does not save iterating arrays etc.
981   It does not save any messaging information.
982   Does not save scaling values.
983   It does not know about all types of virtual functions.
984*/
985COINLIBAPI int COINLINKAGE
986Clp_saveModel(Clp_Simplex *model, const char *fileName)
987{
988  return model->model_->saveModel(fileName);
989}
990/* Restore model from file, returns 0 if success,
991   deletes current model */
992COINLIBAPI int COINLINKAGE
993Clp_restoreModel(Clp_Simplex *model, const char *fileName)
994{
995  return model->model_->restoreModel(fileName);
996}
997
998/* Just check solution (for external use) - sets sum of
999   infeasibilities etc */
1000COINLIBAPI void COINLINKAGE
1001Clp_checkSolution(Clp_Simplex *model)
1002{
1003  model->model_->checkSolution();
1004}
1005/* Number of rows */
1006COINLIBAPI int COINLINKAGE
1007Clp_getNumRows(Clp_Simplex *model)
1008{
1009  return model->model_->getNumRows();
1010}
1011/* Number of columns */
1012COINLIBAPI int COINLINKAGE
1013Clp_getNumCols(Clp_Simplex *model)
1014{
1015  return model->model_->getNumCols();
1016}
1017/* Number of iterations */
1018COINLIBAPI int COINLINKAGE
1019Clp_getIterationCount(Clp_Simplex *model)
1020{
1021  return model->model_->getIterationCount();
1022}
1023/* Are there a numerical difficulties? */
1024COINLIBAPI int COINLINKAGE
1025Clp_isAbandoned(Clp_Simplex *model)
1026{
1027  return model->model_->isAbandoned() ? 1 : 0;
1028}
1029/* Is optimality proven? */
1030COINLIBAPI int COINLINKAGE
1031Clp_isProvenOptimal(Clp_Simplex *model)
1032{
1033  return model->model_->isProvenOptimal() ? 1 : 0;
1034}
1035/* Is primal infeasiblity proven? */
1036COINLIBAPI int COINLINKAGE
1037Clp_isProvenPrimalInfeasible(Clp_Simplex *model)
1038{
1039  return model->model_->isProvenPrimalInfeasible() ? 1 : 0;
1040}
1041/* Is dual infeasiblity proven? */
1042COINLIBAPI int COINLINKAGE
1043Clp_isProvenDualInfeasible(Clp_Simplex *model)
1044{
1045  return model->model_->isProvenDualInfeasible() ? 1 : 0;
1046}
1047/* Is the given primal objective limit reached? */
1048COINLIBAPI int COINLINKAGE
1049Clp_isPrimalObjectiveLimitReached(Clp_Simplex *model)
1050{
1051  return model->model_->isPrimalObjectiveLimitReached() ? 1 : 0;
1052}
1053/* Is the given dual objective limit reached? */
1054COINLIBAPI int COINLINKAGE
1055Clp_isDualObjectiveLimitReached(Clp_Simplex *model)
1056{
1057  return model->model_->isDualObjectiveLimitReached() ? 1 : 0;
1058}
1059/* Iteration limit reached? */
1060COINLIBAPI int COINLINKAGE
1061Clp_isIterationLimitReached(Clp_Simplex *model)
1062{
1063  return model->model_->isIterationLimitReached() ? 1 : 0;
1064}
1065/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
1066COINLIBAPI double COINLINKAGE
1067Clp_getObjSense(Clp_Simplex *model)
1068{
1069  return model->model_->getObjSense();
1070}
1071/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
1072COINLIBAPI void COINLINKAGE
1073Clp_setObjSense(Clp_Simplex *model, double objsen)
1074{
1075  model->model_->setOptimizationDirection(objsen);
1076}
1077/* Primal row solution */
1078COINLIBAPI const double *COINLINKAGE
1079Clp_getRowActivity(Clp_Simplex *model)
1080{
1081  return model->model_->getRowActivity();
1082}
1083/* Primal column solution */
1084COINLIBAPI const double *COINLINKAGE
1085Clp_getColSolution(Clp_Simplex *model)
1086{
1087  return model->model_->getColSolution();
1088}
1089COINLIBAPI void COINLINKAGE
1090Clp_setColSolution(Clp_Simplex *model, const double *input)
1091{
1092  model->model_->setColSolution(input);
1093}
1094/* Dual row solution */
1095COINLIBAPI const double *COINLINKAGE
1096Clp_getRowPrice(Clp_Simplex *model)
1097{
1098  return model->model_->getRowPrice();
1099}
1100/* Reduced costs */
1101COINLIBAPI const double *COINLINKAGE
1102Clp_getReducedCost(Clp_Simplex *model)
1103{
1104  return model->model_->getReducedCost();
1105}
1106/* Row lower */
1107COINLIBAPI const double *COINLINKAGE
1108Clp_getRowLower(Clp_Simplex *model)
1109{
1110  return model->model_->getRowLower();
1111}
1112/* Row upper  */
1113COINLIBAPI const double *COINLINKAGE
1114Clp_getRowUpper(Clp_Simplex *model)
1115{
1116  return model->model_->getRowUpper();
1117}
1118/* Objective */
1119COINLIBAPI const double *COINLINKAGE
1120Clp_getObjCoefficients(Clp_Simplex *model)
1121{
1122  return model->model_->getObjCoefficients();
1123}
1124/* Column Lower */
1125COINLIBAPI const double *COINLINKAGE
1126Clp_getColLower(Clp_Simplex *model)
1127{
1128  return model->model_->getColLower();
1129}
1130/* Column Upper */
1131COINLIBAPI const double *COINLINKAGE
1132Clp_getColUpper(Clp_Simplex *model)
1133{
1134  return model->model_->getColUpper();
1135}
1136/* Objective value */
1137COINLIBAPI double COINLINKAGE
1138Clp_getObjValue(Clp_Simplex *model)
1139{
1140  return model->model_->getObjValue();
1141}
1142/* Get variable basis info */
1143COINLIBAPI int COINLINKAGE
1144Clp_getColumnStatus(Clp_Simplex *model, int sequence)
1145{
1146  return (int)model->model_->getColumnStatus(sequence);
1147}
1148/* Get row basis info */
1149COINLIBAPI int COINLINKAGE
1150Clp_getRowStatus(Clp_Simplex *model, int sequence)
1151{
1152  return (int)model->model_->getRowStatus(sequence);
1153}
1154/* Set variable basis info */
1155COINLIBAPI void COINLINKAGE
1156Clp_setColumnStatus(Clp_Simplex *model, int sequence, int value)
1157{
1158  if (value >= 0 && value <= 5) {
1159    model->model_->setColumnStatus(sequence, (ClpSimplex::Status)value);
1160    if (value == 3 || value == 5)
1161      model->model_->primalColumnSolution()[sequence] = model->model_->columnLower()[sequence];
1162    else if (value == 2)
1163      model->model_->primalColumnSolution()[sequence] = model->model_->columnUpper()[sequence];
1164  }
1165}
1166/* Set row basis info */
1167COINLIBAPI void COINLINKAGE
1168Clp_setRowStatus(Clp_Simplex *model, int sequence, int value)
1169{
1170  if (value >= 0 && value <= 5) {
1171    model->model_->setRowStatus(sequence, (ClpSimplex::Status)value);
1172    if (value == 3 || value == 5)
1173      model->model_->primalRowSolution()[sequence] = model->model_->rowLower()[sequence];
1174    else if (value == 2)
1175      model->model_->primalRowSolution()[sequence] = model->model_->rowUpper()[sequence];
1176  }
1177}
1178/* Small element value - elements less than this set to zero,
1179   default is 1.0e-20 */
1180COINLIBAPI double COINLINKAGE
1181Clp_getSmallElementValue(Clp_Simplex *model)
1182{
1183  return model->model_->getSmallElementValue();
1184}
1185COINLIBAPI void COINLINKAGE
1186Clp_setSmallElementValue(Clp_Simplex *model, double value)
1187{
1188  model->model_->setSmallElementValue(value);
1189}
1190/* Print model */
1191COINLIBAPI void COINLINKAGE
1192Clp_printModel(Clp_Simplex *model, const char *prefix)
1193{
1194  ClpSimplex *clp_simplex = model->model_;
1195  int numrows = clp_simplex->numberRows();
1196  int numcols = clp_simplex->numberColumns();
1197  CoinBigIndex numelem = clp_simplex->getNumElements();
1198  const CoinBigIndex *start = clp_simplex->matrix()->getVectorStarts();
1199  const int *length = clp_simplex->matrix()->getVectorLengths();
1200  const int *index = clp_simplex->matrix()->getIndices();
1201  const double *value = clp_simplex->matrix()->getElements();
1202  const double *collb = model->model_->columnLower();
1203  const double *colub = model->model_->columnUpper();
1204  const double *obj = model->model_->objective();
1205  const double *rowlb = model->model_->rowLower();
1206  const double *rowub = model->model_->rowUpper();
1207  printf("%s numcols = %i, numrows = %i, numelem = %i\n",
1208    prefix, numcols, numrows, numelem);
1209  printf("%s model = %p, start = %p, index = %p, value = %p\n",
1210    prefix, reinterpret_cast< const void * >(model), reinterpret_cast< const void * >(start), reinterpret_cast< const void * >(index), reinterpret_cast< const void * >(value));
1211  clp_simplex->matrix()->dumpMatrix(NULL);
1212  {
1213    int i;
1214    for (i = 0; i <= numcols; i++)
1215      printf("%s start[%i] = %i\n", prefix, i, start[i]);
1216    // may be gaps
1217    for (i = 0; i < numcols; i++) {
1218      for (CoinBigIndex j = start[i]; j < start[i] + length[i]; j++)
1219        printf("%s index[%i] = %i, value[%i] = %g\n",
1220          prefix, j, index[j], j, value[j]);
1221    }
1222  }
1223
1224  printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
1225    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));
1226  printf("%s optimization direction = %g\n", prefix, Clp_optimizationDirection(model));
1227  printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
1228  {
1229    int i;
1230    for (i = 0; i < numcols; i++)
1231      printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
1232        prefix, i, collb[i], i, colub[i], i, obj[i]);
1233    for (i = 0; i < numrows; i++)
1234      printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
1235        prefix, i, rowlb[i], i, rowub[i]);
1236  }
1237}
1238
1239#ifndef SLIM_CLP
1240/** Solve the problem with the idiot code */
1241/* tryhard values:
1242   tryhard & 7:
1243      0: NOT lightweight, 105 iterations within a pass (when mu stays fixed)
1244      1: lightweight, but focus more on optimality (mu is high)
1245         (23 iters in a pass)
1246      2: lightweight, but focus more on feasibility (11 iters in a pass)
1247      3: lightweight, but focus more on feasibility (23 iters in a pass, so it
1248         goes closer to opt than option 2)
1249   tryhard >> 3:
1250      number of passes, the larger the number the closer it gets to optimality
1251*/
1252COINLIBAPI void COINLINKAGE
1253Clp_idiot(Clp_Simplex *model, int tryhard)
1254{
1255  ClpSimplex *clp = model->model_;
1256  Idiot info(*clp);
1257  int numberpass = tryhard >> 3;
1258  int lightweight = tryhard & 7;
1259  info.setLightweight(lightweight);
1260  info.crash(numberpass, clp->messageHandler(), clp->messagesPointer(), false);
1261}
1262#endif
1263
1264COINLIBAPI Clp_Solve *COINLINKAGE
1265ClpSolve_new()
1266{
1267  return new Clp_Solve();
1268}
1269
1270COINLIBAPI void COINLINKAGE
1271ClpSolve_delete(Clp_Solve *solve)
1272{
1273  delete solve;
1274}
1275
1276// space- and error-saving macros
1277#define ClpSolveGetIntProperty(prop) \
1278  COINLIBAPI int COINLINKAGE         \
1279    ClpSolve_##prop(Clp_Solve *s)    \
1280  {                                  \
1281    return s->options.prop();        \
1282  }
1283
1284#define ClpSolveSetIntProperty(prop)       \
1285  COINLIBAPI void COINLINKAGE              \
1286    ClpSolve_##prop(Clp_Solve *s, int val) \
1287  {                                        \
1288    s->options.prop(val);                  \
1289  }
1290
1291COINLIBAPI void COINLINKAGE
1292ClpSolve_setSpecialOption(Clp_Solve *s, int which, int value, int extraInfo)
1293{
1294  s->options.setSpecialOption(which, value, extraInfo);
1295}
1296
1297COINLIBAPI int COINLINKAGE
1298ClpSolve_getSpecialOption(Clp_Solve *s, int which)
1299{
1300  return s->options.getSpecialOption(which);
1301}
1302
1303COINLIBAPI void COINLINKAGE
1304ClpSolve_setSolveType(Clp_Solve *s, int method, int extraInfo)
1305{
1306  s->options.setSolveType(static_cast< ClpSolve::SolveType >(method), extraInfo);
1307}
1308
1309ClpSolveGetIntProperty(getSolveType)
1310
1311  COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve *s, int amount, int extraInfo)
1312{
1313  s->options.setPresolveType(static_cast< ClpSolve::PresolveType >(amount), extraInfo);
1314}
1315
1316ClpSolveGetIntProperty(getPresolveType)
1317
1318  ClpSolveGetIntProperty(getPresolvePasses)
1319
1320    COINLIBAPI int COINLINKAGE
1321  ClpSolve_getExtraInfo(Clp_Solve *s, int which)
1322{
1323  return s->options.getExtraInfo(which);
1324}
1325
1326ClpSolveSetIntProperty(setInfeasibleReturn)
1327  ClpSolveGetIntProperty(infeasibleReturn)
1328
1329    ClpSolveGetIntProperty(doDual)
1330      ClpSolveSetIntProperty(setDoDual)
1331
1332        ClpSolveGetIntProperty(doSingleton)
1333          ClpSolveSetIntProperty(setDoSingleton)
1334
1335            ClpSolveGetIntProperty(doDoubleton)
1336              ClpSolveSetIntProperty(setDoDoubleton)
1337
1338                ClpSolveGetIntProperty(doTripleton)
1339                  ClpSolveSetIntProperty(setDoTripleton)
1340
1341                    ClpSolveGetIntProperty(doTighten)
1342                      ClpSolveSetIntProperty(setDoTighten)
1343
1344                        ClpSolveGetIntProperty(doForcing)
1345                          ClpSolveSetIntProperty(setDoForcing)
1346
1347                            ClpSolveGetIntProperty(doImpliedFree)
1348                              ClpSolveSetIntProperty(setDoImpliedFree)
1349
1350                                ClpSolveGetIntProperty(doDupcol)
1351                                  ClpSolveSetIntProperty(setDoDupcol)
1352
1353                                    ClpSolveGetIntProperty(doDuprow)
1354                                      ClpSolveSetIntProperty(setDoDuprow)
1355
1356                                        ClpSolveGetIntProperty(doSingletonColumn)
1357                                          ClpSolveSetIntProperty(setDoSingletonColumn)
1358
1359                                            ClpSolveGetIntProperty(presolveActions)
1360                                              ClpSolveSetIntProperty(setPresolveActions)
1361
1362                                                ClpSolveGetIntProperty(substitution)
1363                                                  ClpSolveSetIntProperty(setSubstitution)
1364
1365#if defined(__MWERKS__)
1366#pragma export off
1367#endif
1368
1369  /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1370*/
Note: See TracBrowser for help on using the repository browser.