44 #ifndef ROL_BUNDLE_TT_H 45 #define ROL_BUNDLE_TT_H 52 #include "ROL_Ptr.hpp" 53 #include "ROL_LAPACK.hpp" 62 #include "ROL_LinearAlgebra.hpp" 66 #define FIRST_VIOLATED 0 119 Real
GiGj(
const int i,
const int j)
const {
123 Real
sgn(
const Real x)
const {
124 const Real
zero(0), one(1);
125 return ((x <
zero) ? -one :
131 const Real coeff = 0.0,
132 const Real omega = 2.0,
133 const unsigned remSize = 2)
134 :
Bundle<Real>(maxSize,coeff,omega,remSize),
135 maxSize_(maxSize), isInitialized_(false) {
136 maxind_ = std::numeric_limits<int>::max();
137 Id_.reshape(maxSize_,maxSize_);
138 for(
unsigned i=0; i<
maxSize_; ++i) {
139 Id_(i,i) =
static_cast<Real
>(1);
143 unsigned solveDual(
const Real t,
const unsigned maxit = 1000,
const Real tol = 1.e-8) {
161 void swapRowsL(
unsigned ind1,
unsigned ind2,
bool trans=
false) {
162 const Real
zero(0), one(1);
169 for (
unsigned n=ind1+1; n<=ind2; ++n){
170 LA::Matrix<Real> Id_n(LA::Copy,Id_,currSize_,currSize_);
171 Id_n(dd,dd) =
zero; Id_n(dd,n) = one;
172 Id_n(n,dd) = one; Id_n(n,n) =
zero;
173 LA::Matrix<Real> prod(currSize_,currSize_);
175 prod.multiply(LA::ETransp::NO_TRANS,LA::ETransp::NO_TRANS,one,Id_n,L_,
zero);
178 prod.multiply(LA::ETransp::NO_TRANS,LA::ETransp::NO_TRANS,one,L_,Id_n,
zero);
186 if (currSize_ <= dependent_) {
187 kappa_ =
static_cast<Real
>(1);
190 Real tmpdiagMax = ROL_NINF<Real>();
191 Real tmpdiagMin = ROL_INF<Real>();
192 for (
unsigned j=0;j<currSize_-
dependent_;j++){
193 if(
L_(j,j) > tmpdiagMax ){
194 tmpdiagMax =
L_(j,j);
197 if(
L_(j,j) < tmpdiagMin ){
198 tmpdiagMin =
L_(j,j);
202 kappa_ = tmpdiagMax/tmpdiagMin;
210 if(dependent_ && (ind == currSize_-1)){
213 tmp = base_[currSize_-2];
214 base_[currSize_-2] = base_[currSize_-1];
215 base_[currSize_-1] = tmp;
222 unsigned zsize = ind+1;
223 z1_.resize(zsize); z2_.resize(zsize);
224 z1_[ind] = (
static_cast<Real
>(1) - lhz1_ ) / delta;
229 if(delta >
L_(LiMax_,LiMax_)){
231 kappa_ = delta/
L_(LiMin_,LiMin_);
233 if(delta <
L_(LiMin_,LiMin_)){
235 kappa_ =
L_(LiMax_,LiMax_)/delta;
240 const Real
zero(0), one(1);
242 if (ind >= currSize_-dependent_){
244 if (ind < currSize_-1){
247 base_[ind] = base_[currSize_-1];
255 L_.reshape(currSize_,currSize_);
256 base_.resize(currSize_);
280 for (
unsigned j=ind+1; j<currSize_-
dependent_; ++j){
282 if (std::abs(ai) <= tol*currSize_) {
289 if (std::abs(aj) <= tol*currSize_){
294 else if ( std::abs(ai) > std::abs(aj) ){
297 Real u = sgnb * std::sqrt(one + t*t );
305 Real u = sgna * std::sqrt(one + t*t );
319 Real tmp1 =
L_(h,ind);
321 L_(h,ind) = Gc*tmp1 + Gs*tmp2;
322 L_(h,j) = Gc*tmp2 - Gs*tmp1;
325 Real tmp1 = z1_[ind];
327 Real tmp3 = z2_[ind];
329 z1_[ind] = Gc*tmp1 + Gs*tmp2;
330 z1_[j] = Gc*tmp2 - Gs*tmp1;
331 z2_[ind] = Gc*tmp3 + Gs*tmp4;
332 z2_[j] = Gc*tmp4 - Gs*tmp3;
336 deltaLh_ =
L_(currSize_-dependent_,ind);
338 deltaLj_ =
L_(currSize_-1,ind);
344 L_.reshape(currSize_-1,currSize_-1);
349 for(
unsigned m=ind; m<zsize; m++ ){
357 base_.erase(base_.begin()+ind);
366 Real ghNorm =
GiGj(base_[currSize_-dependent_],base_[currSize_-dependent_]);
369 for (
unsigned ii=0; ii<currSize_-
dependent_; ++ii){
370 lhnrm +=
L_(currSize_-dependent_,ii)*
L_(currSize_-dependent_,ii);
372 deltaLh_ = std::abs(ghNorm - lhnrm);
374 Real sgn1 =
sgn(deltaLh_);
375 Real sgn2 =
sgn(dletaLj);
376 Real signum = sgn1 * sgn2;
377 deltaLh_ = std::abs( ghNorm - lhNorm + deltaLh_ * deltaLh_);
380 if( std::sqrt(deltaLh_) > tol*kappa_*std::max(static_cast<Real>(1),ghNorm) ){
387 for (
unsigned ii=0; ii<newind; ++ii){
388 lh_[ii] =
L_(newind,ii);
389 lhz1_ += lh_[ii]*z1_[ii];
390 lhz2_ += lh_[ii]*z2_[ii];
392 deltaLh_ = std::sqrt(deltaLh_);
397 Real gjNorm =
GiGj(base_[currSize_-1],base_[currSize_-1]);
400 deltaLj_ = std::abs(gjNorm - ljNorm);
402 deltaLj_ = - std::sqrt( deltaLj_ );
404 deltaLj_ = std::sqrt( deltaLj_ );
407 Real gjTgh =
GiGj(base_[currSize_-1],base_[currSize_-2]);
410 ljTlh +=
L_(currSize_-1,ii)*
L_(currSize_-2,ii);
412 deltaLj_ = (gjTgh - ljTlh) / deltaLh_;
420 Real gjNorm =
GiGj(base_[currSize_-1],base_[currSize_-1]);
423 for (
unsigned ii=0; ii<
currSize_; ++ii) {
424 ljnrm +=
L_(currSize_-1,ii)*
L_(currSize_-1,ii);
426 deltaLj_ = std::abs(gjNorm - ljnrm);
428 deltaLj_ = std::abs( gjNorm - ljNorm + deltaLj_ * deltaLj_);
431 if( std::sqrt(deltaLj_) > tol*kappa_*std::max(static_cast<Real>(1),gjNorm) ){
432 unsigned newind = currSize_-1;
438 for (
unsigned ii=0;ii<newind-1;ii++){
439 lj_[ii] =
L_(newind,ii);
440 ljz1_ += lj_[ii]*z1_[ii];
441 ljTz2 += lj_[ii]*z2_[ii];
443 deltaLj_ = std::sqrt(deltaLj_);
446 deltaLh_ =
GiGj(base_[currSize_-2],base_[currSize_-1]);
447 for (
unsigned ii=0;ii<currSize_-1;ii++){
448 deltaLh_ -=
L_(currSize_-2,ii)*
L_(currSize_-1,ii);
453 deltaLh_ = - std::sqrt( deltaLh_ );
456 deltaLh_ = std::sqrt ( deltaLh_ );
468 if( L.numRows()!=
size )
469 std::cout <<
"Error: Wrong size matrix!" << std::endl;
470 else if( v.numRows()!=
size )
471 std::cout <<
"Error: Wrong size vector!" << std::endl;
476 lapack_.TRTRS(
'L', tran,
'N', size, 1, L.values(), L.stride(), v.values(), v.stride(), &info );
483 for(
int i=0;i<v.numRows();i++){
491 unsigned solveDual_TT(
const Real t,
const unsigned maxit = 1000,
const Real tol = 1.e-8) {
492 const Real
zero(0), half(0.5), one(1);
493 Real z1z2(0), z1z1(0);
500 rho_ = ROL_INF<Real>();
505 L_(0,0) = std::sqrt(
GiGj(0,0));
513 z1_.resize(1); z2_.resize(1);
514 z1_[0] = one/
L_(0,0);
519 objval_ = ROL_INF<Real>();
520 minobjval_ = ROL_INF<Real>();
524 for (iter=0;iter<maxit;iter++){
527 switch( dependent_ ){
535 rho_ = ( one + z1z2/t )/z1z1;
536 tempv_ =
z1_; tempv_.scale(rho_);
537 tempw1_ =
z2_; tempw1_.scale(one/t);
549 LA::Matrix<Real> LBprime( LA::Copy,L_,currSize_-1,currSize_-1);
550 lh_.size(currSize_-1);
553 for(
unsigned i=0; i<currSize_-1; ++i){
554 Real tmp =
L_(currSize_-1,i);
560 if (std::abs(lhz1_-one) <= tol*kappa_){
564 tempv_.resize(currSize_);
565 tempv_[currSize_-1] = -one;
573 Real tmp = ( one + z1z2 / t - rho_ * z1z1 )/( one - lhz1_ );
574 tempw1_ =
z1_; tempw1_.scale(rho_);
575 tempw2_ =
z2_; tempw2_.scale(one/t);
577 tempw2_ =
lh_; tempw2_.scale(tmp);
581 tempv_.resize(currSize_);
582 tempv_[currSize_-1] = tmp;
593 LA::Matrix<Real> LBprime( LA::Copy,L_,currSize_-2,currSize_-2 );
594 lj_.size(currSize_-2);
595 lh_.size(currSize_-2);
598 for(
unsigned i=0; i<currSize_-2; ++i){
599 Real tmp1 =
L_(currSize_-1,i);
600 Real tmp2 =
L_(currSize_-2,i);
601 ljz1_ += tmp1*
z1_(i);
602 lhz1_ += tmp2*
z1_(i);
606 if(std::abs(ljz1_-one) <= tol*kappa_){
610 tempv_.resize(currSize_);
611 tempv_[currSize_-2] =
zero;
612 tempv_[currSize_-1] = -one;
616 Real mu = ( one -
lhz1_ )/( one - ljz1_ );
617 tempw1_ =
lj_; tempw1_.scale(-mu);
621 tempv_.resize(currSize_);
622 tempv_[currSize_-2] = -one;
623 tempv_[currSize_-1] = mu;
649 if ( tempv_[currSize_-1] <
zero )
664 Real step = ROL_INF<Real>();
672 if (step <=
zero || step == ROL_INF<Real>()){
685 for (
unsigned baseitem=0; baseitem<
currSize_; ++baseitem){
691 if( base_[baseitem] == entering_ ){
692 taboo_.push_back(entering_);
709 Real newobjval(0), Lin(0), Quad(0);
713 if (rho_ == ROL_NINF<Real>()){
715 newobjval = -half*Quad;
719 newobjval = half*(rho_ + Lin/t);
725 if( ( entering_ < maxind_ ) && ( objval_ < ROL_INF<Real>() ) ){
726 if( newobjval >= objval_ - std::max( tol*std::abs(objval_), ROL_EPSILON<Real>() ) ){
727 taboo_.push_back(entering_);
735 if ( objval_ + std::max( tol*std::abs(objval_), ROL_EPSILON<Real>() ) <= minobjval_ ){
741 if ( (rho_ >= ROL_NINF<Real>()) && (objval_ <= ROL_NINF<Real>()) )
745 Real minro = - std::max( tol*currSize_*std::abs(objval_), ROL_EPSILON<Real>() );
746 #if ( ! FIRST_VIOLATED ) 747 Real diff = ROL_NINF<Real>(), olddiff = ROL_NINF<Real>();
750 for (
unsigned bundleitem=0; bundleitem<Bundle<Real>::size(); ++bundleitem){
752 if ( std::find(taboo_.begin(),taboo_.end(),bundleitem) != taboo_.end() ){
756 if ( std::find(base_.begin(),base_.end(),bundleitem) == base_.end() ){
765 if (rho_ >= ROL_NINF<Real>()){
769 ro = ROL_NINF<Real>();
770 minobjval_ = ROL_INF<Real>();
771 objval_ = ROL_INF<Real>();
775 #if ( FIRST_VIOLATED ) 776 entering_ = bundleitem;
780 if ( diff > olddiff ){
781 entering_ = bundleitem;
791 if (entering_ < maxind_){
794 base_.push_back(entering_);
800 for (
unsigned i=0; i<zsize; ++i){
801 lh_[i] =
GiGj(entering_,base_[i]);
803 LA::Matrix<Real> LBprime( LA::Copy,L_,zsize,zsize);
805 for (
unsigned i=0; i<zsize; ++i){
806 lhz1_ += lh_[i]*z1_[i];
807 lhz2_ += lh_[i]*z2_[i];
810 Real nrm = lh_.dot(lh_);
811 Real delta =
GiGj(entering_,entering_) - nrm;
821 L_.reshape(currSize_,currSize_);
823 for (
unsigned i=0; i<zsize-1; ++i){
824 L_(currSize_-1,i) = lh_[i];
827 Real deltaeps = tol*kappa_*std::max(one,lh_.dot(lh_));
828 if ( delta > deltaeps ){
830 unsigned ind = currSize_-1;
831 delta = std::sqrt(delta);
834 else if(delta < -deltaeps){
844 if( objval_ - std::max( tol*std::abs( objval_ ), ROL_EPSILON<Real>() ) > minobjval_ ){
860 unsigned outermaxit = 20;
861 bool increase =
false, decrease =
false;
863 for (
unsigned it=0; it < outermaxit; ++it ){
865 if ( QPStatus_ == 1 ) {
868 else if ( QPStatus_ == -2 || QPStatus_ == -3 ) {
869 mytol /=
static_cast<Real
>(10);
873 mytol *=
static_cast<Real
>(10);
876 if ( (mytol > static_cast<Real>(1e-4))
877 || (mytol < static_cast<Real>(1e-16)) ){
880 if ( increase && decrease ) {
Real GiGj(const int i, const int j) const
Bundle_TT(const unsigned maxSize=10, const Real coeff=0.0, const Real omega=2.0, const unsigned remSize=2)
unsigned solveDual_TT(const Real t, const unsigned maxit=1000, const Real tol=1.e-8)
void resetDualVariables(void)
bool isFeasible(LA::Vector< Real > &v, const Real &tol)
unsigned solveDual(const Real t, const unsigned maxit=1000, const Real tol=1.e-8)
unsigned solveDual_arbitrary(const Real t, const unsigned maxit=1000, const Real tol=1.e-8)
const Real alpha(const unsigned i) const
LA::Vector< Real > tempw2_
void setDualVariable(const unsigned i, const Real val)
Contains definitions of custom data types in ROL.
ROL::LAPACK< int, Real > lapack_
Real sgn(const Real x) const
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
LA::Vector< Real > tempw1_
const Real getDualVariable(const unsigned i) const
LA::Vector< Real > tempv_
void solveSystem(int size, char tran, LA::Matrix< Real > &L, LA::Vector< Real > &v)
unsigned size(void) const
unsigned solveDual_dim1(const Real t, const unsigned maxit=1000, const Real tol=1.e-8)
void deleteSubgradFromBase(unsigned ind, Real tol)
Provides the interface for and implements a bundle. The semidefinite quadratic subproblem is solved u...
void addSubgradToBase(unsigned ind, Real delta)
std::vector< int > taboo_
unsigned solveDual_dim2(const Real t, const unsigned maxit=1000, const Real tol=1.e-8)
void swapRowsL(unsigned ind1, unsigned ind2, bool trans=false)
Provides the interface for and implements a bundle.