Ipopt  3.11.8
 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 2476 2014-04-08 09:41:07Z 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  nrm2_cache_tag_(0),
451  asum_cache_tag_(0),
452  amax_cache_tag_(0),
453  max_cache_tag_(0),
454  min_cache_tag_(0),
455  sum_cache_tag_(0),
456  sumlogs_cache_tag_(0),
457  cached_valid_(0)
458  {
460  }
461 
462  inline
464  {
465  return owner_space_->MakeNew();
466  }
467 
468  inline
470  {
471  // ToDo: We can probably copy also the cached values for Norms etc here
472  Vector* copy = MakeNew();
473  copy->Copy(*this);
474  return copy;
475  }
476 
477  inline
478  void Vector::Copy(const Vector& x)
479  {
480  CopyImpl(x);
481  ObjectChanged();
482  // Also copy any cached scalar values from the original vector
483  // ToDo: Check if that is too much overhead
484  TaggedObject::Tag x_tag = x.GetTag();
485  if (x_tag == x.nrm2_cache_tag_) {
488  }
489  if (x_tag == x.asum_cache_tag_) {
492  }
493  if (x_tag == x.amax_cache_tag_) {
496  }
497  if (x_tag == x.max_cache_tag_) {
500  }
501  if (x_tag == x.min_cache_tag_) {
504  }
505  if (x_tag == x.sum_cache_tag_) {
508  }
509  if (x_tag == x.sumlogs_cache_tag_) {
512  }
513  }
514 
515  inline
516  void Vector::Axpy(Number alpha, const Vector &x)
517  {
518  AxpyImpl(alpha, x);
519  ObjectChanged();
520  }
521 
522  inline
523  Number Vector::Dot(const Vector &x) const
524  {
525  // The current implementation of the caching doesn't allow to have
526  // a dependency of something with itself. Therefore, we use the
527  // Nrm2 method if the dot product is to be taken with the vector
528  // itself. Might be more efficient anyway.
529  if (this==&x) {
530  Number nrm2 = Nrm2();
531  return nrm2*nrm2;
532  }
533  Number retValue;
534  if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
535  retValue = DotImpl(x);
536  dot_cache_.AddCachedResult2Dep(retValue, this, &x);
537  }
538  return retValue;
539  }
540 
541  inline
543  {
544  if (nrm2_cache_tag_ != GetTag()) {
547  }
548  return cached_nrm2_;
549  }
550 
551  inline
553  {
554  if (asum_cache_tag_ != GetTag()) {
557  }
558  return cached_asum_;
559  }
560 
561  inline
563  {
564  if (amax_cache_tag_ != GetTag()) {
567  }
568  return cached_amax_;
569  }
570 
571  inline
573  {
574  if (sum_cache_tag_ != GetTag()) {
575  cached_sum_ = SumImpl();
577  }
578  return cached_sum_;
579  }
580 
581  inline
583  {
584  if (sumlogs_cache_tag_ != GetTag()) {
587  }
588  return cached_sumlogs_;
589  }
590 
591  inline
593  {
595  ObjectChanged();
596  }
597 
598  inline
599  void Vector::Set(Number alpha)
600  {
601  // Could initialize caches here
602  SetImpl(alpha);
603  ObjectChanged();
604  }
605 
606  inline
608  {
610  ObjectChanged();
611  }
612 
613  inline
615  {
617  ObjectChanged();
618  }
619 
620  inline
622  {
624  ObjectChanged();
625  }
626 
627  inline
629  {
630  // Could initialize some caches here
632  ObjectChanged();
633  }
634 
635  inline
637  {
638  // Could initialize some caches here
640  ObjectChanged();
641  }
642 
643  inline
645  {
646  // Could initialize some caches here
648  ObjectChanged();
649  }
650 
651  inline
653  {
655  ObjectChanged();
656  }
657 
658  inline
660  {
661  // Could initialize some caches here
662  AddScalarImpl(scalar);
663  ObjectChanged();
664  }
665 
666  inline
668  {
669  if (max_cache_tag_ != GetTag()) {
670  cached_max_ = MaxImpl();
672  }
673  return cached_max_;
674  }
675 
676  inline
678  {
679  if (min_cache_tag_ != GetTag()) {
680  cached_min_ = MinImpl();
682  }
683  return cached_min_;
684  }
685 
686  inline
687  void Vector::AddOneVector(Number a, const Vector& v1, Number c)
688  {
689  AddTwoVectors(a, v1, 0., v1, c);
690  }
691 
692  inline
694  Number b, const Vector& v2, Number c)
695  {
696  AddTwoVectorsImpl(a, v1, b, v2, c);
697  ObjectChanged();
698  }
699 
700  inline
701  Number Vector::FracToBound(const Vector& delta, Number tau) const
702  {
703  /* AW: I avoid the caching here, since it leads to overhead in the
704  quality function search. Caches for this are in
705  CalculatedQuantities.
706  Number retValue;
707  std::vector<const TaggedObject*> tdeps(1);
708  tdeps[0] = &delta;
709  std::vector<Number> sdeps(1);
710  sdeps[0] = tau;
711  if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
712  retValue = FracToBoundImpl(delta, tau);
713  frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
714  }
715  return retValue;
716  */
717  return FracToBoundImpl(delta, tau);
718  }
719 
720  inline
722  const Vector& s, Number c)
723  {
724  AddVectorQuotientImpl(a, z, s, c);
725  ObjectChanged();
726  }
727 
728  inline
730  {
731  if (valid_cache_tag_ != GetTag()) {
734  }
735  return cached_valid_;
736  }
737 
738  inline
740  {
741  return owner_space_->Dim();
742  }
743 
744  inline
746  {
747  return owner_space_;
748  }
749 
750  inline
752  :
753  dim_(dim)
754  {}
755 
756 } // namespace Ipopt
757 
758 // Macro definitions for debugging vectors
759 #if COIN_IPOPT_VERBOSITY == 0
760 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
761 #else
762 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
763  if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
764  if (dbg_jrnl.Jnlst()!=NULL) { \
765  (__vec).Print(dbg_jrnl.Jnlst(), \
766  J_ERROR, J_DBG, \
767  __vec_name, \
768  dbg_jrnl.IndentationLevel()*2, \
769  "# "); \
770  } \
771  }
772 #endif //if COIN_IPOPT_VERBOSITY == 0
773 
774 #endif