source: stable/1.15/Clp/src/Clp_C_Interface.cpp @ 2017

Last change on this file since 2017 was 2017, checked in by stefan, 6 years ago

add method Clp_freeRay to C interface to free a ray given by Clp_infeasibility/unboundedRay

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