00001
00002
00003
00004
00005
00006
00007
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
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
00375
00376
00377
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
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
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
00476
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
00519
00520
00521
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
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
00624 ElementWiseMaxImpl(x);
00625 ObjectChanged();
00626 }
00627
00628 inline
00629 void Vector::ElementWiseMin(const Vector& x)
00630 {
00631
00632 ElementWiseMinImpl(x);
00633 ObjectChanged();
00634 }
00635
00636 inline
00637 void Vector::ElementWiseAbs()
00638 {
00639
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
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
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
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 }
00750
00751
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