- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/SVN-release/Ipopt-3.2.1/Ipopt/src/LinAlg/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