// Copyright (C) 2004, 2007 International Business Machines and others. // All Rights Reserved. // This code is published under the Eclipse Public License. // // $Id: IpNLPScaling.hpp 2269 2013-05-05 11:32:40Z stefan $ // // 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 repsonsible for determining the scaling factors * and mapping quantities in and out of scaled and unscaled * versions */ class NLPScalingObject : public ReferencedObject { public: /**@name Constructors/Destructors */ //@{ NLPScalingObject(); /** Default 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: /** Implementation of the 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&); /** Overloaded Equals 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 StandardScalingBase : public NLPScalingObject { public: /**@name Constructors/Destructors */ //@{ StandardScalingBase(); /** Default destructor */ virtual ~StandardScalingBase(); //@} /** Methods to map scaled and unscaled matrices */ //@{ /** Returns an obj-scaled version of the given scalar */ virtual Number apply_obj_scaling(const Number& f); /** Returns an obj-unscaled version of the given scalar */ virtual Number unapply_obj_scaling(const Number& f); /** Returns an x-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_x_NonConst(const SmartPtr& v); /** Returns an x-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_x(const SmartPtr& v); /** Returns an x-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_x_NonConst(const SmartPtr& v); /** Returns an x-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_x(const SmartPtr& v); /** Returns an c-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_c(const SmartPtr& v); /** Returns an c-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_c(const SmartPtr& v); /** Returns an c-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_c_NonConst(const SmartPtr& v); /** Returns an c-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_c_NonConst(const SmartPtr& v); /** Returns an d-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_d(const SmartPtr& v); /** Returns an d-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_d(const SmartPtr& v); /** Returns an d-scaled version of the given vector */ virtual SmartPtr apply_vector_scaling_d_NonConst(const SmartPtr& v); /** Returns an d-unscaled version of the given vector */ virtual SmartPtr unapply_vector_scaling_d_NonConst(const SmartPtr& v); /** 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); /** 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); /** 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); //@} /** @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); /** Methods for IpoptType */ //@{ static void RegisterOptions(SmartPtr roptions); //@} protected: /** Overloaded initialization method */ 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&); /** Overloaded Equals 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 NoNLPScalingObject : public StandardScalingBase { public: /**@name Constructors/Destructors */ //@{ NoNLPScalingObject() {} /** Default 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&); /** Overloaded Equals Operator */ void operator=(const NoNLPScalingObject&); //@} }; } // namespace Ipopt #endif