vector.txx 11 KB

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