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
00018 #include <vector>
00019
00020 namespace Ipopt
00021 {
00022
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
00340
00341
00342
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
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
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
00448
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
00491
00492
00493
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
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
00596 ElementWiseMaxImpl(x);
00597 ObjectChanged();
00598 }
00599
00600 inline
00601 void Vector::ElementWiseMin(const Vector& x)
00602 {
00603
00604 ElementWiseMinImpl(x);
00605 ObjectChanged();
00606 }
00607
00608 inline
00609 void Vector::ElementWiseAbs()
00610 {
00611
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
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
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
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 }
00722
00723
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