10 #include "IpTSymLinearSolver.hpp"
11 #include "IpGenTMatrix.hpp"
12 #include "IpIdentityMatrix.hpp"
13 #include "IpZeroMatrix.hpp"
14 #include "IpDenseVector.hpp"
18 # include "IpMa27TSolverInterface.hpp"
21 # include "IpMa57TSolverInterface.hpp"
24 # include "IpMc19TSymScalingMethod.hpp"
27 # include "IpPardisoSolverInterface.hpp"
30 # include "IpTAUCSSolverInterface.hpp"
33 # include "IpWsmpSolverInterface.hpp"
36 # include "IpMumpsSolverInterface.hpp"
41 using namespace Ipopt;
62 eq_g_fixed_map_(NULL),
63 all_x_free_map_(NULL),
64 all_g_fixed_map_(NULL),
66 eq_projected_d_(NULL),
81 std::string linear_solver;
82 options->GetStringValue(
"linear_solver", linear_solver, prefix_);
83 if (linear_solver==
"ma27") {
85 SolverInterface1 =
new Ma27TSolverInterface();
86 SolverInterface2 =
new Ma27TSolverInterface();
89 THROW_EXCEPTION(OPTION_INVALID,
90 "Selected linear solver MA27 not available.");
94 else if (linear_solver==
"ma57") {
96 SolverInterface1 =
new Ma57TSolverInterface();
97 SolverInterface2 =
new Ma57TSolverInterface();
100 THROW_EXCEPTION(OPTION_INVALID,
101 "Selected linear solver MA57 not available.");
105 else if (linear_solver==
"pardiso") {
107 SolverInterface1 =
new PardisoSolverInterface();
108 SolverInterface2 =
new PardisoSolverInterface();
111 THROW_EXCEPTION(OPTION_INVALID,
112 "Selected linear solver Pardiso not available.");
116 else if (linear_solver==
"taucs") {
118 SolverInterface1 =
new TAUCSSolverInterface();
119 SolverInterface2 =
new TAUCSSolverInterface();
122 THROW_EXCEPTION(OPTION_INVALID,
123 "Selected linear solver TAUCS not available.");
127 else if (linear_solver==
"wsmp") {
129 SolverInterface1 =
new WsmpSolverInterface();
130 SolverInterface2 =
new WsmpSolverInterface();
133 THROW_EXCEPTION(OPTION_INVALID,
134 "Selected linear solver WSMP not available.");
138 else if (linear_solver==
"mumps") {
139 #ifdef COIN_HAS_MUMPS
140 SolverInterface1 =
new MumpsSolverInterface();
141 SolverInterface2 =
new MumpsSolverInterface();
144 THROW_EXCEPTION(OPTION_INVALID,
145 "Selected linear solver MUMPS not available.");
152 std::string linear_system_scaling;
153 if (!options->GetStringValue(
"linear_system_scaling",
154 linear_system_scaling, prefix_)) {
156 if (linear_solver!=
"ma27" && linear_solver!=
"ma57") {
157 linear_system_scaling=
"none";
160 if (linear_system_scaling==
"mc19") {
162 ScalingMethod1 =
new Mc19TSymScalingMethod();
163 ScalingMethod2 =
new Mc19TSymScalingMethod();
166 THROW_EXCEPTION(OPTION_INVALID,
167 "Selected linear system scaling method MC19 not available.");
172 eq_tsymlinearsolver_ =
173 new TSymLinearSolver(SolverInterface1, ScalingMethod1);
174 all_tsymlinearsolver_ =
175 new TSymLinearSolver(SolverInterface2, ScalingMethod2);
183 delete [] irows_jac_;
184 delete [] jcols_jac_;
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_;
200 DBG_ASSERT(!initialized_);
207 TNLP::IndexStyleEnum index_style;
208 if (!tnlp_->get_nlp_info(n_, m_, nnz_jac_, nnz_hess_, index_style)) {
215 grad_f_ =
new Number[n_];
218 delete [] irows_jac_;
219 delete [] jcols_jac_;
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)) {
228 if (index_style == TNLP::FORTRAN_STYLE) {
229 for (Index i=0; i<nnz_jac_; i++) {
236 jac_vals_ =
new Number[nnz_jac_];
238 delete [] irows_hess_;
240 irows_hess_ =
new Index[nnz_hess_];
241 delete [] jcols_hess_;
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)) {
248 if (index_style == TNLP::FORTRAN_STYLE) {
249 for (Index i=0; i<nnz_hess_; i++) {
254 delete [] hess_vals_;
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_];
275 lambda_ =
new Number[m_];
278 delete [] eq_projected_d_;
279 eq_projected_d_ = NULL;
280 eq_projected_d_ =
new Number[n_];
301 const Number* orig_d,
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]);
311 for (
int i=0; i<
m; i++) {
312 printf(
"lam[%3d] = %15.8e\n", i, lam[i]);
328 if (!tnlp_->eval_jac_g(n_, x, new_x, m_, nnz_jac_,
329 NULL, NULL, jac_vals_)) {
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_)) {
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_)) {
356 if (eq_ng_fixed_>0) {
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_)) {
364 orig_d = eq_projected_d_;
369 bool new_activities =
false;
370 if (new_bounds || new_mults) {
371 new_activities =
true;
373 if (eq_ng_fixed_>0) {
374 const Number zTol = 1
e-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);
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);
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];
407 const Number lamTol = 1
e-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) {
414 active_g_.push_back(-(j+1));
415 DBG_ASSERT(g_l[j] > -1e19);
418 active_g_.push_back(j+1);
419 DBG_ASSERT(g_u[j] < 1e19);
422 jnlst_->Printf(J_MOREDETAILED, J_NLP,
423 "g[%5d] (%e,%e)\n", j, lam[j], jacTd[j]);
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_)) {
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_)) {
453 if (!tnlp_->eval_grad_f(n_, x, new_x, grad_f_)) {
456 if (!SolveSystem(grad_f_, NULL, NULL, lambda_)) {
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",
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_)) {
483 Number* trash =
new Number[m_];
484 for (Index
j=0;
j<m_;
j++) {
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];
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]);
500 Index imax = IpBlasIdamax(m_, trash, 1)-1;
501 Number max_trash = trash[imax];
503 const Number max_trash_tol = 1
e-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);
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]);
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];
533 if (!Compute_dTHLagd(projected_d, x, new_x, lam, new_lambda, dTHLagd)) {
538 printf(
"gradLagTd = %e dTHLagd = %e\n",gradLagTd,dTHLagd);
548 std::vector<int>& active_x,
549 std::vector<int>& active_g,
558 for (Index i=0; i<n_; i++) {
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_);
566 x_free_map[(-*i)-1] = -1;
567 DBG_ASSERT(x_l[(-*i)-1] > -1e19);
570 x_free_map[(*i)-1] = -1;
571 DBG_ASSERT(x_u[(*i)-1] < 1e19);
575 for (Index i=0; i<n_; i++) {
576 if (x_l[i] == x_u[i]) {
583 for (Index i=0; i<n_; i++) {
584 if (x_free_map[i] == 0) {
585 x_free_map[i] = nx_free++;
590 for (Index
j=0;
j<m_;
j++) {
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_);
598 g_fixed_map[(-*i)-1] = 0;
599 DBG_ASSERT(g_l[(-*i)-1] > -1e19);
602 g_fixed_map[(*i)-1] = 0;
603 DBG_ASSERT(g_u[(*i)-1] < 1e19);
607 for (Index
j=0;
j<m_;
j++) {
608 if (g_l[
j] == g_u[
j]) {
615 for (Index
j=0;
j<m_;
j++) {
616 if (g_fixed_map[
j] == 0) {
617 g_fixed_map[
j] = ng_fixed++;
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;
638 new GenTMatrixSpace(ng_fixed, nx_free, nnz_proj_jac, iRows, jCols);
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);
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);
653 comp_vec_space =
new CompoundVectorSpace(2, nx_free+ng_fixed);
655 comp_vec_space->SetCompSpace(0, *x_space);
657 comp_vec_space->SetCompSpace(1, *g_space);
663 const Index* x_free_map,
664 const Index* g_fixed_map,
669 comp_proj_matrix = comp_proj_matrix_space->MakeNewCompoundSymMatrix();
672 Number* vals = tjac->Values();
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];
681 DBG_ASSERT(inz == tjac->Nonzeros());
685 tsymlinearsolver->ReducedInitialize(*jnlst_, *options_, prefix_);
693 Number* sol_x, Number* sol_g,
694 const Index* x_free_map,
695 const Index* g_fixed_map,
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];
712 xvals[ix] = rhs_x[i];
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];
726 gvals[jg] = rhs_g[
j];
736 ESymSolverStatus solver_retval =
737 tsymlinearsolver->Solve(*comp_proj_matrix, *rhs, *sol,
false, 0);
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");
744 tsymlinearsolver->Solve(*comp_proj_matrix, *rhs, *sol,
false, 0);
747 if (solver_retval != SYMSOLVER_SUCCESS) {
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];
762 sol_x[i] = xvals[ix];
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];
777 sol_g[
j] = gvals[ig];
789 const Number* d,
const Number*
x,
bool new_x,
const Number* lambda,
790 bool new_lambda, Number& dTHLagd)
792 if (new_x || new_lambda || !hess_vals_) {
794 hess_vals_ =
new Number[nnz_hess_];
796 if (!tnlp_->eval_h(n_, x, new_x, 1., m_, lambda, new_lambda, nnz_hess_,
797 NULL, NULL, hess_vals_)) {
802 for (Index i=0; i<nnz_hess_; i++) {
803 Index
irow = irows_hess_[i];
804 Index jcol = jcols_hess_[i];
806 dTHLagd += d[
irow]*d[
irow]*hess_vals_[i];
809 dTHLagd += 2.*d[
irow]*d[jcol]*hess_vals_[i];
bool IsValid(const OSSmartPtr< U > &smart_ptr)
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 ...
bool Compute_dTHLagd(const Number *d, const Number *x, bool new_x, const Number *lambda, bool new_lambda, Number &dTHLagd)
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)
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 fint fint real fint real * x