COOPY » Guide
version 0.6.5
|
00001 #ifndef COOPY_SPARSESHEET 00002 #define COOPY_SPARSESHEET 00003 00004 #include <coopy/EfficientMap.h> 00005 #include <coopy/DataSheet.h> 00006 #include <coopy/IntSheet.h> 00007 #include <coopy/FloatSheet.h> 00008 #include <coopy/Stat.h> 00009 00010 #include <set> 00011 00012 namespace coopy { 00013 namespace store { 00014 template <class T> class SparseSheet; 00015 class SparseFloatSheet; 00016 class SparseIntSheet; 00017 class SparseByteSheet; 00018 class SparseStringSheet; 00019 } 00020 } 00021 00022 template <class T> 00023 class coopy::store::SparseSheet : public DataSheet { 00024 private: 00025 std::set<int> empty_set; 00026 T zero; 00027 public: 00028 efficient_map<long long,T> data; 00029 efficient_map<long, std::set<int> > row; 00030 efficient_map<long, std::set<int> > col; 00031 int h, w; 00032 00033 SparseSheet() { 00034 h = w = 0; 00035 } 00036 00037 00038 const SparseSheet& operator = (const SparseSheet& alt) { 00039 data = alt.data; 00040 row = alt.row; 00041 col = alt.col; 00042 h = alt.h; 00043 w = alt.w; 00044 zero = alt.zero; 00045 return *this; 00046 } 00047 00048 bool resize(int w, int h, const T& zero) { 00049 data.clear(); 00050 row.clear(); 00051 col.clear(); 00052 this->zero = zero; 00053 this->h = h; 00054 this->w = w; 00055 return true; 00056 } 00057 00058 bool nonDestructiveResize(int w, int h, const T& zero) { 00059 this->zero = zero; 00060 this->h = h; 00061 this->w = w; 00062 return true; 00063 } 00064 00065 void reheight(int h) { 00066 if (h>=this->h) { 00067 this->h = h; 00068 } 00069 } 00070 00071 void clear() { 00072 data.clear(); 00073 row.clear(); 00074 col.clear(); 00075 } 00076 00077 int width() const { 00078 return w; 00079 } 00080 00081 int height() const { 00082 return h; 00083 } 00084 00085 const T *pcell_const(int x, int y) const { 00086 typename efficient_map<long long,T>::const_iterator it = data.find(((long long)y)*w+x); 00087 if (it==data.end()) { 00088 return 0/*NULL*/; 00089 } 00090 return &(it->second); 00091 } 00092 00093 T *pcell(int x, int y) { 00094 typename efficient_map<long long,T>::const_iterator it = data.find(((long long)y)*w+x); 00095 if (it==data.end()) { 00096 return 0/*NULL*/; 00097 } 00098 return &(it->second); 00099 } 00100 00101 const T& cell(int x, int y) const { 00102 typename efficient_map<long long,T>::const_iterator it = data.find(((long long)y)*w+x); 00103 if (it==data.end()) { 00104 return zero; 00105 } 00106 return it->second; 00107 } 00108 00109 const T& cell_const(int x, int y) const { 00110 typename efficient_map<long long,T>::const_iterator it = data.find(((long long)y)*w+x); 00111 if (it==data.end()) { 00112 return zero; 00113 } 00114 return it->second; 00115 } 00116 00117 T& cell(int x, int y) { 00118 typename efficient_map<long long,T>::iterator it = data.find(((long long)y)*w+x); 00119 if (it==data.end()) { 00120 T& result = data[((long long)y)*w+x]; 00121 row[y].insert(x); 00122 col[x].insert(y); 00123 result = zero; 00124 return result; 00125 } 00126 return it->second; 00127 } 00128 00129 bool remove(int x, int y) { 00130 typename efficient_map<long long,T>::iterator it = data.find(((long long)y)*w+x); 00131 if (it!=data.end()) { 00132 data.erase(it); 00133 return true; 00134 } 00135 return false; 00136 } 00137 00138 const std::set<int>& getCellsInRow(int y) const { 00139 typename efficient_map<long, std::set<int> >::const_iterator it = 00140 row.find(y); 00141 if (it==row.end()) { 00142 return empty_set; 00143 } 00144 return it->second; 00145 } 00146 00147 const std::set<int>& getCellsInCol(int x) const { 00148 typename efficient_map<long, std::set<int> >::const_iterator it = 00149 col.find(x); 00150 if (it==col.end()) { 00151 return empty_set; 00152 } 00153 return it->second; 00154 } 00155 00156 virtual std::string getDescription() const { 00157 return "sparse"; 00158 } 00159 00160 virtual ColumnRef insertColumn(const ColumnRef& base, 00161 const ColumnInfo& info) { 00162 return ColumnRef(); 00163 } 00164 00165 virtual bool modifyColumn(const ColumnRef& base, 00166 const ColumnInfo& info) { 00167 return false; 00168 } 00169 00170 }; 00171 00172 00173 class coopy::store::SparseStringSheet : public SparseSheet<std::string> { 00174 public: 00175 using SparseSheet<std::string>::resize; 00176 00177 virtual std::string cellString(int x, int y) const { 00178 return cell(x,y); 00179 } 00180 }; 00181 00182 class coopy::store::SparseFloatSheet : public SparseSheet<float> { 00183 public: 00184 using SparseSheet<float>::resize; 00185 using SparseSheet<float>::nonDestructiveResize; 00186 00187 virtual std::string cellString(int x, int y) const { 00188 char buf[256]; 00189 const float& v = cell(x,y); 00190 snprintf(buf,sizeof(buf),"%g",v); 00191 return buf; 00192 } 00193 00194 Stat normalize(int first=-1, int last=-1, float sc=0.1, bool modify = true); 00195 00196 void rescale(double factor) { 00197 for (efficient_map<long long,float>::iterator it=data.begin(); it!=data.end(); it++) { 00198 it->second *= factor; 00199 } 00200 } 00201 00202 void offset(double offset) { 00203 for (efficient_map<long long,float>::iterator it=data.begin(); it!=data.end(); it++) { 00204 it->second += offset; 00205 } 00206 } 00207 00208 void findBest(IntSheet& bestIndex, FloatSheet& bestValue, FloatSheet& bestInc); 00209 00210 bool resize(int w, int h) { 00211 float zero = 0; 00212 return resize(w,h,zero); 00213 } 00214 00215 bool nonDestructiveResize(int w, int h) { 00216 float zero = 0; 00217 return nonDestructiveResize(w,h,zero); 00218 } 00219 00220 bool canResize() { 00221 return true; 00222 } 00223 00224 const float& operator()(int x, int y) const { 00225 return cell(x,y); 00226 } 00227 00228 float& operator()(int x, int y) { 00229 return cell(x,y); 00230 } 00231 }; 00232 00233 class coopy::store::SparseIntSheet : public SparseSheet<int> { 00234 public: 00235 using SparseSheet<int>::resize; 00236 using SparseSheet<int>::nonDestructiveResize; 00237 00238 virtual std::string cellString(int x, int y) const { 00239 const int& v = cell(x,y); 00240 return IntSheet::int2string(v); 00241 } 00242 00243 bool resize(int w, int h) { 00244 int zero = 0; 00245 return resize(w,h,zero); 00246 } 00247 00248 bool nonDestructiveResize(int w, int h) { 00249 int zero = 0; 00250 return nonDestructiveResize(w,h,zero); 00251 } 00252 00253 bool canResize() { 00254 return true; 00255 } 00256 00257 const int& operator()(int x, int y) const { 00258 return cell(x,y); 00259 } 00260 00261 int& operator()(int x, int y) { 00262 return cell(x,y); 00263 } 00264 }; 00265 00266 00267 class coopy::store::SparseByteSheet : public SparseSheet<unsigned char> { 00268 public: 00269 using SparseSheet<unsigned char>::resize; 00270 using SparseSheet<unsigned char>::nonDestructiveResize; 00271 00272 virtual std::string cellString(int x, int y) const { 00273 const unsigned char& v = cell(x,y); 00274 return IntSheet::int2string(v); 00275 } 00276 00277 bool resize(int w, int h) { 00278 unsigned char zero = 0; 00279 return resize(w,h,zero); 00280 } 00281 00282 bool nonDestructiveResize(int w, int h) { 00283 unsigned char zero = 0; 00284 return nonDestructiveResize(w,h,zero); 00285 } 00286 00287 00288 00289 bool canResize() { 00290 return true; 00291 } 00292 00293 const unsigned char& operator()(int x, int y) const { 00294 return cell(x,y); 00295 } 00296 00297 unsigned char& operator()(int x, int y) { 00298 return cell(x,y); 00299 } 00300 }; 00301 00302 #endif