My Project
OSBonminSolver.cpp
Go to the documentation of this file.
1/* $Id$ */
17
18#include <iostream>
19
20#include "OSBonminSolver.h"
21#include "OSGeneral.h"
22#include "OSOutput.h"
23#include "OSParameters.h"
24#include "OSMathUtil.h"
25#include "CoinFinite.hpp"
26#include "CoinTime.hpp"
27#include "BonOsiTMINLPInterface.hpp"
28#include "BonTMINLP.hpp"
29
30using namespace Bonmin;
31using namespace Ipopt;
32
33using std::endl;
34using std::ostringstream;
35
37{
38 osrlwriter = new OSrLWriter();
39 osresult = new OSResult();
40 m_osilreader = NULL;
41 m_osolreader = NULL;
42 bonminErrorMsg = "";
43}
44
46{
47#ifndef NDEBUG
48 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "inside BonminSolver destructor\n");
49#endif
50 if(m_osilreader != NULL) delete m_osilreader;
51 m_osilreader = NULL;
52 if(m_osolreader != NULL) delete m_osolreader;
53 m_osolreader = NULL;
54
55 if(osrlwriter != NULL )delete osrlwriter;
56 osrlwriter = NULL;
57 if(osresult != NULL )
58 {
59 delete osresult;
60 osresult = NULL;
61 }
62#ifndef NDEBUG
63 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "leaving BonminSolver destructor\n");
64#endif
65}
66
67
68bool BonminProblem::get_variables_types(Index n, VariableType* var_types)
69{
70 int i = 0;
71 char *varType;
72 varType = osinstance->getVariableTypes();
73 n = osinstance->getVariableNumber();
74 for(i = 0; i < n; i++)
75 {
76 if( varType[i] == 'B')
77 {
78 var_types[i] = BINARY;
79 }
80 else
81 {
82 if( varType[i] == 'I')
83 {
84 var_types[i] = INTEGER;
85 }
86 else
87 {
88 if( varType[i] == 'C')
89 {
90 var_types[i] = CONTINUOUS;
91 }
92 else
93 {
94 throw ErrorClass("variable type not yet implemented");
95 }
96 }
97 }
98 }
99 return true;
100}
101
102
103bool BonminProblem::get_variables_linearity(Index n, Ipopt::TNLP::LinearityType* var_types)
104{
105 std::ostringstream outStr;
106 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "Initialize Nonlinear Structures\n");
107 try
108 {
109 osinstance->initForAlgDiff( );
110 }
111 catch(const ErrorClass& eclass)
112 {
113 bonminErrorMsg = eclass.errormsg;
114 throw;
115 }
121 std::map<int, int> varIndexMap;
122 std::map<int, int>::iterator posVarIndexMap;
123 varIndexMap = osinstance->getAllNonlinearVariablesIndexMap( );
124 /* first make all continuous */
125
126 int i;
127
128 for(i = 0; i < n; i++)
129 {
130 var_types[ i] = Ipopt::TNLP::LINEAR;
131 }
136 outStr.str("");
137 outStr.clear();
138 for(posVarIndexMap = varIndexMap.begin(); posVarIndexMap != varIndexMap.end(); ++posVarIndexMap)
139 {
140 outStr << "Variable Index = " << posVarIndexMap->first << std::endl ;
141 var_types[ posVarIndexMap->first] = Ipopt::TNLP::NON_LINEAR;
142 }
143 outStr << "Number of nonlinear variables = " << varIndexMap.size() << std::endl;
145
146 return true;
147}
148
149bool BonminProblem::get_constraints_linearity(Index m, Ipopt::TNLP::LinearityType* const_types)
150{
151 std::ostringstream outStr;
152 int i;
153
154 for(i = 0; i < m; i++)
155 {
156 const_types[ i] = Ipopt::TNLP::LINEAR;
157 }
158
159 int mm = osinstance->getNumberOfNonlinearExpressionTreeModIndexes();
160
161 outStr.str("");
162 outStr.clear();
163 for(i = 0; i < mm; i++)
164 {
165 if(osinstance->getNonlinearExpressionTreeModIndexes()[ i] >= 0)
166 {
167 outStr << osinstance->getNonlinearExpressionTreeModIndexes()[ i] << std::endl;
168 const_types[ osinstance->getNonlinearExpressionTreeModIndexes()[ i] ] = Ipopt::TNLP::NON_LINEAR;
169 }
170 }
172
173 return true;
174}
175
176// returns the size of the problem
177bool BonminProblem::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
178 Index& nnz_h_lag, TNLP::IndexStyleEnum& index_style)
179{
180 std::ostringstream outStr;
181 //if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Bonmin NEEDS AN OBJECTIVE FUNCTION");
182 // number of variables
183 n = osinstance->getVariableNumber();
184 // number of constraints
185 m = osinstance->getConstraintNumber();
186#ifndef NDEBUG
187 outStr.str("");
188 outStr.clear();
189 outStr << "Bonmin number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << n << endl;
190 outStr << "Bonmin number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << m << endl;
192#endif
193 try
194 {
195 osinstance->initForAlgDiff( );
196 }
197 catch(const ErrorClass& eclass)
198 {
199 bonminErrorMsg = eclass.errormsg;
200 throw;
201 }
202 // use the OS Expression tree for function evaluations instead of CppAD
203 osinstance->bUseExpTreeForFunEval = true;
204 SparseJacobianMatrix *sparseJacobian = NULL;
205 try
206 {
207 sparseJacobian = osinstance->getJacobianSparsityPattern();
208 }
209 catch(const ErrorClass& eclass)
210 {
211 bonminErrorMsg = eclass.errormsg;
212 throw;
213 }
214 nnz_jac_g = sparseJacobian->valueSize;
215#ifndef NDEBUG
216 outStr.str("");
217 outStr.clear();
218 outStr << "nnz_jac_g !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_jac_g << endl;
220#endif
221 // nonzeros in upper hessian
222
223 if( (osinstance->getNumberOfNonlinearExpressions() == 0) && (osinstance->getNumberOfQuadraticTerms() == 0) )
224 {
225 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_warning, "This is a linear program\n");
226 nnz_h_lag = 0;
227 }
228 else
229 {
230 SparseHessianMatrix *sparseHessian = osinstance->getLagrangianHessianSparsityPattern();
231 nnz_h_lag = sparseHessian->hessDimension;
232 }
233#ifndef NDEBUG
234 outStr.str("");
235 outStr.clear();
236 outStr << "nnz_h_lag !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_h_lag << endl;
238#endif
239 // use the C style indexing (0-based)
240 index_style = TNLP::C_STYLE;
241
242 return true;
243}//get_nlp_info
244
245
246bool BonminProblem::get_bounds_info(Index n, Number* x_l, Number* x_u,
247 Index m, Number* g_l, Number* g_u)
248{
249 std::ostringstream outStr;
250 int i;
251
252 double * mdVarLB = osinstance->getVariableLowerBounds();
253 // variables upper bounds
254 double * mdVarUB = osinstance->getVariableUpperBounds();
255
256 for(i = 0; i < n; i++)
257 {
258 x_l[ i] = mdVarLB[ i];
259 x_u[ i] = mdVarUB[ i];
260#ifndef NDEBUG
261 outStr.str("");
262 outStr.clear();
263 outStr << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
264 outStr << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
266#endif
267 }
268 // Bonmin interprets any number greater than nlp_upper_bound_inf as
269 // infinity. The default value of nlp_upper_bound_inf and nlp_lower_bound_inf
270 // is 1e19 and can be changed through bonmin options.
271 // e.g. g_u[0] = 2e19;
272
273 //constraint lower bounds
274 double * mdConLB = osinstance->getConstraintLowerBounds();
275 //constraint upper bounds
276 double * mdConUB = osinstance->getConstraintUpperBounds();
277
278 for(int i = 0; i < m; i++)
279 {
280 g_l[ i] = mdConLB[ i];
281 g_u[ i] = mdConUB[ i];
282#ifndef NDEBUG
283 outStr.str("");
284 outStr.clear();
285 outStr << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_l[i] << endl;
286 outStr << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_u[i] << endl;
288#endif
289 }
290 return true;
291}//get_bounds_info
292
293
294// returns the initial point for the problem
295bool BonminProblem::get_starting_point(Index n, bool init_x, Number* x,
296 bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda,
297 Number* lambda)
298{
299 std::ostringstream outStr;
300 // Here, we assume we only have starting values for x, if you code
301 // your own NLP, you can provide starting values for the dual variables
302 // if you wish
303 assert(init_x == true);
304 assert(init_z == false);
305 assert(init_lambda == false);
306 int i, m1, n1;
307
308
309#ifndef NDEBUG
311 "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!!\n");
312#endif
313
314 //now set initial values
315#ifndef NDEBUG
317 "get number of initial values !!!!!!!!!!!!!!!!!!!!!!!!!!\n");
318#endif
319 int k;
320 if (osoption != NULL)
321 m1 = osoption->getNumberOfInitVarValues();
322 else
323 m1 = 0;
324#ifndef NDEBUG
325 outStr.str("");
326 outStr.clear();
327 outStr << "number of variables initialed: " << m1 << endl;
329#endif
330
331 n1 = osinstance->getVariableNumber();
332 bool* initialed;
333 initialed = new bool[n1];
334#ifndef NDEBUG
335 outStr.str("");
336 outStr.clear();
337 outStr << "number of variables in total: " << n1 << endl;
339#endif
340
341
342 for(k = 0; k < n1; k++)
343 initialed[k] = false;
344
345 if (m1 > 0)
346 {
347#ifndef NDEBUG
349#endif
350
351 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
352#ifndef NDEBUG
354#endif
355
356 double initval;
357 try
358 {
359 for(k = 0; k < m1; k++)
360 {
361 i = initVarVector[k]->idx;
362 if (initVarVector[k]->idx > n1)
363 throw ErrorClass ("Illegal index value in variable initialization");
364
365 initval = initVarVector[k]->value;
366 if (osinstance->instanceData->variables->var[i]->ub == OSDBL_MAX)
367 {
368 if (osinstance->instanceData->variables->var[i]->lb > initval)
369 throw ErrorClass ("Initial value outside of bounds");
370 }
371 else if (osinstance->instanceData->variables->var[i]->lb == -OSDBL_MAX)
372 {
373 if (osinstance->instanceData->variables->var[i]->ub < initval)
374 throw ErrorClass ("Initial value outside of bounds");
375 }
376 else
377 {
378 if ((osinstance->instanceData->variables->var[i]->lb > initval) ||
379 (osinstance->instanceData->variables->var[i]->ub < initval))
380 throw ErrorClass ("Initial value outside of bounds");
381 }
382
383 x[initVarVector[k]->idx] = initval;
384 initialed[initVarVector[k]->idx] = true;
385 }
386 }
387 catch(const ErrorClass& eclass)
388 {
390 "Error in BonminProblem::get_starting_point (OSBonminSolver.cpp)\n\n\n");
391 }
392 } // end if (m1 > 0)
393
394 double default_initval;
395 default_initval = 1.7171;
396
397
398 for(k = 0; k < n1; k++)
399 {
400 if (!initialed[k])
401 {
402 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
403 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
404 x[k] = default_initval;
405 else
406 x[k] = osinstance->instanceData->variables->var[k]->lb;
407 else if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
408 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
409 x[k] = default_initval;
410 else
411 x[k] = osinstance->instanceData->variables->var[k]->ub;
412 else if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
413 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
414 x[k] = default_initval;
415 else if (osinstance->instanceData->variables->var[k]->lb > default_initval)
416 x[k] = osinstance->instanceData->variables->var[k]->lb;
417 else
418 x[k] = osinstance->instanceData->variables->var[k]->ub;
419 }
420 }
421
422#ifndef NDEBUG
423 outStr.str("");
424 outStr.clear();
425 for(i = 0; i < n1; i++)
426 {
427 outStr << "INITIAL VALUE !!!!!!!!!!!!!!!!!!!! " << x[ i] << std::endl;
428 }
430#endif
431
432 osinstance->calculateAllObjectiveFunctionValues( x, true);
433 delete[] initialed;
434 return true;
435}//get_starting_point
436
437
438// returns the value of the objective function
439bool BonminProblem::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
440{
441
442 try
443 {
444 if(osinstance->getObjectiveNumber() > 0)
445 {
446 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") == 0)
447 {
448 obj_value = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
449 }
450 else // we have a max
451 {
452 obj_value = -osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
453 }
454 }
455 }
456 catch(const ErrorClass& eclass)
457 {
458 bonminErrorMsg = eclass.errormsg;
459 throw;
460 }
461 if( CoinIsnan( (double)obj_value) ) return false;
462 return true;
463}
464
465bool BonminProblem::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
466{
467 int i;
468 double *objGrad = NULL;
469 if(osinstance->getObjectiveNumber() > 0)
470 {
471 try
472 {
473 // we assume we are doing the objective function indexed by -1
474 objGrad = osinstance->calculateObjectiveFunctionGradient( const_cast<double*>(x), NULL, NULL, -1, new_x, 1);
475 }
476 catch(const ErrorClass& eclass)
477 {
478 bonminErrorMsg = eclass.errormsg;
479 throw;
480 }
481
482 for(i = 0; i < n; i++)
483 {
484 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") == 0)
485 {
486 grad_f[ i] = objGrad[ i];
487 }
488 else
489 {
490 grad_f[ i] = -objGrad[ i];
491 }
492 }
493 }
494 return true;
495}//eval_grad_f
496
497// return the value of the constraints: g(x)
498bool BonminProblem::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
499{
500 try
501 {
502 double *conVals = osinstance->calculateAllConstraintFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 );
503 int i;
504 for(i = 0; i < m; i++)
505 {
506 if( CoinIsnan( (double)conVals[ i] ) ) return false;
507 g[i] = conVals[ i] ;
508 }
509 return true;
510 }
511 catch(const ErrorClass& eclass)
512 {
513 bonminErrorMsg = eclass.errormsg;
514 throw;
515 }
516}//eval_g
517
518
519// return the structure or values of the jacobian
520bool BonminProblem::eval_jac_g(Index n, const Number* x, bool new_x,
521 Index m, Index nele_jac, Index* iRow, Index *jCol,
522 Number* values)
523{
524 SparseJacobianMatrix *sparseJacobian;
525 if (values == NULL)
526 {
527 // return the structure of the jacobian
528 try
529 {
530 sparseJacobian = osinstance->getJacobianSparsityPattern();
531 }
532 catch(const ErrorClass& eclass)
533 {
534 bonminErrorMsg = eclass.errormsg;
535 throw;
536 }
537 int i = 0;
538 int k, idx;
539 for(idx = 0; idx < m; idx++)
540 {
541 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++)
542 {
543 iRow[i] = idx;
544 jCol[i] = *(sparseJacobian->indexes + k);
545 i++;
546 }
547 }
548 }
549 else
550 {
551 try
552 {
553 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1);
554 }
555 catch(const ErrorClass& eclass)
556 {
557 bonminErrorMsg = eclass.errormsg;
558 throw;
559 }
560 //osinstance->getIterateResults( (double*)x, 0.0, NULL, -1, new_x, 1);
561 for(int i = 0; i < nele_jac; i++)
562 {
563 values[ i] = sparseJacobian->values[i];
564 //values[ i] = osinstance->m_mdJacValue[ i];
565 }
566 }
567 return true;
568}//eval_jac_g
569
570//return the structure or values of the hessian
571bool BonminProblem::eval_h(Index n, const Number* x, bool new_x,
572 Number obj_factor, Index m, const Number* lambda,
573 bool new_lambda, Index nele_hess, Index* iRow,
574 Index* jCol, Number* values)
575{
576
577 SparseHessianMatrix *sparseHessian;
578
579 int i;
580 if (values == NULL)
581 {
582 // return the structure. This is a symmetric matrix, fill the lower left triangle only.
583 try
584 {
585 sparseHessian = osinstance->getLagrangianHessianSparsityPattern( );
586 }
587 catch(const ErrorClass& eclass)
588 {
589 bonminErrorMsg = eclass.errormsg;
590 throw;
591 }
592 for(i = 0; i < nele_hess; i++)
593 {
594 iRow[i] = *(sparseHessian->hessColIdx + i);
595 jCol[i] = *(sparseHessian->hessRowIdx + i);
596 }
597 }
598 else
599 {
600 // return the values. This is a symmetric matrix, fill the lower left triangle only
601 double* objMultipliers = new double[1];
602 objMultipliers[0] = obj_factor;
603 try
604 {
605 sparseHessian = osinstance->calculateLagrangianHessian( const_cast<double*>(x), objMultipliers, const_cast<double*>(lambda) , new_x, 2);
606 delete[] objMultipliers;
607 }
608 catch(const ErrorClass& eclass)
609 {
610 bonminErrorMsg = eclass.errormsg;
611 delete[] objMultipliers;
612 throw;
613 }
614 for(i = 0; i < nele_hess; i++)
615 {
616 values[ i] = *(sparseHessian->hessValues + i);
617 }
618 }
620 return true;
621}//eval_h
622
624 bool& use_x_scaling, Index n,
625 Number* x_scaling,
626 bool& use_g_scaling, Index m,
627 Number* g_scaling)
628{
629 /*
630 * Bonmin assumes problems cast as a min
631 * if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
632 obj_scaling = -1;
633 }
634 else obj_scaling = 1;
635 use_x_scaling = false;
636 use_g_scaling = false;
637 */
638 return true;
639}//get_scaling_parameters
640
641
642
643
644void BonminProblem::finalize_solution(TMINLP::SolverReturn status_,
645 Index n, const Number* x, Number obj_value)
646{
647 std::ostringstream outStr;
648
649 status = status_;
650#ifndef NDEBUG
651 outStr.str("");
652 outStr.clear();
653 outStr << "FINALIZE OBJ SOLUTION VALUE = " << obj_value << std::endl;
655#endif
656
657}
658
659
661{
662 try
663 {
664 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
665 if(osinstance == NULL)
666 {
667 m_osilreader = new OSiLReader();
668 osinstance = m_osilreader->readOSiL( osil);
669 }
670
671 // Can't handle multiobjective problems properly --- especially nonlinear ones
672 if (osinstance->getObjectiveNumber() > 1)
673 throw ErrorClass("Solver cannot handle multiple objectives --- please delete all but one");
674
675 // Create a new instance of your nlp
677 this->bCallbuildSolverInstance = true;
678 //Now initialize from tminlp
679 //bonminSetup.initialize( GetRawPtr(tminlp) );
680 }
681 catch(const ErrorClass& eclass)
682 {
684 osresult->setGeneralMessage( eclass.errormsg);
685 osresult->setGeneralStatusType( "error");
686 osrl = osrlwriter->writeOSrL( osresult);
687 throw ErrorClass( osrl) ;
688 }
689}//end buildSolverInstance()
690
691
692
694{
695 std::ostringstream outStr;
696 try
697 {
698 this->bSetSolverOptions = true;
699 bonminSetup.initializeOptionsAndJournalist();
700 //Register an additional option -- just an example
701 bonminSetup.roptions()->AddStringOption2("print_solution","Do we print the solution or not?",
702 "yes",
703 "no", "No, we don't.",
704 "yes", "Yes, we do.",
705 "A longer comment can be put here");
706
707 // Here we can change the default value of some Bonmin or Ipopt option
708 bonminSetup.options()->SetNumericValue("bonmin.time_limit", 5000); //changes bonmin's time limit
709 //bonminSetup.options()->SetIntegerValue("bonmin.num_resolve_at_node", 3);
710 //bonminSetup.options()->SetIntegerValue("bonmin.num_resolve_at_root", 3);
711 //bonminSetup.options()->SetIntegerValue("bonmin.num_retry_unsolved_random_point", 30);
712 //bonminSetup.options()->SetIntegerValue("print_level", 12);
713 //bonminSetup.options()->SetIntegerValue("bonmin.bb_log_level", 4);
714 //bonminSetup.options()->SetStringValue("bonmin.nlp_failure_behavior", "fathom");
715 //bonminSetup.options()->SetNumericValue("bonmin.allowable_gap", -1);
716 //bonminSetup.options()->SetNumericValue("bonmin.allowable_fraction_gap", -.1);
717 //bonminSetup.options()->SetNumericValue("bonmin.cutoff_decr", -1);
718 //bonminSetup.options()->SetStringValue("mu_oracle","loqo");
719
720
721 //Here we read several option files
722 //bonminSetup.readOptionsFile("Mybonmin.opt");
723 //bonminSetup.readOptionsFile();// This reads the default file "bonmin.opt"
724
725 // Options can also be set by using a string with a format similar to the bonmin.opt file
726 bonminSetup.readOptionsString("bonmin.algorithm B-BB\n");
727
728 //turn off a lot of output -- this can be overridden by using OSOptions
729 bonminSetup.options()->SetIntegerValue("bonmin.bb_log_level", 0 );
730 bonminSetup.options()->SetIntegerValue("bonmin.nlp_log_level", 0 );
731
732 // Now we can obtain the value of the new option
733 int printSolution;
734 bonminSetup.options()->GetEnumValue("print_solution", printSolution,"");
735 if(printSolution == 1)
736 {
737 tminlp->printSolutionAtEndOfAlgorithm();
738 }
739 //
740 if(osoption == NULL && osol.length() > 0)
741 {
742 m_osolreader = new OSoLReader();
743 osoption = m_osolreader->readOSoL( osol);
744 }
745
746 if(osoption != NULL && osoption->getNumberOfSolverOptions() > 0 )
747 {
748 char *pEnd;
749 int i;
750 std::vector<SolverOption*> optionsVector;
751 optionsVector = osoption->getSolverOptions( "bonmin",true);
752 int num_bonmin_options = optionsVector.size();
753 for(i = 0; i < num_bonmin_options; i++)
754 {
755 if(optionsVector[ i]->type == "numeric" )
756 {
757 outStr.str("");
758 outStr.clear();
759 outStr << "FOUND A NUMERIC OPTION "
760 << os_strtod( optionsVector[ i]->value.c_str(), &pEnd )
761 << std::endl;
763 if(optionsVector[ i]->category == "ipopt")
764 {
765 bonminSetup.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
766 }
767 else
768 {
769 if(optionsVector[ i]->category == "cbc" )
770 {
771 bonminSetup.options()->SetNumericValue("milp_solver."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
772 }
773 else
774 {
775 bonminSetup.options()->SetNumericValue("bonmin."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
776 }
777 }
778 }
779 else if(optionsVector[ i]->type == "integer" )
780 {
781 outStr.str("");
782 outStr.clear();
783 outStr << "FOUND AN INTEGER OPTION " << optionsVector[ i]->name << std::endl;
785 if(optionsVector[ i]->category == "ipopt")
786 {
787 bonminSetup.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
788 }
789 else
790 {
791 if(optionsVector[ i]->category == "cbc" )
792 {
794 "SETTING INTEGER CBC OPTION\n");
795 bonminSetup.options()->SetIntegerValue("milp_solver."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ));
796 }
797 else
798 {
799 bonminSetup.options()->SetIntegerValue("bonmin."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
800 }
801 }
802 }
803 else if(optionsVector[ i]->type == "string" )
804 {
805 outStr.str("");
806 outStr.clear();
807 outStr << "FOUND A STRING OPTION " << optionsVector[ i]->name << std::endl;
809 if(optionsVector[ i]->category == "ipopt")
810 {
811 bonminSetup.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value );
812 }
813 else
814 {
815 if(optionsVector[ i]->category == "cbc" )
816 {
817 bonminSetup.options()->SetStringValue("milp_solver."+optionsVector[ i]->name, optionsVector[ i]->value);
818 }
819 else
820 {
821 bonminSetup.options()->SetStringValue("bonmin."+optionsVector[ i]->name, optionsVector[ i]->value);
822 }
823 }
824 }
825 }
826 }
827 }
828
829 catch(const ErrorClass& eclass)
830 {
832 osresult->setGeneralMessage( eclass.errormsg);
833 osresult->setGeneralStatusType( "error");
834 osrl = osrlwriter->writeOSrL( osresult);
835 throw ErrorClass( osrl) ;
836 }
837}//end setSolverOptions()
838
839
841{
842 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
843 if( this->bSetSolverOptions == false) setSolverOptions();
844 try
845 {
846 try
847 {
848 bonminSetup.initialize( GetRawPtr(tminlp) );
849 // bb is a Bonmin BonCbc object;;
850 bb( bonminSetup); //process parameter file using Ipopt and do branch and bound using Cbc
851 }
852 catch(TNLPSolver::UnsolvedError *E)
853 {
854 //There has been a failure to solve a problem with Ipopt.
855 osresult->setGeneralMessage("Ipopt has failed to solve a problem");
856 osresult->setGeneralStatusType( "error");
857 osrl = osrlwriter->writeOSrL( osresult);
858 throw ErrorClass( osrl) ;
859 }
860 catch(OsiTMINLPInterface::SimpleError &E)
861 {
862 ostringstream outStr;
863 outStr << E.className() << "::"<< E.methodName() << std::endl << E.message() << std::endl;
864
865 osresult->setGeneralMessage(outStr.str());
866 osresult->setGeneralStatusType( "error");
867 osrl = osrlwriter->writeOSrL( osresult);
868 throw ErrorClass( osrl) ;
869 }
870 catch(CoinError &E)
871 {
872 ostringstream outStr;
873 outStr << E.className() << "::"<< E.methodName() << std::endl << E.message() << std::endl;
874
875 osresult->setGeneralMessage(outStr.str());
876 osresult->setGeneralStatusType( "error");
877 osrl = osrlwriter->writeOSrL( osresult);
878 throw ErrorClass( osrl);
879 }
880
881 if(( bb.model().isContinuousUnbounded() == true) && (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() <= 0) )
882 {
883 std::string solutionDescription = "";
884 std::string message = "Success";
885 int solIdx = 0;
886
887 if(osresult->setServiceName( "Bonmin solver service") != true)
888 throw ErrorClass("OSResult error: setServiceName");
889 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
890 throw ErrorClass("OSResult error: setInstanceName");
891 if(osresult->setVariableNumber( osinstance->getVariableNumber() ) != true)
892 throw ErrorClass("OSResult error: setVariableNumber");
893 if(osresult->setObjectiveNumber( 1) != true)
894 throw ErrorClass("OSResult error: setObjectiveNumber");
895 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
896 throw ErrorClass("OSResult error: setConstraintNumber");
897 if(osresult->setSolutionNumber( 1) != true)
898 throw ErrorClass("OSResult error: setSolutionNumer");
899 if(osresult->setGeneralMessage( message) != true)
900 throw ErrorClass("OSResult error: setGeneralMessage");
901 solutionDescription = "The problem is unbounded";
902 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
903 osresult->setGeneralStatusType("normal");
904 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
905 osrl = osrlwriter->writeOSrL( osresult);
906 return;
907 }
908
909
910 if(( bb.model().isProvenInfeasible() == true) )
911 {
912 std::string solutionDescription = "";
913 std::string message = "Success";
914 int solIdx = 0;
915
916
917 if(osresult->setServiceName( "Bonmin solver service") != true)
918 throw ErrorClass("OSResult error: setServiceName");
919 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
920 throw ErrorClass("OSResult error: setInstanceName");
921 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
922 throw ErrorClass("OSResult error: setVariableNumer");
923 if(osresult->setObjectiveNumber( 1) != true)
924 throw ErrorClass("OSResult error: setObjectiveNumber");
925 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
926 throw ErrorClass("OSResult error: setConstraintNumber");
927 if(osresult->setSolutionNumber( 1) != true)
928 throw ErrorClass("OSResult error: setSolutionNumber");
929 if(osresult->setGeneralMessage( message) != true)
930 throw ErrorClass("OSResult error: setGeneralMessage");
931 solutionDescription = "The problem is infeasible";
932 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
933
934 osresult->setGeneralStatusType("normal");
935 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
936 osrl = osrlwriter->writeOSrL( osresult);
937 return;
938 }
939 status = tminlp->status;
940 writeResult();
941
942 }
943 catch(const ErrorClass& eclass)
944 {
945 osresult->setGeneralMessage( eclass.errormsg);
946 osresult->setGeneralStatusType( "error");
947 osrl = osrlwriter->writeOSrL( osresult);
948 throw ErrorClass( osrl) ;
949 }
950}//solve
951
952
954{
955 double *x = NULL;
956 double *z = NULL;
957 int i = 0;
958 int solIdx = 0;
959 std::string solutionDescription = "";
960 std::string message = "Bonmin solver finishes to the end.";
961 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(0, "Warning: this problem has zero decision variables!");
962
963
964 try
965 {
966 if(osinstance->getVariableNumber() > 0) x = new double[osinstance->getVariableNumber() ];
967 z = new double[1];
968 // resultHeader information
969 if(osresult->setServiceName( OSgetVersionInfo()) != true)
970 throw ErrorClass("OSResult error: setServiceName");
971 if(osresult->setSolverInvoked( "COIN-OR Bonmin") != true)
972 throw ErrorClass("OSResult error: setSolverInvoked");
973 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
974 throw ErrorClass("OSResult error: setInstanceName");
975 //if(osresult->setJobID( osoption->jobID) != true)
976 // throw ErrorClass("OSResult error: setJobID");
977 // set basic problem parameters
978
979 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
980 throw ErrorClass("OSResult error: setVariableNumer");
981 if(osresult->setObjectiveNumber( 1) != true)
982 throw ErrorClass("OSResult error: setObjectiveNumber");
983 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
984 throw ErrorClass("OSResult error: setConstraintNumber");
985 if(osresult->setSolutionNumber( 1) != true)
986 throw ErrorClass("OSResult error: setSolutionNumer");
987 if(osresult->setGeneralMessage( message) != true)
988 throw ErrorClass("OSResult error: setGeneralMessage");
989
990 switch( status)
991 {
992 case TMINLP::SUCCESS:
993 solutionDescription = "SUCCESS[BONMIN]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
994 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
995 /* Retrieve the solution */
996 if(osinstance->getObjectiveNumber() > 0)
997 {
998 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
999 osresult->setObjectiveValuesDense(solIdx, z);
1000 }
1001 if( osinstance->getVariableNumber() > 0)
1002 {
1003 for(i=0; i < osinstance->getVariableNumber(); i++)
1004 {
1005 *(x + i) = bb.bestSolution()[i];
1006 }
1007 osresult->setPrimalVariableValuesDense(solIdx, x);
1008 }
1009 break;
1010
1011 case TMINLP::LIMIT_EXCEEDED:
1012 solutionDescription = "LIMIT_EXCEEDED[BONMIN]: A resource limit was exceeded, we provide the current solution.";
1013 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
1014 //osresult->setPrimalVariableValuesDense(solIdx, const_cast<double*>(x));
1015 //osresult->setDualVariableValuesDense(solIdx, const_cast<double*>( lambda));
1016 /* Retrieve the solution */
1017 if(osinstance->getObjectiveNumber() > 0)
1018 {
1019 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
1020 osresult->setObjectiveValuesDense(solIdx, z);
1021 }
1022 if( osinstance->getVariableNumber() > 0)
1023 {
1024 for(i=0; i < osinstance->getVariableNumber(); i++)
1025 {
1026 *(x + i) = bb.bestSolution()[i];
1027 }
1028 osresult->setPrimalVariableValuesDense(solIdx, x);
1029 }
1030 break;
1031
1032 case TMINLP::MINLP_ERROR:
1033 solutionDescription = "MINLP_ERROR [BONMIN]: Algorithm stopped with unspecified error.";
1034 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
1035
1036 break;
1037
1038 case TMINLP::CONTINUOUS_UNBOUNDED:
1039 solutionDescription = "CONTINUOUS_UNBOUNDED [BONMIN]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
1040 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
1041
1042 break;
1043
1044
1045 case TMINLP::INFEASIBLE:
1046 solutionDescription = "INFEASIBLE [BONMIN]: Problem may be infeasible.";
1047 osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
1048 break;
1049
1050
1051 default:
1052 solutionDescription = "OTHER[BONMIN]: other unknown solution status from Bonmin solver";
1053 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
1054 }//switch end
1055 osresult->setGeneralStatusType("normal");
1056 osrl = osrlwriter->writeOSrL( osresult);
1057 if(osinstance->getVariableNumber() > 0 ) delete[] x;
1058 x = NULL;
1059 delete[] z;
1060 z = NULL;
1061 }//end try
1062
1063
1064 catch(const ErrorClass& eclass)
1065 {
1066 if(osinstance->getVariableNumber() > 0) delete[] x;
1067 x = NULL;
1068 delete[] z;
1069 z = NULL;
1070 osresult->setGeneralMessage( eclass.errormsg);
1071 osresult->setGeneralStatusType( "error");
1072 osrl = osrlwriter->writeOSrL( osresult);
1073 throw ErrorClass( osrl) ;
1074 }
1075}// end writeResult()
1076
1077
1079{
1080 std::ostringstream outStr;
1081
1082 int i;
1083
1084 // print out problem parameters
1085 outStr << "This is problem: " << osinstance->getInstanceName() << endl;
1086 outStr << "The problem source is: " << osinstance->getInstanceSource() << endl;
1087 outStr << "The problem description is: " << osinstance->getInstanceDescription() << endl;
1088 outStr << "number of variables = " << osinstance->getVariableNumber() << endl;
1089 outStr << "number of Rows = " << osinstance->getConstraintNumber() << endl;
1090
1091 // print out the variable information
1092 if(osinstance->getVariableNumber() > 0)
1093 {
1094 for(i = 0; i < osinstance->getVariableNumber(); i++)
1095 {
1096 if(osinstance->getVariableNames() != NULL) outStr << "variable Names " << osinstance->getVariableNames()[ i] << endl;
1097 if(osinstance->getVariableTypes() != NULL) outStr << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
1098 if(osinstance->getVariableLowerBounds() != NULL) outStr << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
1099 if(osinstance->getVariableUpperBounds() != NULL) outStr << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
1100 }
1101 }
1102
1103 // print out objective function information
1104 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0)
1105 {
1106 if( osinstance->getObjectiveMaxOrMins()[0] == "min") outStr << "problem is a minimization" << endl;
1107 else outStr << "problem is a maximization" << endl;
1108 for(i = 0; i < osinstance->getVariableNumber(); i++)
1109 {
1110 outStr << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
1111 }
1112 }
1113 // print out constraint information
1114 if(osinstance->getConstraintNumber() > 0)
1115 {
1116 for(i = 0; i < osinstance->getConstraintNumber(); i++)
1117 {
1118 if(osinstance->getConstraintNames() != NULL) outStr << "row name = " << osinstance->getConstraintNames()[i] << endl;
1119 if(osinstance->getConstraintLowerBounds() != NULL) outStr << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
1120 if(osinstance->getConstraintUpperBounds() != NULL) outStr << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
1121 }
1122 }
1123
1124 // print out linear constraint data
1125 outStr << endl;
1126 outStr << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
1127 for(i = 0; i <= osinstance->getVariableNumber(); i++)
1128 {
1129 outStr << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
1130 }
1131 outStr << endl;
1132 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++)
1133 {
1134 outStr << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
1135 outStr << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
1136 }
1137
1138 // print out quadratic data
1139 outStr << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
1140 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++)
1141 {
1142 outStr << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
1143 outStr << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
1144 outStr << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
1145 outStr << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
1147 }
1148} // end dataEchoCheck
1149
1150
1152{
1153 osinstance = osinstance_;
1154 osoption = osoption_;
1155 printSol_ = false;
1156}
1157
1162
1163
1164
const OSSmartPtr< OSOutput > osoutput
Definition OSOutput.cpp:39
std::string OSgetVersionInfo()
#define INTEGER
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
double os_strtod(const char *s00, char **se)
Definition OSdtoa.cpp:2541
bool printSol_
Method called by Ipopt at the end of optimization.
virtual ~BonminProblem()
the BonminProblem class destructor
virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType *const_types)
Pass the type of the constraints (LINEAR, NON_LINEAR) to the optimizer.
virtual bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Method to return the constraint residuals.
virtual void finalize_solution(Bonmin::TMINLP::SolverReturn status_, Ipopt::Index n, const Ipopt::Number *x, Ipopt::Number obj_value)
Method called by Ipopt at the end of optimization.
virtual bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
Method to pass the main dimensions of the problem to Ipopt.
OSOption * osoption
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Method to return the gradient of the objective.
OSInstance * osinstance
virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
Method to return the starting point for the algorithm.
virtual bool get_variables_types(Ipopt::Index n, VariableType *var_types)
Pass the type of the variables (INTEGER, BINARY, CONTINUOUS) to the optimizer.
virtual bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Method to return the objective value.
virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType *var_types)
Pass info about linear and nonlinear variables.
virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
Bonmin specific methods for defining the nlp problem.
std::string bonminErrorMsg
Bonmin::TMINLP::SolverReturn status
BonminProblem(OSInstance *osinstance_, OSOption *osoption_)
the BonminProblemclass constructor
virtual bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the hessian of the lagrangian (if "values" is NULL) 2) The valu...
virtual bool get_scaling_parameters(Ipopt::Number &obj_scaling, bool &use_x_scaling, Ipopt::Index n, Ipopt::Number *x_scaling, bool &use_g_scaling, Ipopt::Index m, Ipopt::Number *g_scaling)
Method to pass the main dimensions of the problem to Ipopt.
virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the jacobian (if "values" is NULL) 2) The values of the jacobia...
Bonmin::TMINLP::SolverReturn status
std::string bonminErrorMsg
Ipopt::SmartPtr< BonminProblem > tminlp
Bonmin::Bab bb
virtual void setSolverOptions()
The implementation of the virtual functions.
virtual void buildSolverInstance()
buildSolverInstance is a virtual function – the actual solvers will implement their own buildSolverIn...
void dataEchoCheck()
use this for debugging, print out the instance that the solver thinks it has and compare this with th...
Bonmin::BonminSetup bonminSetup
OSiLReader * m_osilreader
m_osilreader is an OSiLReader object used to create an osinstance from an osil string if needed
void writeResult()
use this to write the solution information to an OSResult object
OSoLReader * m_osolreader
m_osolreader is an OSoLReader object used to create an osoption from an osol string if needed
~BonminSolver()
the IpoptSolver class destructor
virtual void solve()
solve results in an instance being read into the Bonmin data structrues and optimized
OSrLWriter * osrlwriter
BonminSolver()
the BonminSolver class constructor
std::string osol
osol holds the options for the solver
bool bSetSolverOptions
bSetSolverOptions is set to true if setSolverOptions has been called, false otherwise
std::string osrl
osrl holds the solution or result of the model
OSInstance * osinstance
osinstance holds the problem instance in-memory as an OSInstance object
bool bCallbuildSolverInstance
bCallbuildSolverInstance is set to true if buildSolverService has been called
std::string osil
osil holds the problem instance as a std::string
OSOption * osoption
osoption holds the solver options in-memory as an OSOption object
OSResult * osresult
osresult holds the solution or result of the model in-memory as an OSResult object
used for throwing exceptions.
std::string errormsg
errormsg is the error that is causing the exception to be thrown
the InitVarValue class.
Definition OSOption.h:1160
double value
initial value
Definition OSOption.h:1170
int idx
variable index
Definition OSOption.h:1164
The in-memory representation of an OSiL instance..
The Option Class.
Definition OSOption.h:3565
The Result Class.
Definition OSResult.h:2549
Used to read an OSiL string.
Definition OSiLReader.h:38
Used to read an OSoL string.
Definition OSoLReader.h:38
Take an OSResult object and write a string that validates against OSrL.
Definition OSrLWriter.h:31
The in-memory representation of a SparseHessianMatrix..
Definition OSGeneral.h:377
int * hessRowIdx
hessRowIdx is an integer array of row indices in the range 0, ..., n - 1.
Definition OSGeneral.h:394
int hessDimension
hessDimension is the number of nonzeros in each array.
Definition OSGeneral.h:389
double * hessValues
hessValues is a double array of the Hessian values.
Definition OSGeneral.h:404
int * hessColIdx
hessColIdx is an integer array of column indices in the range 0, ..., n - 1.
Definition OSGeneral.h:399
a sparse Jacobian matrix data structure
Definition OSGeneral.h:301
int * indexes
indexes holds an integer array of variable indices.
Definition OSGeneral.h:335
int valueSize
valueSize is the dimension of the values array
Definition OSGeneral.h:318
int * starts
starts holds an integer array of start elements, each start element points to the start of partials f...
Definition OSGeneral.h:324
double * values
values holds a double array of nonzero partial derivatives
Definition OSGeneral.h:340
@ ENUM_OUTPUT_LEVEL_debug
@ ENUM_OUTPUT_LEVEL_error
@ ENUM_OUTPUT_LEVEL_info
@ ENUM_OUTPUT_LEVEL_warning
@ ENUM_OUTPUT_AREA_OSSolverInterfaces
#define OSDBL_MAX