IpVector.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. // Copyright (C) 2004, 2008 International Business Machines and others.
  2. // All Rights Reserved.
  3. // This code is published under the Eclipse Public License.
  4. //
  5. // $Id: IpVector.hpp 2276 2013-05-05 12:33:44Z stefan $
  6. //
  7. // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
  8. #ifndef __IPVECTOR_HPP__
  9. #define __IPVECTOR_HPP__
  10. #include "IpTypes.hpp"
  11. #include "IpTaggedObject.hpp"
  12. #include "IpCachedResults.hpp"
  13. #include "IpSmartPtr.hpp"
  14. #include "IpJournalist.hpp"
  15. #include "IpException.hpp"
  16. #include <vector>
  17. namespace Ipopt
  18. {
  19. /** Exception that can be used to flag unimplemented linear algebra
  20. * methods */
  21. DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED);
  22. /* forward declarations */
  23. class VectorSpace;
  24. /** Vector Base Class.
  25. * This is the base class for all derived vector types. Those vectors
  26. * are meant to store entities like iterates, Lagrangian multipliers,
  27. * constraint values etc. The implementation of a vector type depends
  28. * on the computational environment (e.g. just a double array on a shared
  29. * memory machine, or distributed double arrays for a distributed
  30. * memory machine.)
  31. *
  32. * Deriving from Vector: This class inherits from tagged object to
  33. * implement an advanced caching scheme. Because of this, the
  34. * TaggedObject method ObjectChanged() must be called each time the
  35. * Vector changes. If you overload the XXXX_Impl protected methods,
  36. * this taken care of (along with caching if possible) for you. If
  37. * you have additional methods in your derived class that change the
  38. * underlying data (vector values), you MUST remember to call
  39. * ObjectChanged() AFTER making the change!
  40. */
  41. class Vector : public TaggedObject
  42. {
  43. public:
  44. /** @name Constructor/Destructor */
  45. //@{
  46. /** Constructor. It has to be given a pointer to the
  47. * corresponding VectorSpace.
  48. */
  49. inline
  50. Vector(const VectorSpace* owner_space);
  51. /** Destructor */
  52. inline
  53. virtual ~Vector();
  54. //@}
  55. /** Create new Vector of the same type with uninitialized data */
  56. inline
  57. Vector* MakeNew() const;
  58. /** Create new Vector of the same type and copy the data over */
  59. inline
  60. Vector* MakeNewCopy() const;
  61. /**@name Standard BLAS-1 Operations
  62. * (derived classes do NOT overload these
  63. * methods, instead, overload the
  64. * protected versions of these methods). */
  65. //@{
  66. /** Copy the data of the vector x into this vector (DCOPY). */
  67. inline
  68. void Copy(const Vector& x);
  69. /** Scales the vector by scalar alpha (DSCAL) */
  70. void Scal(Number alpha);
  71. /** Add the multiple alpha of vector x to this vector (DAXPY) */
  72. inline
  73. void Axpy(Number alpha, const Vector &x);
  74. /** Computes inner product of vector x with this (DDOT) */
  75. inline
  76. Number Dot(const Vector &x) const;
  77. /** Computes the 2-norm of this vector (DNRM2) */
  78. inline
  79. Number Nrm2() const;
  80. /** Computes the 1-norm of this vector (DASUM) */
  81. inline
  82. Number Asum() const;
  83. /** Computes the max-norm of this vector (based on IDAMAX) */
  84. inline
  85. Number Amax() const;
  86. //@}
  87. /** @name Additional (Non-BLAS) Vector Methods
  88. * (derived classes do NOT overload these
  89. * methods, instead, overload the
  90. * protected versions of these methods). */
  91. //@{
  92. /** Set each element in the vector to the scalar alpha. */
  93. inline
  94. void Set(Number alpha);
  95. /** Element-wise division \f$y_i \gets y_i/x_i\f$*/
  96. inline
  97. void ElementWiseDivide(const Vector& x);
  98. /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */
  99. inline
  100. void ElementWiseMultiply(const Vector& x);
  101. /** Element-wise max against entries in x */
  102. inline
  103. void ElementWiseMax(const Vector& x);
  104. /** Element-wise min against entries in x */
  105. inline
  106. void ElementWiseMin(const Vector& x);
  107. /** Reciprocates the entries in the vector */
  108. inline
  109. void ElementWiseReciprocal();
  110. /** Absolute values of the entries in the vector */
  111. inline
  112. void ElementWiseAbs();
  113. /** Element-wise square root of the entries in the vector */
  114. inline
  115. void ElementWiseSqrt();
  116. /** Replaces the vector values with their sgn values
  117. ( -1 if x_i < 0, 0 if x_i == 0, and 1 if x_i > 0)
  118. */
  119. inline
  120. void ElementWiseSgn();
  121. /** Add scalar to every vector component */
  122. inline
  123. void AddScalar(Number scalar);
  124. /** Returns the maximum value in the vector */
  125. inline
  126. Number Max() const;
  127. /** Returns the minimum value in the vector */
  128. inline
  129. Number Min() const;
  130. /** Returns the sum of the vector entries */
  131. inline
  132. Number Sum() const;
  133. /** Returns the sum of the logs of each vector entry */
  134. inline
  135. Number SumLogs() const;
  136. //@}
  137. /** @name Methods for specialized operations. A prototype
  138. * implementation is provided, but for efficient implementation
  139. * those should be specially implemented.
  140. */
  141. //@{
  142. /** Add one vector, y = a * v1 + c * y. This is automatically
  143. * reduced to call AddTwoVectors. */
  144. inline
  145. void AddOneVector(Number a, const Vector& v1, Number c);
  146. /** Add two vectors, y = a * v1 + b * v2 + c * y. Here, this
  147. * vector is y */
  148. inline void AddTwoVectors(Number a, const Vector& v1,
  149. Number b, const Vector& v2, Number c);
  150. /** Fraction to the boundary parameter. Computes \f$\alpha =
  151. * \max\{\bar\alpha\in(0,1] : x + \bar\alpha \Delta \geq (1-\tau)x\}\f$
  152. */
  153. inline
  154. Number FracToBound(const Vector& delta, Number tau) const;
  155. /** Add the quotient of two vectors, y = a * z/s + c * y. */
  156. inline
  157. void AddVectorQuotient(Number a, const Vector& z, const Vector& s,
  158. Number c);
  159. //@}
  160. /** Method for determining if all stored numbers are valid (i.e.,
  161. * no Inf or Nan). */
  162. inline
  163. bool HasValidNumbers() const;
  164. /** @name Accessor methods */
  165. //@{
  166. /** Dimension of the Vector */
  167. inline
  168. Index Dim() const;
  169. /** Return the owner VectorSpace*/
  170. inline
  171. SmartPtr<const VectorSpace> OwnerSpace() const;
  172. //@}
  173. /** @name Output methods
  174. * (derived classes do NOT overload these
  175. * methods, instead, overload the
  176. * protected versions of these methods). */
  177. //@{
  178. /** Print the entire vector */
  179. void Print(SmartPtr<const Journalist> jnlst,
  180. EJournalLevel level,
  181. EJournalCategory category,
  182. const std::string& name,
  183. Index indent=0,
  184. const std::string& prefix="") const;
  185. void Print(const Journalist& jnlst,
  186. EJournalLevel level,
  187. EJournalCategory category,
  188. const std::string& name,
  189. Index indent=0,
  190. const std::string& prefix="") const;
  191. //@}
  192. protected:
  193. /** @name implementation methods (derived classes MUST
  194. * overload these pure virtual protected methods.)
  195. */
  196. //@{
  197. /** Copy the data of the vector x into this vector (DCOPY). */
  198. virtual void CopyImpl(const Vector& x)=0;
  199. /** Scales the vector by scalar alpha (DSCAL) */
  200. virtual void ScalImpl(Number alpha)=0;
  201. /** Add the multiple alpha of vector x to this vector (DAXPY) */
  202. virtual void AxpyImpl(Number alpha, const Vector &x)=0;
  203. /** Computes inner product of vector x with this (DDOT) */
  204. virtual Number DotImpl(const Vector &x) const =0;
  205. /** Computes the 2-norm of this vector (DNRM2) */
  206. virtual Number Nrm2Impl() const =0;
  207. /** Computes the 1-norm of this vector (DASUM) */
  208. virtual Number AsumImpl() const =0;
  209. /** Computes the max-norm of this vector (based on IDAMAX) */
  210. virtual Number AmaxImpl() const =0;
  211. /** Set each element in the vector to the scalar alpha. */
  212. virtual void SetImpl(Number alpha)=0;
  213. /** Element-wise division \f$y_i \gets y_i/x_i\f$*/
  214. virtual void ElementWiseDivideImpl(const Vector& x)=0;
  215. /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */
  216. virtual void ElementWiseMultiplyImpl(const Vector& x)=0;
  217. /** Element-wise max against entries in x */
  218. virtual void ElementWiseMaxImpl(const Vector& x)=0;
  219. /** Element-wise min against entries in x */
  220. virtual void ElementWiseMinImpl(const Vector& x)=0;
  221. /** Reciprocates the elements of the vector */
  222. virtual void ElementWiseReciprocalImpl()=0;
  223. /** Take elementwise absolute values of the elements of the vector */
  224. virtual void ElementWiseAbsImpl()=0;
  225. /** Take elementwise square-root of the elements of the vector */
  226. virtual void ElementWiseSqrtImpl()=0;
  227. /** Replaces entries with sgn of the entry */
  228. virtual void ElementWiseSgnImpl()=0;
  229. /** Add scalar to every component of vector */
  230. virtual void AddScalarImpl(Number scalar)=0;
  231. /** Max value in the vector */
  232. virtual Number MaxImpl() const=0;
  233. /** Min number in the vector */
  234. virtual Number MinImpl() const=0;
  235. /** Sum of entries in the vector */
  236. virtual Number SumImpl() const=0;
  237. /** Sum of logs of entries in the vector */
  238. virtual Number SumLogsImpl() const=0;
  239. /** Add two vectors (a * v1 + b * v2). Result is stored in this
  240. vector. */
  241. virtual void AddTwoVectorsImpl(Number a, const Vector& v1,
  242. Number b, const Vector& v2, Number c);
  243. /** Fraction to boundary parameter. */
  244. virtual Number FracToBoundImpl(const Vector& delta, Number tau) const;
  245. /** Add the quotient of two vectors */
  246. virtual void AddVectorQuotientImpl(Number a, const Vector& z,
  247. const Vector& s, Number c);
  248. /** Method for determining if all stored numbers are valid (i.e.,
  249. * no Inf or Nan). A default implementation using Asum is
  250. * provided. */
  251. virtual bool HasValidNumbersImpl() const;
  252. /** Print the entire vector */
  253. virtual void PrintImpl(const Journalist& jnlst,
  254. EJournalLevel level,
  255. EJournalCategory category,
  256. const std::string& name,
  257. Index indent,
  258. const std::string& prefix) const =0;
  259. //@}
  260. private:
  261. /**@name Default Compiler Generated Methods
  262. * (Hidden to avoid implicit creation/calling).
  263. * These methods are not implemented and
  264. * we do not want the compiler to implement
  265. * them for us, so we declare them private
  266. * and do not define them. This ensures that
  267. * they will not be implicitly created/called. */
  268. //@{
  269. /** Default constructor */
  270. Vector();
  271. /** Copy constructor */
  272. Vector(const Vector&);
  273. /** Overloaded Equals Operator */
  274. Vector& operator=(const Vector&);
  275. //@}
  276. /** Vector Space */
  277. const SmartPtr<const VectorSpace> owner_space_;
  278. /**@name CachedResults data members */
  279. //@{
  280. /** Cache for dot products */
  281. mutable CachedResults<Number> dot_cache_;
  282. mutable TaggedObject::Tag nrm2_cache_tag_;
  283. mutable Number cached_nrm2_;
  284. mutable TaggedObject::Tag asum_cache_tag_;
  285. mutable Number cached_asum_;
  286. mutable TaggedObject::Tag amax_cache_tag_;
  287. mutable Number cached_amax_;
  288. mutable TaggedObject::Tag max_cache_tag_;
  289. mutable Number cached_max_;
  290. mutable TaggedObject::Tag min_cache_tag_;
  291. mutable Number cached_min_;
  292. mutable TaggedObject::Tag sum_cache_tag_;
  293. mutable Number cached_sum_;
  294. mutable TaggedObject::Tag sumlogs_cache_tag_;
  295. mutable Number cached_sumlogs_;
  296. mutable TaggedObject::Tag valid_cache_tag_;
  297. mutable bool cached_valid_;
  298. // AW: I removed this cache since it gets in the way for the
  299. // quality function search
  300. // /** Cache for FracToBound */
  301. // mutable CachedResults<Number> frac_to_bound_cache_;
  302. //@}
  303. };
  304. /** VectorSpace base class, corresponding to the Vector base class.
  305. * For each Vector implementation, a corresponding VectorSpace has
  306. * to be implemented. A VectorSpace is able to create new Vectors
  307. * of a specific type. The VectorSpace should also store
  308. * information that is common to all Vectors of that type. For
  309. * example, the dimension of a Vector is stored in the VectorSpace
  310. * base class.
  311. */
  312. class VectorSpace : public ReferencedObject
  313. {
  314. public:
  315. /** @name Constructors/Destructors */
  316. //@{
  317. /** Constructor, given the dimension of all vectors generated by
  318. * this VectorSpace.
  319. */
  320. VectorSpace(Index dim);
  321. /** Destructor */
  322. virtual ~VectorSpace()
  323. {}
  324. //@}
  325. /** Pure virtual method for creating a new Vector of the
  326. * corresponding type.
  327. */
  328. virtual Vector* MakeNew() const=0;
  329. /** Accessor function for the dimension of the vectors of this type.*/
  330. Index Dim() const
  331. {
  332. return dim_;
  333. }
  334. private:
  335. /**@name Default Compiler Generated Methods
  336. * (Hidden to avoid implicit creation/calling).
  337. * These methods are not implemented and
  338. * we do not want the compiler to implement
  339. * them for us, so we declare them private
  340. * and do not define them. This ensures that
  341. * they will not be implicitly created/called. */
  342. //@{
  343. /** default constructor */
  344. VectorSpace();
  345. /** Copy constructor */
  346. VectorSpace(const VectorSpace&);
  347. /** Overloaded Equals Operator */
  348. VectorSpace& operator=(const VectorSpace&);
  349. //@}
  350. /** Dimension of the vectors in this vector space. */
  351. const Index dim_;
  352. };
  353. /* inline methods */
  354. inline
  355. Vector::~Vector()
  356. {}
  357. inline
  358. Vector::Vector(const VectorSpace* owner_space)
  359. :
  360. TaggedObject(),
  361. owner_space_(owner_space),
  362. dot_cache_(10),
  363. cached_valid_(0)
  364. {
  365. DBG_ASSERT(IsValid(owner_space_));
  366. }
  367. inline
  368. Vector* Vector::MakeNew() const
  369. {
  370. return owner_space_->MakeNew();
  371. }
  372. inline
  373. Vector* Vector::MakeNewCopy() const
  374. {
  375. // ToDo: We can probably copy also the cached values for Norms etc here
  376. Vector* copy = MakeNew();
  377. copy->Copy(*this);
  378. return copy;
  379. }
  380. inline
  381. void Vector::Copy(const Vector& x)
  382. {
  383. CopyImpl(x);
  384. ObjectChanged();
  385. // Also copy any cached scalar values from the original vector
  386. // ToDo: Check if that is too much overhead
  387. TaggedObject::Tag x_tag = x.GetTag();
  388. if (x_tag == x.nrm2_cache_tag_) {
  389. nrm2_cache_tag_ = GetTag();
  390. cached_nrm2_ = x.cached_nrm2_;
  391. }
  392. if (x_tag == x.asum_cache_tag_) {
  393. asum_cache_tag_ = GetTag();
  394. cached_asum_ = x.cached_asum_;
  395. }
  396. if (x_tag == x.amax_cache_tag_) {
  397. amax_cache_tag_ = GetTag();
  398. cached_amax_ = x.cached_amax_;
  399. }
  400. if (x_tag == x.max_cache_tag_) {
  401. max_cache_tag_ = GetTag();
  402. cached_max_ = x.cached_max_;
  403. }
  404. if (x_tag == x.min_cache_tag_) {
  405. min_cache_tag_ = GetTag();
  406. cached_min_ = x.cached_min_;
  407. }
  408. if (x_tag == x.sum_cache_tag_) {
  409. sum_cache_tag_ = GetTag();
  410. cached_sum_ = x.cached_sum_;
  411. }
  412. if (x_tag == x.sumlogs_cache_tag_) {
  413. sumlogs_cache_tag_ = GetTag();
  414. cached_sumlogs_ = x.cached_sumlogs_;
  415. }
  416. }
  417. inline
  418. void Vector::Axpy(Number alpha, const Vector &x)
  419. {
  420. AxpyImpl(alpha, x);
  421. ObjectChanged();
  422. }
  423. inline
  424. Number Vector::Dot(const Vector &x) const
  425. {
  426. // The current implementation of the caching doesn't allow to have
  427. // a dependency of something with itself. Therefore, we use the
  428. // Nrm2 method if the dot product is to be taken with the vector
  429. // itself. Might be more efficient anyway.
  430. if (this==&x) {
  431. Number nrm2 = Nrm2();
  432. return nrm2*nrm2;
  433. }
  434. Number retValue;
  435. if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
  436. retValue = DotImpl(x);
  437. dot_cache_.AddCachedResult2Dep(retValue, this, &x);
  438. }
  439. return retValue;
  440. }
  441. inline
  442. Number Vector::Nrm2() const
  443. {
  444. if (nrm2_cache_tag_ != GetTag()) {
  445. cached_nrm2_ = Nrm2Impl();
  446. nrm2_cache_tag_ = GetTag();
  447. }
  448. return cached_nrm2_;
  449. }
  450. inline
  451. Number Vector::Asum() const
  452. {
  453. if (asum_cache_tag_ != GetTag()) {
  454. cached_asum_ = AsumImpl();
  455. asum_cache_tag_ = GetTag();
  456. }
  457. return cached_asum_;
  458. }
  459. inline
  460. Number Vector::Amax() const
  461. {
  462. if (amax_cache_tag_ != GetTag()) {
  463. cached_amax_ = AmaxImpl();
  464. amax_cache_tag_ = GetTag();
  465. }
  466. return cached_amax_;
  467. }
  468. inline
  469. Number Vector::Sum() const
  470. {
  471. if (sum_cache_tag_ != GetTag()) {
  472. cached_sum_ = SumImpl();
  473. sum_cache_tag_ = GetTag();
  474. }
  475. return cached_sum_;
  476. }
  477. inline
  478. Number Vector::SumLogs() const
  479. {
  480. if (sumlogs_cache_tag_ != GetTag()) {
  481. cached_sumlogs_ = SumLogsImpl();
  482. sumlogs_cache_tag_ = GetTag();
  483. }
  484. return cached_sumlogs_;
  485. }
  486. inline
  487. void Vector::ElementWiseSgn()
  488. {
  489. ElementWiseSgnImpl();
  490. ObjectChanged();
  491. }
  492. inline
  493. void Vector::Set(Number alpha)
  494. {
  495. // Could initialize caches here
  496. SetImpl(alpha);
  497. ObjectChanged();
  498. }
  499. inline
  500. void Vector::ElementWiseDivide(const Vector& x)
  501. {
  502. ElementWiseDivideImpl(x);
  503. ObjectChanged();
  504. }
  505. inline
  506. void Vector::ElementWiseMultiply(const Vector& x)
  507. {
  508. ElementWiseMultiplyImpl(x);
  509. ObjectChanged();
  510. }
  511. inline
  512. void Vector::ElementWiseReciprocal()
  513. {
  514. ElementWiseReciprocalImpl();
  515. ObjectChanged();
  516. }
  517. inline
  518. void Vector::ElementWiseMax(const Vector& x)
  519. {
  520. // Could initialize some caches here
  521. ElementWiseMaxImpl(x);
  522. ObjectChanged();
  523. }
  524. inline
  525. void Vector::ElementWiseMin(const Vector& x)
  526. {
  527. // Could initialize some caches here
  528. ElementWiseMinImpl(x);
  529. ObjectChanged();
  530. }
  531. inline
  532. void Vector::ElementWiseAbs()
  533. {
  534. // Could initialize some caches here
  535. ElementWiseAbsImpl();
  536. ObjectChanged();
  537. }
  538. inline
  539. void Vector::ElementWiseSqrt()
  540. {
  541. ElementWiseSqrtImpl();
  542. ObjectChanged();
  543. }
  544. inline
  545. void Vector::AddScalar(Number scalar)
  546. {
  547. // Could initialize some caches here
  548. AddScalarImpl(scalar);
  549. ObjectChanged();
  550. }
  551. inline
  552. Number Vector::Max() const
  553. {
  554. if (max_cache_tag_ != GetTag()) {
  555. cached_max_ = MaxImpl();
  556. max_cache_tag_ = GetTag();
  557. }
  558. return cached_max_;
  559. }
  560. inline
  561. Number Vector::Min() const
  562. {
  563. if (min_cache_tag_ != GetTag()) {
  564. cached_min_ = MinImpl();
  565. min_cache_tag_ = GetTag();
  566. }
  567. return cached_min_;
  568. }
  569. inline
  570. void Vector::AddOneVector(Number a, const Vector& v1, Number c)
  571. {
  572. AddTwoVectors(a, v1, 0., v1, c);
  573. }
  574. inline
  575. void Vector::AddTwoVectors(Number a, const Vector& v1,
  576. Number b, const Vector& v2, Number c)
  577. {
  578. AddTwoVectorsImpl(a, v1, b, v2, c);
  579. ObjectChanged();
  580. }
  581. inline
  582. Number Vector::FracToBound(const Vector& delta, Number tau) const
  583. {
  584. /* AW: I avoid the caching here, since it leads to overhead in the
  585. quality function search. Caches for this are in
  586. CalculatedQuantities.
  587. Number retValue;
  588. std::vector<const TaggedObject*> tdeps(1);
  589. tdeps[0] = &delta;
  590. std::vector<Number> sdeps(1);
  591. sdeps[0] = tau;
  592. if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
  593. retValue = FracToBoundImpl(delta, tau);
  594. frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
  595. }
  596. return retValue;
  597. */
  598. return FracToBoundImpl(delta, tau);
  599. }
  600. inline
  601. void Vector::AddVectorQuotient(Number a, const Vector& z,
  602. const Vector& s, Number c)
  603. {
  604. AddVectorQuotientImpl(a, z, s, c);
  605. ObjectChanged();
  606. }
  607. inline
  608. bool Vector::HasValidNumbers() const
  609. {
  610. if (valid_cache_tag_ != GetTag()) {
  611. cached_valid_ = HasValidNumbersImpl();
  612. valid_cache_tag_ = GetTag();
  613. }
  614. return cached_valid_;
  615. }
  616. inline
  617. Index Vector::Dim() const
  618. {
  619. return owner_space_->Dim();
  620. }
  621. inline
  622. SmartPtr<const VectorSpace> Vector::OwnerSpace() const
  623. {
  624. return owner_space_;
  625. }
  626. inline
  627. VectorSpace::VectorSpace(Index dim)
  628. :
  629. dim_(dim)
  630. {}
  631. } // namespace Ipopt
  632. // Macro definitions for debugging vectors
  633. #if COIN_IPOPT_VERBOSITY == 0
  634. # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
  635. #else
  636. # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
  637. if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
  638. if (dbg_jrnl.Jnlst()!=NULL) { \
  639. (__vec).Print(dbg_jrnl.Jnlst(), \
  640. J_ERROR, J_DBG, \
  641. __vec_name, \
  642. dbg_jrnl.IndentationLevel()*2, \
  643. "# "); \
  644. } \
  645. }
  646. #endif //if COIN_IPOPT_VERBOSITY == 0
  647. #endif