Codebase list votca-xtp / e70a901 include / votca / xtp / trustregion.h
e70a901

Tree @e70a901 (Download .tar.gz)

trustregion.h @e70a901raw · history · blame

/* 
 *            Copyright 2009-2018 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef __XTP_TRUSTREGION__H
#define __XTP_TRUSTREGION__H

#include <votca/xtp/eigen.h>
#include <iostream>

// Solves the trustregion subproblem g^T*s+0.5*s^T H s = min with ||s||<=delta

namespace votca {
    namespace xtp {
       
        class TrustRegion {
        public:

            Eigen::VectorXd CalculateStep(const Eigen::VectorXd& gradient, const Eigen::MatrixXd& Hessian, double delta)const;
            
        private:    
            
            
            class TrustRegionFunction{
                public:
                TrustRegionFunction(const Eigen::VectorXd& factor,const Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd>& hessian,double trust_radius,int startindex)
                :_factor(factor),_hessian(hessian),_trust_radius(trust_radius),_startindex(startindex){;}
                    
                //Calculates \phi and \phi/\phi'
                std::pair<double,double> Evaluate(double lambda){
                    int size=_factor.size()-_startindex;
                    Eigen::ArrayXd quotient=(_hessian.eigenvalues().array()+lambda).tail(size);
                    const double p2=(_factor.array().tail(size)/(quotient.pow(2))).sum();
                    const double p=std::sqrt(p2);
                    const double q2=(_factor.array().tail(size)/(quotient.pow(3))).sum();
                    std::pair<double,double> result;
                    result.first=1/_trust_radius-1/p; 
                    result.second=p2/q2*(p-_trust_radius)/_trust_radius;
                    return result;
                }
                        
            private:

                const Eigen::VectorXd& _factor;
                const Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd>& _hessian;
                double _trust_radius;
                int _startindex;
};
            
        
        };

    }
}
#endif /* TRUSTREGION_H */