1// $Id: Clp_C_Interface.cpp 1753 2011-06-19 16:27:26Z 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() override;
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 override ;
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 delete [] on these arrays. */
641COINLIBAPI double * COINLINKAGE
642Clp_infeasibilityRay(Clp_Simplex * model)
643{
644 return model->model_->infeasibilityRay();
645}
646COINLIBAPI double * COINLINKAGE
647Clp_unboundedRay(Clp_Simplex * model)
648{
649 return model->model_->unboundedRay();
650}
651/* See if status array exists (partly for OsiClp) */
652COINLIBAPI int COINLINKAGE
653Clp_statusExists(Clp_Simplex * model)
654{
655 return model->model_->statusExists() ? 1 : 0;
656}
657/* Return address of status array (char[numberRows+numberColumns]) */
658COINLIBAPI unsigned char * COINLINKAGE
659Clp_statusArray(Clp_Simplex * model)
660{
661 return model->model_->statusArray();
662}
663/* Copy in status vector */
664COINLIBAPI void COINLINKAGE
665Clp_copyinStatus(Clp_Simplex * model, const unsigned char * statusArray)
666{
667 model->model_->copyinStatus(statusArray);
668}
669
670/* User pointer for whatever reason */
671COINLIBAPI void COINLINKAGE
672Clp_setUserPointer (Clp_Simplex * model, void * pointer)
673{
674 model->model_->setUserPointer(pointer);
675}
676COINLIBAPI void * COINLINKAGE
677Clp_getUserPointer (Clp_Simplex * model)
678{
679 return model->model_->getUserPointer();
680}
681/* Pass in Callback function */
682COINLIBAPI void COINLINKAGE
683Clp_registerCallBack(Clp_Simplex * model,
684 clp_callback userCallBack)
685{
686 // Will be copy of users one
687 delete model->handler_;
688 model->handler_ = new CMessageHandler(*(model->model_->messageHandler()));
689 model->handler_->setCallBack(userCallBack);
690 model->handler_->setModel(model);
691 model->model_->passInMessageHandler(model->handler_);
692}
693/* Unset Callback function */
694COINLIBAPI void COINLINKAGE
695Clp_clearCallBack(Clp_Simplex * model)
696{
697 delete model->handler_;
698 model->handler_ = NULL;
699}
700/* Amount of print out:
701 0 - none
702 1 - just final
703 2 - just factorizations
704 3 - as 2 plus a bit more
705 4 - verbose
706 above that 8,16,32 etc just for selective debug
707*/
708COINLIBAPI void COINLINKAGE
709Clp_setLogLevel(Clp_Simplex * model, int value)
710{
711 model->model_->setLogLevel(value);
712}
713COINLIBAPI int COINLINKAGE
714Clp_logLevel(Clp_Simplex * model)
715{
716 return model->model_->logLevel();
717}
718/* length of names (0 means no names0 */
719COINLIBAPI int COINLINKAGE
720Clp_lengthNames(Clp_Simplex * model)
721{
722 return model->model_->lengthNames();
723}
724/* Fill in array (at least lengthNames+1 long) with a row name */
725COINLIBAPI void COINLINKAGE
726Clp_rowName(Clp_Simplex * model, int iRow, char * name)
727{
728 std::string rowName = model->model_->rowName(iRow);
729 strcpy(name, rowName.c_str());
730}
731/* Fill in array (at least lengthNames+1 long) with a column name */
732COINLIBAPI void COINLINKAGE
733Clp_columnName(Clp_Simplex * model, int iColumn, char * name)
734{
735 std::string columnName = model->model_->columnName(iColumn);
736 strcpy(name, columnName.c_str());
737}
738
739/* General solve algorithm which can do presolve.
740 See ClpSolve.hpp for options
741*/
742COINLIBAPI int COINLINKAGE
743Clp_initialSolve(Clp_Simplex * model)
744{
745 return model->model_->initialSolve();
746}
747/* Barrier initial solve */
748COINLIBAPI int COINLINKAGE
749Clp_initialBarrierSolve(Clp_Simplex * model0)
750{
751 ClpSimplex *model = model0->model_;
752
753 return model->initialBarrierSolve();
754
755}
756/* Barrier initial solve */
757COINLIBAPI int COINLINKAGE
758Clp_initialBarrierNoCrossSolve(Clp_Simplex * model0)
759{
760 ClpSimplex *model = model0->model_;
761
762 return model->initialBarrierNoCrossSolve();
763
764}
765/* Dual initial solve */
766COINLIBAPI int COINLINKAGE
767Clp_initialDualSolve(Clp_Simplex * model)
768{
769 return model->model_->initialDualSolve();
770}
771/* Primal initial solve */
772COINLIBAPI int COINLINKAGE
773Clp_initialPrimalSolve(Clp_Simplex * model)
774{
775 return model->model_->initialPrimalSolve();
776}
777/* Dual algorithm - see ClpSimplexDual.hpp for method */
778COINLIBAPI int COINLINKAGE
779Clp_dual(Clp_Simplex * model, int ifValuesPass)
780{
781 return model->model_->dual(ifValuesPass);
782}
783/* Primal algorithm - see ClpSimplexPrimal.hpp for method */
784COINLIBAPI int COINLINKAGE
785Clp_primal(Clp_Simplex * model, int ifValuesPass)
786{
787 return model->model_->primal(ifValuesPass);
788}
789/* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */
790COINLIBAPI void COINLINKAGE
791Clp_scaling(Clp_Simplex * model, int mode)
792{
793 model->model_->scaling(mode);
794}
795/* Gets scalingFlag */
796COINLIBAPI int COINLINKAGE
797Clp_scalingFlag(Clp_Simplex * model)
798{
799 return model->model_->scalingFlag();
800}
801/* Crash - at present just aimed at dual, returns
802 -2 if dual preferred and crash basis created
803 -1 if dual preferred and all slack basis preferred
804 0 if basis going in was not all slack
805 1 if primal preferred and all slack basis preferred
806 2 if primal preferred and crash basis created.
807
808 if gap between bounds <="gap" variables can be flipped
809
810 If "pivot" is
811 0 No pivoting (so will just be choice of algorithm)
812 1 Simple pivoting e.g. gub
813 2 Mini iterations
814*/
815COINLIBAPI int COINLINKAGE
816Clp_crash(Clp_Simplex * model, double gap, int pivot)
817{
818 return model->model_->crash(gap, pivot);
819}
820/* If problem is primal feasible */
821COINLIBAPI int COINLINKAGE
822Clp_primalFeasible(Clp_Simplex * model)
823{
824 return model->model_->primalFeasible() ? 1 : 0;
825}
826/* If problem is dual feasible */
827COINLIBAPI int COINLINKAGE
828Clp_dualFeasible(Clp_Simplex * model)
829{
830 return model->model_->dualFeasible() ? 1 : 0;
831}
832/* Dual bound */
833COINLIBAPI double COINLINKAGE
834Clp_dualBound(Clp_Simplex * model)
835{
836 return model->model_->dualBound();
837}
838COINLIBAPI void COINLINKAGE
839Clp_setDualBound(Clp_Simplex * model, double value)
840{
841 model->model_->setDualBound(value);
842}
843/* Infeasibility cost */
844COINLIBAPI double COINLINKAGE
845Clp_infeasibilityCost(Clp_Simplex * model)
846{
847 return model->model_->infeasibilityCost();
848}
849COINLIBAPI void COINLINKAGE
850Clp_setInfeasibilityCost(Clp_Simplex * model, double value)
851{
852 model->model_->setInfeasibilityCost(value);
853}
854/* Perturbation:
855 50 - switch on perturbation
856 100 - auto perturb if takes too long (1.0e-6 largest nonzero)
857 101 - we are perturbed
858 102 - don't try perturbing again
859 default is 100
860 others are for playing
861*/
862COINLIBAPI int COINLINKAGE
863Clp_perturbation(Clp_Simplex * model)
864{
865 return model->model_->perturbation();
866}
867COINLIBAPI void COINLINKAGE
868Clp_setPerturbation(Clp_Simplex * model, int value)
869{
870 model->model_->setPerturbation(value);
871}
872/* Current (or last) algorithm */
873COINLIBAPI int COINLINKAGE
874Clp_algorithm(Clp_Simplex * model)
875{
876 return model->model_->algorithm();
877}
878/* Set algorithm */
879COINLIBAPI void COINLINKAGE
880Clp_setAlgorithm(Clp_Simplex * model, int value)
881{
882 model->model_->setAlgorithm(value);
883}
884/* Sum of dual infeasibilities */
885COINLIBAPI double COINLINKAGE
886Clp_sumDualInfeasibilities(Clp_Simplex * model)
887{
888 return model->model_->sumDualInfeasibilities();
889}
890/* Number of dual infeasibilities */
891COINLIBAPI int COINLINKAGE
892Clp_numberDualInfeasibilities(Clp_Simplex * model)
893{
894 return model->model_->numberDualInfeasibilities();
895}
896/* Sum of primal infeasibilities */
897COINLIBAPI double COINLINKAGE
898Clp_sumPrimalInfeasibilities(Clp_Simplex * model)
899{
900 return model->model_->sumPrimalInfeasibilities();
901}
902/* Number of primal infeasibilities */
903COINLIBAPI int COINLINKAGE
904Clp_numberPrimalInfeasibilities(Clp_Simplex * model)
905{
906 return model->model_->numberPrimalInfeasibilities();
907}
908/* Save model to file, returns 0 if success. This is designed for
909 use outside algorithms so does not save iterating arrays etc.
910 It does not save any messaging information.
911 Does not save scaling values.
912 It does not know about all types of virtual functions.
913*/
914COINLIBAPI int COINLINKAGE
915Clp_saveModel(Clp_Simplex * model, const char * fileName)
916{
917 return model->model_->saveModel(fileName);
918}
919/* Restore model from file, returns 0 if success,
920 deletes current model */
921COINLIBAPI int COINLINKAGE
922Clp_restoreModel(Clp_Simplex * model, const char * fileName)
923{
924 return model->model_->restoreModel(fileName);
925}
926
927/* Just check solution (for external use) - sets sum of
928 infeasibilities etc */
929COINLIBAPI void COINLINKAGE
930Clp_checkSolution(Clp_Simplex * model)
931{
932 model->model_->checkSolution();
933}
934/* Number of rows */
935COINLIBAPI int COINLINKAGE
936Clp_getNumRows(Clp_Simplex * model)
937{
938 return model->model_->getNumRows();
939}
940/* Number of columns */
941COINLIBAPI int COINLINKAGE
942Clp_getNumCols(Clp_Simplex * model)
943{
944 return model->model_->getNumCols();
945}
946/* Number of iterations */
947COINLIBAPI int COINLINKAGE
948Clp_getIterationCount(Clp_Simplex * model)
949{
950 return model->model_->getIterationCount();
951}
952/* Are there a numerical difficulties? */
953COINLIBAPI int COINLINKAGE
954Clp_isAbandoned(Clp_Simplex * model)
955{
956 return model->model_->isAbandoned() ? 1 : 0;
957}
958/* Is optimality proven? */
959COINLIBAPI int COINLINKAGE
960Clp_isProvenOptimal(Clp_Simplex * model)
961{
962 return model->model_->isProvenOptimal() ? 1 : 0;
963}
964/* Is primal infeasiblity proven? */
965COINLIBAPI int COINLINKAGE
966Clp_isProvenPrimalInfeasible(Clp_Simplex * model)
967{
968 return model->model_->isProvenPrimalInfeasible() ? 1 : 0;
969}
970/* Is dual infeasiblity proven? */
971COINLIBAPI int COINLINKAGE
972Clp_isProvenDualInfeasible(Clp_Simplex * model)
973{
974 return model->model_->isProvenDualInfeasible() ? 1 : 0;
975}
976/* Is the given primal objective limit reached? */
977COINLIBAPI int COINLINKAGE
978Clp_isPrimalObjectiveLimitReached(Clp_Simplex * model)
979{
980 return model->model_->isPrimalObjectiveLimitReached() ? 1 : 0;
981}
982/* Is the given dual objective limit reached? */
983COINLIBAPI int COINLINKAGE
984Clp_isDualObjectiveLimitReached(Clp_Simplex * model)
985{
986 return model->model_->isDualObjectiveLimitReached() ? 1 : 0;
987}
988/* Iteration limit reached? */
989COINLIBAPI int COINLINKAGE
990Clp_isIterationLimitReached(Clp_Simplex * model)
991{
992 return model->model_->isIterationLimitReached() ? 1 : 0;
993}
994/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
995COINLIBAPI double COINLINKAGE
996Clp_getObjSense(Clp_Simplex * model)
997{
998 return model->model_->getObjSense();
999}
1000/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */
1001COINLIBAPI void COINLINKAGE
1002Clp_setObjSense(Clp_Simplex * model, double objsen)
1003{
1004 model->model_->setOptimizationDirection(objsen);
1005}
1006/* Primal row solution */
1007COINLIBAPI const double * COINLINKAGE
1008Clp_getRowActivity(Clp_Simplex * model)
1009{
1010 return model->model_->getRowActivity();
1011}
1012/* Primal column solution */
1013COINLIBAPI const double * COINLINKAGE
1014Clp_getColSolution(Clp_Simplex * model)
1015{
1016 return model->model_->getColSolution();
1017}
1018COINLIBAPI void COINLINKAGE
1019Clp_setColSolution(Clp_Simplex * model, const double * input)
1020{
1021 model->model_->setColSolution(input);
1022}
1023/* Dual row solution */
1024COINLIBAPI const double * COINLINKAGE
1025Clp_getRowPrice(Clp_Simplex * model)
1026{
1027 return model->model_->getRowPrice();
1028}
1029/* Reduced costs */
1030COINLIBAPI const double * COINLINKAGE
1031Clp_getReducedCost(Clp_Simplex * model)
1032{
1033 return model->model_->getReducedCost();
1034}
1035/* Row lower */
1036COINLIBAPI const double* COINLINKAGE
1037Clp_getRowLower(Clp_Simplex * model)
1038{
1039 return model->model_->getRowLower();
1040}
1041/* Row upper */
1042COINLIBAPI const double* COINLINKAGE
1043Clp_getRowUpper(Clp_Simplex * model)
1044{
1045 return model->model_->getRowUpper();
1046}
1047/* Objective */
1048COINLIBAPI const double * COINLINKAGE
1049Clp_getObjCoefficients(Clp_Simplex * model)
1050{
1051 return model->model_->getObjCoefficients();
1052}
1053/* Column Lower */
1054COINLIBAPI const double * COINLINKAGE
1055Clp_getColLower(Clp_Simplex * model)
1056{
1057 return model->model_->getColLower();
1058}
1059/* Column Upper */
1060COINLIBAPI const double * COINLINKAGE
1061Clp_getColUpper(Clp_Simplex * model)
1062{
1063 return model->model_->getColUpper();
1064}
1065/* Objective value */
1066COINLIBAPI double COINLINKAGE
1067Clp_getObjValue(Clp_Simplex * model)
1068{
1069 return model->model_->getObjValue();
1070}
1071/* Get variable basis info */
1072COINLIBAPI int COINLINKAGE
1073Clp_getColumnStatus(Clp_Simplex * model, int sequence)
1074{
1075 return (int) model->model_->getColumnStatus(sequence);
1076}
1077/* Get row basis info */
1078COINLIBAPI int COINLINKAGE
1079Clp_getRowStatus(Clp_Simplex * model, int sequence)
1080{
1081 return (int) model->model_->getRowStatus(sequence);
1082}
1083/* Set variable basis info */
1084COINLIBAPI void COINLINKAGE
1085Clp_setColumnStatus(Clp_Simplex * model, int sequence, int value)
1086{
1087 if (value >= 0 && value <= 5) {
1088 model->model_->setColumnStatus(sequence, (ClpSimplex::Status) value );
1089 if (value == 3 || value == 5)
1090 model->model_->primalColumnSolution()[sequence] =
1091 model->model_->columnLower()[sequence];
1092 else if (value == 2)
1093 model->model_->primalColumnSolution()[sequence] =
1094 model->model_->columnUpper()[sequence];
1095 }
1096}
1097/* Set row basis info */
1098COINLIBAPI void COINLINKAGE
1099Clp_setRowStatus(Clp_Simplex * model, int sequence, int value)
1100{
1101 if (value >= 0 && value <= 5) {
1102 model->model_->setRowStatus(sequence, (ClpSimplex::Status) value );
1103 if (value == 3 || value == 5)
1104 model->model_->primalRowSolution()[sequence] =
1105 model->model_->rowLower()[sequence];
1106 else if (value == 2)
1107 model->model_->primalRowSolution()[sequence] =
1108 model->model_->rowUpper()[sequence];
1109 }
1110}
1111/* Small element value - elements less than this set to zero,
1112 default is 1.0e-20 */
1113COINLIBAPI double COINLINKAGE
1114Clp_getSmallElementValue(Clp_Simplex * model)
1115{
1116 return model->model_->getSmallElementValue();
1117}
1118COINLIBAPI void COINLINKAGE
1119Clp_setSmallElementValue(Clp_Simplex * model, double value)
1120{
1121 model->model_->setSmallElementValue(value);
1122}
1123/* Print model */
1124COINLIBAPI void COINLINKAGE
1125Clp_printModel(Clp_Simplex * model, const char * prefix)
1126{
1127 ClpSimplex *clp_simplex = model->model_;
1128 int numrows = clp_simplex->numberRows();
1129 int numcols = clp_simplex->numberColumns();
1130 int numelem = clp_simplex->getNumElements();
1131 const CoinBigIndex *start = clp_simplex->matrix()->getVectorStarts();
1132 const int *index = clp_simplex->matrix()->getIndices();
1133 const double *value = clp_simplex->matrix()->getElements();
1134 const double *collb = model->model_->columnLower();
1135 const double *colub = model->model_->columnUpper();
1136 const double *obj = model->model_->objective();
1137 const double *rowlb = model->model_->rowLower();
1138 const double *rowub = model->model_->rowUpper();
1139 printf("%s numcols = %i, numrows = %i, numelem = %i\n",
1140 prefix, numcols, numrows, numelem);
1141 printf("%s model = %p, start = %p, index = %p, value = %p\n",
1142 prefix, reinterpret_cast<const void *>(model), reinterpret_cast<const void *>(start), reinterpret_cast<const void *>(index), reinterpret_cast<const void *>(value));
1143 clp_simplex->matrix()->dumpMatrix(NULL);
1144 {
1145 int i;
1146 for (i = 0; i <= numcols; i++)
1147 printf("%s start[%i] = %i\n", prefix, i, start[i]);
1148 for (i = 0; i < numelem; i++)
1149 printf("%s index[%i] = %i, value[%i] = %g\n",
1150 prefix, i, index[i], i, value[i]);
1151 }
1152
1153 printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
1154 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));
1155 printf("%s optimization direction = %g\n", prefix, Clp_optimizationDirection(model));
1156 printf(" (1 - minimize, -1 - maximize, 0 - ignore)\n");
1157 {
1158 int i;
1159 for (i = 0; i < numcols; i++)
1160 printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
1161 prefix, i, collb[i], i, colub[i], i, obj[i]);
1162 for (i = 0; i < numrows; i++)
1163 printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
1164 prefix, i, rowlb[i], i, rowub[i]);
1165 }
1166}
1167
1168#ifndef SLIM_CLP
1169/** Solve the problem with the idiot code */
1170/* tryhard values:
1171 tryhard & 7:
1172 0: NOT lightweight, 105 iterations within a pass (when mu stays fixed)
1173 1: lightweight, but focus more on optimality (mu is high)
1174 (23 iters in a pass)
1175 2: lightweight, but focus more on feasibility (11 iters in a pass)
1176 3: lightweight, but focus more on feasibility (23 iters in a pass, so it
1177 goes closer to opt than option 2)
1178 tryhard >> 3:
1179 number of passes, the larger the number the closer it gets to optimality
1180*/
1181COINLIBAPI void COINLINKAGE
1182Clp_idiot(Clp_Simplex * model, int tryhard)
1183{
1184 ClpSimplex *clp = model->model_;
1185 Idiot info(*clp);
1186 int numberpass = tryhard >> 3;
1187 int lightweight = tryhard & 7;
1188 info.setLightweight(lightweight);
1189 info.crash(numberpass, clp->messageHandler(), clp->messagesPointer(), false);
1190}
1191#endif
1192
1193#if defined(__MWERKS__)
1194#pragma export off
1195#endif
1196