57 #include "Teuchos_oblackholestream.hpp"
58 #include "Teuchos_GlobalMPISession.hpp"
78 Teuchos::SerialDenseMatrix<int, Real>
H_;
90 void apply_mass(std::vector<Real> &Mz,
const std::vector<Real> &z ) {
91 Mz.resize(this->
nu_,0.0);
92 for (
int i=0; i<this->
nu_; i++) {
94 Mz[i] = this->
hu_/6.0*(2.0*z[i] + z[i+1]);
96 else if ( i == this->nu_-1 ) {
97 Mz[i] = this->
hu_/6.0*(z[i-1] + 2.0*z[i]);
100 Mz[i] = this->
hu_/6.0*(z[i-1] + 4.0*z[i] + z[i+1]);
106 return (x <= 0.5) ? 1.0 : 0.0;
110 const std::vector<Real> &d,
const std::vector<Real> &u,
111 bool addBC =
true ) {
113 Bd.resize(this->
nu_,0.0);
114 for (
int i = 0; i < this->
nu_; i++) {
116 Bd[i] = 1.0/this->
hu_*( u[i]*d[i] + (u[i]-u[i+1])*d[i+1] );
118 else if ( i == this->nu_-1 ) {
119 Bd[i] = 1.0/this->
hu_*( (u[i]-u[i-1])*d[i] + u[i]*d[i+1] );
122 Bd[i] = 1.0/this->
hu_*( (u[i]-u[i-1])*d[i] + (u[i]-u[i+1])*d[i+1] );
126 Bd[ 0] -= this->
u0_*d[ 0]/this->
hu_;
127 Bd[this->nu_-1] -= this->
u1_*d[this->
nz_-1]/this->
hu_;
132 const std::vector<Real> &d,
const std::vector<Real> &u,
133 bool addBC =
true ) {
135 Bd.resize(this->
nz_,0.0);
136 for (
int i = 0; i < this->
nz_; i++) {
138 Bd[i] = 1.0/this->
hu_*u[i]*d[i];
140 else if ( i == this->nz_-1 ) {
141 Bd[i] = 1.0/this->
hu_*u[i-1]*d[i-1];
144 Bd[i] = 1.0/this->
hu_*( (u[i]-u[i-1])*(d[i]-d[i-1]) );
148 Bd[ 0] -= this->
u0_*d[ 0]/this->
hu_;
149 Bd[this->nz_-1] -= this->
u1_*d[this->
nu_-1]/this->
hu_;
156 std::vector<Real> d(this->
nu_,1.0);
157 std::vector<Real> o(this->
nu_-1,1.0);
158 for (
int i = 0; i < this->
nu_; i++ ) {
159 d[i] = (z[i] + z[i+1])/this->
hu_;
160 if ( i < this->nu_-1 ) {
161 o[i] *= -z[i+1]/this->
hu_;
166 u.resize(this->nu_,0.0);
167 u[ 0] = z[ 0]/this->
hu_ * this->
u0_;
168 u[this->nu_-1] = z[this->
nz_-1]/this->
hu_ * this->
u1_;
170 Teuchos::LAPACK<int,Real> lp;
174 lp.PTTRF(this->nu_,&d[0],&o[0],&info);
175 lp.PTTRS(this->nu_,nhrs,&d[0],&o[0],&u[0],ldb,&info);
180 std::vector<Real> d(this->
nu_,1.0);
181 std::vector<Real> o(this->
nu_-1,1.0);
182 for (
int i = 0; i < this->
nu_; i++ ) {
183 d[i] = (z[i] + z[i+1])/this->
hu_;
184 if ( i < this->nu_-1 ) {
185 o[i] *= -z[i+1]/this->
hu_;
189 std::vector<Real> r(this->nu_,0.0);
190 for (
int i = 0; i < this->
nu_; i++) {
194 p.resize(this->nu_,0.0);
197 Teuchos::LAPACK<int,Real> lp;
201 lp.PTTRF(this->nu_,&d[0],&o[0],&info);
202 lp.PTTRS(this->nu_,nhrs,&d[0],&o[0],&p[0],ldb,&info);
206 const std::vector<Real> &u,
const std::vector<Real> &z) {
208 std::vector<Real> d(this->
nu_,1.0);
209 std::vector<Real> o(this->
nu_-1,1.0);
210 for (
int i = 0; i < this->
nu_; i++ ) {
211 d[i] = (z[i] + z[i+1])/this->
hu_;
212 if ( i < this->nu_-1 ) {
213 o[i] *= -z[i+1]/this->
hu_;
218 w.resize(this->nu_,0.0);
221 Teuchos::LAPACK<int,Real> lp;
225 lp.PTTRF(this->nu_,&d[0],&o[0],&info);
226 lp.PTTRS(this->nu_,nhrs,&d[0],&o[0],&w[0],ldb,&info);
230 const std::vector<Real> &v,
const std::vector<Real> &p,
231 const std::vector<Real> &u,
const std::vector<Real> &z) {
233 std::vector<Real> d(this->
nu_,1.0);
234 std::vector<Real> o(this->
nu_-1,1.0);
235 for (
int i = 0; i < this->
nu_; i++ ) {
236 d[i] = (z[i] + z[i+1])/this->
hu_;
237 if ( i < this->nu_-1 ) {
238 o[i] *= -z[i+1]/this->
hu_;
243 q.resize(this->nu_,0.0);
245 std::vector<Real> res(this->nu_,0.0);
247 for (
int i = 0; i < this->
nu_; i++) {
251 Teuchos::LAPACK<int,Real> lp;
255 lp.PTTRF(this->nu_,&d[0],&o[0],&info);
256 lp.PTTRS(this->nu_,nhrs,&d[0],&o[0],&q[0],ldb,&info);
262 this->
H_.shape(this->
nz_,this->
nz_);
263 Teuchos::RCP<ROL::Vector<Real> > e = z.
clone();
264 Teuchos::RCP<ROL::Vector<Real> > h = z.
clone();
265 for (
int i = 0; i < this->
nz_; i++ ) {
268 for (
int j = 0; j < this->
nz_; j++ ) {
270 (this->
H_)(j,i) = e->dot(*h);
273 std::vector<std::vector<Real> > eigenvals = ROL::computeEigenvalues<Real>(this->
H_);
274 std::sort((eigenvals[0]).begin(), (eigenvals[0]).end());
275 Real inertia = (eigenvals[0])[0];
276 Real correction = 0.0;
277 if ( inertia <= 0.0 ) {
279 if ( inertia == 0.0 ) {
281 while ( eigenvals[0][cnt] == 0.0 ) {
285 if ( cnt == this->nz_-1 ) {
289 for (
int i = 0; i < this->
nz_; i++ ) {
290 (this->
H_)(i,i) += correction;
298 Teuchos::RCP<const std::vector<Real> > zp =
301 std::vector<Real> u(this->
nu_,0.0);
305 for (
int i=0; i<this->
nz_;i++) {
306 val += this->
hz_*this->
alpha_*0.5*(*zp)[i]*(*zp)[i];
312 for (
int i=0; i<this->
nu_; i++) {
316 res = this->
hu_/6.0*(2.0*res1 + res2)*res1;
318 else if ( i == this->nu_-1 ) {
321 res = this->hu_/6.0*(res1 + 2.0*res2)*res2;
327 res = this->hu_/6.0*(res1 + 4.0*res2 + res3)*res2;
335 Teuchos::RCP<const std::vector<Real> > zp =
337 Teuchos::RCP<std::vector<Real> > gp =
338 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(g)).getVector());
340 std::vector<Real> u(this->
nu_,0.0);
343 std::vector<Real> p(this->
nu_,0.0);
348 for (
int i = 0; i < this->
nz_; i++ ) {
349 (*gp)[i] += this->
hz_*this->
alpha_*(*zp)[i];
371 Teuchos::RCP<const std::vector<Real> > vp =
373 Teuchos::RCP<const std::vector<Real> > zp =
375 Teuchos::RCP<std::vector<Real> > hvp =
376 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(hv)).getVector());
378 std::vector<Real> u(this->
nu_,0.0);
381 std::vector<Real> p(this->
nu_,0.0);
384 std::vector<Real> w(this->
nu_,0.0);
387 std::vector<Real> q(this->
nu_,0.0);
392 std::vector<Real> tmp(this->
nz_,0.0);
394 for (
int i=0; i < this->
nz_; i++) {
398 for (
int i=0; i < this->
nz_; i++) {
399 (*hvp)[i] += this->
hz_*this->
alpha_*(*vp)[i];
404 Teuchos::RCP<std::vector<Real> > vp =
406 Teuchos::RCP<std::vector<Real> > hvp =
407 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(hv)).getVector());
409 Teuchos::SerialDenseVector<int, Real> hv_teuchos(Teuchos::View, &((*hvp)[0]), this->
nz_);
410 Teuchos::SerialDenseVector<int, Real> v_teuchos(Teuchos::View, &(( *vp)[0]), this->
nz_);
411 hv_teuchos.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, this->
H_, v_teuchos, 0.0);
427 x_lo_.assign(lo.begin(),lo.end());
429 x_up_.assign(up.begin(),up.end());
430 for (
unsigned i = 0; i < (unsigned)
dim_; i++ ) {
441 Teuchos::RCP<const std::vector<Real> > ex =
445 for (
int i = 0; i < this->
dim_; i++ ) {
446 if ( (*ex)[i] >= this->
x_lo_[i] && (*ex)[i] <= this->
x_up_[i] ) { cnt *= 1; }
449 if ( cnt == 0 ) { val =
false; }
453 Teuchos::RCP<std::vector<Real> > ex =
454 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(x)).getVector());
455 for (
int i = 0; i < this->
dim_; i++ ) {
456 (*ex)[i] = std::max(this->
x_lo_[i],std::min(this->
x_up_[i],(*ex)[i]));
460 Teuchos::RCP<const std::vector<Real> > ex =
462 Teuchos::RCP<std::vector<Real> > ev =
463 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
464 Real epsn = std::min(eps,this->
min_diff_);
465 for (
int i = 0; i < this->
dim_; i++ ) {
466 if ( ((*ex)[i] <= this->
x_lo_[i]+epsn) ) {
472 Teuchos::RCP<const std::vector<Real> > ex =
474 Teuchos::RCP<std::vector<Real> > ev =
475 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
476 Real epsn = std::min(eps,this->
min_diff_);
477 for (
int i = 0; i < this->
dim_; i++ ) {
478 if ( ((*ex)[i] >= this->
x_up_[i]-epsn) ) {
484 Teuchos::RCP<const std::vector<Real> > ex =
486 Teuchos::RCP<const std::vector<Real> > eg =
488 Teuchos::RCP<std::vector<Real> > ev =
489 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
490 Real epsn = std::min(eps,this->
min_diff_);
491 for (
int i = 0; i < this->
dim_; i++ ) {
492 if ( ((*ex)[i] <= this->
x_lo_[i]+epsn && (*eg)[i] > 0.0) ){
498 Teuchos::RCP<const std::vector<Real> > ex =
500 Teuchos::RCP<const std::vector<Real> > eg =
502 Teuchos::RCP<std::vector<Real> > ev =
503 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
504 Real epsn = std::min(eps,this->
min_diff_);
505 for (
int i = 0; i < this->
dim_; i++ ) {
506 if ( ((*ex)[i] >= this->
x_up_[i]-epsn && (*eg)[i] < 0.0) ) {
512 Teuchos::RCP<std::vector<Real> > us = Teuchos::rcp(
new std::vector<Real>(this->
dim_,0.0) );
513 us->assign(this->
x_up_.begin(),this->
x_up_.end());
518 Teuchos::RCP<std::vector<Real> > ls = Teuchos::rcp(
new std::vector<Real>(this->
dim_,0.0) );
519 ls->assign(this->
x_lo_.begin(),this->
x_lo_.end());
529 int main(
int argc,
char *argv[]) {
531 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
534 int iprint = argc - 1;
535 Teuchos::RCP<std::ostream> outStream;
536 Teuchos::oblackholestream bhs;
538 outStream = Teuchos::rcp(&std::cout,
false);
540 outStream = Teuchos::rcp(&bhs,
false);
553 Teuchos::RCP<std::vector<RealT> > x_rcp = Teuchos::rcp(
new std::vector<RealT> (dim, 0.0) );
554 Teuchos::RCP<std::vector<RealT> > y_rcp = Teuchos::rcp(
new std::vector<RealT> (dim, 0.0) );
556 for (
int i=0; i<dim; i++) {
557 (*x_rcp)[i] = (
RealT)rand()/(
RealT)RAND_MAX + 1.e2;
558 (*y_rcp)[i] = (
RealT)rand()/(
RealT)RAND_MAX + 1.e2;
565 std::vector<RealT> lo(dim,1.0);
566 std::vector<RealT> up(dim,10.0);
569 Teuchos::ParameterList parlist;
571 parlist.set(
"Trust-Region Subproblem Solver Type",
"Truncated CG");
572 parlist.set(
"Initial Trust-Region Radius", 100.0);
574 parlist.set(
"Secant Type",
"Limited-Memory BFGS");
575 parlist.set(
"Maximum Secant Storage", 100);
577 parlist.set(
"Absolute Krylov Tolerance", 1.e-8);
578 parlist.set(
"Relative Krylov Tolerance", 1.e-4);
579 parlist.set(
"Maximum Number of Krylov Iterations", dim);
581 parlist.set(
"PDAS Relative Step Tolerance", 1.e-8);
582 parlist.set(
"PDAS Relative Gradient Tolerance", 1.e-6);
583 parlist.set(
"PDAS Maximum Number of Iterations", 10);
584 parlist.set(
"PDAS Dual Scaling", alpha);
586 parlist.set(
"Use Secant Hessian-Times-A-Vector",
true);
600 algo.
run(x,obj,icon,
true);
604 file.open(
"control_PDAS.txt");
605 for (
unsigned i = 0; i < (unsigned)dim; i++ ) {
606 file << (*x_rcp)[i] <<
"\n";
612 parlist.set(
"Use Secant Hessian-Times-A-Vector",
false);
619 algo_tr.
run(y,obj,icon,
true);
621 std::ofstream file_tr;
622 file_tr.open(
"control_TR.txt");
623 for (
unsigned i = 0; i < (unsigned)dim; i++ ) {
624 file_tr << (*y_rcp)[i] <<
"\n";
628 std::vector<RealT> u;
630 std::ofstream file_u;
631 file_u.open(
"state.txt");
632 for (
unsigned i = 0; i < (unsigned)(dim-1); i++ ) {
633 file_u << u[i] <<
"\n";
637 Teuchos::RCP<ROL::Vector<RealT> > diff = x.
clone();
640 RealT error = diff->norm()/std::sqrt((
RealT)dim-1.0);
641 std::cout <<
"\nError between PDAS solution and TR solution is " << error <<
"\n";
645 catch (std::logic_error err) {
646 *outStream << err.what() <<
"\n";
651 std::cout <<
"End Result: TEST FAILED\n";
653 std::cout <<
"End Result: TEST PASSED\n";
Implements the computation of optimization steps with the Newton primal-dual active set method...
Provides the interface to evaluate objective functions.
BoundConstraint_PoissonInversion(std::vector< Real > &lo, std::vector< Real > &up)
void solve_state_equation(std::vector< Real > &u, const std::vector< Real > &z)
std::vector< Real > x_up_
void apply_transposed_linearized_control_operator(std::vector< Real > &Bd, const std::vector< Real > &z, const std::vector< Real > &d, const std::vector< Real > &u, bool addBC=true)
Contains definitions of custom data types in ROL.
bool isFeasible(const ROL::Vector< Real > &x)
Check if the vector, v, is feasible.
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
void solve_adjoint_sensitivity_equation(std::vector< Real > &q, const std::vector< Real > &w, const std::vector< Real > &v, const std::vector< Real > &p, const std::vector< Real > &u, const std::vector< Real > &z)
virtual std::vector< std::vector< Real > > checkGradient(const Vector< Real > &x, const Vector< Real > &d, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference gradient check.
Teuchos::RCP< Vector< Real > > clone() const
Clone to make a new (uninitialized) vector.
void apply_mass(std::vector< Real > &Mz, const std::vector< Real > &z)
std::vector< Real > x_lo_
Provides the std::vector implementation of the ROL::Vector interface.
virtual std::vector< std::string > run(Vector< Real > &x, Objective< Real > &obj, bool print=false, std::ostream &outStream=std::cout)
Run algorithm on unconstrained problems (Type-U). This is the primary Type-U interface.
Real value(const ROL::Vector< Real > &z, Real &tol)
Compute value.
void pruneLowerActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the lower -active set.
void update(const ROL::Vector< Real > &z, bool flag, int iter)
Update objective function.
void deactivateInertia(void)
int main(int argc, char *argv[])
Provides an interface to check status of optimization algorithms.
void hessVec_true(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
void pruneUpperActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &g, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the upper -binding set.
void setVectorToLowerBound(ROL::Vector< Real > &l)
Set the input vector to the lower bound.
Provides the interface to apply upper and lower bound constraints.
void solve_adjoint_equation(std::vector< Real > &p, const std::vector< Real > &u, const std::vector< Real > &z)
void setVectorToUpperBound(ROL::Vector< Real > &u)
Set the input vector to the upper bound.
void solve_state_sensitivity_equation(std::vector< Real > &w, const std::vector< Real > &v, const std::vector< Real > &u, const std::vector< Real > &z)
void pruneLowerActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &g, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the lower -binding set.
void project(ROL::Vector< Real > &x)
Project optimization variables onto the bounds.
void hessVec(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
Apply Hessian approximation to vector.
virtual std::vector< std::vector< Real > > checkHessVec(const Vector< Real > &x, const Vector< Real > &v, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference Hessian-applied-to-vector check.
virtual void set(const Vector &x)
Set where .
virtual Teuchos::RCP< Vector > basis(const int i) const
Return i-th basis vector.
void pruneUpperActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the upper -active set.
void apply_linearized_control_operator(std::vector< Real > &Bd, const std::vector< Real > &z, const std::vector< Real > &d, const std::vector< Real > &u, bool addBC=true)
void activateInertia(void)
void hessVec_inertia(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
Objective_PoissonInversion(int nz=32, Real alpha=1.e-4)
void gradient(ROL::Vector< Real > &g, const ROL::Vector< Real > &z, Real &tol)
Compute gradient.
Real evaluate_target(Real x)
Teuchos::SerialDenseMatrix< int, Real > H_
Provides the interface to compute optimization steps with trust regions.
static const double ROL_EPSILON
Platform-dependent machine epsilon.