- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/SVN-release/Ipopt-3.5.1/Ipopt/src/LinAlg/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 Common Public License.
    00004 //
    00005 // $Id: IpVector.hpp 1290 2008-08-25 15:48:22Z 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 #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     Vector(const VectorSpace* owner_space);
    00056
    00058     virtual ~Vector();
    00060
    00062     Vector* MakeNew() const;
    00063
    00065     Vector* MakeNewCopy() const;
    00066
    00073     void Copy(const Vector& x);
    00074
    00076     void Scal(Number alpha);
    00077
    00079     void Axpy(Number alpha, const Vector &x);
    00080
    00082     Number Dot(const Vector &x) const;
    00083
    00085     Number Nrm2() const;
    00086
    00088     Number Asum() const;
    00089
    00091     Number Amax() const;
    00093
    00100     void Set(Number alpha);
    00101
    00103     void ElementWiseDivide(const Vector& x);
    00104
    00106     void ElementWiseMultiply(const Vector& x);
    00107
    00109     void ElementWiseMax(const Vector& x);
    00110
    00112     void ElementWiseMin(const Vector& x);
    00113
    00115     void ElementWiseReciprocal();
    00116
    00118     void ElementWiseAbs();
    00119
    00121     void ElementWiseSqrt();
    00122
    00126     void ElementWiseSgn();
    00127
    00129     void AddScalar(Number scalar);
    00130
    00132     Number Max() const;
    00133
    00135     Number Min() const;
    00136
    00138     Number Sum() const;
    00139
    00141     Number SumLogs() const;
    00143
    00151     void AddOneVector(Number a, const Vector& v1, Number c);
    00152
    00155     void AddTwoVectors(Number a, const Vector& v1,
    00156                        Number b, const Vector& v2, Number c);
    00160     Number FracToBound(const Vector& delta, Number tau) const;
    00162     void AddVectorQuotient(Number a, const Vector& z, const Vector& s,
    00163                            Number c);
    00165
    00168     bool HasValidNumbers() const;
    00169
    00173     Index Dim() const;
    00174
    00176     SmartPtr<const VectorSpace> OwnerSpace() const;
    00178
    00185     void Print(SmartPtr<const Journalist> jnlst,
    00186                EJournalLevel level,
    00187                EJournalCategory category,
    00188                const std::string& name,
    00189                Index indent=0,
    00190                const std::string& prefix="") const;
    00191     void Print(const Journalist& jnlst,
    00192                EJournalLevel level,
    00193                EJournalCategory category,
    00194                const std::string& name,
    00195                Index indent=0,
    00196                const std::string& prefix="") const;
    00198
    00199   protected:
    00205     virtual void CopyImpl(const Vector& x)=0;
    00206
    00208     virtual void ScalImpl(Number alpha)=0;
    00209
    00211     virtual void AxpyImpl(Number alpha, const Vector &x)=0;
    00212
    00214     virtual Number DotImpl(const Vector &x) const =0;
    00215
    00217     virtual Number Nrm2Impl() const =0;
    00218
    00220     virtual Number AsumImpl() const =0;
    00221
    00223     virtual Number AmaxImpl() const =0;
    00224
    00226     virtual void SetImpl(Number alpha)=0;
    00227
    00229     virtual void ElementWiseDivideImpl(const Vector& x)=0;
    00230
    00232     virtual void ElementWiseMultiplyImpl(const Vector& x)=0;
    00233
    00235     virtual void ElementWiseMaxImpl(const Vector& x)=0;
    00236
    00238     virtual void ElementWiseMinImpl(const Vector& x)=0;
    00239
    00241     virtual void ElementWiseReciprocalImpl()=0;
    00242
    00244     virtual void ElementWiseAbsImpl()=0;
    00245
    00247     virtual void ElementWiseSqrtImpl()=0;
    00248
    00250     virtual void ElementWiseSgnImpl()=0;
    00251
    00253     virtual void AddScalarImpl(Number scalar)=0;
    00254
    00256     virtual Number MaxImpl() const=0;
    00257
    00259     virtual Number MinImpl() const=0;
    00260
    00262     virtual Number SumImpl() const=0;
    00263
    00265     virtual Number SumLogsImpl() const=0;
    00266
    00269     virtual void AddTwoVectorsImpl(Number a, const Vector& v1,
    00270                                    Number b, const Vector& v2, Number c);
    00271
    00273     virtual Number FracToBoundImpl(const Vector& delta, Number tau) const;
    00274
    00276     virtual void AddVectorQuotientImpl(Number a, const Vector& z,
    00277                                        const Vector& s, Number c);
    00278
    00282     virtual bool HasValidNumbersImpl() const;
    00283
    00285     virtual void PrintImpl(const Journalist& jnlst,
    00286                            EJournalLevel level,
    00287                            EJournalCategory category,
    00288                            const std::string& name,
    00289                            Index indent,
    00290                            const std::string& prefix) const =0;
    00292
    00293   private:
    00303     Vector();
    00304
    00306     Vector(const Vector&);
    00307
    00309     Vector& operator=(const Vector&);
    00311
    00313     const SmartPtr<const VectorSpace> owner_space_;
    00314
    00318     mutable CachedResults<Number> dot_cache_;
    00319
    00320     mutable TaggedObject::Tag nrm2_cache_tag_;
    00321     mutable Number cached_nrm2_;
    00322
    00323     mutable TaggedObject::Tag asum_cache_tag_;
    00324     mutable Number cached_asum_;
    00325
    00326     mutable TaggedObject::Tag amax_cache_tag_;
    00327     mutable Number cached_amax_;
    00328
    00329     mutable TaggedObject::Tag max_cache_tag_;
    00330     mutable Number cached_max_;
    00331
    00332     mutable TaggedObject::Tag min_cache_tag_;
    00333     mutable Number cached_min_;
    00334
    00335     mutable TaggedObject::Tag sum_cache_tag_;
    00336     mutable Number cached_sum_;
    00337
    00338     mutable TaggedObject::Tag sumlogs_cache_tag_;
    00339     mutable Number cached_sumlogs_;
    00340
    00341     mutable TaggedObject::Tag valid_cache_tag_;
    00342     mutable bool cached_valid_;
    00343
    00344     //     AW: I removed this cache since it gets in the way for the
    00345     //         quality function search
    00346     //     /** Cache for FracToBound */
    00347     //     mutable CachedResults<Number> frac_to_bound_cache_;
    00349
    00350   };
    00351
    00360   class VectorSpace : public ReferencedObject
    00361   {
    00362   public:
    00368     VectorSpace(Index dim);
    00369
    00371     virtual ~VectorSpace()
    00372     {}
    00374
    00378     virtual Vector* MakeNew() const=0;
    00379
    00381     Index Dim() const
    00382     {
    00383       return dim_;
    00384     }
    00385
    00386   private:
    00396     VectorSpace();
    00397
    00399     VectorSpace(const VectorSpace&);
    00400
    00402     VectorSpace& operator=(const VectorSpace&);
    00404
    00406     const Index dim_;
    00407   };
    00408
    00409   /* inline methods */
    00410   inline
    00411   Vector::~Vector()
    00412   {}
    00413
    00414   inline
    00415   Vector::Vector(const VectorSpace* owner_space)
    00416       :
    00417       TaggedObject(),
    00418       owner_space_(owner_space),
    00419       dot_cache_(10),
    00420       nrm2_cache_tag_(0),
    00421       asum_cache_tag_(0),
    00422       amax_cache_tag_(0),
    00423       max_cache_tag_(0),
    00424       min_cache_tag_(0),
    00425       sum_cache_tag_(0),
    00426       sumlogs_cache_tag_(0),
    00427       cached_valid_(0)
    00428   {
    00429     DBG_ASSERT(IsValid(owner_space_));
    00430   }
    00431
    00432   inline
    00433   Vector* Vector::MakeNew() const
    00434   {
    00435     return owner_space_->MakeNew();
    00436   }
    00437
    00438   inline
    00439   Vector* Vector::MakeNewCopy() const
    00440   {
    00441     // ToDo: We can probably copy also the cached values for Norms etc here
    00442     Vector* copy = MakeNew();
    00443     copy->Copy(*this);
    00444     return copy;
    00445   }
    00446
    00447   inline
    00448   void Vector::Copy(const Vector& x)
    00449   {
    00450     CopyImpl(x);
    00451     ObjectChanged();
    00452     // Also copy any cached scalar values from the original vector
    00453     // ToDo: Check if that is too much overhead
    00454     TaggedObject::Tag x_tag = x.GetTag();
    00455     if (x_tag == x.nrm2_cache_tag_) {
    00456       nrm2_cache_tag_ = GetTag();
    00457       cached_nrm2_ = x.cached_nrm2_;
    00458     }
    00459     if (x_tag == x.asum_cache_tag_) {
    00460       asum_cache_tag_ = GetTag();
    00461       cached_asum_ = x.cached_asum_;
    00462     }
    00463     if (x_tag == x.amax_cache_tag_) {
    00464       amax_cache_tag_ = GetTag();
    00465       cached_amax_ = x.cached_amax_;
    00466     }
    00467     if (x_tag == x.max_cache_tag_) {
    00468       max_cache_tag_ = GetTag();
    00469       cached_max_ = x.cached_max_;
    00470     }
    00471     if (x_tag == x.min_cache_tag_) {
    00472       min_cache_tag_ = GetTag();
    00473       cached_min_ = x.cached_min_;
    00474     }
    00475     if (x_tag == x.sum_cache_tag_) {
    00476       sum_cache_tag_ = GetTag();
    00477       cached_sum_ = x.cached_sum_;
    00478     }
    00479     if (x_tag == x.sumlogs_cache_tag_) {
    00480       sumlogs_cache_tag_ = GetTag();
    00481       cached_sumlogs_ = x.cached_sumlogs_;
    00482     }
    00483   }
    00484
    00485   inline
    00486   void Vector::Axpy(Number alpha, const Vector &x)
    00487   {
    00488     AxpyImpl(alpha, x);
    00489     ObjectChanged();
    00490   }
    00491
    00492   inline
    00493   Number Vector::Dot(const Vector &x) const
    00494   {
    00495     // The current implementation of the caching doesn't allow to have
    00496     // a dependency of something with itself.  Therefore, we use the
    00497     // Nrm2 method if the dot product is to be taken with the vector
    00498     // itself.  Might be more efficient anyway.
    00499     if (this==&x) {
    00500       Number nrm2 = Nrm2();
    00501       return nrm2*nrm2;
    00502     }
    00503     Number retValue;
    00504     if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) {
    00505       retValue = DotImpl(x);
    00506       dot_cache_.AddCachedResult2Dep(retValue, this, &x);
    00507     }
    00508     return retValue;
    00509   }
    00510
    00511   inline
    00512   Number Vector::Nrm2() const
    00513   {
    00514     if (nrm2_cache_tag_ != GetTag()) {
    00515       cached_nrm2_ = Nrm2Impl();
    00516       nrm2_cache_tag_ = GetTag();
    00517     }
    00518     return cached_nrm2_;
    00519   }
    00520
    00521   inline
    00522   Number Vector::Asum() const
    00523   {
    00524     if (asum_cache_tag_ != GetTag()) {
    00525       cached_asum_ = AsumImpl();
    00526       asum_cache_tag_ = GetTag();
    00527     }
    00528     return cached_asum_;
    00529   }
    00530
    00531   inline
    00532   Number Vector::Amax() const
    00533   {
    00534     if (amax_cache_tag_ != GetTag()) {
    00535       cached_amax_ = AmaxImpl();
    00536       amax_cache_tag_ = GetTag();
    00537     }
    00538     return cached_amax_;
    00539   }
    00540
    00541   inline
    00542   Number Vector::Sum() const
    00543   {
    00544     if (sum_cache_tag_ != GetTag()) {
    00545       cached_sum_ = SumImpl();
    00546       sum_cache_tag_ = GetTag();
    00547     }
    00548     return cached_sum_;
    00549   }
    00550
    00551   inline
    00552   Number Vector::SumLogs() const
    00553   {
    00554     if (sumlogs_cache_tag_ != GetTag()) {
    00555       cached_sumlogs_ = SumLogsImpl();
    00556       sumlogs_cache_tag_ = GetTag();
    00557     }
    00558     return cached_sumlogs_;
    00559   }
    00560
    00561   inline
    00562   void Vector::ElementWiseSgn()
    00563   {
    00564     ElementWiseSgnImpl();
    00565     ObjectChanged();
    00566   }
    00567
    00568   inline
    00569   void Vector::Set(Number alpha)
    00570   {
    00571     // Could initialize caches here
    00572     SetImpl(alpha);
    00573     ObjectChanged();
    00574   }
    00575
    00576   inline
    00577   void Vector::ElementWiseDivide(const Vector& x)
    00578   {
    00579     ElementWiseDivideImpl(x);
    00580     ObjectChanged();
    00581   }
    00582
    00583   inline
    00584   void Vector::ElementWiseMultiply(const Vector& x)
    00585   {
    00586     ElementWiseMultiplyImpl(x);
    00587     ObjectChanged();
    00588   }
    00589
    00590   inline
    00591   void Vector::ElementWiseReciprocal()
    00592   {
    00593     ElementWiseReciprocalImpl();
    00594     ObjectChanged();
    00595   }
    00596
    00597   inline
    00598   void Vector::ElementWiseMax(const Vector& x)
    00599   {
    00600     // Could initialize some caches here
    00601     ElementWiseMaxImpl(x);
    00602     ObjectChanged();
    00603   }
    00604
    00605   inline
    00606   void Vector::ElementWiseMin(const Vector& x)
    00607   {
    00608     // Could initialize some caches here
    00609     ElementWiseMinImpl(x);
    00610     ObjectChanged();
    00611   }
    00612
    00613   inline
    00614   void Vector::ElementWiseAbs()
    00615   {
    00616     // Could initialize some caches here
    00617     ElementWiseAbsImpl();
    00618     ObjectChanged();
    00619   }
    00620
    00621   inline
    00622   void Vector::ElementWiseSqrt()
    00623   {
    00624     ElementWiseSqrtImpl();
    00625     ObjectChanged();
    00626   }
    00627
    00628   inline
    00629   void Vector::AddScalar(Number scalar)
    00630   {
    00631     // Could initialize some caches here
    00632     AddScalarImpl(scalar);
    00633     ObjectChanged();
    00634   }
    00635
    00636   inline
    00637   Number Vector::Max() const
    00638   {
    00639     if (max_cache_tag_ != GetTag()) {
    00640       cached_max_ = MaxImpl();
    00641       max_cache_tag_ = GetTag();
    00642     }
    00643     return cached_max_;
    00644   }
    00645
    00646   inline
    00647   Number Vector::Min() const
    00648   {
    00649     if (min_cache_tag_ != GetTag()) {
    00650       cached_min_ = MinImpl();
    00651       min_cache_tag_ = GetTag();
    00652     }
    00653     return cached_min_;
    00654   }
    00655
    00656   inline
    00657   void Vector::AddOneVector(Number a, const Vector& v1, Number c)
    00658   {
    00659     AddTwoVectorsImpl(a, v1, 0., v1, c);
    00660   }
    00661
    00662   inline
    00663   void Vector::AddTwoVectors(Number a, const Vector& v1,
    00664                              Number b, const Vector& v2, Number c)
    00665   {
    00666     AddTwoVectorsImpl(a, v1, b, v2, c);
    00667     ObjectChanged();
    00668   }
    00669
    00670   inline
    00671   Number Vector::FracToBound(const Vector& delta, Number tau) const
    00672   {
    00673     /* AW: I avoid the caching here, since it leads to overhead in the
    00674        quality function search.  Caches for this are in
    00675        CalculatedQuantities.
    00676     Number retValue;
    00677     std::vector<const TaggedObject*> tdeps(1);
    00678     tdeps[0] = &delta;
    00679     std::vector<Number> sdeps(1);
    00680     sdeps[0] = tau;
    00681     if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) {
    00682       retValue = FracToBoundImpl(delta, tau);
    00683       frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps);
    00684     }
    00685     return retValue;
    00686     */
    00687     return FracToBoundImpl(delta, tau);
    00688   }
    00689
    00690   inline
    00691   void Vector::AddVectorQuotient(Number a, const Vector& z,
    00692                                  const Vector& s, Number c)
    00693   {
    00694     AddVectorQuotientImpl(a, z, s, c);
    00695     ObjectChanged();
    00696   }
    00697
    00698   inline
    00699   bool Vector::HasValidNumbers() const
    00700   {
    00701     if (valid_cache_tag_ != GetTag()) {
    00702       cached_valid_ = HasValidNumbersImpl();
    00703       valid_cache_tag_ = GetTag();
    00704     }
    00705     return cached_valid_;
    00706   }
    00707
    00708   inline
    00709   Index Vector::Dim() const
    00710   {
    00711     return owner_space_->Dim();
    00712   }
    00713
    00714   inline
    00715   SmartPtr<const VectorSpace> Vector::OwnerSpace() const
    00716   {
    00717     return owner_space_;
    00718   }
    00719
    00720   inline
    00721   VectorSpace::VectorSpace(Index dim)
    00722       :
    00723       dim_(dim)
    00724   {}
    00725
    00726 } // namespace Ipopt
    00727
    00728 // Macro definitions for debugging vectors
    00729 #if COIN_IPOPT_VERBOSITY == 0
    00730 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec)
    00731 #else
    00732 # define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \
    00733    if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \
    00734       if (dbg_jrnl.Jnlst()!=NULL) { \
    00735         (__vec).Print(dbg_jrnl.Jnlst(), \
    00736         J_ERROR, J_DBG, \
    00737         __vec_name, \
    00738         dbg_jrnl.IndentationLevel()*2, \
    00739         "# "); \
    00740       } \
    00741    }
    00742 #endif //if COIN_IPOPT_VERBOSITY == 0
    00743
    00744 #endif