vector.txx 10 KB

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