IpVector.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2004, 2006 International Business Machines and others.
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // $Id: IpVector.hpp 759 2006-07-07 03:07:08Z andreasw $
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 
00018 #include <vector>
00019 
00020 namespace Ipopt
00021 {
00022   /* forward declarations */
00023   class VectorSpace;
00024 
00042   class Vector : public TaggedObject
00043   {
00044   public:
00050     Vector(const VectorSpace* owner_space);
00051 
00053     virtual ~Vector();
00055 
00057     Vector* MakeNew() const;
00058 
00060     Vector* MakeNewCopy() const;
00061 
00068     void Copy(const Vector& x);
00069 
00071     void Scal(Number alpha);
00072 
00074     void Axpy(Number alpha, const Vector &x);
00075 
00077     Number Dot(const Vector &x) const;
00078 
00080     Number Nrm2() const;
00081 
00083     Number Asum() const;
00084 
00086     Number Amax() const;
00088 
00095     void Set(Number alpha);
00096 
00098     void ElementWiseDivide(const Vector& x);
00099 
00101     void ElementWiseMultiply(const Vector& x);
00102 
00104     void ElementWiseMax(const Vector& x);
00105 
00107     void ElementWiseMin(const Vector& x);
00108 
00110     void ElementWiseReciprocal();
00111 
00113     void ElementWiseAbs();
00114 
00116     void ElementWiseSqrt();
00117 
00121     void ElementWiseSgn();
00122 
00124     void AddScalar(Number scalar);
00125 
00127     Number Max() const;
00128 
00130     Number Min() const;
00131 
00133     Number Sum() const;
00134 
00136     Number SumLogs() const;
00138 
00146     void AddOneVector(Number a, const Vector& v1, Number c);
00147 
00150     void AddTwoVectors(Number a, const Vector& v1,
00151                        Number b, const Vector& v2, Number c);
00155     Number FracToBound(const Vector& delta, Number tau) const;
00157     void AddVectorQuotient(Number a, const Vector& z, const Vector& s,
00158                            Number c);
00160 
00163     bool HasValidNumbers() const;
00164 
00168     Index Dim() const;
00169 
00171     SmartPtr<const VectorSpace> OwnerSpace() const;
00173 
00180     void Print(SmartPtr<const Journalist> jnlst,
00181                EJournalLevel level,
00182                EJournalCategory category,
00183                const std::string& name,
00184                Index indent=0,
00185                const std::string& prefix="") const;
00186     void Print(const Journalist& jnlst,
00187                EJournalLevel level,
00188                EJournalCategory category,
00189                const std::string& name,
00190                Index indent=0,
00191                const std::string& prefix="") const;
00193 
00194   protected:
00200     virtual void CopyImpl(const Vector& x)=0;
00201 
00203     virtual void ScalImpl(Number alpha)=0;
00204 
00206     virtual void AxpyImpl(Number alpha, const Vector &x)=0;
00207 
00209     virtual Number DotImpl(const Vector &x) const =0;
00210 
00212     virtual Number Nrm2Impl() const =0;
00213 
00215     virtual Number AsumImpl() const =0;
00216 
00218     virtual Number AmaxImpl() const =0;
00219 
00221     virtual void SetImpl(Number alpha)=0;
00222 
00224     virtual void ElementWiseDivideImpl(const Vector& x)=0;
00225 
00227     virtual void ElementWiseMultiplyImpl(const Vector& x)=0;
00228 
00230     virtual void ElementWiseMaxImpl(const Vector& x)=0;
00231 
00233     virtual void ElementWiseMinImpl(const Vector& x)=0;
00234 
00236     virtual void ElementWiseReciprocalImpl()=0;
00237 
00239     virtual void ElementWiseAbsImpl()=0;
00240 
00242     virtual void ElementWiseSqrtImpl()=0;
00243 
00245     virtual void ElementWiseSgnImpl()=0;
00246 
00248     virtual void AddScalarImpl(Number scalar)=0;
00249 
00251     virtual Number MaxImpl() const=0;
00252 
00254     virtual Number MinImpl() const=0;
00255 
00257     virtual Number SumImpl() const=0;
00258 
00260     virtual Number SumLogsImpl() const=0;
00261 
00264     virtual void AddTwoVectorsImpl(Number a, const Vector& v1,
00265                                    Number b, const Vector& v2, Number c);
00266 
00268     virtual Number FracToBoundImpl(const Vector& delta, Number tau) const;
00269 
00271     virtual void AddVectorQuotientImpl(Number a, const Vector& z,
00272                                        const Vector& s, Number c);
00273 
00277     virtual bool HasValidNumbersImpl() const;
00278 
00280     virtual void PrintImpl(const Journalist& jnlst,
00281                            EJournalLevel level,
00282                            EJournalCategory category,
00283                            const std::string& name,
00284                            Index indent,
00285                            const std::string& prefix) const =0;
00287 
00288   private:
00298     Vector();
00299 
00301     Vector(const Vector&);
00302 
00304     Vector& operator=(const Vector&);
00306 
00308     const SmartPtr<const VectorSpace> owner_space_;
00309 
00313     mutable CachedResults<Number> dot_cache_;
00314 
00315     mutable TaggedObject::Tag nrm2_cache_tag_;
00316     mutable Number cached_nrm2_;
00317 
00318     mutable TaggedObject::Tag asum_cache_tag_;
00319     mutable Number cached_asum_;
00320 
00321     mutable TaggedObject::Tag amax_cache_tag_;
00322     mutable Number cached_amax_;
00323 
00324     mutable TaggedObject::Tag max_cache_tag_;
00325     mutable Number cached_max_;
00326 
00327     mutable TaggedObject::Tag min_cache_tag_;
00328     mutable Number cached_min_;
00329 
00330     mutable TaggedObject::Tag sum_cache_tag_;
00331     mutable Number cached_sum_;
00332 
00333     mutable TaggedObject::Tag sumlogs_cache_tag_;
00334     mutable Number cached_sumlogs_;
00335 
00336     mutable TaggedObject::Tag valid_cache_tag_;
00337     mutable bool cached_valid_;
00338 
00339     //     AW: I removed this cache since it gets in the way for the
00340     //         quality function search
00341     //     /** Cache for FracToBound */
00342     //     mutable CachedResults<Number> frac_to_bound_cache_;
00344 
00345   };
00346 
00355   class VectorSpace : public ReferencedObject
00356   {
00357   public:
00363     VectorSpace(Index dim);
00364 
00366     virtual ~VectorSpace()
00367     {}
00369 
00373     virtual Vector* MakeNew() const=0;
00374 
00376     Index Dim() const
00377     {
00378       return dim_;
00379     }
00380 
00381   private:
00391     VectorSpace();
00392 
00394     VectorSpace(const VectorSpace&);
00395 
00397     VectorSpace& operator=(const VectorSpace&);
00399 
00401     const Index dim_;
00402   };
00403 
00404   /* inline methods */
00405   inline
00406   Vector::~Vector()
00407   {}
00408 
00409   inline
00410   Vector::Vector(const VectorSpace* owner_space)
00411       :
00412       TaggedObject(),
00413       owner_space_(owner_space),
00414       dot_cache_(10),
00415       nrm2_cache_tag_(0),
00416       asum_cache_tag_(0),
00417       amax_cache_tag_(0),
00418       max_cache_tag_(0),
00419       min_cache_tag_(0),
00420       sum_cache_tag_(0),
00421       sumlogs_cache_tag_(0),
00422       cached_valid_(0)
00423   {
00424     DBG_ASSERT(IsValid(owner_space_));
00425   }
00426 
00427   inline
00428   Vector* Vector::MakeNew() const
00429   {
00430     return owner_space_->MakeNew();
00431   }
00432 
00433   inline
00434   Vector* Vector::MakeNewCopy() const
00435   {
00436     // ToDo: We can probably copy also the cached values for Norms etc here
00437     Vector* copy = MakeNew();
00438     copy->Copy(*this);
00439     return copy;
00440   }
00441 
00442   inline
00443   void Vector::Copy(const Vector& x)
00444   {
00445     CopyImpl(x);
00446     ObjectChanged();
00447     // Also copy any cached scalar values from the original vector
00448     // ToDo: Check if that is too much overhead
00449     TaggedObject::Tag x_tag = x.GetTag();
00450     if (x_tag == x.nrm2_cache_tag_) {
00451       nrm2_cache_tag_ = GetTag();
00452       cached_nrm2_ = x.cached_nrm2_;
00453     }
00454     if (x_tag == x.asum_cache_tag_) {
00455       asum_cache_tag_ = GetTag();
00456       cached_asum_ = x.cached_asum_;
00457     }
00458     if (x_tag == x.amax_cache_tag_) {
00459       amax_cache_tag_ = GetTag();
00460       cached_amax_ = x.cached_amax_;
00461     }
00462     if (x_tag == x.max_cache_tag_) {
00463       max_cache_tag_ = GetTag();
00464       cached_max_ = x.cached_max_;
00465     }
00466     if (x_tag == x.min_cache_tag_) {
00467       min_cache_tag_ = GetTag();
00468       cached_min_ = x.cached_min_;
00469     }
00470     if (x_tag == x.sum_cache_tag_) {
00471       sum_cache_tag_ = GetTag();
00472       cached_sum_ = x.cached_sum_;
00473     }
00474     if (x_tag == x.sumlogs_cache_tag_) {
00475       sumlogs_cache_tag_ = GetTag();
00476       cached_sumlogs_ = x.cached_sumlogs_;
00477     }
00478   }
00479 
00480   inline
00481   void Vector::Axpy(Number alpha, const Vector &x)
00482   {
00483     AxpyImpl(alpha, x);
00484     ObjectChanged();
00485   }
00486 
00487   inline
00488   Number Vector::Dot(const Vector &x) const
00489   {
00490     // The current implementation of the caching doesn't allow to have
00491     // a dependency of something with itself.  Therefore, we use the
00492     // Nrm2 method if the dot product is to be taken with the vector
00493     // itself.  Might be more efficient anyway.
00494     if (this==&x) {
00495       Number nrm2 = Nrm2();
00496       return nrm2*nrm2;
00497     }
00498     Number retValue;
00499     if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
00500       retValue = DotImpl(x);
00501       dot_cache_.AddCachedResult2Dep(retValue, this, &x);
00502     }
00503     return retValue;
00504   }
00505 
00506   inline
00507   Number Vector::Nrm2() const
00508   {
00509     if (nrm2_cache_tag_ != GetTag()) {
00510       cached_nrm2_ = Nrm2Impl();
00511       nrm2_cache_tag_ = GetTag();
00512     }
00513     return cached_nrm2_;
00514   }
00515 
00516   inline
00517   Number Vector::Asum() const
00518   {
00519     if (asum_cache_tag_ != GetTag()) {
00520       cached_asum_ = AsumImpl();
00521       asum_cache_tag_ = GetTag();
00522     }
00523     return cached_asum_;
00524   }
00525 
00526   inline
00527   Number Vector::Amax() const
00528   {
00529     if (amax_cache_tag_ != GetTag()) {
00530       cached_amax_ = AmaxImpl();
00531       amax_cache_tag_ = GetTag();
00532     }
00533     return cached_amax_;
00534   }
00535 
00536   inline
00537   Number Vector::Sum() const
00538   {
00539     if (sum_cache_tag_ != GetTag()) {
00540       cached_sum_ = SumImpl();
00541       sum_cache_tag_ = GetTag();
00542     }
00543     return cached_sum_;
00544   }
00545 
00546   inline
00547   Number Vector::SumLogs() const
00548   {
00549     if (sumlogs_cache_tag_ != GetTag()) {
00550       cached_sumlogs_ = SumLogsImpl();
00551       sumlogs_cache_tag_ = GetTag();
00552     }
00553     return cached_sumlogs_;
00554   }
00555 
00556   inline
00557   void Vector::ElementWiseSgn()
00558   {
00559     ElementWiseSgnImpl();
00560     ObjectChanged();
00561   }
00562 
00563   inline
00564   void Vector::Set(Number alpha)
00565   {
00566     // Could initialize caches here
00567     SetImpl(alpha);
00568     ObjectChanged();
00569   }
00570 
00571   inline
00572   void Vector::ElementWiseDivide(const Vector& x)
00573   {
00574     ElementWiseDivideImpl(x);
00575     ObjectChanged();
00576   }
00577 
00578   inline
00579   void Vector::ElementWiseMultiply(const Vector& x)
00580   {
00581     ElementWiseMultiplyImpl(x);
00582     ObjectChanged();
00583   }
00584 
00585   inline
00586   void Vector::ElementWiseReciprocal()
00587   {
00588     ElementWiseReciprocalImpl();
00589     ObjectChanged();
00590   }
00591 
00592   inline
00593   void Vector::ElementWiseMax(const Vector& x)
00594   {
00595     // Could initialize some caches here
00596     ElementWiseMaxImpl(x);
00597     ObjectChanged();
00598   }
00599 
00600   inline
00601   void Vector::ElementWiseMin(const Vector& x)
00602   {
00603     // Could initialize some caches here
00604     ElementWiseMinImpl(x);
00605     ObjectChanged();
00606   }
00607 
00608   inline
00609   void Vector::ElementWiseAbs()
00610   {
00611     // Could initialize some caches here
00612     ElementWiseAbsImpl();
00613     ObjectChanged();
00614   }
00615 
00616   inline
00617   void Vector::ElementWiseSqrt()
00618   {
00619     ElementWiseSqrtImpl();
00620     ObjectChanged();
00621   }
00622 
00623   inline
00624   void Vector::AddScalar(Number scalar)
00625   {
00626     // Could initialize some caches here
00627     AddScalarImpl(scalar);
00628     ObjectChanged();
00629   }
00630 
00631   inline
00632   Number Vector::Max() const
00633   {
00634     if (max_cache_tag_ != GetTag()) {
00635       cached_max_ = MaxImpl();
00636       max_cache_tag_ = GetTag();
00637     }
00638     return cached_max_;
00639   }
00640 
00641   inline
00642   Number Vector::Min() const
00643   {
00644     if (min_cache_tag_ != GetTag()) {
00645       cached_min_ = MinImpl();
00646       min_cache_tag_ = GetTag();
00647     }
00648     return cached_min_;
00649   }
00650 
00651   inline
00652   void Vector::AddOneVector(Number a, const Vector& v1, Number c)
00653   {
00654     AddTwoVectorsImpl(a, v1, 0., v1, c);
00655   }
00656 
00657   inline
00658   void Vector::AddTwoVectors(Number a, const Vector& v1,
00659                              Number b, const Vector& v2, Number c)
00660   {
00661     AddTwoVectorsImpl(a, v1, b, v2, c);
00662     ObjectChanged();
00663   }
00664 
00665   inline
00666   Number Vector::FracToBound(const Vector& delta, Number tau) const
00667   {
00668     /* AW: I avoid the caching here, since it leads to overhead in the
00669        quality function search.  Caches for this are in
00670        CalculatedQuantities.
00671     Number retValue;
00672     std::vector<const TaggedObject*> tdeps(1);
00673     tdeps[0] = &delta;
00674     std::vector<Number> sdeps(1);
00675     sdeps[0] = tau;
00676     if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
00677       retValue = FracToBoundImpl(delta, tau);
00678       frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
00679     }
00680     return retValue;
00681     */
00682     return FracToBoundImpl(delta, tau);
00683   }
00684 
00685   inline
00686   void Vector::AddVectorQuotient(Number a, const Vector& z,
00687                                  const Vector& s, Number c)
00688   {
00689     AddVectorQuotientImpl(a, z, s, c);
00690     ObjectChanged();
00691   }
00692 
00693   inline
00694   bool Vector::HasValidNumbers() const
00695   {
00696     if (valid_cache_tag_ != GetTag()) {
00697       cached_valid_ = HasValidNumbersImpl();
00698       valid_cache_tag_ = GetTag();
00699     }
00700     return cached_valid_;
00701   }
00702 
00703   inline
00704   Index Vector::Dim() const
00705   {
00706     return owner_space_->Dim();
00707   }
00708 
00709   inline
00710   SmartPtr<const VectorSpace> Vector::OwnerSpace() const
00711   {
00712     return owner_space_;
00713   }
00714 
00715   inline
00716   VectorSpace::VectorSpace(Index dim)
00717       :
00718       dim_(dim)
00719   {}
00720 
00721 } // namespace Ipopt
00722 
00723 // Macro definitions for debugging vectors
00724 #ifndef IP_DEBUG
00725 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
00726 #else
00727 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
00728    if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
00729       if (dbg_jrnl.Jnlst()!=NULL) { \
00730         (__vec).Print(dbg_jrnl.Jnlst(), \
00731               J_ERROR, J_DBG, \
00732               __vec_name, \
00733               dbg_jrnl.IndentationLevel()*2, \
00734               "# "); \
00735       } \
00736    }
00737 #endif // IP_DEBUG
00738 
00739 #endif

Generated on Fri Sep 26 07:44:13 2008 for SimTKcore by  doxygen 1.5.6