#include #include #include #include SCTL_INCLUDE(mem_mgr.hpp) #include SCTL_INCLUDE(profile.hpp) namespace SCTL_NAMESPACE { template void ConstVector::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 ConstVector::ConstVector() { Init(0); } template Vector::Vector() : ConstVector() {} template Vector::Vector(Long dim_, Iterator data_, bool own_data_) { this->Init(dim_, data_, own_data_); } template Vector::Vector(const Vector& V) { this->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 ConstVector::~ConstVector() { if (own_data) { if (data_ptr != NullIterator()) { aligned_delete(data_ptr); } } data_ptr = NullIterator(); capacity = 0; dim = 0; } template void ConstVector::Swap(ConstVector& 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::Swap(Vector& v1) { ConstVector::Swap(v1); } 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_ && this->own_data && dim_ <= this->capacity) { this->dim = dim_; if (data_ != NullIterator()) { memcopy(this->data_ptr, data_, this->dim); } } else { Vector tmp(dim_, data_, own_data_); this->Swap(tmp); } #endif } template void ConstVector::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); if (this->Dim() != (Long)(dim_[0] * dim_[1])) ReInit(dim_[0] * dim_[1]); if (dim_[0] && dim_[1]) readlen = fread(&begin()[0], sizeof(ValueType), dim_[0] * dim_[1], f1); assert(readlen == (Long)(dim_[0] * dim_[1])); SCTL_UNUSED(readlen); fclose(f1); } template inline Long ConstVector::Dim() const { return dim; } //template inline Long Vector::Capacity() const { return capacity; } template void Vector::SetZero() { if (this->Dim() > 0) memset(this->data_ptr, 0, this->Dim()); } template Iterator Vector::begin() { return this->data_ptr; } template ConstIterator ConstVector::begin() const { return this->data_ptr; } template Iterator Vector::end() { return this->data_ptr + this->dim; } template ConstIterator ConstVector::end() const { return this->data_ptr + this->dim; } template void Vector::PushBack(const ValueType& x) { if (this->capacity > this->Dim()) { this->data_ptr[this->Dim()] = x; this->dim++; } else { Vector v((Long)(this->capacity * 1.6) + 1); // TODO: This also calls the constructor. Instead allocate but use the in-place constructor. memcopy(v.data_ptr, this->begin(), this->Dim()); v.dim = this->Dim(); Swap(v); assert(this->capacity > this->Dim()); this->data_ptr[this->Dim()] = x; this->dim++; } } // Element access template inline ValueType& Vector::operator[](Long j) { assert(j >= 0 && j < this->Dim()); return this->data_ptr[j]; } template inline const ValueType& ConstVector::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 (this->dim != V.size()) ReInit(V.size()); memcopy(this->data_ptr, Ptr2ConstItr(&V[0], V.size()), this->dim); return *this; } template Vector& Vector::operator=(const Vector& V) { if (this != &V) { if (this->dim != V.dim) ReInit(V.dim); memcopy(this->data_ptr, V.data_ptr, this->dim); } return *this; } template Vector& Vector::operator+=(const Vector& V) { SCTL_ASSERT(V.Dim() == this->dim); for (Long i = 0; i < this->dim; i++) this->data_ptr[i] += V[i]; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator-=(const Vector& V) { SCTL_ASSERT(V.Dim() == this->dim); for (Long i = 0; i < this->dim; i++) this->data_ptr[i] -= V[i]; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator*=(const Vector& V) { SCTL_ASSERT(V.Dim() == this->dim); for (Long i = 0; i < this->dim; i++) this->data_ptr[i] *= V[i]; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator/=(const Vector& V) { SCTL_ASSERT(V.Dim() == this->dim); for (Long i = 0; i < this->dim; i++) this->data_ptr[i] /= V[i]; Profile::Add_FLOP(this->dim); return *this; } template Vector ConstVector::operator+(const ConstVector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] + V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator-(const ConstVector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] - V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator*(const ConstVector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] * V[i]; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator/(const ConstVector& V) const { Vector Vr(dim); SCTL_ASSERT(V.Dim() == dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] / V[i]; Profile::Add_FLOP(dim); return Vr; } // Vector-Scalar operations template Vector& Vector::operator=(ValueType s) { for (Long i = 0; i < this->dim; i++) this->data_ptr[i] = s; return *this; } template Vector& Vector::operator+=(ValueType s) { for (Long i = 0; i < this->dim; i++) this->data_ptr[i] += s; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator-=(ValueType s) { for (Long i = 0; i < this->dim; i++) this->data_ptr[i] -= s; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator*=(ValueType s) { for (Long i = 0; i < this->dim; i++) this->data_ptr[i] *= s; Profile::Add_FLOP(this->dim); return *this; } template Vector& Vector::operator/=(ValueType s) { for (Long i = 0; i < this->dim; i++) this->data_ptr[i] /= s; Profile::Add_FLOP(this->dim); return *this; } template Vector ConstVector::operator+(ValueType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] + s; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator-(ValueType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] - s; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator*(ValueType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] * s; Profile::Add_FLOP(dim); return Vr; } template Vector ConstVector::operator/(ValueType s) const { Vector Vr(dim); for (Long i = 0; i < dim; i++) Vr.data_ptr[i] = data_ptr[i] / s; Profile::Add_FLOP(dim); return Vr; } template Vector operator+(ValueType 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-(ValueType 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*(ValueType 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/(ValueType 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 ConstVector& 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