My Project
OSKnitroSolver.cpp
Go to the documentation of this file.
1/* $Id$ */
19#include "OSKnitroSolver.h"
20#include "OSCommonUtil.h"
21
22using std::cout;
23using std::endl;
24using std::ostringstream;
25using namespace std;
26
27#if defined(_WIN32)
28#include <windows.h> //-- FOR LoadLibrary
29#else
30#include <dlfcn.h> //-- FOR dlopen
31#endif
32
33
34//--------------------------------------------------------------------
35// Static variables and data
36//--------------------------------------------------------------------
37
38static NlpProblemDef * g_pTheNlpProblemDefInstance = NULL;
39
40//for calling the solver and feeding the nlp problem
41static NlpProblemDef * g_pOptProblem = NULL;
42
43static int wrapperEvalFC (const int evalRequestCode,
44 const int n,
45 const int m,
46 const int nnzJ,
47 const int nnzH,
48 const double * const daX,
49 const double * const daLambda,
50 double * const dObj,
51 double * const daC,
52 double * const daG,
53 double * const daJ,
54 double * const daH,
55 double * const daHV,
56 void * userParams)
57{
58 if (g_pOptProblem == NULL)
59 {
60 cout << "*** Problem not defined <wrapperEvalFC>\n";
61 return( -1 );
62 }
63 if (evalRequestCode != KTR_RC_EVALFC)
64 {
65 cout << "*** Bad request code " << evalRequestCode
66 << " <wrapperEvalFC>\n";
67 return( -1 );
68 }
69 return( g_pOptProblem->evalFC (daX, dObj, daC, userParams) );
70}//wrapperEvalFC
71
72
73//--------------------------------------------------------------------
74// Internal Function: wrapperEvalGA
75//--------------------------------------------------------------------
79static int wrapperEvalGA (const int evalRequestCode,
80 const int n,
81 const int m,
82 const int nnzJ,
83 const int nnzH,
84 const double * const daX,
85 const double * const daLambda,
86 double * const dObj,
87 double * const daC,
88 double * const daG,
89 double * const daJ,
90 double * const daH,
91 double * const daHV,
92 void * userParams)
93{
94 if (g_pOptProblem == NULL)
95 {
96 cout << "*** Problem not defined <wrapperEvalGA>\n";
97 return( -1 );
98 }
99 if (evalRequestCode != KTR_RC_EVALGA)
100 {
101 cout << "*** Bad request code " << evalRequestCode
102 << " <wrapperEvalGA>\n";
103 return( -1 );
104 }
105 return( g_pOptProblem->evalGA (daX, daG, daJ, userParams) );
106}//wrapperEvalGA
107
108
109//--------------------------------------------------------------------
110// Internal Function: wrapperEvalHorHV
111//--------------------------------------------------------------------
115static int wrapperEvalHorHV (const int evalRequestCode,
116 const int n,
117 const int m,
118 const int nnzJ,
119 const int nnzH,
120 const double * const daX,
121 const double * const daLambda,
122 double * const dObj,
123 double * const daC,
124 double * const daG,
125 double * const daJ,
126 double * const daH,
127 double * const daHV,
128 void * userParams)
129{
130 if (g_pOptProblem == NULL)
131 {
132 cout << "*** Problem not defined <wrapperEvalHorHV>\n";
133 return( -1 );
134 }
135 if (evalRequestCode == KTR_RC_EVALH)
136 {
137 if (g_pOptProblem->areDerivativesImplemented (nCAN_COMPUTE_H) == false)
138 {
139 cout << "*** This problem not evaluate H <wrapperEvalHorHV>\n";
140 return( -1 );
141 }
142 return( g_pOptProblem->evalH (daX, daLambda, daH, userParams) );
143 }
144 else if (evalRequestCode == KTR_RC_EVALHV)
145 {
146 if (g_pOptProblem->areDerivativesImplemented (nCAN_COMPUTE_HV) == false)
147 {
148 cout << "*** This problem not evaluate H*v <wrapperEvalHorHV>\n";
149 return( -1 );
150 }
151 return( g_pOptProblem->evalHV (daX, daLambda, daHV, userParams) );
152 }
153 else
154 {
155 cout << "*** Bad request code " << evalRequestCode
156 << " <wrapperEvalHorHV>\n";
157 return( -1 );
158 }
159}//wrapperEvalHorHV
160
161
162
163//--------------------------------------------------------------------
164// Exported Function: getNlpProblemDef
165//--------------------------------------------------------------------
166//++ Export a function that returns the static pointer to this class.
167#ifdef __cplusplus
168extern "C"
169{
170#if defined(_WIN32)
171 __declspec(dllexport) NlpProblemDef * getNlpProblemDef (void)
172#else
173 NlpProblemDef * getNlpProblemDef (void)
174#endif
175 {
176 if (g_pTheNlpProblemDefInstance == NULL)
178
180 }
181}
182#endif
183
184
186{
187
188 _daXInit = NULL;
189 osinstance = osinstance_;
190 osresult = osresult_;
191}
192
193
194
196{
197 delete [] _daXInit;
198 _daXInit = NULL;
199}
200
201
202
203//--------------------------------------------------------------------
204// Simple access methods
205//--------------------------------------------------------------------
206
208{
209 return( _nN );
210}//getN
211
212
214{
215 return( _nM );
216}//getM
217
218
219void KnitroProblem::getInitialX (double * const daX)
220{
221 if (_daXInit == NULL)
222 {
223 cout << "*** Must call 'loadProblemIntoKnitro' before 'KnitroSolver::getInitialX'\n";
224 exit( EXIT_FAILURE );
225 }
226
227 for (int i = 0; i < _nN; i++)
228 {
229 daX[i] = _daXInit[i];
230 }
231 return;
232}//getM
233
234//--------------------------------------------------------------------
235// Method: loadProblemIntoKnitro
236//--------------------------------------------------------------------
241{
242 int i;
243 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Knitro NEEDS AN OBJECTIVE FUNCTION");
244 // number of variables
246 // number of constraints
248 cout << "number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _nN << endl;
249 cout << "number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _nM << endl;
250 try
251 {
253 }
254 catch(const ErrorClass& eclass)
255 {
256 knitroErrorMsg = eclass.errormsg;
257 throw;
258 }
259
260 // variables lower bounds
261 double * mdVarLB = osinstance->getVariableLowerBounds();
262 std::cout << "GET BOUNDS INFORMATION FOR KNITRO!!!!!!!!!!!!!!!" << std::endl;
263 // variables upper bounds
264 double * mdVarUB = osinstance->getVariableUpperBounds();
265
266 _daXLo = new double[_nN];
267 _daXUp = new double[_nN];
268 for(i = 0; i < _nN; i++)
269 {
270 if( mdVarLB[ i] == -OSDBL_MAX) _daXLo[i] = -KTR_INFBOUND;
271 else _daXLo[i] = mdVarLB[ i];
272 if( mdVarUB[ i] == OSDBL_MAX) _daXUp[i] = KTR_INFBOUND;
273 else _daXUp[i] = mdVarUB[ i];
274 //cout << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
275 //cout << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
276 }
277
278 //constraint lower bounds
279 double * mdConLB = osinstance->getConstraintLowerBounds();
280 //constraint upper bounds
281 double * mdConUB = osinstance->getConstraintUpperBounds();
282
283 _naCType = new int[ _nM];
284 _daCLo = new double[ _nM];
285 _daCUp = new double[ _nM];
286 _naCType[0] = KTR_CONTYPE_LINEAR;
287 for(i = 0; i < _nM; i++)
288 {
289 if( mdConLB[ i] == -OSDBL_MAX) _daCLo[i] = -KTR_INFBOUND;
290 else _daCLo[i] = mdConLB[ i];
291 if( mdConUB[ i] == OSDBL_MAX) _daCUp[i] = KTR_INFBOUND;
292 else _daCUp[i] = mdConUB[ i];
293 //cout << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _daCLo[i] << endl;
294 //cout << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _daCUp[i] << endl;
295 _naCType[i] = KTR_CONTYPE_GENERAL; //need change
296 }
297
298 // use the OS Expression tree for function evaluations instead of CppAD
300 std::cout << "Call sparse jacobian" << std::endl;
301 SparseJacobianMatrix *sparseJacobian = NULL;
302 try
303 {
304 sparseJacobian = osinstance->getJacobianSparsityPattern();
305 }
306 catch(const ErrorClass& eclass)
307 {
308 knitroErrorMsg = eclass.errormsg;
309 throw;
310 }
311 std::cout << "Done calling sparse jacobian" << std::endl;
312 _nNnzJ = sparseJacobian->valueSize;
313 //cout << "_nNnzJ !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _nNnzJ << endl;
314 _naJacIndexVars = new int[_nNnzJ];
315 _naJacIndexCons = new int[_nNnzJ];
316 int k, idx;
317 i = 0;
318 for(idx = 0; idx < _nM; idx++)
319 {
320 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++)
321 {
322 _naJacIndexCons[i] = idx;
323 _naJacIndexVars[i] = *(sparseJacobian->indexes + k);
324 //cout << "ROW IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _naJacIndexCons[i] << endl;
325 //cout << "COL IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _naJacIndexVars[i] << endl;
326 i++;
327 }
328 }
329
330
331 // nonzeros in upper hessian
333 {
334 cout << "This is a linear program" << endl;
335 _nNnzH = 0;
336 }
337 else
338 {
339 std::cout << "Get Lagrangain Hessian Sparsity Pattern " << std::endl;
341 std::cout << "Done Getting Lagrangain Hessian Sparsity Pattern " << std::endl;
342 _nNnzH = sparseHessian->hessDimension;
343 _naHessRows = new int[_nNnzH];
344 _naHessCols = new int[_nNnzH];
345 for(i = 0; i < _nNnzH; i++)
346 {
347 _naHessCols[i] = *(sparseHessian->hessColIdx + i);
348 _naHessRows[i] = *(sparseHessian->hessRowIdx + i);
349 cout << "ROW HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _naHessRows[i] << endl;
350 cout << "COL HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << _naHessCols[i] << endl;
351 }
352 }
353 //---- INITIAL GUESS FOR x AND lambda.
354 // Here, we assume we only have starting values for x, if you code
355 // your own NLP, you can provide starting values for the dual variables
356 // if you wish
357 //cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
358 double *mdXInit = osinstance->getVariableInitialValues();
359 _daXInit = new double[_nN];
360 if( mdXInit != NULL)
361 {
362 for(i = 0; i < _nN; i++)
363 {
364 if( CommonUtil::ISOSNAN( mdXInit[ i]) == true)
365 {
366 _daXInit[ i] = 1.7171;
367 }
368 else _daXInit[ i] = mdXInit[ i];
369 }
370 }
371 else
372 {
373 for(i = 0; i < _nN; i++)
374 {
375 _daXInit[ i] = 1.7171;
376 }
377 }
378 //cout << "got initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
379
380 double * daLambdaInit = new double[_nM + _nN];
381 for (i = 0; i < _nM + _nN; i++)
382 daLambdaInit[i] = 0.0;
383
384 // set obj type
385 int iObjSense = KTR_OBJGOAL_MINIMIZE;
386 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("max") == 0)
387 {
388 iObjSense = KTR_OBJGOAL_MAXIMIZE;
389 }
390 int iObjType = KTR_OBJTYPE_GENERAL; //KTR_OBJTYPE_LINEAR, KTR_OBJTYPE_QUADRATIC
391 i = KTR_init_problem (kc, _nN,
392 iObjSense, iObjType,
393 _daXLo, _daXUp,
394 _nM, _naCType, _daCLo, _daCUp,
395 _nNnzJ, _naJacIndexVars, _naJacIndexCons,
396 _nNnzH, _naHessRows, _naHessCols,
397 _daXInit, daLambdaInit);
398
399 delete [] _daXLo;
400 delete [] _daXUp;
401 delete [] _naCType;
402 delete [] _daCLo;
403 delete [] _daCUp;
404 delete [] _naJacIndexVars;
405 delete [] _naJacIndexCons;
406 delete [] _naHessRows;
407 delete [] _naHessCols;
408 delete [] daLambdaInit;
409
410 if (i != 0)
411 {
412 cout << "*** KTR_init_problem() returned " << i << "\n";
413 return( false );
414 }
415
416 return( true );
417}//loadProblemIntoKnitro
418
419//--------------------------------------------------------------------
420// Method: areDerivativesImplemented
421//--------------------------------------------------------------------
422bool KnitroProblem::areDerivativesImplemented(const DerivativesImplementedType nWhichDers)
423{
424 if (nWhichDers == nCAN_COMPUTE_GA)
425 return( true );
426 if (nWhichDers == nCAN_COMPUTE_H)
427 return( true );
428 if (nWhichDers == nCAN_COMPUTE_HV)
429 return( false);
430 return( false );
431}//areDerivativesImplemented
432
433
434//--------------------------------------------------------------------
435// Method: evalFC
436//--------------------------------------------------------------------
437int KnitroProblem::evalFC (const double * const daX,
438 double * const dObj,
439 double * const daC,
440 void * userParams)
441{
442 try
443 {
444 *dObj = osinstance->calculateAllObjectiveFunctionValues((double*)daX, NULL, NULL, true, 0 )[0];
445 }
446 catch(const ErrorClass& eclass)
447 {
448 knitroErrorMsg = eclass.errormsg;
449 return (-1);
450 }
451 if( CommonUtil::ISOSNAN( *dObj )) return (-1);
452
453
454
455 try
456 {
457 double *conVals = osinstance->calculateAllConstraintFunctionValues((double*)daX, NULL, NULL, true, 0 );
458 int i;
459 for(i = 0; i < _nM; i++)
460 {
461 if( CommonUtil::ISOSNAN( (double)conVals[ i] ) ) return (-1);
462 daC[i] = conVals[ i] ;
463 }
464 }
465 catch(const ErrorClass& eclass)
466 {
467 knitroErrorMsg = eclass.errormsg;
468 return (-1);
469 }
470
471
472 return( 0 );
473}//evalFC
474
475
476//--------------------------------------------------------------------
477// Method: evalGA
478//--------------------------------------------------------------------
479int KnitroProblem::evalGA (const double * const daX,
480 double * const daG,
481 double * const daJ,
482 void * userParams)
483{
484 try
485 {
486 double *objGrad = osinstance->calculateAllObjectiveFunctionGradients((double*)daX, NULL, NULL, true, 1 )[0];
487 int i;
488 std::cout << "EVALUATING OBJ GRADIENT" << std::endl;
489 for(i = 0; i < _nN; i++)
490 {
491 if( CommonUtil::ISOSNAN( (double)objGrad[ i] ) ) return (-1);
492 daG[i] = objGrad[ i] ;
493 }
494 }
495 catch(const ErrorClass& eclass)
496 {
497 knitroErrorMsg = eclass.errormsg;
498 return (-1);
499 }
500
501 SparseJacobianMatrix *sparseJacobian;
502 std::cout << "EVALUATING JACOBIAN" << std::endl;
503 try
504 {
505 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients((double*)daX, NULL, NULL, true, 1);
506 }
507 catch(const ErrorClass& eclass)
508 {
509 knitroErrorMsg = eclass.errormsg;
510 return (-1);
511 }
512 //osinstance->getIterateResults( (double*)x, 0.0, NULL, -1, true, 1);
513 for(int i = 0; i < _nNnzJ; i++)
514 {
515 daJ[ i] = sparseJacobian->values[i];
516 //daJ[ i] = osinstance->m_mdJacValue[ i];
517 cout << "daJ[i]:!!!!!!!!!!!! " << daJ[ i] << endl;
518 //cout << "m_mdJacValue[ i]:!!!!!!!!!!!! " << osinstance->m_mdJacValue[ i] << endl;
519 }
520
521 return( 0 );
522}//evalGA
523
524
525//--------------------------------------------------------------------
526// Method: evalH
527//--------------------------------------------------------------------
528int KnitroProblem::evalH (const double * const daX,
529 const double * const daLambda,
530 double * const daH,
531 void * userParams)
532{
533 SparseHessianMatrix *sparseHessian;
534 int i;
535 double* objMultipliers = new double[1];
536 objMultipliers[0] = 1;
537 try
538 {
539 sparseHessian = osinstance->calculateLagrangianHessian((double*)daX, objMultipliers, (double*)daLambda , true, 2);
540 }
541 catch(const ErrorClass& eclass)
542 {
543 knitroErrorMsg = eclass.errormsg;
544 return (-1);
545 }
546 for(i = 0; i < _nNnzH; i++)
547 {
548 daH[ i] = *(sparseHessian->hessValues + i);
549 std::cout << "Hessian Value = " << daH[ i] << std::endl;
550 }
551 delete[] objMultipliers;
552 return( 0 );
553}//evalH
554
555
556//--------------------------------------------------------------------
557// Method: evalHV
558//--------------------------------------------------------------------
559int KnitroProblem::evalHV (const double * const daX,
560 const double * const daLambda,
561 double * const daHV,
562 void * userParams)
563{
564
565 return( 0 );
566}//evalHV
567
568//OS specific default solver methods
569
570
572{
573 osrlwriter = new OSrLWriter();
574 osresult = new OSResult();
575 knitroErrorMsg = "";
576
577}
578
579
581{
582 try
583 {
584
585 }
586 catch(const ErrorClass& eclass)
587 {
588 std::cout << "THERE IS AN ERROR" << std::endl;
592 throw ErrorClass( osrl) ;
593 }
594}//end buildSolverInstance()
595
596
597
598
599void Knitro::setSolverOptions()
600{
601 try
602 {
603
604 }
605 catch(const ErrorClass& eclass)
606 {
607 std::cout << "THERE IS AN ERROR" << std::endl;
610 osrl = osrlwriter->writeOSrL( osresult);
611 throw ErrorClass( osrl) ;
612 }
613}//end setSolverOptions()
614
616{
617#ifdef DEBUG
618 cout << "inside KnitroSolver destructor" << endl;
619#endif
620 delete osresult;
621 osresult = NULL;
622 delete osrlwriter;
623 osrlwriter = NULL;
624 //delete osinstance;
625 //osinstance = NULL;
626#ifdef DEBUG
627 cout << "leaving KnitroSolver destructor" << endl;
628#endif
629}
630
632{
633 try
634 {
635 OSiLReader* osilreader = NULL;
636 //osresult = new OSResult();
637 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
638 clock_t start, finish;
639 double duration;
640 start = clock();
641 bool newOSiLReader = false;
642 if( osinstance == NULL)
643 {
644 osilreader = new OSiLReader();
645 osinstance = osilreader->readOSiL( osil);
646 newOSiLReader = true;
647 }
648 OSiLWriter osilwriter;
649 //cout << osilwriter.writeOSiL( osinstance) << endl;
650 if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Knitro requires decision variables");
651 finish = clock();
652 duration = (double) (finish - start) / CLOCKS_PER_SEC;
653 cout << "Parsing took (seconds): "<< duration << endl;
654 //dataEchoCheck();
655
656 /***************now the Knitro invokation*********************/
657 // Create a new instance of your nlp
658 NlpProblemDef *pOptProb = new KnitroProblem(osinstance, osresult);
659 bool bWantToSolve;
660
661 //---- OPEN A NEW INSTANCE OF KNITRO.
662 KTR_context *kc;
663 kc = KTR_new();
664 if (kc == NULL)
665 {
666 cout << "*** KTR_new failed, maybe a license issue?\n";
667 exit( EXIT_FAILURE );
668 }
669
670 //---- APPLY ANY USER OPTIONS (PROCEED EVEN IF THERE IS AN ERROR).
671 KTR_load_param_file (kc, "knitro.opt");
672 //---- LOAD THE PROBLEM INTO KNITRO.
673 if (pOptProb->loadProblemIntoKnitro ( kc) == false)
674 {
675 cout << "*** loadProblemIntoKnitro failed\n";
676 exit( EXIT_FAILURE );
677 }
678
679 //---- SET CALLBACK POINTERS FOR EVALUATION OF PROBLEM INFORMATION.
680 //---- IF THE TEST CODE DOES NOT SUPPLY DERIVATIVES, THEN THE
681 //---- USER OPTIONS IN "knitro.opt" SHOULD REQUEST AN ALTERNATIVE,
682 //---- SUCH AS FINITE DIFFERENCES.
683 g_pOptProblem = pOptProb;
684 if (KTR_set_func_callback (kc, wrapperEvalFC) != 0)
685 {
686 cout << "*** KTR_set_func_callback failed\n";
687 exit( EXIT_FAILURE );
688 }
689 if (pOptProb->areDerivativesImplemented (nCAN_COMPUTE_GA) == true)
690 {
691 if (KTR_set_grad_callback (kc, wrapperEvalGA) != 0)
692 {
693 cout << "*** KTR_set_grad_callback failed\n";
694 exit( EXIT_FAILURE );
695 }
696 }
697 if ((pOptProb->areDerivativesImplemented (nCAN_COMPUTE_H) == true)
698 || (pOptProb->areDerivativesImplemented (nCAN_COMPUTE_HV) == true))
699 {
700 if (KTR_set_hess_callback (kc, wrapperEvalHorHV) != 0)
701 {
702 cout << "*** KTR_set_hess_callback failed\n";
703 exit( EXIT_FAILURE );
704 }
705 }
706
707 //---- ALLOCATE ARRAYS
708 double * daX = new double[pOptProb->getN()];
709 double * daLambda = new double[pOptProb->getM() + pOptProb->getN()];
710 double* mdObjValues = new double[1];
711 bWantToSolve = true;
712 if (bWantToSolve == true)
713 {
714 //---- CALL KNITRO AND SOLVE.
715 double dFinalObj;
716 int nStatus = KTR_solve (kc, daX, daLambda, 0, &dFinalObj,
717 NULL, NULL, NULL, NULL, NULL, NULL);
718 std::cout << "dFinalObj = " << dFinalObj << std::endl;
719 cout << "*** Final KNITRO status = " << nStatus << "\n";
720 cout << "dax[0] = " << daX[0] << "\n";
721
722 //construct osresult
723 int solIdx = 0;
724
725 std::string message = "Knitro solver finishes to the end.";
726 std::string solutionDescription = "";
727
728 // resultHeader infomration
729 if(osresult->setServiceName( "Knitro solver service") != true)
730 throw ErrorClass("OSResult error: setServiceName");
732 throw ErrorClass("OSResult error: setInstanceName");
733
734 //if(osresult->setJobID( osoption->jobID) != true)
735 // throw ErrorClass("OSResult error: setJobID");
736
737 // set basic problem parameters
739 throw ErrorClass("OSResult error: setVariableNumer");
740 if(osresult->setObjectiveNumber( 1) != true)
741 throw ErrorClass("OSResult error: setObjectiveNumber");
743 throw ErrorClass("OSResult error: setConstraintNumber");
744 if(osresult->setSolutionNumber( 1) != true)
745 throw ErrorClass("OSResult error: setSolutionNumer");
746
747
748 if(osresult->setGeneralMessage( message) != true)
749 throw ErrorClass("OSResult error: setGeneralMessage");
750 std::cout << "START CASES " << 0 << endl;
751 switch( nStatus)
752 {
753 case 0:
754 std::cout << "WE ARE IN CASE " << 0 << endl;
755 solutionDescription = "LOCALLY OPTIMAL SOLUTION FOUND[KNITRO STATUS 0]: Knitro found a locally optimal point which satisfies the stopping criterion.If the problem is convex (for example, a linear program), then this point corresponds to a globally optimal solution.";
756 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
757 std::cout << "SET SOLUTION STATUS " << endl;
759 std::cout << "SET PRIMAL VALUES " << endl;
760 osresult->setDualVariableValuesDense(solIdx, daLambda);
761 mdObjValues[0] = dFinalObj;
762 osresult->setObjectiveValuesDense(solIdx, mdObjValues);
763 std::cout << "SET OBJECTIVE VALUES " << endl;
764 break;
765 case -1:
766 solutionDescription = "Iteration limit reached[KNITRO STATUS -1]: The iteration limit was reached before being able to satisfy the required stopping criteria.";
767 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
769 osresult->setDualVariableValuesDense(solIdx, daLambda);
770 mdObjValues[0] = dFinalObj;
771 osresult->setObjectiveValuesDense(solIdx, mdObjValues);
772 break;
773 case -2:
774 solutionDescription = "Convergence to an infeasible point[KNITRO STATUS -2]: Problem may be locally infeasible.The algorithm has converged to an infeasible point from which it cannot further decrease the infeasibility measure. This happens when the problem is infeasible, but may also occur on occasion for feasible problems with nonlinear constraints or badly scaled problems. It is recommended to try various initial points. If this occurs for a variety of initial points, it is likely the problem is infeasible.";
775 osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
776 break;
777 case -3:
778 solutionDescription = "Problem appears to be unbounded[KNITRO STATUS -3]: Iterate is feasible and objective magnitude > objrange. The objective function appears to be decreasing without bound, while satisfying the constraints.If the problem really is bounded, increase the size of the parameter objrange to avoid terminating with this message.";
779 osresult->setSolutionStatus(solIdx, "unbounded", solutionDescription);
780 break;
781 case -4:
782 solutionDescription = "Relative change in solution estimate < xtol[KNITRO STATUS -4]: The relative change in the solution estimate is less than that specified by the paramater xtol.To try to get more accuracy one may decrease xtol. If xtol is very small already, it is an indication that no more significant progress can be made. If the current point is feasible, it is possible it may be optimal, however the stopping tests cannot be satisfied (perhaps because of degeneracy, ill-conditioning or bad scaling).";
783 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
785 osresult->setDualVariableValuesDense(solIdx, daLambda);
786 mdObjValues[0] = dFinalObj;
787 osresult->setObjectiveValuesDense(solIdx, mdObjValues);
788 break;
789 case -5:
790 solutionDescription = "Current solution estimate cannot be improved. Point appears to be optimal, but desired accuracy could not be achieved.[KNITRO STATUS -5]: No more progress can be made, but the stopping tests are close to being satisfied (within a factor of 100) and so the current approximate solution is believed to be optimal.";
791 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
793 osresult->setDualVariableValuesDense(solIdx, daLambda);
794 mdObjValues[0] = dFinalObj;
795 osresult->setObjectiveValuesDense(solIdx, mdObjValues);
796 break;
797 case -6:
798 solutionDescription = "Time limit reached[KNITRO STATUS -6]: The time limit was reached before being able to satisfy the required stopping criteria.";
799 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
801 osresult->setDualVariableValuesDense(solIdx, daLambda);
802 mdObjValues[0] = dFinalObj;
803 osresult->setObjectiveValuesDense(solIdx, mdObjValues);
804 break;
805 case -50:
806 case -51:
807 case -52:
808 case -53:
809 case -54:
810 case -55:
811 case -56:
812 case -57:
813 case -58:
814 case -59:
815 case -60:
816 solutionDescription = "Input Error[KNITRO STATUS -50 to -60]: Termination values in this range imply some input error. If outlev>0 details of this error will be printed to standard output or the file knitro.log depending on the value of outmode.";
817 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
818 break;
819 case -90:
820 solutionDescription = "Callback function error[KNITRO STATUS -90]: This termination value indicates that an error (i.e., negative return value) occurred in a user provided callback routine.";
821 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
822 break;
823 case -97:
824 solutionDescription = "LP solver error[KNITRO STATUS -97]: This termination value indicates that an unrecoverable error occurred in the LP solver used in the active-set algorithm preventing the optimization from continuing.";
825 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
826 break;
827 case -98:
828 solutionDescription = "Evaluation error[KNITRO STATUS -98]: This termination value indicates that an evaluation error occurred (e.g., divide by 0, taking the square root of a negative number), preventing the optimization from continuing.";
829 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
830 break;
831 case -99:
832 solutionDescription = "Not enough memory available to solve problem[KNITRO STATUS -99]: This termination value indicates that there was not enough memory available to solve the problem.";
833 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
834 break;
835 default:
836 solutionDescription = "OTHER[KNITRO]: other unknown solution status from Knitro solver";
837 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
838 }
839
842 }
843 else
844 {
845 //---- USE KNITRO TO CHECK THE DERIVATIVES CODED IN THE TEST PROBLEM.
846 pOptProb->getInitialX (daX);
847 KTR_check_first_ders (kc, daX, 2, 1.0e-14, 1.0e-14,
848 0, 0.0, NULL, NULL, NULL, NULL);
849 }
850
851 if(newOSiLReader == true)
852 {
853 delete osilreader;
854 osilreader = NULL;
855 }
856 delete [] daX;
857 delete [] daLambda;
858 delete [] mdObjValues;
859
860 KTR_free( &kc);
861 delete pOptProb;
862
863
864 //return( EXIT_SUCCESS ); //to do
865 }
866 catch(const ErrorClass& eclass)
867 {
871 //throw ErrorClass( osrl) ; //to do
872 }
873}//solve
874
875
877{
878
879 int i;
880
881 // print out problem parameters
882 cout << "This is problem: " << osinstance->getInstanceName() << endl;
883 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
884 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
885 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
886 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
887
888 // print out the variable information
890 {
891 for(i = 0; i < osinstance->getVariableNumber(); i++)
892 {
893 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
894 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
895 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
896 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
897 }
898 }
899
900 // print out objective function information
902 {
903 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
904 else cout << "problem is a maximization" << endl;
905 for(i = 0; i < osinstance->getVariableNumber(); i++)
906 {
907 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
908 }
909 }
910 // print out constraint information
912 {
913 for(i = 0; i < osinstance->getConstraintNumber(); i++)
914 {
915 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
916 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
917 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
918 }
919 }
920
921 // print out linear constraint data
922 cout << endl;
923 cout << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
924 for(i = 0; i <= osinstance->getVariableNumber(); i++)
925 {
926 cout << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
927 }
928 cout << endl;
930 {
931 cout << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
932 cout << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
933 }
934
935 // print out quadratic data
936 cout << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
937 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++)
938 {
939 cout << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
940 cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
941 cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
942 cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
943 }
944} // end dataEchoCheck
945
946
947NlpProblemDef::~NlpProblemDef (void)
948{
949 //---- DO NOTHING.
950 //return;
951}
952
953
954
955
static NlpProblemDef * g_pTheNlpProblemDefInstance
static int wrapperEvalGA(const int evalRequestCode, const int n, const int m, const int nnzJ, const int nnzH, const double *const daX, const double *const daLambda, double *const dObj, double *const daC, double *const daG, double *const daJ, double *const daH, double *const daHV, void *userParams)
By necessity this wrapper signature matches the function KTR_callback.
static int wrapperEvalFC(const int evalRequestCode, const int n, const int m, const int nnzJ, const int nnzH, const double *const daX, const double *const daLambda, double *const dObj, double *const daC, double *const daG, double *const daJ, double *const daH, double *const daHV, void *userParams)
static int wrapperEvalHorHV(const int evalRequestCode, const int n, const int m, const int nnzJ, const int nnzH, const double *const daX, const double *const daLambda, double *const dObj, double *const daC, double *const daG, double *const daJ, double *const daH, double *const daHV, void *userParams)
By necessity this wrapper signature matches the function KTR_callback.
static NlpProblemDef * g_pOptProblem
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
std::string osil
osil holds the problem instance as a std::string
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
Objectives * objectives
objectives is a pointer to a Objectives object
int evalGA(const double *const daX, double *const daG, double *const daJ, void *userParams)
int evalFC(const double *const daX, double *const dObj, double *const daC, void *userParams)
std::string knitroErrorMsg
OSInstance * osinstance
int evalHV(const double *const daX, const double *const daLambda, double *const daHV, void *userParams)
int evalH(const double *const daX, const double *const daLambda, double *const daH, void *userParams)
KnitroProblem(OSInstance *osinstance_, OSResult *osresult_)
the IpoptProblemclass constructor
OSResult * osresult
void getInitialX(double *const daX)
bool areDerivativesImplemented(const DerivativesImplementedType nWhichDers)
virtual ~KnitroProblem()
the IpoptProblem class destructor
bool loadProblemIntoKnitro(KTR_context_ptr kc)
Define the fixed problem definition information and pass it to KNITRO by calling KTR_init_problem.
KnitroSolver()
the KnitroSolver class constructor
virtual void solve()
solve results in an instance being read into the Knitro data structrues and optimized
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...
OSrLWriter * osrlwriter
~KnitroSolver()
the KnitroSolver class constructor
std::string knitroErrorMsg
The in-memory representation of an OSiL instance..
SparseJacobianMatrix * calculateAllConstraintFunctionGradients(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the gradient of all constraint functions.
double * getConstraintLowerBounds()
Get constraint lower bounds.
int getNumberOfQuadraticTerms()
Get the number of specified (usually nonzero) qTerms in the quadratic coefficients.
double * getVariableUpperBounds()
Get variable upper bounds.
SparseJacobianMatrix * getJacobianSparsityPattern()
bool bUseExpTreeForFunEval
bUseExpTreeForFunEval is set to true if you wish to use the OS Expression Tree for function evaluatio...
std::string getInstanceDescription()
Get instance description.
std::string getInstanceSource()
Get instance source.
int getConstraintNumber()
Get number of constraints.
double * calculateAllConstraintFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the constraint function values.
int getLinearConstraintCoefficientNumber()
Get number of specified (usually nonzero) linear constraint coefficient values.
char * getVariableTypes()
Get variable initial values.
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
SparseMatrix * getLinearConstraintCoefficientsInColumnMajor()
Get linear constraint coefficients in column major.
double ** getDenseObjectiveCoefficients()
getDenseObjectiveCoefficients.
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
InstanceData * instanceData
A pointer to an InstanceData object.
int getNumberOfNonlinearExpressions()
Get number of nonlinear expressions.
SparseHessianMatrix * getLagrangianHessianSparsityPattern()
QuadraticTerms * getQuadraticTerms()
Get all the quadratic terms in the instance.
double * getVariableLowerBounds()
Get variable lower bounds.
int getVariableNumber()
Get number of variables.
std::string * getVariableNames()
Get variable names.
std::string getInstanceName()
Get instance name.
SparseHessianMatrix * calculateLagrangianHessian(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the Hessian of the Lagrangian Expression Tree This method will build the CppAD expression t...
std::string * getConstraintNames()
Get constraint names.
std::string * getObjectiveMaxOrMins()
Get objective maxOrMins.
double ** calculateAllObjectiveFunctionGradients(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the gradient of all objective functions.
double * getConstraintUpperBounds()
Get constraint upper bounds.
int getObjectiveNumber()
Get number of objectives.
The Result Class.
Definition OSResult.h:2549
bool setGeneralMessage(std::string message)
Set the general message.
bool setSolutionNumber(int number)
set the number of solutions.
bool setInstanceName(std::string instanceName)
Set instance name.
bool setObjectiveValuesDense(int solIdx, double *objectiveValues)
Set the [i]th optimization solution's objective values, where i equals the given solution index.
bool setGeneralStatusType(std::string type)
Set the general status type, which can be: success, error, warning.
bool setObjectiveNumber(int objectiveNumber)
Set the objective number.
bool setPrimalVariableValuesDense(int solIdx, double *x)
Set the [i]th optimization solution's primal variable values, where i equals the given solution index...
bool setServiceName(std::string serviceName)
Set service name.
bool setVariableNumber(int variableNumber)
Set the variable number.
bool setDualVariableValuesDense(int solIdx, double *y)
Set the [i]th optimization solution's dual variable values, where i equals the given solution index.
bool setSolutionStatus(int solIdx, std::string type, std::string description)
Set the [i]th optimization solution status, where i equals the given solution index.
bool setConstraintNumber(int constraintNumber)
Set the constraint number.
Used to read an OSiL string.
Definition OSiLReader.h:38
OSInstance * readOSiL(const std::string &osil)
parse the OSiL model instance.
Take an OSInstance object and write a string that validates against the OSiL schema.
Definition OSiLWriter.h:30
Take an OSResult object and write a string that validates against OSrL.
Definition OSrLWriter.h:31
std::string writeOSrL(OSResult *theosresult)
create an osrl string from an OSResult object
std::string maxOrMin
declare the objective function to be a max or a min
Definition OSInstance.h:157
int numberOfObjectives
numberOfObjectives is the number of objective functions in the instance
Definition OSInstance.h:201
Objective ** obj
coef is pointer to an array of ObjCoef object pointers
Definition OSInstance.h:205
int * varTwoIndexes
varTwoIndexes holds an integer array of the second variable indexes of all the quadratic terms.
Definition OSGeneral.h:450
int * rowIndexes
rowIndexes holds an integer array of row indexes of all the quadratic terms.
Definition OSGeneral.h:440
double * coefficients
coefficients holds a double array all the quadratic term coefficients.
Definition OSGeneral.h:455
int * varOneIndexes
varOneIndexes holds an integer array of the first variable indexes of all the quadratic terms.
Definition OSGeneral.h:445
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
int * indexes
indexes holds an integer array of rowIdx (or colIdx) elements in coefMatrix (AMatrix).
Definition OSGeneral.h:258
int * starts
starts holds an integer array of start elements in coefMatrix (AMatrix), which points to the start of...
Definition OSGeneral.h:252
double * values
values holds a double array of value elements in coefMatrix (AMatrix), which contains nonzero element...
Definition OSGeneral.h:264
#define OSDBL_MAX
OSResult * osresult