#include #include #include #include SCTL_INCLUDE(mem_mgr.hpp) #include SCTL_INCLUDE(profile.hpp) namespace SCTL_NAMESPACE { template void Vector::Init(Long dim_, Iterator data_, bool own_data_) { dim = dim_; capacity = dim; own_data = own_data_; if (own_data) { if (dim > 0) { data_ptr = aligned_new(capacity); if (data_ != NullIterator()) { memcopy(data_ptr, data_, dim); } } else data_ptr = NullIterator(); } else data_ptr = data_; } template Vector::Vector() { Init(0); } template Vector::Vector(Long dim_, Iterator data_, bool own_data_) { Init(dim_, data_, own_data_); } template Vector::Vector(const Vector& V) { Init(V.Dim(), (Iterator)V.begin()); } template Vector::Vector(const std::vector& V) { Init(V.size(), Ptr2Itr((ValueType*)(V.size()?&V[0]:nullptr), V.size())); } template Vector::Vector(std::initializer_list V) { Init(V.size(), Ptr2Itr((ValueType*)(V.size()?&(V.begin()[0]):nullptr), V.size())); } template Vector::~Vector() { if (own_data) { if (data_ptr != NullIterator()) { aligned_delete(data_ptr); } } data_ptr = NullIterator(); capacity = 0; dim = 0; } template void Vector::Swap(Vector& v1) { Long dim_ = dim; Long capacity_ = capacity; Iterator data_ptr_ = data_ptr; bool own_data_ = own_data; dim = v1.dim; capacity = v1.capacity; data_ptr = v1.data_ptr; own_data = v1.own_data; v1.dim = dim_; v1.capacity = capacity_; v1.data_ptr = data_ptr_; v1.own_data = own_data_; } template void Vector::ReInit(Long dim_, Iterator data_, bool own_data_) { #ifdef SCTL_MEMDEBUG Vector tmp(dim_, data_, own_data_); this->Swap(tmp); #else if (own_data_ && own_data && dim_ <= capacity) { dim = dim_; if (dim && (data_ptr != NullIterator()) && (data_ != NullIterator())) { memcopy(data_ptr, data_, dim); } } else { Vector tmp(dim_, data_, own_data_); this->Swap(tmp); } #endif } template void Vector::Write(const char* fname) const { FILE* f1 = fopen(fname, "wb+"); if (f1 == nullptr) { std::cout << "Unable to open file for writing:" << fname << '\n'; return; } StaticArray dim_; dim_[0] = (uint64_t)Dim(); dim_[1] = 1; fwrite(&dim_[0], sizeof(uint64_t), 2, f1); if (dim_[0] && dim_[1]) fwrite(&data_ptr[0], sizeof(ValueType), dim_[0] * dim_[1], f1); fclose(f1); } template void Vector::Read(const char* fname) { FILE* f1 = fopen(fname, "r"); if (f1 == nullptr) { std::cout << "Unable to open file for reading:" << fname << '\n'; return; } StaticArray dim_; Long readlen = fread(&dim_[0], sizeof(uint64_t), 2, f1); assert(readlen == 2); SCTL_UNUSED(readlen); if (Dim() != (Long)(dim_[0] * dim_[1])) ReInit(dim_[0] * dim_[1]); if (dim_[0] && dim_[1]) readlen = fread(&data_ptr[0], sizeof(ValueType), dim_[0] * dim_[1], f1); assert(readlen == (Long)(dim_[0] * dim_[1])); fclose(f1); } template inline Long Vector::Dim() const { return dim; } //template inline Long Vector::Capacity() const { return capacity; } template void Vector::SetZero() { if (dim > 0) memset(data_ptr, 0, dim); } template Iterator Vector::begin() { return data_ptr; } template ConstIterator Vector::begin() const { return data_ptr; } template Iterator Vector::end() { return data_ptr + dim; } template ConstIterator Vector::end() const { return data_ptr + dim; } template void Vector::PushBack(const ValueType& x) { if (capacity > dim) { data_ptr[dim] = x; dim++; } else { Vector v((Long)(capacity * 1.6) + 1); memcopy(v.data_ptr, data_ptr, dim); v.dim = dim; Swap(v); assert(capacity > dim); data_ptr[dim] = x; dim++; } } // Element access template inline ValueType& Vector::operator[](Long j) { assert(j >= 0 && j < dim); return data_ptr[j]; } template inline const ValueType& Vector::operator[](Long j) const { assert(j >= 0 && j < dim); return data_ptr[j]; } // Vector-Vector operations template Vector& Vector::operator=(const std::vector& V) { if (dim != (Long)V.size()) ReInit(V.size()); memcopy(data_ptr, Ptr2ConstItr(&V[0], V.size()), dim); return *this; } template Vector& Vector::operator=(const Vector& V) { if (this != &V) { if (dim != V.dim) ReInit(V.dim); memcopy(data_ptr, V.data_ptr, dim); } return *this; } template Vector& Vector::operator+=(const Vector& V) { SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) data_ptr[i] += V[i]; Profile::Add_FLOP(dim); return *this; } template Vector& Vector::operator-=(const Vector& V) { SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) data_ptr[i] -= V[i]; Profile::Add_FLOP(dim); return *this; } template Vector& Vector::operator*=(const Vector& V) { SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) data_ptr[i] *= V[i]; Profile::Add_FLOP(dim); return *this; } template Vector& Vector::operator/=(const Vector& V) { SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) data_ptr[i] /= V[i]; Profile::Add_FLOP(dim); return *this; } template Vector Vector::operator+(const Vector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] + V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector Vector::operator-(const Vector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] - V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector Vector::operator*(const Vector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] * V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector Vector::operator/(const Vector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] / V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector Vector::operator-() const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = -data_ptr[i]; return Vr; } // Vector-Scalar operations template template Vector& Vector::operator=(VType s) { for (Long i = 0; i < dim; i++) data_ptr[i] = s; return *this; } template template Vector& Vector::operator+=(VType s) { for (Long i = 0; i < dim; i++) data_ptr[i] += s; Profile::Add_FLOP(dim); return *this; } template template Vector& Vector::operator-=(VType s) { for (Long i = 0; i < dim; i++) data_ptr[i] -= s; Profile::Add_FLOP(dim); return *this; } template template Vector& Vector::operator*=(VType s) { for (Long i = 0; i < dim; i++) data_ptr[i] *= s; Profile::Add_FLOP(dim); return *this; } template template Vector& Vector::operator/=(VType s) { for (Long i = 0; i < dim; i++) data_ptr[i] /= s; Profile::Add_FLOP(dim); return *this; } template template Vector Vector::operator+(VType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] + s; Profile::Add_FLOP(dim); return Vr; } template template Vector Vector::operator-(VType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] - s; Profile::Add_FLOP(dim); return Vr; } template template Vector Vector::operator*(VType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] * s; Profile::Add_FLOP(dim); return Vr; } template template Vector Vector::operator/(VType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = data_ptr[i] / s; Profile::Add_FLOP(dim); return Vr; } template Vector operator+(VType s, const Vector& V) { Long dim = V.Dim(); Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = s + V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector operator-(VType s, const Vector& V) { Long dim = V.Dim(); Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = s - V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector operator*(VType s, const Vector& V) { Long dim = V.Dim(); Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = s * V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector operator/(VType s, const Vector& V) { Long dim = V.Dim(); Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr[i] = s / V[i]; Profile::Add_FLOP(dim); return Vr; } template std::ostream& operator<<(std::ostream& output, const Vector& V) { std::ios::fmtflags f(std::cout.flags()); output << std::fixed << std::setprecision(4) << std::setiosflags(std::ios::left); for (Long i = 0; i < V.Dim(); i++) output << std::setw(10) << V[i] << ' '; output << ";\n"; std::cout.flags(f); return output; } } // end namespace