Ipopt
trunk
|
00001 // Copyright (C) 2004, 2009 International Business Machines and others. 00002 // All Rights Reserved. 00003 // This code is published under the Eclipse Public License. 00004 // 00005 // $Id$ 00006 // 00007 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 00008 00009 #ifndef __IPDENSEVECTOR_HPP__ 00010 #define __IPDENSEVECTOR_HPP__ 00011 00012 #include "IpUtils.hpp" 00013 #include "IpVector.hpp" 00014 #include <map> 00015 00016 namespace Ipopt 00017 { 00018 00019 /* forward declarations */ 00020 class DenseVectorSpace; 00021 00024 DECLARE_STD_EXCEPTION(METADATA_ERROR); 00026 00040 class DenseVector : public Vector 00041 { 00042 public: 00043 00048 DenseVector(const DenseVectorSpace* owner_space); 00049 00052 virtual ~DenseVector(); 00054 00058 SmartPtr<DenseVector> MakeNewDenseVector() const; 00059 00061 void SetValues(const Number *x); 00062 00068 inline Number* Values(); 00069 00078 inline const Number* Values() const; 00079 00083 const Number* ExpandedValues() const; 00084 00087 inline Number* ExpandedValues() 00088 { 00089 return Values(); 00090 } 00091 00094 bool IsHomogeneous() const 00095 { 00096 return homogeneous_; 00097 } 00098 00100 Number Scalar() const 00101 { 00102 DBG_ASSERT(homogeneous_); 00103 return scalar_; 00104 } 00106 00112 void CopyToPos(Index Pos, const Vector& x); 00116 void CopyFromPos(Index Pos, const Vector& x); 00118 00119 protected: 00123 virtual void CopyImpl(const Vector& x); 00124 00126 virtual void ScalImpl(Number alpha); 00127 00129 virtual void AxpyImpl(Number alpha, const Vector &x); 00130 00132 virtual Number DotImpl(const Vector &x) const; 00133 00135 virtual Number Nrm2Impl() const; 00136 00138 virtual Number AsumImpl() const; 00139 00141 virtual Number AmaxImpl() const; 00142 00144 virtual void SetImpl(Number value); 00145 00147 virtual void ElementWiseDivideImpl(const Vector& x); 00148 00150 virtual void ElementWiseMultiplyImpl(const Vector& x); 00151 00153 virtual void ElementWiseMaxImpl(const Vector& x); 00154 00156 virtual void ElementWiseMinImpl(const Vector& x); 00157 00159 virtual void ElementWiseReciprocalImpl(); 00160 00162 virtual void ElementWiseAbsImpl(); 00163 00165 virtual void ElementWiseSqrtImpl(); 00166 00168 virtual void ElementWiseSgnImpl(); 00169 00171 virtual void AddScalarImpl(Number scalar); 00172 00174 virtual Number MaxImpl() const; 00175 00177 virtual Number MinImpl() const; 00178 00180 virtual Number SumImpl() const; 00181 00183 virtual Number SumLogsImpl() const; 00184 00189 void AddTwoVectorsImpl(Number a, const Vector& v1, 00190 Number b, const Vector& v2, Number c); 00192 Number FracToBoundImpl(const Vector& delta, Number tau) const; 00194 void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, 00195 Number c); 00197 00200 /* Print the entire vector with padding */ 00201 virtual void PrintImpl(const Journalist& jnlst, 00202 EJournalLevel level, 00203 EJournalCategory category, 00204 const std::string& name, 00205 Index indent, 00206 const std::string& prefix) const 00207 { 00208 PrintImplOffset(jnlst, level, category, name, indent, prefix, 1); 00209 } 00210 /* Print the entire vector with padding, and start counting with 00211 an offset. */ 00212 void PrintImplOffset(const Journalist& jnlst, 00213 EJournalLevel level, 00214 EJournalCategory category, 00215 const std::string& name, 00216 Index indent, 00217 const std::string& prefix, 00218 Index offset) const; 00220 friend class ParVector; 00221 00222 private: 00232 DenseVector(); 00233 00235 DenseVector(const DenseVector&); 00236 00238 void operator=(const DenseVector&); 00240 00244 const DenseVectorSpace* owner_space_; 00245 00247 Number* values_; 00248 00250 mutable Number* expanded_values_; 00251 00254 inline 00255 Number* values_allocated(); 00256 00259 bool initialized_; 00260 00265 bool homogeneous_; 00266 00269 Number scalar_; 00270 00273 void set_values_from_scalar(); 00274 }; 00275 00279 typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType; 00280 typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType; 00281 typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType; 00282 00285 class DenseVectorSpace : public VectorSpace 00286 { 00287 public: 00293 DenseVectorSpace(Index dim) 00294 : 00295 VectorSpace(dim) 00296 {} 00297 00299 ~DenseVectorSpace() 00300 {} 00302 00304 inline 00305 DenseVector* MakeNewDenseVector() const 00306 { 00307 return new DenseVector(this); 00308 } 00309 00313 virtual Vector* MakeNew() const 00314 { 00315 return MakeNewDenseVector(); 00316 } 00317 00324 inline 00325 Number* AllocateInternalStorage() const; 00326 00328 inline 00329 void FreeInternalStorage(Number* values) const; 00331 00336 inline 00337 bool HasStringMetaData(const std::string tag) const; 00338 00340 inline 00341 bool HasIntegerMetaData(const std::string tag) const; 00342 00344 inline 00345 bool HasNumericMetaData(const std::string tag) const; 00346 00348 inline 00349 const std::vector<std::string>& GetStringMetaData(const std::string& tag) const; 00350 00352 inline 00353 const std::vector<Index>& GetIntegerMetaData(const std::string& tag) const; 00354 00356 inline 00357 const std::vector<Number>& GetNumericMetaData(const std::string& tag) const; 00358 00360 inline 00361 void SetStringMetaData(std::string tag, std::vector<std::string> meta_data); 00362 00364 inline 00365 void SetIntegerMetaData(std::string tag, std::vector<Index> meta_data); 00366 00368 inline 00369 void SetNumericMetaData(std::string tag, std::vector<Number> meta_data); 00370 00372 inline 00373 const StringMetaDataMapType& GetStringMetaData() const; 00374 00376 inline 00377 const IntegerMetaDataMapType& GetIntegerMetaData() const; 00378 00380 inline 00381 const NumericMetaDataMapType& GetNumericMetaData() const; 00383 00384 private: 00385 // variables to store vector meta data 00386 StringMetaDataMapType string_meta_data_; 00387 IntegerMetaDataMapType integer_meta_data_; 00388 NumericMetaDataMapType numeric_meta_data_; 00389 00390 }; 00391 00392 // inline functions 00393 inline Number* DenseVector::Values() 00394 { 00395 // Here we assume that every time someone requests this direct raw 00396 // pointer, the data is going to change and the Tag for this 00397 // vector has to be updated. 00398 00399 if (initialized_ && homogeneous_) { 00400 // If currently the vector is a homogeneous vector, set all elements 00401 // explicitly to this value 00402 set_values_from_scalar(); 00403 } 00404 ObjectChanged(); 00405 initialized_= true; 00406 homogeneous_ = false; 00407 return values_allocated(); 00408 } 00409 00410 inline const Number* DenseVector::Values() const 00411 { 00412 DBG_ASSERT(initialized_ && (Dim()==0 || values_)); 00413 return values_; 00414 } 00415 00416 inline Number* DenseVector::values_allocated() 00417 { 00418 if (values_==NULL) { 00419 values_ = owner_space_->AllocateInternalStorage(); 00420 } 00421 return values_; 00422 } 00423 00424 inline 00425 Number* DenseVectorSpace::AllocateInternalStorage() const 00426 { 00427 if (Dim()>0) { 00428 return new Number[Dim()]; 00429 } 00430 else { 00431 return NULL; 00432 } 00433 } 00434 00435 inline 00436 void DenseVectorSpace::FreeInternalStorage(Number* values) const 00437 { 00438 delete [] values; 00439 } 00440 00441 inline 00442 SmartPtr<DenseVector> DenseVector::MakeNewDenseVector() const 00443 { 00444 return owner_space_->MakeNewDenseVector(); 00445 } 00446 00447 inline 00448 bool DenseVectorSpace::HasStringMetaData(const std::string tag) const 00449 { 00450 StringMetaDataMapType::const_iterator iter; 00451 iter = string_meta_data_.find(tag); 00452 00453 if (iter != string_meta_data_.end()) { 00454 return true; 00455 } 00456 00457 return false; 00458 } 00459 00460 inline 00461 bool DenseVectorSpace::HasIntegerMetaData(const std::string tag) const 00462 { 00463 IntegerMetaDataMapType::const_iterator iter; 00464 iter = integer_meta_data_.find(tag); 00465 00466 if (iter != integer_meta_data_.end()) { 00467 return true; 00468 } 00469 00470 return false; 00471 } 00472 00473 inline 00474 bool DenseVectorSpace::HasNumericMetaData(const std::string tag) const 00475 { 00476 NumericMetaDataMapType::const_iterator iter; 00477 iter = numeric_meta_data_.find(tag); 00478 00479 if (iter != numeric_meta_data_.end()) { 00480 return true; 00481 } 00482 00483 return false; 00484 } 00485 00486 inline 00487 const std::vector<std::string>& DenseVectorSpace::GetStringMetaData(const std::string& tag) const 00488 { 00489 DBG_ASSERT(HasStringMetaData(tag)); 00490 StringMetaDataMapType::const_iterator iter; 00491 iter = string_meta_data_.find(tag); 00492 return iter->second; 00493 } 00494 00495 inline 00496 const std::vector<Index>& DenseVectorSpace::GetIntegerMetaData(const std::string& tag) const 00497 { 00498 DBG_ASSERT(HasIntegerMetaData(tag)); 00499 IntegerMetaDataMapType::const_iterator iter; 00500 iter = integer_meta_data_.find(tag); 00501 return iter->second; 00502 } 00503 00504 inline 00505 const std::vector<Number>& DenseVectorSpace::GetNumericMetaData(const std::string& tag) const 00506 { 00507 DBG_ASSERT(HasNumericMetaData(tag)); 00508 NumericMetaDataMapType::const_iterator iter; 00509 iter = numeric_meta_data_.find(tag); 00510 return iter->second; 00511 } 00512 00513 inline 00514 void DenseVectorSpace::SetStringMetaData(std::string tag, std::vector<std::string> meta_data) 00515 { 00516 string_meta_data_[tag] = meta_data; 00517 } 00518 00519 inline 00520 void DenseVectorSpace::SetIntegerMetaData(std::string tag, std::vector<Index> meta_data) 00521 { 00522 integer_meta_data_[tag] = meta_data; 00523 } 00524 00525 inline 00526 void DenseVectorSpace::SetNumericMetaData(std::string tag, std::vector<Number> meta_data) 00527 { 00528 numeric_meta_data_[tag] = meta_data; 00529 } 00530 00531 inline 00532 const StringMetaDataMapType& DenseVectorSpace::GetStringMetaData() const 00533 { 00534 return string_meta_data_; 00535 } 00536 00537 inline 00538 const IntegerMetaDataMapType& DenseVectorSpace::GetIntegerMetaData() const 00539 { 00540 return integer_meta_data_; 00541 } 00542 00543 inline 00544 const NumericMetaDataMapType& DenseVectorSpace::GetNumericMetaData() const 00545 { 00546 return numeric_meta_data_; 00547 } 00548 00549 } // namespace Ipopt 00550 #endif