OSAlgorithmicDiffTest.cpp
Go to the documentation of this file.
1 /* $Id: OSAlgorithmicDiffTest.cpp 2698 2009-06-09 04:14:07Z kmartin $ */
73 #include <cstddef>
74 #include <cstdlib>
75 #include <cctype>
76 #include <cassert>
77 #include <stack>
78 #include <cppad/cppad.hpp>
79 #include <iostream>
80 
81 // CoinHelperFunctions <has cmath>
82 #include "CoinHelperFunctions.hpp"
83 #include "OSInstance.h"
84 #include "OSiLWriter.h"
85 #include "OSParameters.h"
86 #include "OSnLNode.h"
87 #include "OSErrorClass.h"
88 #include "OSFileUtil.h"
89 #include "OSiLReader.h"
90 #include "OSInstance.h"
91 #include "OSExpressionTree.h"
92 #include "OSnLNode.h"
93 #include "OSDataStructures.h"
94 
95 
96 
97 #include <vector>
98 #include <map>
99 #include <string>
100 
101 
102 int main(){
103  WindowsErrorPopupBlocker();
104  using std::cout;
105  using std::endl;
106  using CppAD::AD;
107  //using CppAD::NearEqual;
108  using CppAD::vector;
109  std::cout.precision(12);
110  // error checking functions
111  bool CheckFunctionValues( double *conVals, double objValue,
112  double x0, double x1, double x2, double x3, double y0, double y1, double z );
113  bool CheckHessianUpper( SparseHessianMatrix *sparseHessian,
114  double x0, double x1, double x2, double x3, double y0, double y1, double z );
115  bool CheckGradientValues( SparseJacobianMatrix *sparseJac, double *objGrad,
116  double x0, double x1, double x2, double x3, double y0, double y1, double z );
117  bool ok = true;
118  int k, idx;
119  //
120  // get the problem data
121  //
122  FileUtil *fileUtil = NULL;
123  std::string osilFileName;
124  std::string osil;
125  // get the input file
126  const char dirsep = CoinFindDirSeparator();
127  // Set directory containing mps data files.
128  std::string dataDir;
129  dataDir = dirsep == '/' ? "../data/" : "..\\data\\";
130  //osilFileName = dataDir + "osilFiles" + dirsep + "HS071_NLP.osil";
131  osilFileName = dataDir + "osilFiles" + dirsep + "CppADTestLag.osil";
132  std::cout << "osilFileName = " << osilFileName << std::endl;
133  fileUtil = new FileUtil();
134  osil = fileUtil->getFileAsString( &osilFileName[0]);
135  //
136  // create OSReader and OSInstance objects
137  OSiLReader *osilreader = NULL;
138  OSInstance *osinstance = NULL;
139  // create reader, parse the OSiL, and generate the OSInstance object
140  try{
141  // a counter
142  int kjl;
143  osilreader = new OSiLReader();
144  osinstance = osilreader->readOSiL( osil);
145  std::vector<double> funVals(3);
146  std::vector<double> dfunVals(6);
147  double *conVals = NULL;
148  //conVals = new double[ 2];
149  double *objVals = NULL;
150  //objVals = new double[ 1];
151 
165  //
166  // first initialize the nonlinear structures for call backs
167  std::cout << "Initialize Nonlinear Structures" << std::endl;
168  osinstance->initForAlgDiff( );
169  //osinstance->getJacobianSparsityPattern( );
170 
171 
172 
178  std::map<int, int> varIndexMap;
179  std::map<int, int>::iterator posVarIndexMap;
180  varIndexMap = osinstance->getAllNonlinearVariablesIndexMap( );
185  for(posVarIndexMap = varIndexMap.begin(); posVarIndexMap != varIndexMap.end(); ++posVarIndexMap){
186  std::cout << "Variable Index = " << posVarIndexMap->first << std::endl ;
187  }
188  std::cout << "Number of nonlinear variables = " << varIndexMap.size() << std::endl;
189 
190  //
191 
192  // get the number of nonlinear terms
193 
194  int mm = osinstance->getNumberOfNonlinearExpressionTreeModIndexes();
195 
196  int jj;
197 
198  for(jj = 0; jj < mm; jj++){
199  std::cout << osinstance->getNonlinearExpressionTreeModIndexes()[ jj] << std::endl;
200  }
201 
202  std::cout << "Number of unique nonlinear terms = " << mm << std::endl;
203  //return 0;
204 
205 
206 
207  // domain space vector
208  size_t n = varIndexMap.size(); // three variables
209  // range space vector
210  size_t m = 3; // Lagrangian has an objective and two constraints
211 
212  std::vector<double> x0( n);
217  x0[0] = 1; // the value for variable x0
218  x0[1] = 5; // the value for variable x1
219  x0[2] = 5; // the value for variable x3
220  std::cout << "CALL forward" << std::endl;
221  funVals = osinstance->forwardAD(0, x0);
222  for( kjl = 0; kjl < 3; kjl++){
223  std::cout << "forward 0 " << funVals[ kjl] << std::endl;
224  }
225  // get the third column of the Jacobian from a forward sweep
226  std::vector<double> x1( n);
227  x1[0] = 0;
228  x1[1] = 0;
229  x1[2] = 1;
230  std::cout << "Now get the third column of the Jacobian forwardAD(1, x1)" << std::endl;
231  funVals = osinstance->forwardAD(1, x1);
232  for( kjl = 0; kjl < 3; kjl++){
233  std::cout << "forward 1 " << funVals[ kjl] << std::endl;
234  }
235 
244  x1[0] = 1;
245  x1[1] = 0;
246  x1[2] = 1;
247  // recalculate the forward sweep with the new x1 vector
248  funVals = osinstance->forwardAD(1, x1);
249  std::vector<double> x2( n);
250  x2[0] = 0;
251  x2[1] = 0;
252  x2[2] = 0;
253  std::cout << "Now calcuate forwardAD(2, x2)" << std::endl;
254  funVals = osinstance->forwardAD(2, x2);
255  for( kjl = 0; kjl < 3; kjl++){
256  std::cout << "forward 2 " << funVals[ kjl] << std::endl;
257  }
258 
266  std::vector<double> vlambda(3);
267  vlambda[0] = 0;
268  vlambda[1] = 0;
269  vlambda[2] = 1;
270  // reverse sweep to get third row of Jacobian
271  std::cout << "Now get the third row of the Jacobian reverseAD(1, vlambda)" << std::endl;
272  osinstance->forwardAD(0, x0);
273  funVals = osinstance->reverseAD(1, vlambda);
274  for( kjl = 0; kjl < 3; kjl++){
275  std::cout << "reverse 1 " << funVals[ kjl] << std::endl;
276  }
277  // now get the Hessian of the Lagrangian of objective and
278  // with the following multipliers
279  vlambda[0] = 1;
280  vlambda[1] = 2;
281  vlambda[2] = 1;
287  x1[0] = 0;
288  x1[1] = 0;
289  x1[2] = 1;
290  funVals = osinstance->forwardAD(1, x1);
291 
302  dfunVals = osinstance->reverseAD(2, vlambda);
303  // get the first partials of the Lagrangian
304  std::cout << "Here are the first partials of the Lagrangain" << std::endl;
305  for(int kjl = 0; kjl <= 4; kjl+=2){
306  std::cout << dfunVals[ kjl] << std::endl;
307  }
313  std::cout << "Here is the third row (column) of Hessian of Lagrangian" << std::endl;
314  for(int kjl = 1; kjl <= 5; kjl+=2){
315  std::cout << dfunVals[ kjl] << std::endl;
316  }
322  double* x = new double[4]; //primal variables
323  double* z = new double[2]; //Lagrange multipliers on constraints
324  double* w = new double[1]; //Lagrange multiplier on objective
325  x[ 0] = 1; // primal variable 0
326  x[ 1] = 5; // primal variable 1
327  x[ 2] = 10; // primal variable 2
328  x[ 3] = 5; // primal variable 3
329  z[ 0] = 2; // Lagrange multiplier on constraint 0
330  z[ 1] = 1; // Lagrange multiplier on constraint 1
331  w[ 0] = 1; // Lagrange multiplier on the objective function
332 
362  osinstance->bUseExpTreeForFunEval = false;
363  std::cout << "Calculate objective, idx = -1" << std::endl;
364  std::cout << "obj value = " << osinstance->calculateFunctionValue(-1, x, true) << std::endl;
365 
366  std::cout << "Calculate first constraint, idx = 0" << std::endl;
367  std::cout << "constraint index 0 value = " << osinstance->calculateFunctionValue(0, x, true) << std::endl;
368 
369  std::cout << "Now use calculateAllConstraintFunctionValues" << std::endl;
370  conVals = osinstance->calculateAllConstraintFunctionValues(x, true);
371  for( idx = 0; idx < osinstance->getConstraintNumber(); idx++){
372  std::cout << "CONSTRAINT FUNCTION INDEX = " << idx << " CONSTRAINT FUNCTION VALUE = " << *(conVals + idx) << std::endl;
373  }
374  //
375  std::cout << "Now use calculateAllObjectiveFunctionValues" << std::endl;
376  objVals = osinstance->calculateAllObjectiveFunctionValues( x, NULL, NULL, true, 0);
377  for( idx = 0; idx < osinstance->getObjectiveNumber(); idx++){
378  std::cout << "OBJECTIVE FUNCTION INDEX = " << idx << " OBJECTIVE FUNCTION VALUE = " << *(objVals + idx) << std::endl;
379  }
380  ok = CheckFunctionValues( conVals, *objVals, x[ 0], x[1], x[2], x[3], z[0], z[1], w[0] );
381  if( ok == 0){
382  std::cout << "FAILED CHECKING FUNCTION VALUES TEST" << std::endl;
383  return 0;
384  }
385  else{
386  std::cout << "PASSED CHECKING FUNCTION VALUES TEST" << std::endl;
387  }
388 
395  std::cout << "PLACE CALL TO JACOBIAN SPARSITY PATTERN" << std::endl;
396  SparseJacobianMatrix *sparseJac;
397  sparseJac = osinstance->getJacobianSparsityPattern();
398  // print out just the sparsity pattern
399  std::cout << "JACOBIAN SPARSITY PATTERN" << std::endl;
400  std::cout << "JACOBIAN START SIZE " << sparseJac->startSize << std::endl;
401  for(idx = 0; idx < osinstance->getConstraintNumber(); idx++){
402  // some solvers (e.g. reduced gradient solvers) may want to know which values of the
403  // Jacobian matrix are constant, i.e. linear, sparseJac->conVals is the number of constant
404  // terms in the gradient for each rowt, the first conVals terms are constant, when getting
405  std::cout << "number constant terms in constraint " << idx << " is "
406  << *(sparseJac->conVals + idx) << std::endl;
407  for(k = *(sparseJac->starts + idx); k < *(sparseJac->starts + idx + 1); k++){
408  std::cout << "row idx = " << idx << " col idx = "<< *(sparseJac->indexes + k) << std::endl;
409  }
410  }
411 
412  SparseHessianMatrix *sparseHessian;
413  // the Hessian test
414  // get the sparsity pattern -- many solvers want to initialize with just the sparsity
415  std::cout << "GET LAGRANGIAN HESSIAN SPARSITY PATTERN" << std::endl;
416  sparseHessian = osinstance->getLagrangianHessianSparsityPattern( );
417  for(idx = 0; idx < sparseHessian->hessDimension; idx++){
418  std::cout << "Row Index = " << *(sparseHessian->hessRowIdx + idx) ;
419  std::cout << " Column Index = " << *(sparseHessian->hessColIdx + idx) << std::endl;
420  }
421 
437  double *objGrad;
438  std::cout << "OBJECTIVE FUNCTION GRADIENT" << std::endl;
439  // in our implementation the objective function is a dense gradient
440  objGrad = osinstance->calculateObjectiveFunctionGradient( x, NULL, NULL, -1, false, 1);
441  for(idx = 0; idx < osinstance->getVariableNumber(); idx++){
442  std::cout << "col idxx = " << idx << " value = " << *(objGrad + idx) << std::endl;
443  }
444  std::cout << "CONSTRAINT JACOBIAN MATRIX" << std::endl;
445  // now make the gradient calculations and fill in the sparse Jacobian matrix
446  sparseJac = osinstance->calculateAllConstraintFunctionGradients( x, NULL, NULL, false, 1);
447  for(idx = 0; idx < osinstance->getConstraintNumber(); idx++){
448  for(k = *(sparseJac->starts + idx); k < *(sparseJac->starts + idx + 1); k++){
449  std::cout << "row idx = " << idx << " col idx = "<< *(sparseJac->indexes + k)
450  << " value = " << *(sparseJac->values + k) << std::endl;
451  }
452  }
453  ok = CheckGradientValues( sparseJac, objGrad, x[ 0], x[1], x[2], x[3], z[0], z[1], w[0] );
454  if( ok == 0){
455  std::cout << "FAILED THE GRADIENT TEST" << std::endl;
456  return 0;
457  }
458  else{
459  std::cout << "PASSED THE GRADIENT TEST" << std::endl;
460  }
470  //first iteration
471  std::cout << "GET LAGRANGIAN HESSIAN FIRST TIME" << std::endl;
472  sparseHessian = osinstance->calculateLagrangianHessian( x, w, z, false, 2);
473  for(idx = 0; idx < sparseHessian->hessDimension; idx++){
474  std::cout << "row idx = " << *(sparseHessian->hessRowIdx + idx) <<
475  " col idx = "<< *(sparseHessian->hessColIdx + idx)
476  << " value = " << *(sparseHessian->hessValues + idx) << std::endl;
477  }
478  ok = CheckHessianUpper( sparseHessian, x[0], x[1], x[2], x[3], z[0], z[1], w[0]);
479  if( ok == 0){
480  std::cout << "FAILED THE FIRST HESSIAN TEST" << std::endl;
481  return 0;
482  }
483  else{
484  std::cout << "PASSED THE FIRST HESSIAN TEST" << std::endl;
485  }
486  // now change an x value, we don't rebuild the tree, however new_x
487  // must be set to true
488  x[0] = 5;
489 
490 
491 
492  std::cout << "NOW GET LAGRANGIAN HESSIAN SECOND TIME FOR x[0] = 5" << std::endl;
493 
501  osinstance->calculateAllObjectiveFunctionValues( x, w, z, true, 2);
515  for(idx = 0; idx < sparseHessian->hessDimension; idx++){
516  std::cout << "row idx = " << *(sparseHessian->hessRowIdx + idx) <<
517  " col idx = "<< *(sparseHessian->hessColIdx + idx)
518  << " value = " << *(sparseHessian->hessValues + idx) << std::endl;
519  }
520  ok = CheckHessianUpper( sparseHessian , x[0], x[1], x[2], x[3], z[0], z[1], w[0] );
521  if( ok == 0){
522  std::cout << "FAILED THE SECOND HESSIAN TEST" << std::endl;
523  return 0;
524  }
525  else{
526  std::cout << "PASSED THE SECOND HESSIAN TEST" << std::endl << std::endl ;
527  }
531  std::cout << "HERE IS ROW 1 OF JACOBIAN MATRIX" << std::endl;
532  idx = 1;
533  for(k = *(sparseJac->starts + idx); k < *(sparseJac->starts + idx + 1); k++){
534  std::cout << "row idx = " << idx << " col idx = "<< *(sparseJac->indexes + k)
535  << " value = " << *(sparseJac->values + k) << std::endl;
536  }
537  std::cout << std::endl;
544  sparseHessian = osinstance->calculateHessian(x, 1, true);
545  std::cout << "HERE IS ROW 1 HESSIAN MATRIX" << std::endl;
546  for(idx = 0; idx < sparseHessian->hessDimension; idx++){
547  std::cout << "row idx = " << *(sparseHessian->hessRowIdx + idx) <<
548  " col idx = "<< *(sparseHessian->hessColIdx + idx)
549  << " value = " << *(sparseHessian->hessValues + idx) << std::endl;
550  }
551  //
552  // adjust the Lagrange multipliers to correspond to finding Hessian of constraint 1
553  z[ 0] = 0; // Lagrange multiplier on constraint 0
554  z[ 1] = 1; // Lagrange multiplier on constraint 1
555  w[ 0] = 0; // Lagrange multiplier on the objective function
556  ok = CheckHessianUpper( sparseHessian , x[0], x[1], x[2], x[3], z[0], z[1], w[0] );
557  if( ok == 0){
558  std::cout << "FAILED THE THIRD HESSIAN TEST" << std::endl;
559  return 0;
560  }
561  else{
562  std::cout << "PASSED THE THIRD HESSIAN TEST" << std::endl << std::endl ;
563  }
564  //set x[0] back to its original value of 1
565  x[ 0] = 1;
566  //return 0;
567  //
568  //
569  // now work directly with the CppAD package instead of OSInstance API
570  //
571  n = 4;
572  m = 3;
573  CppADvector< AD<double> > X(n);
574  CppADvector< AD<double> > Y(m);
575  X[0] = 5;
576  X[1] = 5;
577  X[2] = 0;
578  X[3] = 1;
579  // declare independent variables and start tape recording
580  std::cout << "Start Taping" << std::endl;
581  CppAD::Independent( X);
582  // range space vector
583  // we include the constant terms in the CppAD functions
584  Y[ 0] = CppAD::pow(X[0], 2) + 9*X[1];
585  Y[ 1] = 33 - 105 + 1.37*X[1] + 2*X[3] + 5*X[1] ;
586  Y[ 2] = log(X[0]*X[3]) + 7*X[2] ;
587  // create f: x -> y and stop tape recording
588  CppAD::ADFun<double> f(X, Y);
589  std::cout << "Stop Taping" << std::endl;
590  // get function values
591  std::vector<double> x_vec( n);
592  x_vec[ 0] = x[ 0];
593  x_vec[ 1] = x[ 1];
594  x_vec[ 2] = x[ 2];
595  x_vec[ 3] = x[ 3];
596  funVals = f.Forward(0, x_vec);
597  conVals[ 0] = funVals[ 1];
598  std::cout << "conVals[ 0] = " << conVals[ 0] << std::endl;
599  conVals[ 1] = funVals[ 2];
600  std::cout << "conVals[ 1] = " << conVals[ 1] << std::endl;
601  objVals[ 0] = funVals[ 0];
602  std::cout << "objVals[ 0] = " << objVals[ 0] << std::endl;
603  ok = CheckFunctionValues( conVals, funVals[ 0], x[ 0], x[1], x[2], x[3], z[0], z[1], w[0] );
604  if( ok == 0){
605  std::cout << "FAILED CHECKING FUNCTION VALUES TEST" << std::endl;
606  return 0;
607  }
608  else{
609  std::cout << "PASSED CHECKING FUNCTION VALUES TEST" << std::endl;
610  }
611  // now get gradient and Hessian
612  // first define and initialze unit vector vector
613  sparseJac = osinstance->getJacobianSparsityPattern();
614  std::vector<double> unit_col_vec( n);
615  std::vector<double> lagMultipliers( m);
616  std::vector<double> gradVals( m);
617  lagMultipliers[ 0] = w[ 0];
618  lagMultipliers[ 1] = z[ 0];
619  lagMultipliers[ 2] = z[ 1];
620  unsigned int index, kj;
621  //return 0;
622  for(index = 0; index < n; index++){
623  unit_col_vec[ index] = 0;
624  }
625  for(index = 0; index < n; index++){
626  unit_col_vec[ index] = 1;
627  // calculate column i of the Jacobian matrix
628  gradVals = f.Forward(1, unit_col_vec);
629  unit_col_vec[ index] = 0;
630  // get the nonzero gradient values in constraint k
631  for(kj = 0; kj < m; kj++){
632  std::cout << "variable " << index << " row " << kj << " gradient value" << std::endl;
633  std::cout << "gradient value = " << gradVals[ kj] << std::endl;
634  }
635  // get row i of the Lagrangian function!!!
636  std::cout << "CALL f.Reverse -------" << std::endl;
637  f.Reverse(2, lagMultipliers);
638  std::cout << "FINISH CALL f.Reverse -------" << std::endl;
639  }
640  // done with CppAD test
641  // do garbage collection
642  delete osilreader;
643  osilreader = NULL;
644  std::cout << "OSILREADER DELETED" << std::endl;
645  //delete[] conVals;
646  //delete[] objVals;
647  delete[] x;
648  delete[] z;
649  delete[] w;
650  }
651  catch(const ErrorClass& eclass){
652  std::cout << eclass.errormsg << std::endl;
653  }
654 
655  //
656  {
657  //checking CppAD power, another illustration of CppAD
658  size_t n = 2;
659  double x0 = 4;
660  double x1 = .5;
661  CppADvector< AD<double> > x(n);
662  x[0] = x0;
663  x[1] = x1;
664  // declare independent variables and start tape recording
665  CppAD::Independent(x);
666  // range space vector
667  size_t m = 1;
668  CppADvector< AD<double> > y(m);
669  y[0] = std::pow(x0, x1);
670  // create f: x -> y and stop tape recording
671  CppAD::ADFun<double> f(x, y);
672  // check value
673  double check = std::pow(x0, x1);
674  // forward computation of first partial w.r.t. x[0]
675  std::vector<double> dx(n);
676  std::vector<double> dy(m);
677  dx[0] = 4.;
678  dx[1] = 1/2.;
679  dy = f.Forward(1, dx);
680  std::cout << "dy = " << dy[ 0] << std::endl;
681  check = x1 * std::pow(x0, x1-1.);
682  //ok &= NearEqual(dy[0], check, 1e-10, 1e-10);
683  ok = ( fabs(check - dy[0])/(fabs( check) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
684  }
685 
686  {
687 
688  //checking CppAD sparsity features
689  // domain space vector
690  size_t n = 3;
691  CPPAD_TEST_VECTOR< AD<double> > X(n);
692  X[0] = 0.;
693  X[1] = 1.;
694  X[2] = 2.;
695  // declare independent variables and start recording
696  CppAD::Independent(X);
697  // range space vector
698  size_t m = 2;
699  CPPAD_TEST_VECTOR< AD<double> > Y(m);
700  Y[0] = CppAD::pow(X[0], 2) + CppAD::pow(X[2], 2);
701  Y[1] = -CppAD::pow(X[0], 2) + CppAD::pow(X[1], 2);
702  // create f: X -> Y and stop tape recording
703  CppAD::ADFun<double> f(X, Y);
704 
705  // sparsity pattern for the identity matrix
706  std::vector<bool> r(n * n);
707  size_t i, j;
708  for(i = 0; i < n; i++) {
709  for(j = 0; j < n; j++)
710  r[ i * n + j ] = false;
711  r[ i * n + i ] = true;
712  }
713  // compute sparsity pattern for J(x) = F^{(1)} (x)
714  f.ForSparseJac(n, r);
718  //std::vector<bool> s(m * m);
719  //for(i = 0; i < m; i++){
720  // for(j = 0; j < m; j++)
721  // s[ i * m + j ] = false;
722  // s[ i * m + i ] = true;
723  // }
724  // sparsity pattern for F'(x)
725  // f.RevSparseJac(m, s);
729  // compute sparsity pattern for H(x) = F_0^{(2)} (x)
730  std::vector<bool> e( m);
731  //Vector s(m);
732  for(i = 0; i < m; i++)
733  e[i] = false;
734  e[ 0] = true;
735  e[ 1] = false;
736  std::vector<bool> h( n*n);
737  //Vector h(n * n);
738  std::cout << "Computing Sparse Hessian" << std::endl;
739  h = f.RevSparseHes(n, e);
740  for(i = 0; i < n; i++){
741  std::cout << "Row " << i << " of Hessian " << std::endl;
742  for(j = 0; j < n; j++){
743  std::cout << h[ i*n + j] << " ";
744  }
745  std::cout << std::endl;
746  }
747  }
748  delete fileUtil;
749  std::cout << "\nTEST OF ALGORITHMIC DIFFERENTIATION CONCLUDED SUCCESSFULLY\n";
750  return 0;
751 }// end main program
752 
753 bool CheckFunctionValues( double *conVals, double objValue,
754  double x0, double x1, double x2, double x3, double z0, double z1, double w ){
755  using CppAD::NearEqual;
756  bool ok = true;
757  double checkObj = x0*x0 + 9*x1;
758  std::cout << "checkObj = " << checkObj << std::endl;
759  std::cout << "objValue = " << objValue << std::endl;
760  //ok &= NearEqual(objValue, checkObj, 1e-10, 1e-10);
761  ok = ( fabs(checkObj - objValue )/(fabs( checkObj) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
762  double checkCon0 = 33. - 105. + 1.37*x1 + 2*x3 + 5*x1;
763  std::cout << "checkCon0 = " << checkCon0 << std::endl;
764  std::cout << "conVals = " << *(conVals + 0) << std::endl;
765  //ok &= NearEqual(*(conVals + 0), checkCon0, 1e-10, 1e-10);
766  ok = ( fabs(checkCon0 - *(conVals + 0) )/(fabs( checkCon0) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
767  double checkCon1 = log(x0*x3) + 7*x2;
768  std::cout << "checkCon1 = " << checkCon1 << std::endl;
769  std::cout << "conVals = " << *(conVals + 1) << std::endl;
770  //ok &= NearEqual( *(conVals + 1), checkCon1, 1e-10, 1e-10);
771  ok = ( fabs(checkCon1 - *(conVals + 1) )/(fabs( checkCon1) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
772  return ok;
773 }//CheckFunctionValues
774 //
775 //
776 bool CheckGradientValues( SparseJacobianMatrix *sparseJac, double *objGrad,
777  double x0, double x1, double x2, double x3, double y0, double y1, double w ){
778  using CppAD::NearEqual;
779  bool ok = true;
780  // first the objective function gradient
781  double checkObjPartial0 = 2*x0;
782  //ok &= NearEqual( *(objGrad + 0), checkObjPartial0, 1e-10, 1e-10);
783  ok = ( fabs(checkObjPartial0 - *(objGrad + 0) )/(fabs( checkObjPartial0) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
784  double checkObjPartial1 = 9;
785  //ok &= NearEqual( *(objGrad + 1), checkObjPartial1, 1e-10, 1e-10);
786  ok = ( fabs(checkObjPartial1 - *(objGrad + 1) )/(fabs( checkObjPartial1) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
787  double checkObjPartial2 = 0;
788  //ok &= NearEqual( *(objGrad + 2), checkObjPartial2, 1e-10, 1e-10);
789  ok = ( fabs(checkObjPartial2 - *(objGrad + 2) )/(fabs( checkObjPartial2) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
790  // get the constrating gradient
791  // row 0 gradient -- there are nonzero partials for variables 1 and 2
792  double checkCon0Partial1 = 1.37 + 5.0;
793  //ok &= NearEqual( *(sparseJac->values + 0), checkCon0Partial1, 1e-10, 1e-10);
794  ok = ( fabs(checkCon0Partial1 - *(sparseJac->values + 0) )/(fabs( checkCon0Partial1) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
795  double checkCon0Partial3 = 2.;
796  //ok &= NearEqual( *(sparseJac->values + 1), checkCon0Partial3, 1e-10, 1e-10);
797  ok = ( fabs(checkCon0Partial3 - *(sparseJac->values + 1) )/(fabs( checkCon0Partial3) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
798  // row 1 gradient -- there are nonzero partials for variables 0 and 2
799  double checkCon1Partial2 = 7;
800  //ok &= NearEqual( *(sparseJac->values + 2), checkCon1Partial2, 1e-10, 1e-10);
801  ok = ( fabs(checkCon1Partial2 - *(sparseJac->values + 2) )/(fabs( checkCon1Partial2) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
802  double checkCon1Partial0 = 1./x0;
803  //ok &= NearEqual( *(sparseJac->values + 3), checkCon1Partial0, 1e-10, 1e-10);
804  ok = ( fabs(checkCon1Partial0 - *(sparseJac->values + 3) )/(fabs( checkCon1Partial0) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
805  double checkCon1Partial3 = 1./x3;
806  //ok &= NearEqual( *(sparseJac->values + 4), checkCon1Partial3, 1e-10, 1e-10);
807  ok = ( fabs(checkCon1Partial3 - *(sparseJac->values + 4) )/(fabs( checkCon1Partial3) + OS_NEAR_EQUAL) <= OS_NEAR_EQUAL) ? true : false;
808  return ok;
809 }//CheckGradientValues
810 //
811 bool CheckHessianUpper( SparseHessianMatrix *sparseHessian ,
812  double x0, double x1, double x2, double x3, double z0, double z1, double w ){
813  using CppAD::NearEqual;
814  bool ok = true;
815  int hessValuesIdx = 0;
816  //assert( sparseHessian->hessDimension = n * (n + 1) /2)
817  // L_00 = 2 * w - z1 / ( x0 * x0 )
818  double check = 2. * w - z1 / (x0 * x0);
819  ok &= NearEqual(*(sparseHessian->hessValues + hessValuesIdx++), check, 1e-10, 1e-10);
820  if(ok == false) std::cout << "FAILED ONE" << std::endl;
821  ok &= NearEqual(*(sparseHessian->hessValues + hessValuesIdx++), 0., 1e-10, 1e-10);
822  if(ok == false) std::cout << "FAILED TWO" << std::endl;
823  // L_22 = - z1 / (x3 * x3)
824  check = - z1 / (x3 * x3);
825  ok &= NearEqual(*(sparseHessian->hessValues + hessValuesIdx++), check, 1e-10, 1e-1);
826  if(ok == false) std::cout << "FAILED THREE" << std::endl;
827  return ok;
828 }//CheckHessianUpper
bool CheckFunctionValues(double *conVals, double objValue, double x0, double x1, double x2, double x3, double z0, double z1, double w)
This file defines the OSnLNode class along with its derived classes.
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...
double * values
values holds a double array of nonzero partial derivatives
Definition: OSGeneral.h:340
double calculateFunctionValue(int idx, double *x, bool new_x)
Calculate the function value for function (constraint or objective) indexed by idx.
bool bUseExpTreeForFunEval
bUseExpTreeForFunEval is set to true if you wish to use the OS Expression Tree for function evaluatio...
Definition: OSInstance.h:4899
int getVariableNumber()
Get number of variables.
ULong x2
Definition: OSdtoa.cpp:1776
SparseHessianMatrix * calculateHessian(double *x, int idx, bool new_x)
Calculate the Hessian of a constraint or objective function.
std::string errormsg
errormsg is the error that is causing the exception to be thrown
Definition: OSErrorClass.h:42
int main(int argc, char *argv[])
Definition: BB_tm.cpp:32
int * getNonlinearExpressionTreeModIndexes()
Get all the nonlinear expression tree indexes, i.e., indexes of rows (objectives or constraints) that...
int startSize
startSize is the dimension of the starts array – should equal number of rows + 1
Definition: OSGeneral.h:313
SparseJacobianMatrix * calculateAllConstraintFunctionGradients(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the gradient of all constraint functions.
int getNumberOfNonlinearExpressionTreeModIndexes()
Get the number of unique nonlinear expression tree indexes after modifying the expression tree to con...
int * hessColIdx
hessColIdx is an integer array of column indices in the range 0, ..., n - 1.
Definition: OSGeneral.h:399
int getObjectiveNumber()
Get number of objectives.
bool CheckHessianUpper(SparseHessianMatrix *sparseHessian, double x0, double x1, double x2, double x3, double z0, double z1, double w)
OSInstance * readOSiL(const std::string &osil)
parse the OSiL model instance.
Definition: OSiLReader.cpp:53
std::map< int, int > getAllNonlinearVariablesIndexMap()
int * hessRowIdx
hessRowIdx is an integer array of row indices in the range 0, ..., n - 1.
Definition: OSGeneral.h:394
static char * j
Definition: OSdtoa.cpp:3622
void fint fint fint real fint real real real real * f
SparseJacobianMatrix * getJacobianSparsityPattern()
void fint fint fint real fint real real real real real real real real real * e
ULong * x0
Definition: OSdtoa.cpp:1776
ULong x1
Definition: OSdtoa.cpp:1776
Used to read an OSiL string.
Definition: OSiLReader.h:37
int * indexes
indexes holds an integer array of variable indices.
Definition: OSGeneral.h:335
double * calculateAllConstraintFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the constraint function values.
int hessDimension
hessDimension is the number of nonzeros in each array.
Definition: OSGeneral.h:389
SparseHessianMatrix * getLagrangianHessianSparsityPattern()
void fint fint * k
double * hessValues
hessValues is a double array of the Hessian values.
Definition: OSGeneral.h:404
void fint fint fint real fint real real real real real real real * r
a sparse Jacobian matrix data structure
Definition: OSGeneral.h:300
#define OS_NEAR_EQUAL
we use OS_NEAR_EQUAL in unitTest to see if we are close to the optimal obj value
Definition: OSParameters.h:89
int * starts
starts holds an integer array of start elements, each start element points to the start of partials f...
Definition: OSGeneral.h:324
int getConstraintNumber()
Get number of constraints.
std::string getFileAsString(const char *fname)
read a file and return contents as a string.
Definition: OSFileUtil.cpp:35
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
std::vector< double > reverseAD(int p, std::vector< double > vdlambda)
Perform an AD reverse sweep.
void fint * m
The in-memory representation of an OSiL instance..
Definition: OSInstance.h:2262
OSInstance * osinstance
int * conVals
conVals holds an integer array of integers, conVals[i] is the number of constant terms in the gradien...
Definition: OSGeneral.h:330
class used to make it easy to read and write files.
Definition: OSFileUtil.h:37
void fint fint fint real fint real real real real real real real real * w
The in-memory representation of a SparseHessianMatrix..
Definition: OSGeneral.h:376
bool CheckGradientValues(SparseJacobianMatrix *sparseJac, double *objGrad, double x0, double x1, double x2, double x3, double y0, double y1, double w)
used for throwing exceptions.
Definition: OSErrorClass.h:31
void fint * n
std::vector< double > forwardAD(int p, std::vector< double > vdX)
Perform an AD forward sweep.
double * calculateObjectiveFunctionGradient(double *x, double *objLambda, double *conLambda, int objIdx, bool new_x, int highestOrder)
Calculate the gradient of the objective function indexed by objIdx.
void fint fint fint real fint real * x
CouExpr & log(CouExpr &e)