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

Last change on this file since 2385 was 2385, checked in by unxusr, 4 months ago

formatting

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