1 // Copyright (C) 2004, 2006 International Business Machines and others. 2 // All Rights Reserved. 3 // This code is published under the Common Public License. 4 // 5 // $Id: IpNLPScaling.hpp 759 2006-07-07 03:07:08Z andreasw $ 6 // 7 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 8 9 #ifndef __IPNLPSCALING_HPP__ 10 #define __IPNLPSCALING_HPP__ 11 12 #include "IpSymMatrix.hpp" 13 #include "IpScaledMatrix.hpp" 14 #include "IpSymScaledMatrix.hpp" 15 #include "IpOptionsList.hpp" 16 #include "IpRegOptions.hpp" 17 18 namespace SimTKIpopt 19 { 20 /** This is the abstract base class for problem scaling. 21 * It is repsonsible for determining the scaling factors 22 * and mapping quantities in and out of scaled and unscaled 23 * versions 24 */ 25 class NLPScalingObject : public ReferencedObject 26 { 27 public: 28 /**@name Constructors/Destructors */ 29 //@{ NLPScalingObject()30 NLPScalingObject() 31 {} 32 33 /** Default destructor */ ~NLPScalingObject()34 virtual ~NLPScalingObject() 35 {} 36 //@} 37 38 /** Method to initialize the options */ Initialize(const Journalist & jnlst,const OptionsList & options,const std::string & prefix)39 bool Initialize(const Journalist& jnlst, 40 const OptionsList& options, 41 const std::string& prefix) 42 { 43 jnlst_ = &jnlst; 44 return InitializeImpl(options, prefix); 45 } 46 47 /** Methods to map scaled and unscaled matrices */ 48 //@{ 49 /** Returns an obj-scaled version of the given scalar */ 50 virtual Number apply_obj_scaling(const Number& f)=0; 51 /** Returns an obj-unscaled version of the given scalar */ 52 virtual Number unapply_obj_scaling(const Number& f)=0; 53 /** Returns an x-scaled version of the given vector */ 54 virtual SmartPtr<Vector> 55 apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; 56 /** Returns an x-scaled version of the given vector */ 57 virtual SmartPtr<const Vector> 58 apply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; 59 /** Returns an x-unscaled version of the given vector */ 60 virtual SmartPtr<Vector> 61 unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; 62 /** Returns an x-unscaled version of the given vector */ 63 virtual SmartPtr<const Vector> 64 unapply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; 65 /** Returns an c-scaled version of the given vector */ 66 virtual SmartPtr<const Vector> 67 apply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; 68 /** Returns an c-unscaled version of the given vector */ 69 virtual SmartPtr<const Vector> 70 unapply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; 71 /** Returns an c-scaled version of the given vector */ 72 virtual SmartPtr<Vector> 73 apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; 74 /** Returns an c-unscaled version of the given vector */ 75 virtual SmartPtr<Vector> 76 unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; 77 /** Returns an d-scaled version of the given vector */ 78 virtual SmartPtr<const Vector> 79 apply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; 80 /** Returns an d-unscaled version of the given vector */ 81 virtual SmartPtr<const Vector> 82 unapply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; 83 /** Returns an d-scaled version of the given vector */ 84 virtual SmartPtr<Vector> 85 apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; 86 /** Returns an d-unscaled version of the given vector */ 87 virtual SmartPtr<Vector> 88 unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; 89 /** Returns a scaled version of the jacobian for c. If the 90 * overloaded method does not make a new matrix, make sure to set 91 * the matrix ptr passed in to NULL. 92 */ 93 virtual SmartPtr<const Matrix> 94 apply_jac_c_scaling(SmartPtr<const Matrix> matrix)=0; 95 /** Returns a scaled version of the jacobian for d If the 96 * overloaded method does not create a new matrix, make sure to 97 * set the matrix ptr passed in to NULL. 98 */ 99 virtual SmartPtr<const Matrix> 100 apply_jac_d_scaling(SmartPtr<const Matrix> matrix)=0; 101 /** Returns a scaled version of the hessian of the lagrangian If 102 * the overloaded method does not create a new matrix, make sure 103 * to set the matrix ptr passed in to NULL. 104 */ 105 virtual SmartPtr<const SymMatrix> 106 apply_hessian_scaling(SmartPtr<const SymMatrix> matrix)=0; 107 //@} 108 109 /** Methods for scaling bounds - these wrap those above */ 110 //@{ 111 /** Returns an x-scaled vector in the x_L or x_U space */ 112 SmartPtr<Vector> apply_vector_scaling_x_LU_NonConst( 113 const Matrix& Px_LU, 114 const SmartPtr<const Vector>& lu, 115 const VectorSpace& x_space); 116 /** Returns an x-scaled vector in the x_L or x_U space */ 117 SmartPtr<const Vector> apply_vector_scaling_x_LU( 118 const Matrix& Px_LU, 119 const SmartPtr<const Vector>& lu, 120 const VectorSpace& x_space); 121 /** Returns an d-scaled vector in the d_L or d_U space */ 122 SmartPtr<Vector> apply_vector_scaling_d_LU_NonConst( 123 const Matrix& Pd_LU, 124 const SmartPtr<const Vector>& lu, 125 const VectorSpace& d_space); 126 /** Returns an d-scaled vector in the d_L or d_U space */ 127 SmartPtr<const Vector> apply_vector_scaling_d_LU( 128 const Matrix& Pd_LU, 129 const SmartPtr<const Vector>& lu, 130 const VectorSpace& d_space); 131 /** Returns an d-unscaled vector in the d_L or d_U space */ 132 SmartPtr<Vector> unapply_vector_scaling_d_LU_NonConst( 133 const Matrix& Pd_LU, 134 const SmartPtr<const Vector>& lu, 135 const VectorSpace& d_space); 136 /** Returns an d-unscaled vector in the d_L or d_U space */ 137 SmartPtr<const Vector> unapply_vector_scaling_d_LU( 138 const Matrix& Pd_LU, 139 const SmartPtr<const Vector>& lu, 140 const VectorSpace& d_space); 141 //@} 142 143 /** Methods for scaling the gradient of the objective - wraps the 144 * virtual methods above 145 */ 146 //@{ 147 /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ 148 virtual SmartPtr<Vector> 149 apply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); 150 /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ 151 virtual SmartPtr<const Vector> 152 apply_grad_obj_scaling(const SmartPtr<const Vector>& v); 153 /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the 154 * given vector */ 155 virtual SmartPtr<Vector> 156 unapply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); 157 /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the 158 * given vector */ 159 virtual SmartPtr<const Vector> 160 unapply_grad_obj_scaling(const SmartPtr<const Vector>& v); 161 //@} 162 163 /** @name Methods for determining whether scaling for entities is 164 * done */ 165 //@{ 166 /** Returns true if the primal x variables are scaled. */ 167 virtual bool have_x_scaling()=0; 168 /** Returns true if the equality constraints are scaled. */ 169 virtual bool have_c_scaling()=0; 170 /** Returns true if the inequality constraints are scaled. */ 171 virtual bool have_d_scaling()=0; 172 //@} 173 174 /** This method is called by the IpoptNLP's at a convenient time to 175 * compute and/or read scaling factors 176 */ 177 virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, 178 const SmartPtr<const VectorSpace> c_space, 179 const SmartPtr<const VectorSpace> d_space, 180 const SmartPtr<const MatrixSpace> jac_c_space, 181 const SmartPtr<const MatrixSpace> jac_d_space, 182 const SmartPtr<const SymMatrixSpace> h_space, 183 SmartPtr<const MatrixSpace>& new_jac_c_space, 184 SmartPtr<const MatrixSpace>& new_jac_d_space, 185 SmartPtr<const SymMatrixSpace>& new_h_space)=0; 186 protected: 187 /** Implementation of the initialization method that has to be 188 * overloaded by for each derived class. */ 189 virtual bool InitializeImpl(const OptionsList& options, 190 const std::string& prefix)=0; 191 192 /** Accessor method for the journalist */ Jnlst() const193 const Journalist& Jnlst() const 194 { 195 return *jnlst_; 196 } 197 private: 198 199 /**@name Default Compiler Generated Methods 200 * (Hidden to avoid implicit creation/calling). 201 * These methods are not implemented and 202 * we do not want the compiler to implement 203 * them for us, so we declare them private 204 * and do not define them. This ensures that 205 * they will not be implicitly created/called. */ 206 //@{ 207 208 /** Copy Constructor */ 209 NLPScalingObject(const NLPScalingObject&); 210 211 /** Overloaded Equals Operator */ 212 void operator=(const NLPScalingObject&); 213 //@} 214 215 SmartPtr<const Journalist> jnlst_; 216 }; 217 218 /** This is a base class for many standard scaling 219 * techniques. The overloaded classes only need to 220 * provide the scaling parameters 221 */ 222 class StandardScalingBase : public NLPScalingObject 223 { 224 public: 225 /**@name Constructors/Destructors */ 226 //@{ StandardScalingBase()227 StandardScalingBase() 228 {} 229 230 /** Default destructor */ ~StandardScalingBase()231 virtual ~StandardScalingBase() 232 {} 233 //@} 234 235 /** Methods to map scaled and unscaled matrices */ 236 //@{ 237 /** Returns an obj-scaled version of the given scalar */ 238 virtual Number apply_obj_scaling(const Number& f) override; 239 /** Returns an obj-unscaled version of the given scalar */ 240 virtual Number unapply_obj_scaling(const Number& f) override; 241 /** Returns an x-scaled version of the given vector */ 242 virtual SmartPtr<Vector> 243 apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v) override; 244 /** Returns an x-scaled version of the given vector */ 245 virtual SmartPtr<const Vector> 246 apply_vector_scaling_x(const SmartPtr<const Vector>& v) override; 247 /** Returns an x-unscaled version of the given vector */ 248 virtual SmartPtr<Vector> 249 unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v) override; 250 /** Returns an x-unscaled version of the given vector */ 251 virtual SmartPtr<const Vector> 252 unapply_vector_scaling_x(const SmartPtr<const Vector>& v) override; 253 /** Returns an c-scaled version of the given vector */ 254 virtual SmartPtr<const Vector> 255 apply_vector_scaling_c(const SmartPtr<const Vector>& v) override; 256 /** Returns an c-unscaled version of the given vector */ 257 virtual SmartPtr<const Vector> 258 unapply_vector_scaling_c(const SmartPtr<const Vector>& v) override; 259 /** Returns an c-scaled version of the given vector */ 260 virtual SmartPtr<Vector> 261 apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v) override; 262 /** Returns an c-unscaled version of the given vector */ 263 virtual SmartPtr<Vector> 264 unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v) override; 265 /** Returns an d-scaled version of the given vector */ 266 virtual SmartPtr<const Vector> 267 apply_vector_scaling_d(const SmartPtr<const Vector>& v) override; 268 /** Returns an d-unscaled version of the given vector */ 269 virtual SmartPtr<const Vector> 270 unapply_vector_scaling_d(const SmartPtr<const Vector>& v) override; 271 /** Returns an d-scaled version of the given vector */ 272 virtual SmartPtr<Vector> 273 apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v) override; 274 /** Returns an d-unscaled version of the given vector */ 275 virtual SmartPtr<Vector> 276 unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v) override; 277 /** Returns a scaled version of the jacobian for c. If the 278 * overloaded method does not make a new matrix, make sure to set 279 * the matrix ptr passed in to NULL. 280 */ 281 virtual SmartPtr<const Matrix> 282 apply_jac_c_scaling(SmartPtr<const Matrix> matrix) override; 283 /** Returns a scaled version of the jacobian for d If the 284 * overloaded method does not create a new matrix, make sure to 285 * set the matrix ptr passed in to NULL. 286 */ 287 virtual SmartPtr<const Matrix> 288 apply_jac_d_scaling(SmartPtr<const Matrix> matrix) override; 289 /** Returns a scaled version of the hessian of the lagrangian If 290 * the overloaded method does not create a new matrix, make sure 291 * to set the matrix ptr passed in to NULL. 292 */ 293 virtual SmartPtr<const SymMatrix> 294 apply_hessian_scaling(SmartPtr<const SymMatrix> matrix) override; 295 //@} 296 297 /** @name Methods for determining whether scaling for entities is 298 * done */ 299 //@{ 300 virtual bool have_x_scaling() override; 301 virtual bool have_c_scaling() override; 302 virtual bool have_d_scaling() override; 303 //@} 304 305 /** This method is called by the IpoptNLP's at a convenient time to 306 * compute and/or read scaling factors 307 */ 308 virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, 309 const SmartPtr<const VectorSpace> c_space, 310 const SmartPtr<const VectorSpace> d_space, 311 const SmartPtr<const MatrixSpace> jac_c_space, 312 const SmartPtr<const MatrixSpace> jac_d_space, 313 const SmartPtr<const SymMatrixSpace> h_space, 314 SmartPtr<const MatrixSpace>& new_jac_c_space, 315 SmartPtr<const MatrixSpace>& new_jac_d_space, 316 SmartPtr<const SymMatrixSpace>& new_h_space) override; 317 318 /** Methods for IpoptType */ 319 //@{ 320 static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); 321 //@} 322 323 protected: 324 /** Overloaded initialization method */ 325 virtual bool InitializeImpl(const OptionsList& options, 326 const std::string& prefix) override; 327 328 /** This is the method that has to be overloaded by a particular 329 * scaling method that somehow computes the scaling vectors dx, 330 * dc, and dd. The pointers to those vectors can be NULL, in 331 * which case no scaling for that item will be done later. */ 332 virtual void DetermineScalingParametersImpl( 333 const SmartPtr<const VectorSpace> x_space, 334 const SmartPtr<const VectorSpace> c_space, 335 const SmartPtr<const VectorSpace> d_space, 336 const SmartPtr<const MatrixSpace> jac_c_space, 337 const SmartPtr<const MatrixSpace> jac_d_space, 338 const SmartPtr<const SymMatrixSpace> h_space, 339 Number& df, 340 SmartPtr<Vector>& dx, 341 SmartPtr<Vector>& dc, 342 SmartPtr<Vector>& dd)=0; 343 344 private: 345 346 /**@name Default Compiler Generated Methods 347 * (Hidden to avoid implicit creation/calling). 348 * These methods are not implemented and 349 * we do not want the compiler to implement 350 * them for us, so we declare them private 351 * and do not define them. This ensures that 352 * they will not be implicitly created/called. */ 353 //@{ 354 355 /** Copy Constructor */ 356 StandardScalingBase(const StandardScalingBase&); 357 358 /** Overloaded Equals Operator */ 359 void operator=(const StandardScalingBase&); 360 //@} 361 362 /** Scaling parameters - we only need to keep copies of 363 * the objective scaling and the x scaling - the others we can 364 * get from the scaled matrix spaces. 365 */ 366 //@{ 367 /** objective scaling parameter */ 368 Number df_; 369 /** x scaling */ 370 SmartPtr<Vector> dx_; 371 //@} 372 373 /** Scaled Matrix Spaces */ 374 //@{ 375 /** Scaled jacobian of c space */ 376 SmartPtr<ScaledMatrixSpace> scaled_jac_c_space_; 377 /** Scaled jacobian of d space */ 378 SmartPtr<ScaledMatrixSpace> scaled_jac_d_space_; 379 /** Scaled hessian of lagrangian spacea */ 380 SmartPtr<SymScaledMatrixSpace> scaled_h_space_; 381 //@} 382 383 /** @name Algorithmic parameters */ 384 //@{ 385 /** Additional scaling value for the objective function */ 386 Number obj_scaling_factor_; 387 //@} 388 }; 389 390 /** Class implementing the scaling object that doesn't to any scaling */ 391 class NoNLPScalingObject : public StandardScalingBase 392 { 393 public: 394 /**@name Constructors/Destructors */ 395 //@{ NoNLPScalingObject()396 NoNLPScalingObject() 397 {} 398 399 /** Default destructor */ ~NoNLPScalingObject()400 virtual ~NoNLPScalingObject() 401 {} 402 //@} 403 404 405 protected: 406 /** Overloaded from StandardScalingBase */ 407 virtual void DetermineScalingParametersImpl( 408 const SmartPtr<const VectorSpace> x_space, 409 const SmartPtr<const VectorSpace> c_space, 410 const SmartPtr<const VectorSpace> d_space, 411 const SmartPtr<const MatrixSpace> jac_c_space, 412 const SmartPtr<const MatrixSpace> jac_d_space, 413 const SmartPtr<const SymMatrixSpace> h_space, 414 Number& df, 415 SmartPtr<Vector>& dx, 416 SmartPtr<Vector>& dc, 417 SmartPtr<Vector>& dd) override; 418 419 private: 420 421 /**@name Default Compiler Generated Methods 422 * (Hidden to avoid implicit creation/calling). 423 * These methods are not implemented and 424 * we do not want the compiler to implement 425 * them for us, so we declare them private 426 * and do not define them. This ensures that 427 * they will not be implicitly created/called. */ 428 //@{ 429 430 /** Copy Constructor */ 431 NoNLPScalingObject(const NoNLPScalingObject&); 432 433 /** Overloaded Equals Operator */ 434 void operator=(const NoNLPScalingObject&); 435 //@} 436 }; 437 438 } // namespace Ipopt 439 440 #endif 441