Ipopt  3.11.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
IpVector.hpp
Go to the documentation of this file.
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 
9 #ifndef __IPVECTOR_HPP__
10 #define __IPVECTOR_HPP__
11 
12 #include "IpTypes.hpp"
13 #include "IpTaggedObject.hpp"
14 #include "IpCachedResults.hpp"
15 #include "IpSmartPtr.hpp"
16 #include "IpJournalist.hpp"
17 #include "IpException.hpp"
18 
19 #include <vector>
20 
21 namespace Ipopt
22 {
25  DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED);
26 
27  /* forward declarations */
28  class VectorSpace;
29 
47  class Vector : public TaggedObject
48  {
49  public:
55  inline
56  Vector(const VectorSpace* owner_space);
57 
59  inline
60  virtual ~Vector();
62 
64  inline
65  Vector* MakeNew() const;
66 
68  inline
69  Vector* MakeNewCopy() const;
70 
77  inline
78  void Copy(const Vector& x);
79 
81  void Scal(Number alpha);
82 
84  inline
85  void Axpy(Number alpha, const Vector &x);
86 
88  inline
89  Number Dot(const Vector &x) const;
90 
92  inline
93  Number Nrm2() const;
94 
96  inline
97  Number Asum() const;
98 
100  inline
101  Number Amax() const;
103 
110  inline
111  void Set(Number alpha);
112 
114  inline
115  void ElementWiseDivide(const Vector& x);
116 
118  inline
119  void ElementWiseMultiply(const Vector& x);
120 
122  inline
123  void ElementWiseMax(const Vector& x);
124 
126  inline
127  void ElementWiseMin(const Vector& x);
128 
130  inline
131  void ElementWiseReciprocal();
132 
134  inline
135  void ElementWiseAbs();
136 
138  inline
139  void ElementWiseSqrt();
140 
144  inline
145  void ElementWiseSgn();
146 
148  inline
149  void AddScalar(Number scalar);
150 
152  inline
153  Number Max() const;
154 
156  inline
157  Number Min() const;
158 
160  inline
161  Number Sum() const;
162 
164  inline
165  Number SumLogs() const;
167 
175  inline
176  void AddOneVector(Number a, const Vector& v1, Number c);
177 
180  inline void AddTwoVectors(Number a, const Vector& v1,
181  Number b, const Vector& v2, Number c);
185  inline
186  Number FracToBound(const Vector& delta, Number tau) const;
188  inline
189  void AddVectorQuotient(Number a, const Vector& z, const Vector& s,
190  Number c);
192 
195  inline
196  bool HasValidNumbers() const;
197 
201  inline
202  Index Dim() const;
203 
205  inline
208 
216  EJournalLevel level,
217  EJournalCategory category,
218  const std::string& name,
219  Index indent=0,
220  const std::string& prefix="") const;
221  void Print(const Journalist& jnlst,
222  EJournalLevel level,
223  EJournalCategory category,
224  const std::string& name,
225  Index indent=0,
226  const std::string& prefix="") const;
228 
229  protected:
235  virtual void CopyImpl(const Vector& x)=0;
236 
238  virtual void ScalImpl(Number alpha)=0;
239 
241  virtual void AxpyImpl(Number alpha, const Vector &x)=0;
242 
244  virtual Number DotImpl(const Vector &x) const =0;
245 
247  virtual Number Nrm2Impl() const =0;
248 
250  virtual Number AsumImpl() const =0;
251 
253  virtual Number AmaxImpl() const =0;
254 
256  virtual void SetImpl(Number alpha)=0;
257 
259  virtual void ElementWiseDivideImpl(const Vector& x)=0;
260 
262  virtual void ElementWiseMultiplyImpl(const Vector& x)=0;
263 
265  virtual void ElementWiseMaxImpl(const Vector& x)=0;
266 
268  virtual void ElementWiseMinImpl(const Vector& x)=0;
269 
271  virtual void ElementWiseReciprocalImpl()=0;
272 
274  virtual void ElementWiseAbsImpl()=0;
275 
277  virtual void ElementWiseSqrtImpl()=0;
278 
280  virtual void ElementWiseSgnImpl()=0;
281 
283  virtual void AddScalarImpl(Number scalar)=0;
284 
286  virtual Number MaxImpl() const=0;
287 
289  virtual Number MinImpl() const=0;
290 
292  virtual Number SumImpl() const=0;
293 
295  virtual Number SumLogsImpl() const=0;
296 
299  virtual void AddTwoVectorsImpl(Number a, const Vector& v1,
300  Number b, const Vector& v2, Number c);
301 
303  virtual Number FracToBoundImpl(const Vector& delta, Number tau) const;
304 
306  virtual void AddVectorQuotientImpl(Number a, const Vector& z,
307  const Vector& s, Number c);
308 
312  virtual bool HasValidNumbersImpl() const;
313 
315  virtual void PrintImpl(const Journalist& jnlst,
316  EJournalLevel level,
317  EJournalCategory category,
318  const std::string& name,
319  Index indent,
320  const std::string& prefix) const =0;
322 
323  private:
333  Vector();
334 
336  Vector(const Vector&);
337 
339  Vector& operator=(const Vector&);
341 
344 
349 
352 
355 
358 
361 
364 
367 
370 
372  mutable bool cached_valid_;
373 
374  // AW: I removed this cache since it gets in the way for the
375  // quality function search
376  // /** Cache for FracToBound */
377  // mutable CachedResults<Number> frac_to_bound_cache_;
379 
380  };
381 
391  {
392  public:
398  VectorSpace(Index dim);
399 
401  virtual ~VectorSpace()
402  {}
404 
408  virtual Vector* MakeNew() const=0;
409 
411  Index Dim() const
412  {
413  return dim_;
414  }
415 
416  private:
426  VectorSpace();
427 
429  VectorSpace(const VectorSpace&);
430 
434 
436  const Index dim_;
437  };
438 
439  /* inline methods */
440  inline
442  {}
443 
444  inline
445  Vector::Vector(const VectorSpace* owner_space)
446  :
447  TaggedObject(),
448  owner_space_(owner_space),
449  dot_cache_(10),
450  cached_valid_(0)
451  {
453  }
454 
455  inline
457  {
458  return owner_space_->MakeNew();
459  }
460 
461  inline
463  {
464  // ToDo: We can probably copy also the cached values for Norms etc here
465  Vector* copy = MakeNew();
466  copy->Copy(*this);
467  return copy;
468  }
469 
470  inline
471  void Vector::Copy(const Vector& x)
472  {
473  CopyImpl(x);
474  ObjectChanged();
475  // Also copy any cached scalar values from the original vector
476  // ToDo: Check if that is too much overhead
477  TaggedObject::Tag x_tag = x.GetTag();
478  if (x_tag == x.nrm2_cache_tag_) {
481  }
482  if (x_tag == x.asum_cache_tag_) {
485  }
486  if (x_tag == x.amax_cache_tag_) {
489  }
490  if (x_tag == x.max_cache_tag_) {
493  }
494  if (x_tag == x.min_cache_tag_) {
497  }
498  if (x_tag == x.sum_cache_tag_) {
501  }
502  if (x_tag == x.sumlogs_cache_tag_) {
505  }
506  }
507 
508  inline
509  void Vector::Axpy(Number alpha, const Vector &x)
510  {
511  AxpyImpl(alpha, x);
512  ObjectChanged();
513  }
514 
515  inline
516  Number Vector::Dot(const Vector &x) const
517  {
518  // The current implementation of the caching doesn't allow to have
519  // a dependency of something with itself. Therefore, we use the
520  // Nrm2 method if the dot product is to be taken with the vector
521  // itself. Might be more efficient anyway.
522  if (this==&x) {
523  Number nrm2 = Nrm2();
524  return nrm2*nrm2;
525  }
526  Number retValue;
527  if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
528  retValue = DotImpl(x);
529  dot_cache_.AddCachedResult2Dep(retValue, this, &x);
530  }
531  return retValue;
532  }
533 
534  inline
536  {
537  if (nrm2_cache_tag_ != GetTag()) {
540  }
541  return cached_nrm2_;
542  }
543 
544  inline
546  {
547  if (asum_cache_tag_ != GetTag()) {
550  }
551  return cached_asum_;
552  }
553 
554  inline
556  {
557  if (amax_cache_tag_ != GetTag()) {
560  }
561  return cached_amax_;
562  }
563 
564  inline
566  {
567  if (sum_cache_tag_ != GetTag()) {
568  cached_sum_ = SumImpl();
570  }
571  return cached_sum_;
572  }
573 
574  inline
576  {
577  if (sumlogs_cache_tag_ != GetTag()) {
580  }
581  return cached_sumlogs_;
582  }
583 
584  inline
586  {
588  ObjectChanged();
589  }
590 
591  inline
592  void Vector::Set(Number alpha)
593  {
594  // Could initialize caches here
595  SetImpl(alpha);
596  ObjectChanged();
597  }
598 
599  inline
601  {
603  ObjectChanged();
604  }
605 
606  inline
608  {
610  ObjectChanged();
611  }
612 
613  inline
615  {
617  ObjectChanged();
618  }
619 
620  inline
622  {
623  // Could initialize some caches here
625  ObjectChanged();
626  }
627 
628  inline
630  {
631  // Could initialize some caches here
633  ObjectChanged();
634  }
635 
636  inline
638  {
639  // Could initialize some caches here
641  ObjectChanged();
642  }
643 
644  inline
646  {
648  ObjectChanged();
649  }
650 
651  inline
653  {
654  // Could initialize some caches here
655  AddScalarImpl(scalar);
656  ObjectChanged();
657  }
658 
659  inline
661  {
662  if (max_cache_tag_ != GetTag()) {
663  cached_max_ = MaxImpl();
665  }
666  return cached_max_;
667  }
668 
669  inline
671  {
672  if (min_cache_tag_ != GetTag()) {
673  cached_min_ = MinImpl();
675  }
676  return cached_min_;
677  }
678 
679  inline
680  void Vector::AddOneVector(Number a, const Vector& v1, Number c)
681  {
682  AddTwoVectors(a, v1, 0., v1, c);
683  }
684 
685  inline
687  Number b, const Vector& v2, Number c)
688  {
689  AddTwoVectorsImpl(a, v1, b, v2, c);
690  ObjectChanged();
691  }
692 
693  inline
694  Number Vector::FracToBound(const Vector& delta, Number tau) const
695  {
696  /* AW: I avoid the caching here, since it leads to overhead in the
697  quality function search. Caches for this are in
698  CalculatedQuantities.
699  Number retValue;
700  std::vector<const TaggedObject*> tdeps(1);
701  tdeps[0] = &delta;
702  std::vector<Number> sdeps(1);
703  sdeps[0] = tau;
704  if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
705  retValue = FracToBoundImpl(delta, tau);
706  frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
707  }
708  return retValue;
709  */
710  return FracToBoundImpl(delta, tau);
711  }
712 
713  inline
715  const Vector& s, Number c)
716  {
717  AddVectorQuotientImpl(a, z, s, c);
718  ObjectChanged();
719  }
720 
721  inline
723  {
724  if (valid_cache_tag_ != GetTag()) {
727  }
728  return cached_valid_;
729  }
730 
731  inline
733  {
734  return owner_space_->Dim();
735  }
736 
737  inline
739  {
740  return owner_space_;
741  }
742 
743  inline
745  :
746  dim_(dim)
747  {}
748 
749 } // namespace Ipopt
750 
751 // Macro definitions for debugging vectors
752 #if COIN_IPOPT_VERBOSITY == 0
753 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
754 #else
755 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
756  if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
757  if (dbg_jrnl.Jnlst()!=NULL) { \
758  (__vec).Print(dbg_jrnl.Jnlst(), \
759  J_ERROR, J_DBG, \
760  __vec_name, \
761  dbg_jrnl.IndentationLevel()*2, \
762  "# "); \
763  } \
764  }
765 #endif //if COIN_IPOPT_VERBOSITY == 0
766 
767 #endif