IpVector.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2004, 2008 International Business Machines and others.
00002 // All Rights Reserved.
00003 // This code is published under the Eclipse Public License.
00004 //
00005 // $Id: IpVector.hpp 2276 2013-05-05 12:33:44Z stefan $
00006 //
00007 // Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
00008 
00009 #ifndef __IPVECTOR_HPP__
00010 #define __IPVECTOR_HPP__
00011 
00012 #include "IpTypes.hpp"
00013 #include "IpTaggedObject.hpp"
00014 #include "IpCachedResults.hpp"
00015 #include "IpSmartPtr.hpp"
00016 #include "IpJournalist.hpp"
00017 #include "IpException.hpp"
00018 
00019 #include <vector>
00020 
00021 namespace Ipopt
00022 {
00025   DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED);
00026 
00027   /* forward declarations */
00028   class VectorSpace;
00029 
00047   class Vector : public TaggedObject
00048   {
00049   public:
00055     inline
00056     Vector(const VectorSpace* owner_space);
00057 
00059     inline
00060     virtual ~Vector();
00062 
00064     inline
00065     Vector* MakeNew() const;
00066 
00068     inline
00069     Vector* MakeNewCopy() const;
00070 
00077     inline
00078     void Copy(const Vector& x);
00079 
00081     void Scal(Number alpha);
00082 
00084     inline
00085     void Axpy(Number alpha, const Vector &x);
00086 
00088     inline
00089     Number Dot(const Vector &x) const;
00090 
00092     inline
00093     Number Nrm2() const;
00094 
00096     inline
00097     Number Asum() const;
00098 
00100     inline
00101     Number Amax() const;
00103 
00110     inline
00111     void Set(Number alpha);
00112 
00114     inline
00115     void ElementWiseDivide(const Vector& x);
00116 
00118     inline
00119     void ElementWiseMultiply(const Vector& x);
00120 
00122     inline
00123     void ElementWiseMax(const Vector& x);
00124 
00126     inline
00127     void ElementWiseMin(const Vector& x);
00128 
00130     inline
00131     void ElementWiseReciprocal();
00132 
00134     inline
00135     void ElementWiseAbs();
00136 
00138     inline
00139     void ElementWiseSqrt();
00140 
00144     inline
00145     void ElementWiseSgn();
00146 
00148     inline
00149     void AddScalar(Number scalar);
00150 
00152     inline
00153     Number Max() const;
00154 
00156     inline
00157     Number Min() const;
00158 
00160     inline
00161     Number Sum() const;
00162 
00164     inline
00165     Number SumLogs() const;
00167 
00175     inline
00176     void AddOneVector(Number a, const Vector& v1, Number c);
00177 
00180     inline void AddTwoVectors(Number a, const Vector& v1,
00181                        Number b, const Vector& v2, Number c);
00185     inline
00186     Number FracToBound(const Vector& delta, Number tau) const;
00188     inline
00189     void AddVectorQuotient(Number a, const Vector& z, const Vector& s,
00190                            Number c);
00192 
00195     inline
00196     bool HasValidNumbers() const;
00197 
00201     inline
00202     Index Dim() const;
00203 
00205     inline
00206     SmartPtr<const VectorSpace> OwnerSpace() const;
00208 
00215     void Print(SmartPtr<const Journalist> jnlst,
00216                EJournalLevel level,
00217                EJournalCategory category,
00218                const std::string& name,
00219                Index indent=0,
00220                const std::string& prefix="") const;
00221     void Print(const Journalist& jnlst,
00222                EJournalLevel level,
00223                EJournalCategory category,
00224                const std::string& name,
00225                Index indent=0,
00226                const std::string& prefix="") const;
00228 
00229   protected:
00235     virtual void CopyImpl(const Vector& x)=0;
00236 
00238     virtual void ScalImpl(Number alpha)=0;
00239 
00241     virtual void AxpyImpl(Number alpha, const Vector &x)=0;
00242 
00244     virtual Number DotImpl(const Vector &x) const =0;
00245 
00247     virtual Number Nrm2Impl() const =0;
00248 
00250     virtual Number AsumImpl() const =0;
00251 
00253     virtual Number AmaxImpl() const =0;
00254 
00256     virtual void SetImpl(Number alpha)=0;
00257 
00259     virtual void ElementWiseDivideImpl(const Vector& x)=0;
00260 
00262     virtual void ElementWiseMultiplyImpl(const Vector& x)=0;
00263 
00265     virtual void ElementWiseMaxImpl(const Vector& x)=0;
00266 
00268     virtual void ElementWiseMinImpl(const Vector& x)=0;
00269 
00271     virtual void ElementWiseReciprocalImpl()=0;
00272 
00274     virtual void ElementWiseAbsImpl()=0;
00275 
00277     virtual void ElementWiseSqrtImpl()=0;
00278 
00280     virtual void ElementWiseSgnImpl()=0;
00281 
00283     virtual void AddScalarImpl(Number scalar)=0;
00284 
00286     virtual Number MaxImpl() const=0;
00287 
00289     virtual Number MinImpl() const=0;
00290 
00292     virtual Number SumImpl() const=0;
00293 
00295     virtual Number SumLogsImpl() const=0;
00296 
00299     virtual void AddTwoVectorsImpl(Number a, const Vector& v1,
00300                                    Number b, const Vector& v2, Number c);
00301 
00303     virtual Number FracToBoundImpl(const Vector& delta, Number tau) const;
00304 
00306     virtual void AddVectorQuotientImpl(Number a, const Vector& z,
00307                                        const Vector& s, Number c);
00308 
00312     virtual bool HasValidNumbersImpl() const;
00313 
00315     virtual void PrintImpl(const Journalist& jnlst,
00316                            EJournalLevel level,
00317                            EJournalCategory category,
00318                            const std::string& name,
00319                            Index indent,
00320                            const std::string& prefix) const =0;
00322 
00323   private:
00333     Vector();
00334 
00336     Vector(const Vector&);
00337 
00339     Vector& operator=(const Vector&);
00341 
00343     const SmartPtr<const VectorSpace> owner_space_;
00344 
00348     mutable CachedResults<Number> dot_cache_;
00349 
00350     mutable TaggedObject::Tag nrm2_cache_tag_;
00351     mutable Number cached_nrm2_;
00352 
00353     mutable TaggedObject::Tag asum_cache_tag_;
00354     mutable Number cached_asum_;
00355 
00356     mutable TaggedObject::Tag amax_cache_tag_;
00357     mutable Number cached_amax_;
00358 
00359     mutable TaggedObject::Tag max_cache_tag_;
00360     mutable Number cached_max_;
00361 
00362     mutable TaggedObject::Tag min_cache_tag_;
00363     mutable Number cached_min_;
00364 
00365     mutable TaggedObject::Tag sum_cache_tag_;
00366     mutable Number cached_sum_;
00367 
00368     mutable TaggedObject::Tag sumlogs_cache_tag_;
00369     mutable Number cached_sumlogs_;
00370 
00371     mutable TaggedObject::Tag valid_cache_tag_;
00372     mutable bool cached_valid_;
00373 
00374     //     AW: I removed this cache since it gets in the way for the
00375     //         quality function search
00376     //     /** Cache for FracToBound */
00377     //     mutable CachedResults<Number> frac_to_bound_cache_;
00379 
00380   };
00381 
00390   class VectorSpace : public ReferencedObject
00391   {
00392   public:
00398     VectorSpace(Index dim);
00399 
00401     virtual ~VectorSpace()
00402     {}
00404 
00408     virtual Vector* MakeNew() const=0;
00409 
00411     Index Dim() const
00412     {
00413       return dim_;
00414     }
00415 
00416   private:
00426     VectorSpace();
00427 
00429     VectorSpace(const VectorSpace&);
00430 
00432     VectorSpace& operator=(const VectorSpace&);
00434 
00436     const Index dim_;
00437   };
00438 
00439   /* inline methods */
00440   inline
00441   Vector::~Vector()
00442   {}
00443 
00444   inline
00445   Vector::Vector(const VectorSpace* owner_space)
00446       :
00447       TaggedObject(),
00448       owner_space_(owner_space),
00449       dot_cache_(10),
00450       cached_valid_(0)
00451   {
00452     DBG_ASSERT(IsValid(owner_space_));
00453   }
00454 
00455   inline
00456   Vector* Vector::MakeNew() const
00457   {
00458     return owner_space_->MakeNew();
00459   }
00460 
00461   inline
00462   Vector* Vector::MakeNewCopy() const
00463   {
00464     // ToDo: We can probably copy also the cached values for Norms etc here
00465     Vector* copy = MakeNew();
00466     copy->Copy(*this);
00467     return copy;
00468   }
00469 
00470   inline
00471   void Vector::Copy(const Vector& x)
00472   {
00473     CopyImpl(x);
00474     ObjectChanged();
00475     // Also copy any cached scalar values from the original vector
00476     // ToDo: Check if that is too much overhead
00477     TaggedObject::Tag x_tag = x.GetTag();
00478     if (x_tag == x.nrm2_cache_tag_) {
00479       nrm2_cache_tag_ = GetTag();
00480       cached_nrm2_ = x.cached_nrm2_;
00481     }
00482     if (x_tag == x.asum_cache_tag_) {
00483       asum_cache_tag_ = GetTag();
00484       cached_asum_ = x.cached_asum_;
00485     }
00486     if (x_tag == x.amax_cache_tag_) {
00487       amax_cache_tag_ = GetTag();
00488       cached_amax_ = x.cached_amax_;
00489     }
00490     if (x_tag == x.max_cache_tag_) {
00491       max_cache_tag_ = GetTag();
00492       cached_max_ = x.cached_max_;
00493     }
00494     if (x_tag == x.min_cache_tag_) {
00495       min_cache_tag_ = GetTag();
00496       cached_min_ = x.cached_min_;
00497     }
00498     if (x_tag == x.sum_cache_tag_) {
00499       sum_cache_tag_ = GetTag();
00500       cached_sum_ = x.cached_sum_;
00501     }
00502     if (x_tag == x.sumlogs_cache_tag_) {
00503       sumlogs_cache_tag_ = GetTag();
00504       cached_sumlogs_ = x.cached_sumlogs_;
00505     }
00506   }
00507 
00508   inline
00509   void Vector::Axpy(Number alpha, const Vector &x)
00510   {
00511     AxpyImpl(alpha, x);
00512     ObjectChanged();
00513   }
00514 
00515   inline
00516   Number Vector::Dot(const Vector &x) const
00517   {
00518     // The current implementation of the caching doesn't allow to have
00519     // a dependency of something with itself.  Therefore, we use the
00520     // Nrm2 method if the dot product is to be taken with the vector
00521     // itself.  Might be more efficient anyway.
00522     if (this==&x) {
00523       Number nrm2 = Nrm2();
00524       return nrm2*nrm2;
00525     }
00526     Number retValue;
00527     if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
00528       retValue = DotImpl(x);
00529       dot_cache_.AddCachedResult2Dep(retValue, this, &x);
00530     }
00531     return retValue;
00532   }
00533 
00534   inline
00535   Number Vector::Nrm2() const
00536   {
00537     if (nrm2_cache_tag_ != GetTag()) {
00538       cached_nrm2_ = Nrm2Impl();
00539       nrm2_cache_tag_ = GetTag();
00540     }
00541     return cached_nrm2_;
00542   }
00543 
00544   inline
00545   Number Vector::Asum() const
00546   {
00547     if (asum_cache_tag_ != GetTag()) {
00548       cached_asum_ = AsumImpl();
00549       asum_cache_tag_ = GetTag();
00550     }
00551     return cached_asum_;
00552   }
00553 
00554   inline
00555   Number Vector::Amax() const
00556   {
00557     if (amax_cache_tag_ != GetTag()) {
00558       cached_amax_ = AmaxImpl();
00559       amax_cache_tag_ = GetTag();
00560     }
00561     return cached_amax_;
00562   }
00563 
00564   inline
00565   Number Vector::Sum() const
00566   {
00567     if (sum_cache_tag_ != GetTag()) {
00568       cached_sum_ = SumImpl();
00569       sum_cache_tag_ = GetTag();
00570     }
00571     return cached_sum_;
00572   }
00573 
00574   inline
00575   Number Vector::SumLogs() const
00576   {
00577     if (sumlogs_cache_tag_ != GetTag()) {
00578       cached_sumlogs_ = SumLogsImpl();
00579       sumlogs_cache_tag_ = GetTag();
00580     }
00581     return cached_sumlogs_;
00582   }
00583 
00584   inline
00585   void Vector::ElementWiseSgn()
00586   {
00587     ElementWiseSgnImpl();
00588     ObjectChanged();
00589   }
00590 
00591   inline
00592   void Vector::Set(Number alpha)
00593   {
00594     // Could initialize caches here
00595     SetImpl(alpha);
00596     ObjectChanged();
00597   }
00598 
00599   inline
00600   void Vector::ElementWiseDivide(const Vector& x)
00601   {
00602     ElementWiseDivideImpl(x);
00603     ObjectChanged();
00604   }
00605 
00606   inline
00607   void Vector::ElementWiseMultiply(const Vector& x)
00608   {
00609     ElementWiseMultiplyImpl(x);
00610     ObjectChanged();
00611   }
00612 
00613   inline
00614   void Vector::ElementWiseReciprocal()
00615   {
00616     ElementWiseReciprocalImpl();
00617     ObjectChanged();
00618   }
00619 
00620   inline
00621   void Vector::ElementWiseMax(const Vector& x)
00622   {
00623     // Could initialize some caches here
00624     ElementWiseMaxImpl(x);
00625     ObjectChanged();
00626   }
00627 
00628   inline
00629   void Vector::ElementWiseMin(const Vector& x)
00630   {
00631     // Could initialize some caches here
00632     ElementWiseMinImpl(x);
00633     ObjectChanged();
00634   }
00635 
00636   inline
00637   void Vector::ElementWiseAbs()
00638   {
00639     // Could initialize some caches here
00640     ElementWiseAbsImpl();
00641     ObjectChanged();
00642   }
00643 
00644   inline
00645   void Vector::ElementWiseSqrt()
00646   {
00647     ElementWiseSqrtImpl();
00648     ObjectChanged();
00649   }
00650 
00651   inline
00652   void Vector::AddScalar(Number scalar)
00653   {
00654     // Could initialize some caches here
00655     AddScalarImpl(scalar);
00656     ObjectChanged();
00657   }
00658 
00659   inline
00660   Number Vector::Max() const
00661   {
00662     if (max_cache_tag_ != GetTag()) {
00663       cached_max_ = MaxImpl();
00664       max_cache_tag_ = GetTag();
00665     }
00666     return cached_max_;
00667   }
00668 
00669   inline
00670   Number Vector::Min() const
00671   {
00672     if (min_cache_tag_ != GetTag()) {
00673       cached_min_ = MinImpl();
00674       min_cache_tag_ = GetTag();
00675     }
00676     return cached_min_;
00677   }
00678 
00679   inline
00680   void Vector::AddOneVector(Number a, const Vector& v1, Number c)
00681   {
00682     AddTwoVectors(a, v1, 0., v1, c);
00683   }
00684 
00685   inline
00686   void Vector::AddTwoVectors(Number a, const Vector& v1,
00687                              Number b, const Vector& v2, Number c)
00688   {
00689     AddTwoVectorsImpl(a, v1, b, v2, c);
00690     ObjectChanged();
00691   }
00692 
00693   inline
00694   Number Vector::FracToBound(const Vector& delta, Number tau) const
00695   {
00696     /* AW: I avoid the caching here, since it leads to overhead in the
00697        quality function search.  Caches for this are in
00698        CalculatedQuantities.
00699     Number retValue;
00700     std::vector<const TaggedObject*> tdeps(1);
00701     tdeps[0] = &delta;
00702     std::vector<Number> sdeps(1);
00703     sdeps[0] = tau;
00704     if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
00705       retValue = FracToBoundImpl(delta, tau);
00706       frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
00707     }
00708     return retValue;
00709     */
00710     return FracToBoundImpl(delta, tau);
00711   }
00712 
00713   inline
00714   void Vector::AddVectorQuotient(Number a, const Vector& z,
00715                                  const Vector& s, Number c)
00716   {
00717     AddVectorQuotientImpl(a, z, s, c);
00718     ObjectChanged();
00719   }
00720 
00721   inline
00722   bool Vector::HasValidNumbers() const
00723   {
00724     if (valid_cache_tag_ != GetTag()) {
00725       cached_valid_ = HasValidNumbersImpl();
00726       valid_cache_tag_ = GetTag();
00727     }
00728     return cached_valid_;
00729   }
00730 
00731   inline
00732   Index Vector::Dim() const
00733   {
00734     return owner_space_->Dim();
00735   }
00736 
00737   inline
00738   SmartPtr<const VectorSpace> Vector::OwnerSpace() const
00739   {
00740     return owner_space_;
00741   }
00742 
00743   inline
00744   VectorSpace::VectorSpace(Index dim)
00745       :
00746       dim_(dim)
00747   {}
00748 
00749 } // namespace Ipopt
00750 
00751 // Macro definitions for debugging vectors
00752 #if COIN_IPOPT_VERBOSITY == 0
00753 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
00754 #else
00755 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
00756    if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
00757       if (dbg_jrnl.Jnlst()!=NULL) { \
00758         (__vec).Print(dbg_jrnl.Jnlst(), \
00759         J_ERROR, J_DBG, \
00760         __vec_name, \
00761         dbg_jrnl.IndentationLevel()*2, \
00762         "# "); \
00763       } \
00764    }
00765 #endif //if COIN_IPOPT_VERBOSITY == 0
00766 
00767 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 19 Dec 2013 for Ipopt by  doxygen 1.6.1