vector.txx 10 KB

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