IpDenseVector.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. // Copyright (C) 2004, 2009 International Business Machines and others.
  2. // All Rights Reserved.
  3. // This code is published under the Eclipse Public License.
  4. //
  5. // $Id: IpDenseVector.hpp 2161 2013-01-01 20:39:05Z stefan $
  6. //
  7. // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
  8. #ifndef __IPDENSEVECTOR_HPP__
  9. #define __IPDENSEVECTOR_HPP__
  10. #include "IpUtils.hpp"
  11. #include "IpVector.hpp"
  12. #include <map>
  13. namespace Ipopt
  14. {
  15. /* forward declarations */
  16. class DenseVectorSpace;
  17. /** @name Exceptions */
  18. //@{
  19. DECLARE_STD_EXCEPTION(METADATA_ERROR);
  20. //@}
  21. /** Dense Vector Implementation. This is the default Vector class
  22. * in Ipopt. It stores vectors in contiguous Number arrays, unless
  23. * the vector has the same value in all entires. In the latter
  24. * case, we call the vector "homogeneous", and we store only the
  25. * values that is repeated in all elements. If you want to obtain
  26. * the values of vector, use the IsHomogeneous() method to find out
  27. * what status the vector is in, and then use either Values() const
  28. * or Scalar() const methods to get the values. To set the values
  29. * of a homogeneous method, use the Set method. To set the values
  30. * of a non-homogeneous vector, use the SetValues method, or use
  31. * the non-const Values method to get an array that you can
  32. * overwrite. In the latter case, storage is ensured.
  33. */
  34. class DenseVector : public Vector
  35. {
  36. public:
  37. /**@name Constructors / Destructors */
  38. //@{
  39. /** Default Constructor
  40. */
  41. DenseVector(const DenseVectorSpace* owner_space);
  42. /** Destructor
  43. */
  44. virtual ~DenseVector();
  45. //@}
  46. /** @name Additional public methods not in Vector base class. */
  47. //@{
  48. /** Create a new DenseVector from same VectorSpace */
  49. SmartPtr<DenseVector> MakeNewDenseVector() const;
  50. /** Set elements in the vector to the Number array x. */
  51. void SetValues(const Number *x);
  52. /** Obtain pointer to the internal Number array with vector
  53. * elements with the indention to change the vector data (USE
  54. * WITH CARE!). This does not produce a copy, and lifetime is not
  55. * guaranteed!.
  56. */
  57. inline Number* Values();
  58. /** Obtain pointer to the internal Number array with vector
  59. * elements without the intention to change the vector data (USE
  60. * WITH CARE!). This does not produce a copy, and lifetime is not
  61. * guaranteed! IMPORTANT: If this method is currently
  62. * homogeneous (i.e. IsHomogeneous returns true), then you cannot
  63. * call this method. Instead, you need to use the Scalar()
  64. * method.
  65. */
  66. inline const Number* Values() const;
  67. /** The same as the const version of Values, but we ensure that we
  68. * always return a valid array, even if IsHomogeneous returns
  69. * true. */
  70. const Number* ExpandedValues() const;
  71. /** This is the same as Values, but we add it here so that
  72. * ExpandedValues can also be used for the non-const case. */
  73. inline Number* ExpandedValues()
  74. {
  75. return Values();
  76. }
  77. /** Indicates if the vector is homogeneous (i.e., all entries have
  78. * the value Scalar() */
  79. bool IsHomogeneous() const
  80. {
  81. return homogeneous_;
  82. }
  83. /** Scalar value of all entries in a homogeneous vector */
  84. Number Scalar() const
  85. {
  86. DBG_ASSERT(homogeneous_);
  87. return scalar_;
  88. }
  89. //@}
  90. /** @name Modifying subranges of the vector. */
  91. //@{
  92. /** Copy the data in x into the subrange of this vector starting
  93. * at position Pos in this vector. Position count starts at 0.
  94. */
  95. void CopyToPos(Index Pos, const Vector& x);
  96. /** Copy a subrange of x, starting at Pos, into the full data of
  97. * this vector. Position count starts at 0.
  98. */
  99. void CopyFromPos(Index Pos, const Vector& x);
  100. //@}
  101. protected:
  102. /** @name Overloaded methods from Vector base class */
  103. //@{
  104. /** Copy the data of the vector x into this vector (DCOPY). */
  105. virtual void CopyImpl(const Vector& x);
  106. /** Scales the vector by scalar alpha (DSCAL) */
  107. virtual void ScalImpl(Number alpha);
  108. /** Add the multiple alpha of vector x to this vector (DAXPY) */
  109. virtual void AxpyImpl(Number alpha, const Vector &x);
  110. /** Computes inner product of vector x with this (DDOT) */
  111. virtual Number DotImpl(const Vector &x) const;
  112. /** Computes the 2-norm of this vector (DNRM2) */
  113. virtual Number Nrm2Impl() const;
  114. /** Computes the 1-norm of this vector (DASUM) */
  115. virtual Number AsumImpl() const;
  116. /** Computes the max-norm of this vector (based on IDAMAX) */
  117. virtual Number AmaxImpl() const;
  118. /** Set each element in the vector to the scalar alpha. */
  119. virtual void SetImpl(Number value);
  120. /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/
  121. virtual void ElementWiseDivideImpl(const Vector& x);
  122. /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/
  123. virtual void ElementWiseMultiplyImpl(const Vector& x);
  124. /** Set entry to max of itself and the corresponding element in x */
  125. virtual void ElementWiseMaxImpl(const Vector& x);
  126. /** Set entry to min of itself and the corresponding element in x */
  127. virtual void ElementWiseMinImpl(const Vector& x);
  128. /** reciprocates the elements of the vector */
  129. virtual void ElementWiseReciprocalImpl();
  130. /** take abs of the elements of the vector */
  131. virtual void ElementWiseAbsImpl();
  132. /** take square-root of the elements of the vector */
  133. virtual void ElementWiseSqrtImpl();
  134. /** Changes each entry in the vector to its sgn value */
  135. virtual void ElementWiseSgnImpl();
  136. /** Add scalar to every component of the vector.*/
  137. virtual void AddScalarImpl(Number scalar);
  138. /** Max value in the vector */
  139. virtual Number MaxImpl() const;
  140. /** Min value in the vector */
  141. virtual Number MinImpl() const;
  142. /** Computes the sum of the lements of vector */
  143. virtual Number SumImpl() const;
  144. /** Computes the sum of the logs of the elements of vector */
  145. virtual Number SumLogsImpl() const;
  146. /** @name Implemented specialized functions */
  147. //@{
  148. /** Add two vectors (a * v1 + b * v2). Result is stored in this
  149. vector. */
  150. void AddTwoVectorsImpl(Number a, const Vector& v1,
  151. Number b, const Vector& v2, Number c);
  152. /** Fraction to the boundary parameter. */
  153. Number FracToBoundImpl(const Vector& delta, Number tau) const;
  154. /** Add the quotient of two vectors, y = a * z/s + c * y. */
  155. void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s,
  156. Number c);
  157. //@}
  158. /** @name Output methods */
  159. //@{
  160. /* Print the entire vector with padding */
  161. virtual void PrintImpl(const Journalist& jnlst,
  162. EJournalLevel level,
  163. EJournalCategory category,
  164. const std::string& name,
  165. Index indent,
  166. const std::string& prefix) const
  167. {
  168. PrintImplOffset(jnlst, level, category, name, indent, prefix, 1);
  169. }
  170. /* Print the entire vector with padding, and start counting with
  171. an offset. */
  172. void PrintImplOffset(const Journalist& jnlst,
  173. EJournalLevel level,
  174. EJournalCategory category,
  175. const std::string& name,
  176. Index indent,
  177. const std::string& prefix,
  178. Index offset) const;
  179. //@}
  180. friend class ParVector;
  181. private:
  182. /**@name Default Compiler Generated Methods
  183. * (Hidden to avoid implicit creation/calling).
  184. * These methods are not implemented and
  185. * we do not want the compiler to implement
  186. * them for us, so we declare them private
  187. * and do not define them. This ensures that
  188. * they will not be implicitly created/called. */
  189. //@{
  190. /** Default Constructor */
  191. DenseVector();
  192. /** Copy Constructor */
  193. DenseVector(const DenseVector&);
  194. /** Overloaded Equals Operator */
  195. void operator=(const DenseVector&);
  196. //@}
  197. /** Copy of the owner_space ptr as a DenseVectorSpace instead
  198. * of a VectorSpace
  199. */
  200. const DenseVectorSpace* owner_space_;
  201. /** Dense Number array of vector values. */
  202. Number* values_;
  203. /** Dense Number array pointer that is used for ExpandedValues */
  204. mutable Number* expanded_values_;
  205. /** Method of getting the internal values array, making sure that
  206. * memory has been allocated */
  207. inline
  208. Number* values_allocated();
  209. /** Flag for Initialization. This flag is false, if the data has
  210. not yet been initialized. */
  211. bool initialized_;
  212. /** Flag indicating whether the vector is currently homogeneous
  213. * (that is, all elements have the same value). This flag is used
  214. * to determine whether the elements of the vector are stored in
  215. * values_ or in scalar_ */
  216. bool homogeneous_;
  217. /** Homogeneous value of all elements if the vector is currently
  218. * homogenous */
  219. Number scalar_;
  220. /** Auxilliary method for setting explicitly all elements in
  221. * values_ to the current scalar value. */
  222. void set_values_from_scalar();
  223. };
  224. /** typedefs for the map variables that define meta data for the
  225. * DenseVectorSpace
  226. */
  227. typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType;
  228. typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType;
  229. typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType;
  230. /** This vectors space is the vector space for DenseVector.
  231. */
  232. class DenseVectorSpace : public VectorSpace
  233. {
  234. public:
  235. /** @name Constructors/Destructors. */
  236. //@{
  237. /** Constructor, requires dimension of all vector for this
  238. * VectorSpace
  239. */
  240. DenseVectorSpace(Index dim)
  241. :
  242. VectorSpace(dim)
  243. {}
  244. /** Destructor */
  245. ~DenseVectorSpace()
  246. {}
  247. //@}
  248. /** Method for creating a new vector of this specific type. */
  249. inline
  250. DenseVector* MakeNewDenseVector() const
  251. {
  252. return new DenseVector(this);
  253. }
  254. /** Instantiation of the generate MakeNew method for the
  255. * VectorSpace base class.
  256. */
  257. virtual Vector* MakeNew() const
  258. {
  259. return MakeNewDenseVector();
  260. }
  261. /**@name Methods called by DenseVector for memory management.
  262. * This could allow to have sophisticated memory management in the
  263. * VectorSpace.
  264. */
  265. //@{
  266. /** Allocate internal storage for the DenseVector */
  267. inline
  268. Number* AllocateInternalStorage() const;
  269. /** Deallocate internal storage for the DenseVector */
  270. inline
  271. void FreeInternalStorage(Number* values) const;
  272. //@}
  273. /**@name Methods for dealing with meta data on the vector
  274. */
  275. //@{
  276. /** Check if string meta exists for tag */
  277. inline
  278. bool HasStringMetaData(const std::string tag) const;
  279. /** Check if Integer meta exists for tag */
  280. inline
  281. bool HasIntegerMetaData(const std::string tag) const;
  282. /** Check if Numeric meta exists for tag */
  283. inline
  284. bool HasNumericMetaData(const std::string tag) const;
  285. /** Get meta data of type std::string by tag */
  286. inline
  287. const std::vector<std::string>& GetStringMetaData(const std::string& tag) const;
  288. /** Get meta data of type Index by tag */
  289. inline
  290. const std::vector<Index>& GetIntegerMetaData(const std::string& tag) const;
  291. /** Get meta data of type Number by tag */
  292. inline
  293. const std::vector<Number>& GetNumericMetaData(const std::string& tag) const;
  294. /** Set meta data of type std::string by tag */
  295. inline
  296. void SetStringMetaData(std::string tag, std::vector<std::string> meta_data);
  297. /** Set meta data of type Index by tag */
  298. inline
  299. void SetIntegerMetaData(std::string tag, std::vector<Index> meta_data);
  300. /** Set meta data of type Number by tag */
  301. inline
  302. void SetNumericMetaData(std::string tag, std::vector<Number> meta_data);
  303. /** Get map of meta data of type Number */
  304. inline
  305. const StringMetaDataMapType& GetStringMetaData() const;
  306. /** Get map of meta data of type Number */
  307. inline
  308. const IntegerMetaDataMapType& GetIntegerMetaData() const;
  309. /** Get map of meta data of type Number */
  310. inline
  311. const NumericMetaDataMapType& GetNumericMetaData() const;
  312. //@}
  313. private:
  314. // variables to store vector meta data
  315. StringMetaDataMapType string_meta_data_;
  316. IntegerMetaDataMapType integer_meta_data_;
  317. NumericMetaDataMapType numeric_meta_data_;
  318. };
  319. // inline functions
  320. inline Number* DenseVector::Values()
  321. {
  322. // Here we assume that every time someone requests this direct raw
  323. // pointer, the data is going to change and the Tag for this
  324. // vector has to be updated.
  325. if (initialized_ && homogeneous_) {
  326. // If currently the vector is a homogeneous vector, set all elements
  327. // explicitly to this value
  328. set_values_from_scalar();
  329. }
  330. ObjectChanged();
  331. initialized_= true;
  332. homogeneous_ = false;
  333. return values_allocated();
  334. }
  335. inline const Number* DenseVector::Values() const
  336. {
  337. DBG_ASSERT(initialized_ && (Dim()==0 || values_));
  338. return values_;
  339. }
  340. inline Number* DenseVector::values_allocated()
  341. {
  342. if (values_==NULL) {
  343. values_ = owner_space_->AllocateInternalStorage();
  344. }
  345. return values_;
  346. }
  347. inline
  348. Number* DenseVectorSpace::AllocateInternalStorage() const
  349. {
  350. if (Dim()>0) {
  351. return new Number[Dim()];
  352. }
  353. else {
  354. return NULL;
  355. }
  356. }
  357. inline
  358. void DenseVectorSpace::FreeInternalStorage(Number* values) const
  359. {
  360. delete [] values;
  361. }
  362. inline
  363. SmartPtr<DenseVector> DenseVector::MakeNewDenseVector() const
  364. {
  365. return owner_space_->MakeNewDenseVector();
  366. }
  367. inline
  368. bool DenseVectorSpace::HasStringMetaData(const std::string tag) const
  369. {
  370. StringMetaDataMapType::const_iterator iter;
  371. iter = string_meta_data_.find(tag);
  372. if (iter != string_meta_data_.end()) {
  373. return true;
  374. }
  375. return false;
  376. }
  377. inline
  378. bool DenseVectorSpace::HasIntegerMetaData(const std::string tag) const
  379. {
  380. IntegerMetaDataMapType::const_iterator iter;
  381. iter = integer_meta_data_.find(tag);
  382. if (iter != integer_meta_data_.end()) {
  383. return true;
  384. }
  385. return false;
  386. }
  387. inline
  388. bool DenseVectorSpace::HasNumericMetaData(const std::string tag) const
  389. {
  390. NumericMetaDataMapType::const_iterator iter;
  391. iter = numeric_meta_data_.find(tag);
  392. if (iter != numeric_meta_data_.end()) {
  393. return true;
  394. }
  395. return false;
  396. }
  397. inline
  398. const std::vector<std::string>& DenseVectorSpace::GetStringMetaData(const std::string& tag) const
  399. {
  400. DBG_ASSERT(HasStringMetaData(tag));
  401. StringMetaDataMapType::const_iterator iter;
  402. iter = string_meta_data_.find(tag);
  403. return iter->second;
  404. }
  405. inline
  406. const std::vector<Index>& DenseVectorSpace::GetIntegerMetaData(const std::string& tag) const
  407. {
  408. DBG_ASSERT(HasIntegerMetaData(tag));
  409. IntegerMetaDataMapType::const_iterator iter;
  410. iter = integer_meta_data_.find(tag);
  411. return iter->second;
  412. }
  413. inline
  414. const std::vector<Number>& DenseVectorSpace::GetNumericMetaData(const std::string& tag) const
  415. {
  416. DBG_ASSERT(HasNumericMetaData(tag));
  417. NumericMetaDataMapType::const_iterator iter;
  418. iter = numeric_meta_data_.find(tag);
  419. return iter->second;
  420. }
  421. inline
  422. void DenseVectorSpace::SetStringMetaData(std::string tag, std::vector<std::string> meta_data)
  423. {
  424. string_meta_data_[tag] = meta_data;
  425. }
  426. inline
  427. void DenseVectorSpace::SetIntegerMetaData(std::string tag, std::vector<Index> meta_data)
  428. {
  429. integer_meta_data_[tag] = meta_data;
  430. }
  431. inline
  432. void DenseVectorSpace::SetNumericMetaData(std::string tag, std::vector<Number> meta_data)
  433. {
  434. numeric_meta_data_[tag] = meta_data;
  435. }
  436. inline
  437. const StringMetaDataMapType& DenseVectorSpace::GetStringMetaData() const
  438. {
  439. return string_meta_data_;
  440. }
  441. inline
  442. const IntegerMetaDataMapType& DenseVectorSpace::GetIntegerMetaData() const
  443. {
  444. return integer_meta_data_;
  445. }
  446. inline
  447. const NumericMetaDataMapType& DenseVectorSpace::GetNumericMetaData() const
  448. {
  449. return numeric_meta_data_;
  450. }
  451. } // namespace Ipopt
  452. #endif