// Copyright (C) 2004, 2007 International Business Machines and others. // All Rights Reserved. // This code is published under the Eclipse Public License. // // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 #ifndef __IPNLPSCALING_HPP__ #define __IPNLPSCALING_HPP__ #include "IpOptionsList.hpp" #include "IpRegOptions.hpp" namespace Ipopt { // forward declarations class Vector; class VectorSpace; class Matrix; class MatrixSpace; class SymMatrix; class SymMatrixSpace; class ScaledMatrixSpace; class SymScaledMatrixSpace; /** This is the abstract base class for problem scaling. * * It is responsible for determining the scaling factors * and mapping quantities in and out of scaled and unscaled * versions. */ class IPOPTLIB_EXPORT NLPScalingObject: public ReferencedObject { public: /**@name Constructors / Destructor */ ///@{ NLPScalingObject(); /** Destructor */ virtual ~NLPScalingObject(); ///@} /** Method to initialize the options */ bool Initialize( const Journalist& jnlst, const OptionsList& options, const std::string& prefix ) { jnlst_ = &jnlst; return InitializeImpl(options, prefix); } /** Methods to map scaled and unscaled matrices */ ///@{ /** Returns an obj-scaled version of the given scalar */ virtual Number apply_obj_scaling( const Number& f ) = 0; /** Returns an obj-unscaled version of the given scalar */ virtual Number unapply_obj_scaling( const Number& f ) = 0; /** Returns an x-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_x_NonConst( const SmartPtr& v ) = 0; /** Returns an x-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_x( const SmartPtr& v ) = 0; /** Returns an x-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_x_NonConst( const SmartPtr& v ) = 0; /** Returns an x-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_x( const SmartPtr& v ) = 0; /** Returns an c-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_c( const SmartPtr& v ) = 0; /** Returns an c-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_c( const SmartPtr& v ) = 0; /** Returns an c-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_c_NonConst( const SmartPtr& v ) = 0; /** Returns an c-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_c_NonConst( const SmartPtr& v ) = 0; /** Returns an d-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_d( const SmartPtr& v ) = 0; /** Returns an d-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_d( const SmartPtr& v ) = 0; /** Returns an d-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_d_NonConst( const SmartPtr& v ) = 0; /** Returns an d-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_d_NonConst( const SmartPtr& v ) = 0; /** Returns a scaled version of the Jacobian for c. * * If the overloaded method does not make a new matrix, * make sure to set the matrix ptr passed in to NULL. */ virtual SmartPtr apply_jac_c_scaling( SmartPtr matrix ) = 0; /** Returns a scaled version of the Jacobian for d * * If the overloaded method does not create a new matrix, * make sure to set the matrix ptr passed in to NULL. */ virtual SmartPtr apply_jac_d_scaling( SmartPtr matrix ) = 0; /** Returns a scaled version of the Hessian of the Lagrangian. * * If the overloaded method does not create a new matrix, * make sure to set the matrix ptr passed in to NULL. */ virtual SmartPtr apply_hessian_scaling( SmartPtr matrix ) = 0; ///@} /** Methods for scaling bounds - these wrap those above */ ///@{ /** Returns an x-scaled vector in the x_L or x_U space */ SmartPtr apply_vector_scaling_x_LU_NonConst( const Matrix& Px_LU, const SmartPtr& lu, const VectorSpace& x_space ); /** Returns an x-scaled vector in the x_L or x_U space */ SmartPtr apply_vector_scaling_x_LU( const Matrix& Px_LU, const SmartPtr& lu, const VectorSpace& x_space ); /** Returns an d-scaled vector in the d_L or d_U space */ SmartPtr apply_vector_scaling_d_LU_NonConst( const Matrix& Pd_LU, const SmartPtr& lu, const VectorSpace& d_space ); /** Returns an d-scaled vector in the d_L or d_U space */ SmartPtr apply_vector_scaling_d_LU( const Matrix& Pd_LU, const SmartPtr& lu, const VectorSpace& d_space ); /** Returns an d-unscaled vector in the d_L or d_U space */ SmartPtr unapply_vector_scaling_d_LU_NonConst( const Matrix& Pd_LU, const SmartPtr& lu, const VectorSpace& d_space ); /** Returns an d-unscaled vector in the d_L or d_U space */ SmartPtr unapply_vector_scaling_d_LU( const Matrix& Pd_LU, const SmartPtr& lu, const VectorSpace& d_space ); ///@} /** Methods for scaling the gradient of the objective - wraps the * virtual methods above */ ///@{ /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ virtual SmartPtr apply_grad_obj_scaling_NonConst( const SmartPtr& v ); /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ virtual SmartPtr apply_grad_obj_scaling( const SmartPtr& v ); /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the * given vector */ virtual SmartPtr unapply_grad_obj_scaling_NonConst( const SmartPtr& v ); /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the * given vector */ virtual SmartPtr unapply_grad_obj_scaling( const SmartPtr& v ); ///@} /** @name Methods for determining whether scaling for entities is done */ ///@{ /** Returns true if the primal x variables are scaled. */ virtual bool have_x_scaling() = 0; /** Returns true if the equality constraints are scaled. */ virtual bool have_c_scaling() = 0; /** Returns true if the inequality constraints are scaled. */ virtual bool have_d_scaling() = 0; ///@} /** This method is called by the IpoptNLP's at a convenient time to * compute and/or read scaling factors */ virtual void DetermineScaling( const SmartPtr x_space, const SmartPtr c_space, const SmartPtr d_space, const SmartPtr jac_c_space, const SmartPtr jac_d_space, const SmartPtr h_space, SmartPtr& new_jac_c_space, SmartPtr& new_jac_d_space, SmartPtr& new_h_space, const Matrix& Px_L, const Vector& x_L, const Matrix& Px_U, const Vector& x_U ) = 0; protected: /** Initialization method that has to be overloaded by for each derived class. */ virtual bool InitializeImpl( const OptionsList& options, const std::string& prefix ) = 0; /** Accessor method for the journalist */ const Journalist& Jnlst() const { return *jnlst_; } private: /**@name Default Compiler Generated Methods * (Hidden to avoid implicit creation/calling). * * These methods are not implemented and * we do not want the compiler to implement * them for us, so we declare them private * and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Copy Constructor */ NLPScalingObject( const NLPScalingObject& ); /** Default Assignment Operator */ void operator=( const NLPScalingObject& ); ///@} SmartPtr jnlst_; }; /** This is a base class for many standard scaling techniques. * * The overloaded classes only need to provide the scaling parameters. */ class IPOPTLIB_EXPORT StandardScalingBase: public NLPScalingObject { public: /**@name Constructors / Destructor */ ///@{ StandardScalingBase(); /** Destructor */ virtual ~StandardScalingBase(); ///@} /** Methods to map scaled and unscaled matrices */ ///@{ virtual Number apply_obj_scaling( const Number& f ); virtual Number unapply_obj_scaling( const Number& f ); virtual SmartPtr apply_vector_scaling_x_NonConst( const SmartPtr& v ); virtual SmartPtr apply_vector_scaling_x( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_x_NonConst( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_x( const SmartPtr& v ); virtual SmartPtr apply_vector_scaling_c( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_c( const SmartPtr& v ); virtual SmartPtr apply_vector_scaling_c_NonConst( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_c_NonConst( const SmartPtr& v ); virtual SmartPtr apply_vector_scaling_d( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_d( const SmartPtr& v ); virtual SmartPtr apply_vector_scaling_d_NonConst( const SmartPtr& v ); virtual SmartPtr unapply_vector_scaling_d_NonConst( const SmartPtr& v ); virtual SmartPtr apply_jac_c_scaling( SmartPtr matrix ); virtual SmartPtr apply_jac_d_scaling( SmartPtr matrix ); virtual SmartPtr apply_hessian_scaling( SmartPtr matrix); ///@} /** @name Methods for determining whether scaling for entities is done */ ///@{ virtual bool have_x_scaling(); virtual bool have_c_scaling(); virtual bool have_d_scaling(); ///@} /** This method is called by the IpoptNLP's at a convenient time to * compute and/or read scaling factors */ virtual void DetermineScaling( const SmartPtr x_space, const SmartPtr c_space, const SmartPtr d_space, const SmartPtr jac_c_space, const SmartPtr jac_d_space, const SmartPtr h_space, SmartPtr& new_jac_c_space, SmartPtr& new_jac_d_space, SmartPtr& new_h_space, const Matrix& Px_L, const Vector& x_L, const Matrix& Px_U, const Vector& x_U ); static void RegisterOptions( SmartPtr roptions ); protected: virtual bool InitializeImpl( const OptionsList& options, const std::string& prefix ); /** This is the method that has to be overloaded by a particular * scaling method that somehow computes the scaling vectors dx, * dc, and dd. * * The pointers to those vectors can be NULL, in * which case no scaling for that item will be done later. */ virtual void DetermineScalingParametersImpl( const SmartPtr x_space, const SmartPtr c_space, const SmartPtr d_space, const SmartPtr jac_c_space, const SmartPtr jac_d_space, const SmartPtr h_space, const Matrix& Px_L, const Vector& x_L, const Matrix& Px_U, const Vector& x_U, Number& df, SmartPtr& dx, SmartPtr& dc, SmartPtr& dd ) = 0; private: /**@name Default Compiler Generated Methods * (Hidden to avoid implicit creation/calling). * * These methods are not implemented and * we do not want the compiler to implement * them for us, so we declare them private * and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Copy Constructor */ StandardScalingBase( const StandardScalingBase& ); /** Default Assignment Operator */ void operator=( const StandardScalingBase& ); ///@} /** Scaling parameters - we only need to keep copies of * the objective scaling and the x scaling - the others we can * get from the scaled matrix spaces. */ ///@{ /** objective scaling parameter */ Number df_; /** x scaling */ SmartPtr dx_; ///@} /** Scaled Matrix Spaces */ ///@{ /** Scaled Jacobian of c space */ SmartPtr scaled_jac_c_space_; /** Scaled Jacobian of d space */ SmartPtr scaled_jac_d_space_; /** Scaled Hessian of Lagrangian spacea */ SmartPtr scaled_h_space_; ///@} /** @name Algorithmic parameters */ ///@{ /** Additional scaling value for the objective function */ Number obj_scaling_factor_; ///@} }; /** Class implementing the scaling object that doesn't to any scaling */ class IPOPTLIB_EXPORT NoNLPScalingObject: public StandardScalingBase { public: /**@name Constructors / Destructor */ ///@{ NoNLPScalingObject() { } /** Destructor */ virtual ~NoNLPScalingObject() { } ///@} protected: /** Overloaded from StandardScalingBase */ virtual void DetermineScalingParametersImpl( const SmartPtr x_space, const SmartPtr c_space, const SmartPtr d_space, const SmartPtr jac_c_space, const SmartPtr jac_d_space, const SmartPtr h_space, const Matrix& Px_L, const Vector& x_L, const Matrix& Px_U, const Vector& x_U, Number& df, SmartPtr& dx, SmartPtr& dc, SmartPtr& dd ); private: /**@name Default Compiler Generated Methods * (Hidden to avoid implicit creation/calling). * * These methods are not implemented and * we do not want the compiler to implement * them for us, so we declare them private * and do not define them. This ensures that * they will not be implicitly created/called. */ ///@{ /** Copy Constructor */ NoNLPScalingObject( const NoNLPScalingObject& ); /** Default Assignment Operator */ void operator=( const NoNLPScalingObject& ); ///@} }; } // namespace Ipopt #endif