BonCurvatureEstimator.cpp
Go to the documentation of this file.
1 // Copyright (C) 2006, 2007 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // $Id: BonCurvatureEstimator.cpp 2106 2015-01-20 10:33:55Z stefan $
6 //
7 // Author: Andreas Waechter IBM 2006-10-11
8 
10 #include "IpTSymLinearSolver.hpp"
11 #include "IpGenTMatrix.hpp"
12 #include "IpIdentityMatrix.hpp"
13 #include "IpZeroMatrix.hpp"
14 #include "IpDenseVector.hpp"
15 #include "IpBlas.hpp"
16 #include <cmath>
17 #ifdef HAVE_MA27
18 # include "IpMa27TSolverInterface.hpp"
19 #endif
20 #ifdef HAVE_MA57
21 # include "IpMa57TSolverInterface.hpp"
22 #endif
23 #ifdef HAVE_MC19
24 # include "IpMc19TSymScalingMethod.hpp"
25 #endif
26 #ifdef HAVE_PARDISO
27 # include "IpPardisoSolverInterface.hpp"
28 #endif
29 #ifdef HAVE_TAUCS
30 # include "IpTAUCSSolverInterface.hpp"
31 #endif
32 #ifdef HAVE_WSMP
33 # include "IpWsmpSolverInterface.hpp"
34 #endif
35 #ifdef COIN_HAS_MUMPS
36 # include "IpMumpsSolverInterface.hpp"
37 #endif
38 
39 namespace Bonmin
40 {
41  using namespace Ipopt;
42 
43  // ToDo: Consider NLP scaling?
44 
47  SmartPtr<OptionsList> options,
48  SmartPtr<TNLP> tnlp)
49  :
50  jnlst_(jnlst),
51  options_(options),
52  prefix_(""),
53  tnlp_(tnlp),
54  grad_f_(NULL),
55  irows_jac_(NULL),
56  jcols_jac_(NULL),
57  jac_vals_(NULL),
58  irows_hess_(NULL),
59  jcols_hess_(NULL),
60  hess_vals_(NULL),
61  eq_x_free_map_(NULL),
62  eq_g_fixed_map_(NULL),
63  all_x_free_map_(NULL),
64  all_g_fixed_map_(NULL),
65  lambda_(NULL),
66  eq_projected_d_(NULL),
67  initialized_(false)
68  {
69  DBG_ASSERT(IsValid(jnlst));
70  DBG_ASSERT(IsValid(options));
71  DBG_ASSERT(IsValid(tnlp));
72 
74  // Create a strategy object for solving the linear system for the //
75  // projection matrix //
77 
78  // The following linear are taken from AlgBuilder in Ipopt
81  std::string linear_solver;
82  options->GetStringValue("linear_solver", linear_solver, prefix_);
83  if (linear_solver=="ma27") {
84 #ifdef HAVE_MA27
85  SolverInterface1 = new Ma27TSolverInterface();
86  SolverInterface2 = new Ma27TSolverInterface();
87 #else
88 
89  THROW_EXCEPTION(OPTION_INVALID,
90  "Selected linear solver MA27 not available.");
91 #endif
92 
93  }
94  else if (linear_solver=="ma57") {
95 #ifdef HAVE_MA57
96  SolverInterface1 = new Ma57TSolverInterface();
97  SolverInterface2 = new Ma57TSolverInterface();
98 #else
99 
100  THROW_EXCEPTION(OPTION_INVALID,
101  "Selected linear solver MA57 not available.");
102 #endif
103 
104  }
105  else if (linear_solver=="pardiso") {
106 #ifdef HAVE_PARDISO
107  SolverInterface1 = new PardisoSolverInterface();
108  SolverInterface2 = new PardisoSolverInterface();
109 #else
110 
111  THROW_EXCEPTION(OPTION_INVALID,
112  "Selected linear solver Pardiso not available.");
113 #endif
114 
115  }
116  else if (linear_solver=="taucs") {
117 #ifdef HAVE_TAUCS
118  SolverInterface1 = new TAUCSSolverInterface();
119  SolverInterface2 = new TAUCSSolverInterface();
120 #else
121 
122  THROW_EXCEPTION(OPTION_INVALID,
123  "Selected linear solver TAUCS not available.");
124 #endif
125 
126  }
127  else if (linear_solver=="wsmp") {
128 #ifdef HAVE_WSMP
129  SolverInterface1 = new WsmpSolverInterface();
130  SolverInterface2 = new WsmpSolverInterface();
131 #else
132 
133  THROW_EXCEPTION(OPTION_INVALID,
134  "Selected linear solver WSMP not available.");
135 #endif
136 
137  }
138  else if (linear_solver=="mumps") {
139 #ifdef COIN_HAS_MUMPS
140  SolverInterface1 = new MumpsSolverInterface();
141  SolverInterface2 = new MumpsSolverInterface();
142 #else
143 
144  THROW_EXCEPTION(OPTION_INVALID,
145  "Selected linear solver MUMPS not available.");
146 #endif
147 
148  }
149 
150  SmartPtr<TSymScalingMethod> ScalingMethod1;
151  SmartPtr<TSymScalingMethod> ScalingMethod2;
152  std::string linear_system_scaling;
153  if (!options->GetStringValue("linear_system_scaling",
154  linear_system_scaling, prefix_)) {
155  // By default, don't use mc19 for non-HSL solvers
156  if (linear_solver!="ma27" && linear_solver!="ma57") {
157  linear_system_scaling="none";
158  }
159  }
160  if (linear_system_scaling=="mc19") {
161 #ifdef HAVE_MC19
162  ScalingMethod1 = new Mc19TSymScalingMethod();
163  ScalingMethod2 = new Mc19TSymScalingMethod();
164 #else
165 
166  THROW_EXCEPTION(OPTION_INVALID,
167  "Selected linear system scaling method MC19 not available.");
168 #endif
169 
170  }
171 
172  eq_tsymlinearsolver_ =
173  new TSymLinearSolver(SolverInterface1, ScalingMethod1);
174  all_tsymlinearsolver_ =
175  new TSymLinearSolver(SolverInterface2, ScalingMethod2);
176  // End of lines from AlgBuilder
177  }
178 
180  {
181  if (initialized_) {
182  delete [] grad_f_;
183  delete [] irows_jac_;
184  delete [] jcols_jac_;
185  delete [] jac_vals_;
186  delete [] irows_hess_;
187  delete [] jcols_hess_;
188  delete [] hess_vals_;
189  delete [] eq_x_free_map_;
190  delete [] eq_g_fixed_map_;
191  delete [] all_x_free_map_;
192  delete [] all_g_fixed_map_;
193  delete [] eq_projected_d_;
194  delete [] lambda_;
195  }
196  }
197 
199  {
200  DBG_ASSERT(!initialized_);
201 
203  // Prepare internal data structures //
205 
206  // Get sizes
207  TNLP::IndexStyleEnum index_style;
208  if (!tnlp_->get_nlp_info(n_, m_, nnz_jac_, nnz_hess_, index_style)) {
209  return false;
210  }
211 
212  // Space for gradient
213  delete [] grad_f_;
214  grad_f_ = NULL;
215  grad_f_ = new Number[n_];
216 
217  // Get nonzero entries in the matrices
218  delete [] irows_jac_;
219  delete [] jcols_jac_;
220  irows_jac_ = NULL;
221  jcols_jac_ = NULL;
222  irows_jac_ = new Index[nnz_jac_];
223  jcols_jac_ = new Index[nnz_jac_];
224  if (!tnlp_->eval_jac_g(n_, NULL, false, m_, nnz_jac_,
225  irows_jac_, jcols_jac_, NULL)) {
226  return false;
227  }
228  if (index_style == TNLP::FORTRAN_STYLE) {
229  for (Index i=0; i<nnz_jac_; i++) {
230  irows_jac_[i]--;
231  jcols_jac_[i]--;
232  }
233  }
234  delete [] jac_vals_;
235  jac_vals_ = NULL;
236  jac_vals_ = new Number[nnz_jac_];
237 
238  delete [] irows_hess_;
239  irows_hess_ = NULL;
240  irows_hess_ = new Index[nnz_hess_];
241  delete [] jcols_hess_;
242  jcols_hess_ = NULL;
243  jcols_hess_ = new Index[nnz_hess_];
244  if (!tnlp_->eval_h(n_, NULL, false, 1., m_, NULL, false, nnz_hess_,
245  irows_hess_, jcols_hess_, NULL)) {
246  return false;
247  }
248  if (index_style == TNLP::FORTRAN_STYLE) {
249  for (Index i=0; i<nnz_hess_; i++) {
250  irows_hess_[i]--;
251  jcols_hess_[i]--;
252  }
253  }
254  delete [] hess_vals_;
255  hess_vals_ = NULL; // We set it to NULL, so that we know later
256  // that we still need to compute the values
257 
258  // Get space for the activities maps
259  delete [] eq_x_free_map_;
260  delete [] eq_g_fixed_map_;
261  delete [] all_x_free_map_;
262  delete [] all_g_fixed_map_;
263  eq_x_free_map_ = NULL;
264  eq_g_fixed_map_ = NULL;
265  all_x_free_map_ = NULL;
266  all_g_fixed_map_ = NULL;
267  eq_x_free_map_ = new Index[n_];
268  eq_g_fixed_map_ = new Index[m_];
269  all_x_free_map_ = new Index[n_];
270  all_g_fixed_map_ = new Index[m_];
271 
272  // Get space for the multipliers
273  delete [] lambda_;
274  lambda_ = NULL;
275  lambda_ = new Number[m_];
276 
277  // Get space for projected d
278  delete [] eq_projected_d_;
279  eq_projected_d_ = NULL;
280  eq_projected_d_ = new Number[n_];
281 
282  initialized_ = true;
283  return true;
284  }
285 
286  bool
288  int n,
289  const Number* x,
290  bool new_x,
291  const Number* x_l,
292  const Number* x_u,
293  const Number* g_l,
294  const Number* g_u,
295  bool new_bounds,
296  const Number* z_L,
297  const Number* z_U,
298  int m,
299  const Number* lam,
300  bool new_mults,
301  const Number* orig_d,
302  Number* projected_d,
303  Number& gradLagTd,
304  Number& dTHLagd)
305  {
306 #if 0
307  printf("new_bounds = %d new_x = %d new_mults = %d\n", new_bounds, new_x, new_mults);
308  for (int i=0; i<n; i++) {
309  printf("x[%3d] = %15.8e orig_d[%3d] = %15.8e z_L[%3d] = %15.8e z_U[%3d] = %15.8e\n",i,x[i],i,orig_d[i],i,z_L[i],i,z_U[i]);
310  }
311  for (int i=0; i<m; i++) {
312  printf("lam[%3d] = %15.8e\n", i, lam[i]);
313  }
314 #endif
315  if (!initialized_) {
316  Initialize();
317  new_bounds = true;
318  new_mults = true;
319  }
320  //DELETEME
321  new_bounds = true;
322 
323  DBG_ASSERT(n == n_);
324  DBG_ASSERT(m == m_);
325 
326  // If necessary, get new Jacobian values (for the original matrix)
327  if (new_x) {
328  if (!tnlp_->eval_jac_g(n_, x, new_x, m_, nnz_jac_,
329  NULL, NULL, jac_vals_)) {
330  return false;
331  }
332  }
333 
334  // First we compute the direction projected into the space of only
335  // the equality constraints
336  if (new_x) {
337  std::vector<int> dummy_active_x;
338  std::vector<int> dummy_active_g;
339  if (!PrepareNewMatrixStructure(x_l, x_u, g_l, g_u,
340  dummy_active_x, dummy_active_g,
341  eq_nx_free_, eq_x_free_map_,
342  eq_ng_fixed_, eq_g_fixed_map_,
343  eq_comp_proj_matrix_space_,
344  eq_comp_vec_space_)) {
345  return false;
346  }
347 
348  if (!PrepareNewMatrixValues(eq_x_free_map_, eq_g_fixed_map_,
349  eq_comp_proj_matrix_space_,
350  eq_comp_proj_matrix_,
351  eq_tsymlinearsolver_)) {
352  return false;
353  }
354  }
355 
356  if (eq_ng_fixed_>0) {
357  // Compute the projection of the direction
358  if (!SolveSystem(orig_d, NULL, eq_projected_d_, NULL,
359  eq_x_free_map_, eq_g_fixed_map_,
360  eq_comp_vec_space_, eq_comp_proj_matrix_,
361  eq_tsymlinearsolver_)) {
362  return false;
363  }
364  orig_d = eq_projected_d_; // This way we don't need to rememeber
365  // how the direction was projected;
366  }
367 
368  // If necessary, determine new activities
369  bool new_activities = false;
370  if (new_bounds || new_mults) {
371  new_activities = true;
372  active_x_.clear();
373  if (eq_ng_fixed_>0) {
374  const Number zTol = 1e-4;
375  jnlst_->Printf(J_MOREDETAILED, J_NLP,
376  "List of variables considered fixed (with orig_d and z)\n");
377  for (Index i=0; i<n; i++) {
378  if (x_l[i] < x_u[i]) {
379  if (orig_d[i]>0. && z_U[i]*orig_d[i]>zTol) {
380  active_x_.push_back(i+1);
381  jnlst_->Printf(J_MOREDETAILED, J_NLP,
382  "x[%5d] (%e,%e)\n", i, orig_d[i], z_U[i]);
383  DBG_ASSERT(x_u[i] < 1e19);
384  }
385  else if (orig_d[i]<0. && -z_L[i]*orig_d[i]>zTol) {
386  active_x_.push_back(-(i+1));
387  jnlst_->Printf(J_MOREDETAILED, J_NLP,
388  "x[%5d] (%e,%e)\n", i, orig_d[i], z_L[i]);
389  DBG_ASSERT(x_l[i] > -1e19);
390  }
391  }
392  }
393  }
394 
395  active_g_.clear();
396  // Compute the product of the direction with the constraint Jacobian
397  // This could be done more efficient if we have d in sparse format
398  Number* jacTd = new Number[m];
399  const Number zero = 0.;
400  IpBlasDcopy(m, &zero, 0, jacTd, 1);
401  for (Index i=0; i<nnz_jac_; i++) {
402  const Index& irow = irows_jac_[i];
403  const Index& jcol = jcols_jac_[i];
404  jacTd[irow] += jac_vals_[i]*orig_d[jcol];
405  }
406 
407  const Number lamTol = 1e-4;
408  jnlst_->Printf(J_MOREDETAILED, J_NLP,
409  "List of constraints considered fixed (with lam and jacTd)\n");
410  for (Index j=0; j<m; j++) {
411  if (g_l[j] < g_u[j] && fabs(lam[j]) > lamTol) {
412  if (lam[j]*jacTd[j] > 0) {
413  if (lam[j] < 0.) {
414  active_g_.push_back(-(j+1));
415  DBG_ASSERT(g_l[j] > -1e19);
416  }
417  else {
418  active_g_.push_back(j+1);
419  DBG_ASSERT(g_u[j] < 1e19);
420  }
421  // active_g_.push_back(j+1);
422  jnlst_->Printf(J_MOREDETAILED, J_NLP,
423  "g[%5d] (%e,%e)\n", j, lam[j], jacTd[j]);
424  }
425  }
426  }
427  delete [] jacTd;
428  }
429 
430  // Check if the structure of the matrix has changed
431  if (new_activities) {
432  if (!PrepareNewMatrixStructure(x_l, x_u, g_l, g_u,
433  active_x_, active_g_,
434  all_nx_free_, all_x_free_map_,
435  all_ng_fixed_, all_g_fixed_map_,
436  all_comp_proj_matrix_space_,
437  all_comp_vec_space_)) {
438  return false;
439  }
440  }
441 
442  bool new_lambda = false;
443  if (new_x || new_activities) {
444  if (!PrepareNewMatrixValues(all_x_free_map_, all_g_fixed_map_,
445  all_comp_proj_matrix_space_,
446  all_comp_proj_matrix_,
447  all_tsymlinearsolver_)) {
448  return false;
449  }
450 
451 #ifdef lambdas
452  // Compute least square multipliers for the given activities
453  if (!tnlp_->eval_grad_f(n_, x, new_x, grad_f_)) {
454  return false;
455  }
456  if (!SolveSystem(grad_f_, NULL, NULL, lambda_)) {
457  return false;
458  }
459  IpBlasDscal(m_, -1., lambda_, 1);
460  if (jnlst_->ProduceOutput(J_MOREVECTOR, J_NLP)) {
461  jnlst_->Printf(J_MOREVECTOR, J_NLP,
462  "Curvature Estimator: least square multiplier:\n");
463  for (Index i=0; i<m_; i++) {
464  jnlst_->Printf(J_MOREVECTOR, J_NLP, "lambda[%5d] = %23.16e\n",
465  i, lambda_[i]);
466  }
467  }
468  new_lambda = true;
469 #endif
470  }
471 
472  // Compute the projection of the direction
473  if (!SolveSystem(orig_d, NULL, projected_d, NULL,
474  all_x_free_map_, all_g_fixed_map_,
475  all_comp_vec_space_, all_comp_proj_matrix_,
476  all_tsymlinearsolver_)) {
477  return false;
478  }
479 
480  // Sanity check to see if the thing is indeed in the null space
481  // (if the constraint gradients are rank-deficient, the solver
482  // might not have done a good job)
483  Number* trash = new Number[m_];
484  for (Index j=0; j<m_; j++) {
485  trash[j] = 0.;
486  }
487  for (Index i=0; i<nnz_jac_; i++) {
488  const Index &irow = irows_jac_[i];
489  const Index &jcol = jcols_jac_[i];
490  if (all_x_free_map_[jcol] >= 0 && all_g_fixed_map_[irow] >= 0) {
491  trash[irow] += jac_vals_[i]*projected_d[jcol];
492  }
493  }
494  if (jnlst_->ProduceOutput(J_MOREVECTOR, J_NLP)) {
495  for (Index j=0; j<m_; j++) {
496  jnlst_->Printf(J_MOREVECTOR, J_NLP,
497  "nullspacevector[%5d] = %e\n", j, trash[j]);
498  }
499  }
500  Index imax = IpBlasIdamax(m_, trash, 1)-1;
501  Number max_trash = trash[imax];
502  delete [] trash;
503  const Number max_trash_tol = 1e-6;
504  if (max_trash > max_trash_tol) {
505  jnlst_->Printf(J_WARNING, J_NLP,
506  "Curvature Estimator: Bad solution from linear solver with max_red = %e:\n", max_trash);
507  return false;
508  }
509 
510  if (jnlst_->ProduceOutput(J_MOREVECTOR, J_NLP)) {
511  jnlst_->Printf(J_MOREVECTOR, J_NLP,
512  "Curvature Estimator: original and projected directions are:\n");
513  for (Index i=0; i<n_; i++) {
514  jnlst_->Printf(J_MOREVECTOR, J_NLP,
515  "orig_d[%5d] = %23.16e proj_d[%5d] = %23.16e\n",
516  i, orig_d[i], i, projected_d[i]);
517  }
518  }
519 
520  gradLagTd = 0.;
521 #ifdef lambdas
522  // Compute the product with the gradient of the Lagrangian
523  gradLagTd = IpBlasDdot(n, projected_d, 1, grad_f_, 1);
524  for (Index i=0; i<nnz_jac_; i++) {
525  const Index &irow = irows_jac_[i];
526  const Index &jcol = jcols_jac_[i];
527  gradLagTd += lambda_[irow]*jac_vals_[i]*projected_d[jcol];
528  }
529 #endif
530 
531  // Compute the product with the Hessian of the Lagrangian
532  // if (!Compute_dTHLagd(projected_d, x, new_x, lambda_, new_lambda, dTHLagd)) {
533  if (!Compute_dTHLagd(projected_d, x, new_x, lam, new_lambda, dTHLagd)) {
534  return false;
535  }
536 
537 #if 0
538  printf("gradLagTd = %e dTHLagd = %e\n",gradLagTd,dTHLagd);
539 #endif
540  return true;
541  }
542 
544  const Number* x_l,
545  const Number* x_u,
546  const Number* g_l,
547  const Number* g_u,
548  std::vector<int>& active_x,
549  std::vector<int>& active_g,
550  Index& nx_free,
551  Index* x_free_map,
552  Index& ng_fixed,
553  Index* g_fixed_map,
554  SmartPtr<CompoundSymMatrixSpace>& comp_proj_matrix_space,
555  SmartPtr<CompoundVectorSpace>& comp_vec_space)
556  {
557  // Deterimine which variables are free
558  for (Index i=0; i<n_; i++) {
559  x_free_map[i] = 0;
560  }
561  // fixed by activities
562  for (std::vector<int>::iterator i=active_x.begin();
563  i != active_x.end(); i++) {
564  DBG_ASSERT(*i != 0 && *i<=n_ && *i>=-n_);
565  if (*i<0) {
566  x_free_map[(-*i)-1] = -1;
567  DBG_ASSERT(x_l[(-*i)-1] > -1e19);
568  }
569  else {
570  x_free_map[(*i)-1] = -1;
571  DBG_ASSERT(x_u[(*i)-1] < 1e19);
572  }
573  }
574  // fixed by bounds
575  for (Index i=0; i<n_; i++) {
576  if (x_l[i] == x_u[i]) {
577  x_free_map[i] = -1;
578  }
579  }
580  // Correct the numbering in the x map and determine number of
581  // free variables
582  nx_free = 0;
583  for (Index i=0; i<n_; i++) {
584  if (x_free_map[i] == 0) {
585  x_free_map[i] = nx_free++;
586  }
587  }
588 
589  // Determine which constraints are fixed
590  for (Index j=0; j<m_; j++) {
591  g_fixed_map[j] = -1;
592  }
593  // fixed by activities
594  for (std::vector<int>::iterator i=active_g.begin();
595  i != active_g.end(); i++) {
596  DBG_ASSERT(*i != 0 && *i<=m_ && *i>=-m_);
597  if (*i<0) {
598  g_fixed_map[(-*i)-1] = 0;
599  DBG_ASSERT(g_l[(-*i)-1] > -1e19); //ToDo look at option?
600  }
601  else {
602  g_fixed_map[(*i)-1] = 0;
603  DBG_ASSERT(g_u[(*i)-1] < 1e19);
604  }
605  }
606  // fixed by bounds
607  for (Index j=0; j<m_; j++) {
608  if (g_l[j] == g_u[j]) {
609  g_fixed_map[j] = 0;
610  }
611  }
612  // Correct the numbering in the g map and determine number of
613  // fixed constraints
614  ng_fixed = 0;
615  for (Index j=0; j<m_; j++) {
616  if (g_fixed_map[j] == 0) {
617  g_fixed_map[j] = ng_fixed++;
618  }
619  }
620 
621  // Determine the row and column indices for the Jacobian of the fixed
622  // constraints in the space of the free variables
623  Index* iRows = new Index[nnz_jac_];
624  Index* jCols = new Index[nnz_jac_];
625  Index nnz_proj_jac = 0;
626  for (Index i=0; i<nnz_jac_; i++) {
627  const Index &irow = irows_jac_[i];
628  const Index &jcol = jcols_jac_[i];
629  if (x_free_map[jcol] >= 0 && g_fixed_map[irow] >= 0) {
630  iRows[nnz_proj_jac] = g_fixed_map[irow] + 1;
631  jCols[nnz_proj_jac] = x_free_map[jcol] + 1;
632  nnz_proj_jac++;
633  }
634  }
635 
636  // Create the matrix space for the Jacobian matrices
637  SmartPtr<GenTMatrixSpace> proj_jac_space =
638  new GenTMatrixSpace(ng_fixed, nx_free, nnz_proj_jac, iRows, jCols);
639  delete [] iRows;
640  delete [] jCols;
641 
642  // Create Matrix space for the projection matrix
643  comp_proj_matrix_space =
644  new CompoundSymMatrixSpace(2, nx_free+ng_fixed);
645  comp_proj_matrix_space->SetBlockDim(0, nx_free);
646  comp_proj_matrix_space->SetBlockDim(1, ng_fixed);
647  SmartPtr<SymMatrixSpace> identity_space =
648  new IdentityMatrixSpace(nx_free);
649  comp_proj_matrix_space->SetCompSpace(0, 0, *identity_space, true);
650  comp_proj_matrix_space->SetCompSpace(1, 0, *proj_jac_space, true);
651 
652  // Create a Vector space for the rhs and sol
653  comp_vec_space = new CompoundVectorSpace(2, nx_free+ng_fixed);
654  SmartPtr<DenseVectorSpace> x_space = new DenseVectorSpace(nx_free);
655  comp_vec_space->SetCompSpace(0, *x_space);
656  SmartPtr<DenseVectorSpace> g_space = new DenseVectorSpace(ng_fixed);
657  comp_vec_space->SetCompSpace(1, *g_space);
658 
659  return true;
660  }
661 
663  const Index* x_free_map,
664  const Index* g_fixed_map,
665  SmartPtr<CompoundSymMatrixSpace>& comp_proj_matrix_space,
666  SmartPtr<CompoundSymMatrix>& comp_proj_matrix,
667  SmartPtr<TSymLinearSolver>& tsymlinearsolver)
668  {
669  comp_proj_matrix = comp_proj_matrix_space->MakeNewCompoundSymMatrix();
670  SmartPtr<Matrix> jac = comp_proj_matrix->GetCompNonConst(1, 0);
671  SmartPtr<GenTMatrix> tjac = static_cast<GenTMatrix*> (GetRawPtr(jac));
672  Number* vals = tjac->Values();
673  Index inz=0;
674  for (Index i=0; i<nnz_jac_; i++) {
675  Index irow = irows_jac_[i];
676  Index jcol = jcols_jac_[i];
677  if (x_free_map[jcol] >= 0 && g_fixed_map[irow] >= 0) {
678  vals[inz++] = jac_vals_[i];
679  }
680  }
681  DBG_ASSERT(inz == tjac->Nonzeros());
682 
683  // We need to reset the linear solver object, so that it knows
684  // that the structure of the linear system has changed
685  tsymlinearsolver->ReducedInitialize(*jnlst_, *options_, prefix_);
686 
687  return true;
688  }
689 
691  const Number* rhs_x,
692  const Number* rhs_g,
693  Number* sol_x, Number* sol_g,
694  const Index* x_free_map,
695  const Index* g_fixed_map,
696  SmartPtr<CompoundVectorSpace>& comp_vec_space,
697  SmartPtr<CompoundSymMatrix>& comp_proj_matrix,
698  SmartPtr<TSymLinearSolver>& tsymlinearsolver)
699  {
700  // Create a vector for the RHS
701  SmartPtr<CompoundVector> rhs = comp_vec_space->MakeNewCompoundVector();
702  SmartPtr<Vector> vrhs_x = rhs->GetCompNonConst(0);
703  SmartPtr<Vector> vrhs_g = rhs->GetCompNonConst(1);
704  // Now fill this vector with the values, extracting the relevant entries
705  if (rhs_x) {
706  SmartPtr<DenseVector> drhs_x =
707  static_cast<DenseVector*> (GetRawPtr(vrhs_x));
708  Number* xvals = drhs_x->Values();
709  for (Index i=0; i<n_; i++) {
710  const Index& ix = x_free_map[i];
711  if (ix>=0) {
712  xvals[ix] = rhs_x[i];
713  }
714  }
715  }
716  else {
717  vrhs_x->Set(0.);
718  }
719  if (rhs_g) {
720  SmartPtr<DenseVector> drhs_g =
721  static_cast<DenseVector*> (GetRawPtr(vrhs_g));
722  Number* gvals = drhs_g->Values();
723  for (Index j=0; j<m_; j++) {
724  const Index& jg = g_fixed_map[j];
725  if (jg>=0) {
726  gvals[jg] = rhs_g[j];
727  }
728  }
729  }
730  else {
731  vrhs_g->Set(0.);
732  }
733 
734  // Solve the linear system
735  SmartPtr<CompoundVector> sol = comp_vec_space->MakeNewCompoundVector();
736  ESymSolverStatus solver_retval =
737  tsymlinearsolver->Solve(*comp_proj_matrix, *rhs, *sol, false, 0);
738  // For now we try, if the system is reported to be singular, to
739  // still get a solution; ToDo
740  if (solver_retval == SYMSOLVER_SINGULAR) {
741  jnlst_->Printf(J_DETAILED, J_NLP,
742  "Projection matrix reported to be singular, but we try to obtain a solution anyway.\n");
743  solver_retval =
744  tsymlinearsolver->Solve(*comp_proj_matrix, *rhs, *sol, false, 0);
745  }
746 
747  if (solver_retval != SYMSOLVER_SUCCESS) {
748  // DELETEME
749  //printf("Return code from Solver is %d\n", solver_retval);
750  return false;
751  }
752 
753  // and get the solution out of it
754  if (sol_x) {
755  SmartPtr<Vector> vsol_x = sol->GetCompNonConst(0);
757  static_cast<const DenseVector*> (GetRawPtr(vsol_x));
758  const Number* xvals = dsol_x->Values();
759  for (Index i=0; i<n_; i++) {
760  const Index& ix = x_free_map[i];
761  if (ix >=0) {
762  sol_x[i] = xvals[ix];
763  }
764  else {
765  sol_x[i] = 0.;
766  }
767  }
768  }
769  if (sol_g) {
770  SmartPtr<Vector> vsol_g = sol->GetCompNonConst(1);
772  static_cast<const DenseVector*> (GetRawPtr(vsol_g));
773  const Number* gvals = dsol_g->Values();
774  for (Index j=0; j<m_; j++) {
775  const Index& ig = g_fixed_map[j];
776  if (ig>=0) {
777  sol_g[j] = gvals[ig];
778  }
779  else {
780  sol_g[j] = 0.;
781  }
782  }
783  }
784 
785  return true;
786  }
787 
789  const Number* d, const Number* x, bool new_x, const Number* lambda,
790  bool new_lambda, Number& dTHLagd)
791  {
792  if (new_x || new_lambda || !hess_vals_) {
793  if (!hess_vals_) {
794  hess_vals_ = new Number[nnz_hess_];
795  }
796  if (!tnlp_->eval_h(n_, x, new_x, 1., m_, lambda, new_lambda, nnz_hess_,
797  NULL, NULL, hess_vals_)) {
798  return false;
799  }
800  }
801  dTHLagd = 0.;
802  for (Index i=0; i<nnz_hess_; i++) {
803  Index irow = irows_hess_[i];
804  Index jcol = jcols_hess_[i];
805  if (irow == jcol) {
806  dTHLagd += d[irow]*d[irow]*hess_vals_[i];
807  }
808  else {
809  dTHLagd += 2.*d[irow]*d[jcol]*hess_vals_[i];
810  }
811  }
812  return true;
813  }
814 
815 
816 } // namespace Bonmin
bool IsValid(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:465
bool ComputeNullSpaceCurvature(int n, const Number *x, bool new_x, const Number *x_l, const Number *x_u, const Number *g_l, const Number *g_u, bool new_bounds, const Number *z_L, const Number *z_U, int m, const Number *lam, bool new_mults, const Number *orig_d, Number *projected_d, Number &gradLagTd, Number &dTHLagd)
Method for computing a direction projected_d related to the given direction orig_d and the two-sided ...
fint irow
bool Compute_dTHLagd(const Number *d, const Number *x, bool new_x, const Number *lambda, bool new_lambda, Number &dTHLagd)
static char * j
Definition: OSdtoa.cpp:3622
virtual ~CurvatureEstimator()
Destructor.
void fint fint fint real fint real real real real real real real real real * e
bool PrepareNewMatrixValues(const Index *x_free_map, const Index *g_fixed_map, SmartPtr< CompoundSymMatrixSpace > &comp_proj_matrix_space, SmartPtr< CompoundSymMatrix > &comp_proj_matrix, SmartPtr< TSymLinearSolver > &tsymlinearsolver)
CurvatureEstimator()
Default Constructor.
bool PrepareNewMatrixStructure(const Number *x_l, const Number *x_u, const Number *g_l, const Number *g_u, std::vector< int > &active_x, std::vector< int > &active_g, Index &nx_free, Index *x_free_map, Index &ng_fixed, Index *g_fixed_map, SmartPtr< CompoundSymMatrixSpace > &comp_proj_matrix_space, SmartPtr< CompoundVectorSpace > &comp_vec_space)
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
bool SolveSystem(const Number *rhs_x, const Number *rhs_g, Number *sol_x, Number *sol_g, const Index *x_free_map, const Index *g_fixed_map, SmartPtr< CompoundVectorSpace > &comp_vec_space, SmartPtr< CompoundSymMatrix > &comp_proj_matrix, SmartPtr< TSymLinearSolver > &tsymlinearsolver)
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real real fint real fint real * lam
void fint * m
void fint * n
void fint fint fint real fint real * x