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 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
00345
00346
00347
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
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
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
00453
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
00496
00497
00498
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
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
00601 ElementWiseMaxImpl(x);
00602 ObjectChanged();
00603 }
00604
00605 inline
00606 void Vector::ElementWiseMin(const Vector& x)
00607 {
00608
00609 ElementWiseMinImpl(x);
00610 ObjectChanged();
00611 }
00612
00613 inline
00614 void Vector::ElementWiseAbs()
00615 {
00616
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
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 AddTwoVectors(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
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
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 }
00727
00728
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