vector.txx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include <cassert>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include SCTL_INCLUDE(mem_mgr.hpp)
  5. #include SCTL_INCLUDE(profile.hpp)
  6. namespace SCTL_NAMESPACE {
  7. template <class ValueType> void ConstVector<ValueType>::Init(Long dim_, Iterator<ValueType> data_, bool own_data_) {
  8. dim = dim_;
  9. capacity = dim;
  10. own_data = own_data_;
  11. if (own_data) {
  12. if (dim > 0) {
  13. data_ptr = aligned_new<ValueType>(capacity);
  14. if (data_ != NullIterator<ValueType>()) {
  15. memcopy(data_ptr, data_, dim);
  16. }
  17. } else
  18. data_ptr = NullIterator<ValueType>();
  19. } else
  20. data_ptr = data_;
  21. }
  22. template <class ValueType> ConstVector<ValueType>::ConstVector() {
  23. Init(0);
  24. }
  25. template <class ValueType> Vector<ValueType>::Vector() : ConstVector<ValueType>() {}
  26. template <class ValueType> Vector<ValueType>::Vector(Long dim_, Iterator<ValueType> data_, bool own_data_) {
  27. this->Init(dim_, data_, own_data_);
  28. }
  29. template <class ValueType> Vector<ValueType>::Vector(const Vector<ValueType>& V) {
  30. this->Init(V.Dim(), (Iterator<ValueType>)V.begin());
  31. }
  32. template <class ValueType> Vector<ValueType>::Vector(const std::vector<ValueType>& V) {
  33. Init(V.size(), Ptr2Itr<ValueType>((ValueType*)(V.size()?&V[0]:nullptr), V.size()));
  34. }
  35. template <class ValueType> ConstVector<ValueType>::~ConstVector() {
  36. if (own_data) {
  37. if (data_ptr != NullIterator<ValueType>()) {
  38. aligned_delete(data_ptr);
  39. }
  40. }
  41. data_ptr = NullIterator<ValueType>();
  42. capacity = 0;
  43. dim = 0;
  44. }
  45. template <class ValueType> void ConstVector<ValueType>::Swap(ConstVector<ValueType>& v1) {
  46. Long dim_ = dim;
  47. Long capacity_ = capacity;
  48. Iterator<ValueType> data_ptr_ = data_ptr;
  49. bool own_data_ = own_data;
  50. dim = v1.dim;
  51. capacity = v1.capacity;
  52. data_ptr = v1.data_ptr;
  53. own_data = v1.own_data;
  54. v1.dim = dim_;
  55. v1.capacity = capacity_;
  56. v1.data_ptr = data_ptr_;
  57. v1.own_data = own_data_;
  58. }
  59. template <class ValueType> void Vector<ValueType>::Swap(Vector<ValueType>& v1) {
  60. ConstVector<ValueType>::Swap(v1);
  61. }
  62. template <class ValueType> void Vector<ValueType>::ReInit(Long dim_, Iterator<ValueType> data_, bool own_data_) {
  63. #ifdef SCTL_MEMDEBUG
  64. Vector<ValueType> tmp(dim_, data_, own_data_);
  65. this->Swap(tmp);
  66. #else
  67. if (own_data_ && this->own_data && dim_ <= this->capacity) {
  68. this->dim = dim_;
  69. if (data_ != NullIterator<ValueType>()) {
  70. memcopy(this->data_ptr, data_, this->dim);
  71. }
  72. } else {
  73. Vector<ValueType> tmp(dim_, data_, own_data_);
  74. this->Swap(tmp);
  75. }
  76. #endif
  77. }
  78. template <class ValueType> void ConstVector<ValueType>::Write(const char* fname) const {
  79. FILE* f1 = fopen(fname, "wb+");
  80. if (f1 == nullptr) {
  81. std::cout << "Unable to open file for writing:" << fname << '\n';
  82. return;
  83. }
  84. StaticArray<uint64_t, 2> dim_;
  85. dim_[0] = (uint64_t)Dim();
  86. dim_[1] = 1;
  87. fwrite(&dim_[0], sizeof(uint64_t), 2, f1);
  88. if (dim_[0] && dim_[1]) fwrite(&data_ptr[0], sizeof(ValueType), dim_[0] * dim_[1], f1);
  89. fclose(f1);
  90. }
  91. template <class ValueType> void Vector<ValueType>::Read(const char* fname) {
  92. FILE* f1 = fopen(fname, "r");
  93. if (f1 == nullptr) {
  94. std::cout << "Unable to open file for reading:" << fname << '\n';
  95. return;
  96. }
  97. StaticArray<uint64_t, 2> dim_;
  98. Long readlen = fread(&dim_[0], sizeof(uint64_t), 2, f1);
  99. assert(readlen == 2);
  100. if (this->Dim() != (Long)(dim_[0] * dim_[1])) ReInit(dim_[0] * dim_[1]);
  101. if (dim_[0] && dim_[1]) readlen = fread(&begin()[0], sizeof(ValueType), dim_[0] * dim_[1], f1);
  102. assert(readlen == (Long)(dim_[0] * dim_[1]));
  103. SCTL_UNUSED(readlen);
  104. fclose(f1);
  105. }
  106. template <class ValueType> inline Long ConstVector<ValueType>::Dim() const { return dim; }
  107. //template <class ValueType> inline Long Vector<ValueType>::Capacity() const { return capacity; }
  108. template <class ValueType> void Vector<ValueType>::SetZero() {
  109. if (this->Dim() > 0) memset<ValueType>(this->data_ptr, 0, this->Dim());
  110. }
  111. template <class ValueType> Iterator<ValueType> Vector<ValueType>::begin() { return this->data_ptr; }
  112. template <class ValueType> ConstIterator<ValueType> ConstVector<ValueType>::begin() const { return this->data_ptr; }
  113. template <class ValueType> Iterator<ValueType> Vector<ValueType>::end() { return this->data_ptr + this->dim; }
  114. template <class ValueType> ConstIterator<ValueType> ConstVector<ValueType>::end() const { return this->data_ptr + this->dim; }
  115. template <class ValueType> void Vector<ValueType>::PushBack(const ValueType& x) {
  116. if (this->capacity > this->Dim()) {
  117. this->data_ptr[this->Dim()] = x;
  118. this->dim++;
  119. } else {
  120. Vector<ValueType> v((Long)(this->capacity * 1.6) + 1); // TODO: This also calls the constructor. Instead allocate but use the in-place constructor.
  121. memcopy(v.data_ptr, this->begin(), this->Dim());
  122. v.dim = this->Dim();
  123. Swap(v);
  124. assert(this->capacity > this->Dim());
  125. this->data_ptr[this->Dim()] = x;
  126. this->dim++;
  127. }
  128. }
  129. // Element access
  130. template <class ValueType> inline ValueType& Vector<ValueType>::operator[](Long j) {
  131. assert(j >= 0 && j < this->Dim());
  132. return this->data_ptr[j];
  133. }
  134. template <class ValueType> inline const ValueType& ConstVector<ValueType>::operator[](Long j) const {
  135. assert(j >= 0 && j < dim);
  136. return data_ptr[j];
  137. }
  138. // Vector-Vector operations
  139. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator=(const std::vector<ValueType>& V) {
  140. if (this->dim != V.size()) ReInit(V.size());
  141. memcopy(this->data_ptr, Ptr2ConstItr<ValueType>(&V[0], V.size()), this->dim);
  142. return *this;
  143. }
  144. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator=(const Vector<ValueType>& V) {
  145. if (this != &V) {
  146. if (this->dim != V.dim) ReInit(V.dim);
  147. memcopy(this->data_ptr, V.data_ptr, this->dim);
  148. }
  149. return *this;
  150. }
  151. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator+=(const Vector<ValueType>& V) {
  152. SCTL_ASSERT(V.Dim() == this->dim);
  153. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] += V[i];
  154. Profile::Add_FLOP(this->dim);
  155. return *this;
  156. }
  157. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator-=(const Vector<ValueType>& V) {
  158. SCTL_ASSERT(V.Dim() == this->dim);
  159. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] -= V[i];
  160. Profile::Add_FLOP(this->dim);
  161. return *this;
  162. }
  163. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator*=(const Vector<ValueType>& V) {
  164. SCTL_ASSERT(V.Dim() == this->dim);
  165. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] *= V[i];
  166. Profile::Add_FLOP(this->dim);
  167. return *this;
  168. }
  169. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator/=(const Vector<ValueType>& V) {
  170. SCTL_ASSERT(V.Dim() == this->dim);
  171. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] /= V[i];
  172. Profile::Add_FLOP(this->dim);
  173. return *this;
  174. }
  175. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator+(const ConstVector<ValueType>& V) const {
  176. Vector<ValueType> Vr(dim);
  177. SCTL_ASSERT(V.Dim() == dim);
  178. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] + V[i];
  179. Profile::Add_FLOP(dim);
  180. return Vr;
  181. }
  182. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator-(const ConstVector<ValueType>& V) const {
  183. Vector<ValueType> Vr(dim);
  184. SCTL_ASSERT(V.Dim() == dim);
  185. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] - V[i];
  186. Profile::Add_FLOP(dim);
  187. return Vr;
  188. }
  189. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator*(const ConstVector<ValueType>& V) const {
  190. Vector<ValueType> Vr(dim);
  191. SCTL_ASSERT(V.Dim() == dim);
  192. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] * V[i];
  193. Profile::Add_FLOP(dim);
  194. return Vr;
  195. }
  196. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator/(const ConstVector<ValueType>& V) const {
  197. Vector<ValueType> Vr(dim);
  198. SCTL_ASSERT(V.Dim() == dim);
  199. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] / V[i];
  200. Profile::Add_FLOP(dim);
  201. return Vr;
  202. }
  203. // Vector-Scalar operations
  204. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator=(ValueType s) {
  205. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] = s;
  206. return *this;
  207. }
  208. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator+=(ValueType s) {
  209. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] += s;
  210. Profile::Add_FLOP(this->dim);
  211. return *this;
  212. }
  213. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator-=(ValueType s) {
  214. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] -= s;
  215. Profile::Add_FLOP(this->dim);
  216. return *this;
  217. }
  218. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator*=(ValueType s) {
  219. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] *= s;
  220. Profile::Add_FLOP(this->dim);
  221. return *this;
  222. }
  223. template <class ValueType> Vector<ValueType>& Vector<ValueType>::operator/=(ValueType s) {
  224. for (Long i = 0; i < this->dim; i++) this->data_ptr[i] /= s;
  225. Profile::Add_FLOP(this->dim);
  226. return *this;
  227. }
  228. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator+(ValueType s) const {
  229. Vector<ValueType> Vr(dim);
  230. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] + s;
  231. Profile::Add_FLOP(dim);
  232. return Vr;
  233. }
  234. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator-(ValueType s) const {
  235. Vector<ValueType> Vr(dim);
  236. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] - s;
  237. Profile::Add_FLOP(dim);
  238. return Vr;
  239. }
  240. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator*(ValueType s) const {
  241. Vector<ValueType> Vr(dim);
  242. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] * s;
  243. Profile::Add_FLOP(dim);
  244. return Vr;
  245. }
  246. template <class ValueType> Vector<ValueType> ConstVector<ValueType>::operator/(ValueType s) const {
  247. Vector<ValueType> Vr(dim);
  248. for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] / s;
  249. Profile::Add_FLOP(dim);
  250. return Vr;
  251. }
  252. template <class ValueType> Vector<ValueType> operator+(ValueType s, const Vector<ValueType>& V) {
  253. Long dim = V.Dim();
  254. Vector<ValueType> Vr(dim);
  255. for (Long i = 0; i < dim; i++) Vr[i] = s + V[i];
  256. Profile::Add_FLOP(dim);
  257. return Vr;
  258. }
  259. template <class ValueType> Vector<ValueType> operator-(ValueType s, const Vector<ValueType>& V) {
  260. Long dim = V.Dim();
  261. Vector<ValueType> Vr(dim);
  262. for (Long i = 0; i < dim; i++) Vr[i] = s - V[i];
  263. Profile::Add_FLOP(dim);
  264. return Vr;
  265. }
  266. template <class ValueType> Vector<ValueType> operator*(ValueType s, const Vector<ValueType>& V) {
  267. Long dim = V.Dim();
  268. Vector<ValueType> Vr(dim);
  269. for (Long i = 0; i < dim; i++) Vr[i] = s * V[i];
  270. Profile::Add_FLOP(dim);
  271. return Vr;
  272. }
  273. template <class ValueType> Vector<ValueType> operator/(ValueType s, const Vector<ValueType>& V) {
  274. Long dim = V.Dim();
  275. Vector<ValueType> Vr(dim);
  276. for (Long i = 0; i < dim; i++) Vr[i] = s / V[i];
  277. Profile::Add_FLOP(dim);
  278. return Vr;
  279. }
  280. template <class ValueType> std::ostream& operator<<(std::ostream& output, const ConstVector<ValueType>& V) {
  281. std::ios::fmtflags f(std::cout.flags());
  282. output << std::fixed << std::setprecision(4) << std::setiosflags(std::ios::left);
  283. for (Long i = 0; i < V.Dim(); i++) output << std::setw(10) << V[i] << ' ';
  284. output << ";\n";
  285. std::cout.flags(f);
  286. return output;
  287. }
  288. } // end namespace