# 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