00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00038 #ifndef LA_MATRIX_H
00039 #define LA_MATRIX_H
00040
00041 #include "fastlib/base/base.h"
00042 #ifndef DISABLE_DISK_MATRIX
00043 #include "fastlib/mmanager/memory_manager.h"
00044 #endif
00045
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <math.h>
00049
00073 template<typename T>
00074 class GenVector {
00075 private:
00077 T *ptr_;
00079 index_t length_;
00081 bool should_free_;
00082
00083 OBJECT_TRAVERSAL_ONLY(GenVector) {
00084 OT_OBJ(length_);
00085 OT_ALLOC(ptr_, length_);
00086 }
00087 OT_REFILL_TRANSIENTS(GenVector) {
00088 should_free_ = true;
00089 }
00090
00091 public:
00095 GenVector() {
00096 DEBUG_ONLY(Uninitialize_());
00097 }
00098
00102 GenVector(const GenVector& other) {
00103 DEBUG_ONLY(Uninitialize_());
00104 Copy(other);
00105 }
00106 ASSIGN_VIA_COPY_CONSTRUCTION(GenVector);
00107
00111 ~GenVector() {
00112 Destruct();
00113 }
00114
00118 void Destruct() {
00119 DEBUG_ASSERT_MSG(ptr_ != BIG_BAD_POINTER(T),
00120 "You forgot to initialize a Vector before it got automatically freed.");
00121
00122
00123 if (unlikely(should_free_)) {
00124 mem::DebugPoison(ptr_, length_);
00125 mem::Free(ptr_);
00126 }
00127
00128 DEBUG_ONLY(Uninitialize_());
00129 }
00130
00135 void Init(index_t in_length) {
00136 ptr_ = mem::Alloc<T>(in_length);
00137 length_ = in_length;
00138 should_free_ = true;
00139 }
00140
00145 void StaticInit(index_t in_length) {
00146 #ifndef DISABLE_DISK_MATRIX
00147 ptr_ = mmapmm::MemoryManager<false>::allocator_->Alloc<T>(in_length);
00148 length_ = in_length;
00149 should_free_ = false;
00150 #else
00151 Init(in_length);
00152 #endif
00153 }
00154
00158 void SetAll(T d) {
00159 mem::RepeatConstruct(ptr_, d, length_);
00160 }
00161
00165 void SetZero() {
00166
00167 SetAll(0);
00168 }
00169
00175 void Copy(const GenVector& other) {
00176 Copy(other.ptr(), other.length());
00177 }
00178
00185 void Copy(const T *doubles, index_t in_length) {
00186 DEBUG_ONLY(AssertUninitialized_());
00187
00188 ptr_ = mem::AllocCopy(doubles, in_length);
00189 length_ = in_length;
00190 should_free_ = true;
00191 }
00192
00199 void StaticCopy(const GenVector& other) {
00200 StaticCopy(other.ptr(), other.length());
00201 }
00202
00210 void StaticCopy(const T *doubles, index_t in_length) {
00211 #ifndef DISABLE_DISK_MATRIX
00212 DEBUG_ONLY(AssertUninitialized_());
00213
00214 ptr_ = mmapmm::MemoryManager<false>::allocator_->Alloc<T>(in_length);
00215 mem::Copy<T, T, T>(ptr_, doubles, in_length);
00216 length_ = in_length;
00217 should_free_ = false;
00218 #else
00219 Copy(doubles, in_length);
00220 #endif
00221 }
00222
00226 void Alias(T *in_ptr, index_t in_length) {
00227 DEBUG_ONLY(AssertUninitialized_());
00228
00229 ptr_ = in_ptr;
00230 length_ = in_length;
00231 should_free_ = false;
00232 }
00233
00237 void WeakCopy(const GenVector& other) {
00238 Alias(other);
00239 }
00240
00246 void Alias(const GenVector& other) {
00247
00248 Alias(other.ptr_, other.length());
00249 }
00250
00259 void Own(GenVector* other) {
00260 Own(other->ptr_, other->length());
00261
00262 DEBUG_ASSERT(other->should_free_);
00263 other->should_free_ = false;
00264 }
00265
00270 void Own(T *in_ptr, index_t in_length) {
00271 DEBUG_ONLY(AssertUninitialized_());
00272
00273 ptr_ = in_ptr;
00274 length_ = in_length;
00275 should_free_ = true;
00276 }
00277
00286 void StaticOwn(GenVector* other) {
00287 #ifndef DISABLE_DISK_MATRIX
00288 StaticOwn(other->ptr_, other->length());
00289 #else
00290 Own(other);
00291 #endif
00292 }
00293
00298 void StaticOwn(T *in_ptr, index_t in_length) {
00299 #ifndef DISABLE_DISK_MATRIX
00300 DEBUG_ONLY(AssertUninitialized_());
00301
00302 ptr_ = in_ptr;
00303 length_ = in_length;
00304 should_free_ = false;
00305 #else
00306 Own(in_ptr, in_length);
00307 #endif
00308 }
00309
00318 void MakeSubvector(index_t start_index, index_t len, GenVector* dest) {
00319 DEBUG_BOUNDS(start_index, length_);
00320 DEBUG_BOUNDS(start_index + len, length_ + 1);
00321
00322 dest->Alias(ptr_ + start_index, len);
00323 }
00324
00333 void SwapValues(GenVector* other) {
00334 DEBUG_ASSERT(length() == other->length());
00335 mem::Swap(ptr_, other->ptr_, length_);
00336 }
00337
00343 void CopyValues(const GenVector& other) {
00344 DEBUG_ASSERT(length() == other.length());
00345 mem::Copy(ptr_, other.ptr_, length_);
00346 }
00347
00354 void CopyValues(const T *src_ptr) {
00355 mem::Copy(ptr_, src_ptr, length_);
00356 }
00357
00364 void PrintDebug(const char *name = "", FILE *stream = stderr) const {
00365 fprintf(stream, "----- VECTOR %s ------\n", name);
00366 for (index_t i = 0; i < length(); i++) {
00367 fprintf(stream, "%+3.3f ", get(i));
00368 }
00369 fprintf(stream, "\n");
00370 }
00371
00372 public:
00374 index_t length() const {
00375 return length_;
00376 }
00377
00381 T *ptr() {
00382 return ptr_;
00383 }
00384
00388 const T *ptr() const {
00389 return ptr_;
00390 }
00391
00395 T operator [] (index_t i) const {
00396 DEBUG_BOUNDS(i, length_);
00397 return ptr_[i];
00398 }
00399
00403 T &operator [] (index_t i) {
00404 DEBUG_BOUNDS(i, length_);
00405 return ptr_[i];
00406 }
00407
00421 T get(index_t i) const {
00422 DEBUG_BOUNDS(i, length_);
00423 return ptr_[i];
00424 }
00425
00426 private:
00427 void AssertUninitialized_() const {
00428 DEBUG_ASSERT_MSG(length_ == BIG_BAD_NUMBER, "Cannot re-init vectors.");
00429 }
00430
00431 void Uninitialize_() {
00432 DEBUG_ONLY(ptr_ = BIG_BAD_POINTER(T));
00433 DEBUG_ONLY(length_ = BIG_BAD_NUMBER);
00434 }
00435
00436 void AssertInitialized_() {
00437 DEBUG_ASSERT_MSG(ptr_ != BIG_BAD_POINTER(T),
00438 "Vector was not initialized.");
00439 }
00440 };
00441
00444 typedef GenVector<double> Vector;
00445
00456 template<typename T>
00457 class GenMatrix {
00458 private:
00460 T *ptr_;
00462 index_t n_rows_;
00464 index_t n_cols_;
00466 bool should_free_;
00467
00468 OBJECT_TRAVERSAL_ONLY(GenMatrix) {
00469 OT_OBJ(n_rows_);
00470 OT_OBJ(n_cols_);
00471 OT_ALLOC(ptr_, n_elements());
00472 }
00473 OT_REFILL_TRANSIENTS(GenMatrix) {
00474 should_free_ = false;
00475 }
00476
00477 public:
00481 GenMatrix(index_t in_rows, index_t in_cols) {
00482 DEBUG_ONLY(Uninitialize_());
00483 Init(in_rows, in_cols);
00484 }
00485
00489 GenMatrix(const GenMatrix<T>& other) {
00490 DEBUG_ONLY(Uninitialize_());
00491 Copy(other);
00492 }
00493 ASSIGN_VIA_COPY_CONSTRUCTION(GenMatrix);
00494
00498 GenMatrix() {
00499 DEBUG_ONLY(Uninitialize_());
00500 }
00501
00505 ~GenMatrix() {
00506 Destruct();
00507 }
00508
00513 void Destruct() {
00514 DEBUG_ASSERT_MSG(ptr_ != BIG_BAD_POINTER(T),
00515 "You forgot to initialize a Matrix before it got automatically freed.");
00516 if (unlikely(should_free_)) {
00517 mem::DebugPoison(ptr_, n_rows_ * n_cols_);
00518 mem::Free(ptr_);
00519 DEBUG_ONLY(Uninitialize_());
00520 }
00521 DEBUG_POISON_PTR(ptr_);
00522 DEBUG_ONLY(n_rows_ = BIG_BAD_NUMBER);
00523 DEBUG_ONLY(n_cols_ = BIG_BAD_NUMBER);
00524 }
00525
00529 void Init(index_t in_rows, index_t in_cols) {
00530 DEBUG_ONLY(AssertUninitialized_());
00531 ptr_ = mem::Alloc<T>(in_rows * in_cols);
00532 n_rows_ = in_rows;
00533 n_cols_ = in_cols;
00534 should_free_ = true;
00535 }
00536
00540 void InitDiagonal(const GenVector<T>& v) {
00541 Init(v.length(), v.length());
00542 SetDiagonal(v);
00543 }
00544
00549 void StaticInit(index_t in_rows, index_t in_cols) {
00550 #ifndef DISABLE_DISK_MATRIX
00551 DEBUG_ONLY(AssertUninitialized_());
00552 ptr_ = mmapmm::MemoryManager<false>::allocator_->Alloc<T>
00553 (in_rows * in_cols);
00554 n_rows_ = in_rows;
00555 n_cols_ = in_cols;
00556 should_free_ = false;
00557 #else
00558 Init(in_rows, in_cols);
00559 #endif
00560 }
00561
00565 void StaticInitDiagonal(const GenVector<T>& v) {
00566 StaticInit(v.length(), v.length());
00567 SetDiagonal(v);
00568 }
00569
00573 void SetAll(T d) {
00574 mem::RepeatConstruct(ptr_, d, n_elements());
00575 }
00576
00580 void SetZero() {
00581
00582
00583 SetAll(0);
00584 }
00585
00589 void SetDiagonal(const GenVector<T>& v) {
00590 DEBUG_ASSERT(n_rows() == v.length());
00591 DEBUG_ASSERT(n_cols() == v.length());
00592 SetZero();
00593 index_t n = v.length();
00594 for (index_t i = 0; i < n; i++) {
00595 set(i, i, v[i]);
00596 }
00597 }
00598
00604 void Copy(const GenMatrix& other) {
00605 Copy(other.ptr(), other.n_rows(), other.n_cols());
00606 }
00607
00615 void Copy(const T *ptr_in, index_t n_rows_in, index_t n_cols_in) {
00616 DEBUG_ONLY(AssertUninitialized_());
00617
00618 ptr_ = mem::AllocCopy(ptr_in, n_rows_in * n_cols_in);
00619 n_rows_ = n_rows_in;
00620 n_cols_ = n_cols_in;
00621 should_free_ = true;
00622 }
00623
00630 void StaticCopy(const GenMatrix& other) {
00631 StaticCopy(other.ptr(), other.n_rows(), other.n_cols());
00632 }
00633
00642 void StaticCopy(const T *ptr_in, index_t n_rows_in, index_t n_cols_in) {
00643 #ifndef DISABLE_DISK_MATRIX
00644 DEBUG_ONLY(AssertUninitialized_());
00645
00646 ptr_ = mmapmm::MemoryManager<false>::allocator_->Alloc<T>
00647 (n_rows_in * n_cols_in);
00648 mem::Copy<T, T, T>(ptr_, ptr_in, n_rows_in * n_cols_in);
00649
00650 n_rows_ = n_rows_in;
00651 n_cols_ = n_cols_in;
00652 should_free_ = false;
00653 #else
00654 Copy(ptr_in, n_rows_in, n_cols_in);
00655 #endif
00656 }
00657
00665 void Alias(const GenMatrix& other) {
00666
00667 Alias(other.ptr_, other.n_rows(), other.n_cols());
00668 }
00669
00677 void Alias(T *ptr_in, index_t n_rows_in, index_t n_cols_in) {
00678 DEBUG_ONLY(AssertUninitialized_());
00679
00680 ptr_ = ptr_in;
00681 n_rows_ = n_rows_in;
00682 n_cols_ = n_cols_in;
00683 should_free_ = false;
00684 }
00685
00691 void AliasRowVector(const GenVector<T>& row_vector) {
00692 Alias(const_cast<T*>(row_vector.ptr()), 1, row_vector.length());
00693 }
00694
00700 void AliasColVector(const GenVector<T>& col_vector) {
00701 Alias(const_cast<T*>(col_vector.ptr()), col_vector.length(), 1);
00702 }
00703
00709 void WeakCopy(const GenMatrix& other) {
00710 Alias(other);
00711 }
00712
00722 void Own(GenMatrix* other) {
00723 Own(other->ptr(), other->n_rows(), other->n_cols());
00724
00725 DEBUG_ASSERT(other->should_free_);
00726 other->should_free_ = false;
00727 }
00728
00738 void Own(T *ptr_in, index_t n_rows_in, index_t n_cols_in) {
00739 DEBUG_ONLY(AssertUninitialized_());
00740
00741 ptr_ = ptr_in;
00742 n_rows_ = n_rows_in;
00743 n_cols_ = n_cols_in;
00744 should_free_ = true;
00745 }
00746
00756 void StaticOwn(GenMatrix* other) {
00757 #ifndef DISABLE_DISK_MATRIX
00758 StaticOwn(other->ptr(), other->n_rows(), other->n_cols());
00759 #else
00760 Own(other);
00761 #endif
00762 }
00763
00773 void StaticOwn(T *ptr_in, index_t n_rows_in, index_t n_cols_in) {
00774 #ifndef DISABLE_DISK_MATRIX
00775 DEBUG_ONLY(AssertUninitialized_());
00776
00777 ptr_ = ptr_in;
00778 n_rows_ = n_rows_in;
00779 n_cols_ = n_cols_in;
00780 should_free_ = false;
00781 #else
00782 Own(ptr_in, n_rows_in, n_cols_in);
00783 #endif
00784 }
00785
00793 void MakeColumnSlice(index_t start_col, index_t n_cols_new,
00794 GenMatrix *dest) const {
00795 DEBUG_BOUNDS(start_col, n_cols_);
00796 DEBUG_BOUNDS(start_col + n_cols_new, n_cols_ + 1);
00797 dest->Alias(ptr_ + start_col * n_rows_,
00798 n_rows_, n_cols_new);
00799 }
00800
00821 void MakeReshaped(index_t n_rows_in, index_t n_cols_in,
00822 GenMatrix *dest) const {
00823 DEBUG_ASSERT(n_rows_in * n_cols_in == n_rows() * n_cols());
00824 dest->Alias(ptr_, n_rows_in, n_cols_in);
00825 }
00826
00834 void MakeColumnVector(index_t col, GenVector<T> *dest) const {
00835 DEBUG_BOUNDS(col, n_cols_);
00836 dest->Alias(n_rows_ * col + ptr_, n_rows_);
00837 }
00838
00848 void MakeColumnSubvector(index_t col, index_t start_row, index_t n_rows_new,
00849 GenVector<T> *dest) const {
00850 DEBUG_BOUNDS(col, n_cols_);
00851 DEBUG_BOUNDS(start_row, n_rows_);
00852 DEBUG_BOUNDS(start_row + n_rows_new, n_rows_ + 1);
00853 dest->Alias(n_rows_ * col + start_row + ptr_, n_rows_new);
00854 }
00855
00864 T *GetColumnPtr(index_t col) {
00865 DEBUG_BOUNDS(col, n_cols_);
00866 return n_rows_ * col + ptr_;
00867 }
00868
00877 const T *GetColumnPtr(index_t col) const {
00878 DEBUG_BOUNDS(col, n_cols_);
00879 return n_rows_ * col + ptr_;
00880 }
00881
00889 void CopyColumnFromMat(index_t col1, index_t col2, GenMatrix<T> &mat) {
00890 DEBUG_BOUNDS(col1, n_cols_);
00891 DEBUG_BOUNDS(col2, mat.n_cols());
00892 DEBUG_ASSERT(n_rows_==mat.n_rows());
00893 memcpy(ptr_ + n_rows_ * col1, mat.GetColumnPtr(col2), n_rows_*sizeof(T));
00894 }
00903 void CopyColumnFromMat(index_t col1, index_t col2, index_t ncols, GenMatrix<T> &mat) {
00904 DEBUG_BOUNDS(col1, n_cols_);
00905 DEBUG_BOUNDS(col2, mat.n_cols());
00906 DEBUG_BOUNDS(col1+ncols-1, n_cols_);
00907 DEBUG_BOUNDS(col2+ncols-1, mat.n_cols());
00908 DEBUG_ASSERT(n_rows_==mat.n_rows());
00909 memcpy(ptr_ + n_rows_ * col1, mat.GetColumnPtr(col2), ncols*n_rows_*sizeof(T));
00910 }
00911
00917 void CopyVectorToColumn(index_t col, GenVector<T> &vec) {
00918 DEBUG_BOUNDS(col, n_cols_);
00919 memcpy(ptr_ + n_rows_ * col, vec.ptr(), n_rows_*sizeof(T));
00920 }
00921
00930 void ResizeNoalias(index_t new_n_cols) {
00931 DEBUG_ASSERT(should_free_);
00932 n_cols_ = new_n_cols;
00933 ptr_ = mem::Realloc(ptr_, n_elements());
00934 }
00935
00944 void SwapValues(GenMatrix* other) {
00945 DEBUG_ASSERT(n_cols() == other->n_cols());
00946 DEBUG_ASSERT(n_rows() == other->n_rows());
00947 mem::Swap(ptr_, other->ptr_, n_elements());
00948 }
00949
00955 void CopyValues(const GenMatrix& other) {
00956 DEBUG_ASSERT(n_rows() == other.n_rows());
00957 DEBUG_ASSERT(n_cols() == other.n_cols());
00958 mem::Copy(ptr_, other.ptr_, n_elements());
00959 }
00960
00967 void PrintDebug(const char *name = "", FILE *stream = stderr) const {
00968 fprintf(stream, "----- MATRIX %s ------\n", name);
00969 for (index_t r = 0; r < n_rows(); r++) {
00970 for (index_t c = 0; c < n_cols(); c++) {
00971 fprintf(stream, "%+3.3f ", get(r, c));
00972 }
00973 fprintf(stream, "\n");
00974 }
00975 }
00976
00977 public:
00984 const T *ptr() const {
00985 return ptr_;
00986 }
00987
00994 T *ptr() {
00995 return ptr_;
00996 }
00997
01004 T get(index_t r, index_t c) const {
01005 DEBUG_BOUNDS(r, n_rows_);
01006 DEBUG_BOUNDS(c, n_cols_);
01007 return ptr_[c * n_rows_ + r];
01008 }
01009
01017 void set(index_t r, index_t c, T v) {
01018 DEBUG_BOUNDS(r, n_rows_);
01019 DEBUG_BOUNDS(c, n_cols_);
01020 ptr_[c * n_rows_ + r] = v;
01021 }
01022
01030 T &ref(index_t r, index_t c) {
01031 DEBUG_BOUNDS(r, n_rows_);
01032 DEBUG_BOUNDS(c, n_cols_);
01033 return ptr_[c * n_rows_ + r];
01034 }
01035
01037 index_t n_cols() const {
01038 return n_cols_;
01039 }
01040
01042 index_t n_rows() const {
01043 return n_rows_;
01044 }
01045
01052 size_t n_elements() const {
01053
01054
01055
01056 return size_t(n_rows_) * size_t(n_cols_);
01057 }
01058
01059 private:
01060 void AssertUninitialized_() const {
01061 DEBUG_ASSERT_MSG(n_rows_ == BIG_BAD_NUMBER, "Cannot re-init matrices.");
01062 }
01063
01064 void Uninitialize_() {
01065 DEBUG_POISON_PTR(ptr_);
01066 DEBUG_ONLY(n_rows_ = BIG_BAD_NUMBER);
01067 DEBUG_ONLY(n_cols_ = BIG_BAD_NUMBER);
01068 }
01069
01070 };
01071
01075 template<int t_length>
01076 class SmallVector : public Vector {
01077 private:
01078 double array_[t_length];
01079
01080 public:
01081 SmallVector() {
01082 Alias(array_, t_length);
01083 }
01084 ~SmallVector() {}
01085
01086 public:
01087 index_t length() const {
01088 return t_length;
01089 }
01090
01091 double *ptr() {
01092 return array_;
01093 }
01094
01095 const double *ptr() const {
01096 return array_;
01097 }
01098
01099 double operator [] (index_t i) const {
01100 DEBUG_BOUNDS(i, t_length);
01101 return array_[i];
01102 }
01103
01104 double &operator [] (index_t i) {
01105 DEBUG_BOUNDS(i, t_length);
01106 return array_[i];
01107 }
01108
01109 double get(index_t i) const {
01110 DEBUG_BOUNDS(i, t_length);
01111 return array_[i];
01112 }
01113 };
01114
01117 typedef GenMatrix<double> Matrix;
01118
01122 template<int t_rows, int t_cols>
01123 class SmallMatrix : public Matrix {
01124 private:
01125 double array_[t_cols][t_rows];
01126
01127 public:
01128 SmallMatrix() {
01129 Alias(array_[0], t_rows, t_cols);
01130 }
01131 ~SmallMatrix() {}
01132
01133 public:
01134 const double *ptr() const {
01135 return array_[0];
01136 }
01137
01138 double *ptr() {
01139 return array_[0];
01140 }
01141
01142 double get(index_t r, index_t c) const {
01143 DEBUG_BOUNDS(r, t_rows);
01144 DEBUG_BOUNDS(c, t_cols);
01145 return array_[c][r];
01146 }
01147
01148 void set(index_t r, index_t c, double v) {
01149 DEBUG_BOUNDS(r, t_rows);
01150 DEBUG_BOUNDS(c, t_cols);
01151 array_[c][r] = v;
01152 }
01153
01154 double &ref(index_t r, index_t c) {
01155 DEBUG_BOUNDS(r, t_rows);
01156 DEBUG_BOUNDS(c, t_cols);
01157 return array_[c][r];
01158 }
01159
01160 index_t n_cols() const {
01161 return t_cols;
01162 }
01163
01164 index_t n_rows() const {
01165 return t_rows;
01166 }
01167
01168 size_t n_elements() const {
01169
01170
01171
01172 return size_t(t_rows) * size_t(t_cols);
01173 }
01174
01175 double *GetColumnPtr(index_t col) {
01176 DEBUG_BOUNDS(col, t_cols);
01177 return array_[col];
01178 }
01179
01180 const double *GetColumnPtr(index_t col) const {
01181 DEBUG_BOUNDS(col, t_cols);
01182 return array_[col];
01183 }
01184 };
01185
01186 #endif