#ifndef gra_IdentityPoints_H__ #define gra_IdentityPoints_H__ #include "../Self.h" #include "../math/Vector.h" #include "../oo/ObjBase.h" #include #include #include namespace meow { /*! * @brief 把一個 \c std::map > 包起來 * * @author cat_leopard */ template class IdentityPoints: public ObjBase { public: typedef typename std::map > IdentityPointsMap; typedef typename IdentityPointsMap:: iterator IdentityPointsMapIter; typedef typename IdentityPointsMap::const_iterator IdentityPointsMapIterK; private: struct Myself { IdentityPointsMap points_; size_t dimension_; Myself(): dimension_(1) { } Myself(Myself const& m): points_(m.points_), dimension_(m.dimension_) { } ~Myself() { } }; Self const self; public: /*! * @brief constructor */ IdentityPoints(): self() { } /*! * @brief constructor, 並且複製資料 */ IdentityPoints(IdentityPoints const& b): self(b.self, Self::COPY_FROM) { } /*! * @brief destructor */ ~IdentityPoints() { } /*! * @brief 複製資料 */ IdentityPoints& copyFrom(IdentityPoints const& b) { self().copyFrom(b.self); return *this; } /*! * @brief 參照 */ IdentityPoints& referenceFrom(IdentityPoints const& b) { self().referenceFrom(b.self); return *this; } /*! * @brief 清除一切identity points */ void clear() { self()->points_.clear(); } /*! * @brief 回傳有幾個identity points */ size_t size() const { return self->points_.size(); } /*! * @brief 回傳是否沒有identity points */ bool empty() const { return (size() == 0u); } /*! * @brief 檢查某id是否有使用 */ bool exist(ID const& id) const { return (self->points_.find(id) != self->points_.end()); } /*! * @brief 回傳dimension */ size_t dimension() const { return self->dimension_; } /*! * @brief 設定dimension, 並且清空資料 */ size_t dimension(size_t dim) { self()->dimension_ = dim; clear(); return dimension(); } /*! * @brief 設定dimension, 並且針對每個identity point指定重設dimension */ size_t dimension(size_t dim, Scalar const& init_value) { self()->dimension_ = dim; for (IdentityPointsMapIter it = self()->points_.begin(); it != self()->points_.end(); ++it) { it.second.dimension(dim, init_value); } return dimension(); } /*! * @brief 取得所有identity points */ IdentityPointsMap const& points() const { return self()->points_; } /*! * @brief 設定所有identity points */ IdentityPointsMap const& points(IdentityPointsMap const& points) { clear(); return pointsAdd(points); } /*! * @brief 加入identity Points */ IdentityPointsMap const& pointsAdd(IdentityPointsMap const& points) { for (IdentityPointsMapIterK it = points.begin(); it != points.end(); ++it) { pointAdd(it.first, it.second); } return points(); } /*! * @brief 移除identity Points */ IdentityPointsMap const& pointsDel(std::set const& ids) { for (typename std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) { pointDel(*it); } return points(); } /*! * @brief 取得一個identity point */ Vector point(ID const& id) const { return (exist(id) ? self->points_.find(id)->second : Vector()); } /*! * @brief 修改一個identity point */ Vector point(ID const& id, Vector const& b) { if (b.dimension() == self->dimension_ && exist(id)) { self()->points_[id].copyFrom(b); } return point(id); } /*! * @brief 新增一個identity point */ Vector pointAdd(ID const& id, Vector const& b) { if (b.dimension() == self->dimension_ && !exist(id)) { self()->points_[id].copyFrom(b); } return point(id); } /*! * @brief 刪除一個identity point */ void pointDel(ID const& id) { self()->points_.erase(id); } /*! * @brief 取得一個identity point, non-constant reference */ Vector& pointGet(ID const& id) { return self()->points_[id]; } /*! * @brief same as \c copyFrom(b) */ IdentityPoints& operator=(IdentityPoints const& b) { return copyFrom(b); } /*! @brief 將資料寫入檔案 * * @note 未完成 */ bool write(FILE* f, bool bin, unsigned int fg) const { if (bin) { long dim, ct; if (fwrite(&(dim = dimension()), sizeof(dim), 1, f) < 1) return false; if (fwrite(&(ct = size()), sizeof(ct), 1, f) < 1) return false; for (IdentityPointsMapIterK it = points().begin(), ed = points().end(); it != ed; ++it) { double tmp; if (fwrite(&(tmp = it->first), sizeof(tmp), 1, f) < 1) return false; for (long i = 0; i < dim; ++i) { if (fwrite(&(tmp = it->second(i)), sizeof(tmp), 1, f) < 1) return false; } } } else { if (fprintf(f, "%ld %lu\n", dimension(), size()) < 1) return false; for (IdentityPointsMapIterK it = points().begin(), ed = points().end(); it != ed; ++it) { if (fprintf(f, "%f ", (double)it->first) < 1) return false; for (long i = 0, I = dimension(); i < I; ++i) { if (fprintf(f, "%f ", (double)it->second(i)) < 1) return false; } fprintf(f, "\n"); } } return true; } /*! @brief 將資料讀入 * * @note 未完成 */ bool read(FILE* f, bool bin, unsigned int fg) { long dim, ct; if (bin) { if (fread(&dim, sizeof(dim), 1, f) < 1) return false; dimension(dim); if (fread(&ct, sizeof(ct), 1, f) < 1) return false; double id, tt; Vector tmp(dim, 0); for (int i = 0; i < ct; ++i) { if (fread(&id, sizeof(id), 1, f) < 1) return false; for (size_t j = 0, J = dim; j < J; ++j) { if (fread(&tt, sizeof(tt), 1, f) < 1) return false; tmp.scalar(j, tt); } pointAdd((ID)id, tmp); } } else { if (fscanf(f, "%ld %ld", &dim, &ct) < 2) return false; dimension(dim); double id, tt; Vector tmp(dim, 0); for (int i = 0; i < ct; ++i) { if (fscanf(f, "%lf", &id) < 1) return false; for (int j = 0, J = dim; j < J; ++j) { if (fscanf(f, "%lf", &tt) < 1) return false; tmp.scalar(j, tt); } pointAdd((ID)id, tmp); } } return true; } /*! @brief new一個自己 * * @return 一個new出來的Bitmap */ ObjBase* create() const { return new IdentityPoints(); } /*! @brief 複製資料 * * 輸入型別是 \c ObjBase \c const* * 這裡假設實體其實是 \c Bitmap. * 事實上這個method就只是幫忙轉型然後呼叫原本的\c copyFrom * * @param [in] b 資料來源 * @return this */ ObjBase* copyFrom(ObjBase const* b) { return &(copyFrom(*(IdentityPoints*)b)); } /*! @brief 回傳class的type * * @return \c char \c const\c * 形式的typename */ char const* ctype() const { return typeid(*this).name(); } /*! @brief 回傳class的type * * @return \c std::string 形式的typename */ std::string type() const { return std::string(ctype()); } }; } // meow #endif // gra_IdentityPoints_H__