aboutsummaryrefslogblamecommitdiffstats
path: root/meowpp/gra/IdentityPoints.h
blob: edac56e0124a91a120c1fab289b9e9df154efe8a (plain) (tree)
1
2
3
4
5
6
7
8
9



                                
                           


                          
              















                                                                            
 



                                 
 
                             
     
    
                                                                           
     
    
               

     
 




                          
                            
   
 


                                           

                                          
   
 




                      
 






                                                     
 






                                                          
 





                                       
 





                                          
 





                                             
 





                                                           
 





                            
 







                                               
 










                                                                                  
 


                                       

                                           
   
 


                                       
                                                                    
            
                             
   
 


                                 
                                                                       
                                                                                
                                    
     
                    
   
 


                                 
                                                               

                                                   
                    
     
                    
   
 


                                      
                                            

                                                                           
 


                                      
                                                               


                                                         
                     
   
 


                                      
                                                                  


                                                          
                     
   
 


                                      
                               

                              
 


                                                              
                                          

                               
 





                                                      
 




                                                        




                                                                            
                                                                        










                                                                            
                                                                        







                                                                         
   
 




                                                 










                                                             
                            
         
                              










                                                            
                            
         
                              


                








                                             
 











                                                                               
 



                                                    

                                
   
 








                                              
         

                                
#ifndef   gra_IdentityPoints_H__
#define   gra_IdentityPoints_H__

#include "../Self.h"
#include "../math/Vector.h"
#include "../oo/ObjBase.h"

#include <map>
#include <set>

#include <cstdlib>

namespace meow {

/*!
 * @brief 把一個 \c std::map<ID,Vector<Scalar> > 包起來
 *
 * @author cat_leopard
 */
template<class ID, class Scalar>
class IdentityPoints: public ObjBase {
public:
  typedef typename std::map<ID, Vector<Scalar> >     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<Myself> const self;
public:
  /*!
   * @brief constructor
   */
  IdentityPoints(): self() {
  }

  /*!
   * @brief constructor, 並且複製資料
   */
  IdentityPoints(IdentityPoints const& b):
  self(b.self, Self<Myself>::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<ID> const& ids) {
    for (typename std::set<ID>::const_iterator
         it = ids.begin(); it != ids.end(); ++it) {
      pointDel(*it);
    }
    return points();
  }

  /*!
   * @brief 取得一個identity point
   */
  Vector<Scalar> point(ID const& id) const {
    return (exist(id) ? self->points_.find(id)->second : Vector<Scalar>());
  }

  /*!
   * @brief 修改一個identity point
   */
  Vector<Scalar> point(ID const& id, Vector<Scalar> const& b) {
    if (b.dimension() == self->dimension_ && exist(id)) {
      self()->points_[id].copyFrom(b);
    }
    return point(id);
  }

  /*!
   * @brief 新增一個identity point
   */
  Vector<Scalar> pointAdd(ID const& id, Vector<Scalar> 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<Scalar>& 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<Scalar> 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<Scalar> 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<Pixel>
   */
  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__