00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef __SPARSEARRAY_H_
00037 #define __SPARSEARRAY_H_
00038
00039 #include <ext/hash_map>
00040
00041
00042
00043
00044
00045
00046 namespace matrix
00047 {
00048
00049 #define COMPARE_EPS 1e-12
00050
00051
00052
00053
00054
00055
00056 template<typename I, typename D> class SparseArray
00057 {
00058 public:
00059 class ArrayElement
00060 {
00061 public:
00062 ArrayElement() : index(0), value(0), hashData(0), dummy(0) { }
00063
00064 inline void reallocate(__gnu_cxx::hash_map<I, D* >* hashData)
00065 {
00066 this->hashData=hashData;
00067 value=0;
00068 dummy=0;
00069 }
00070
00071 inline void set (const I index, D value, D* dummy)
00072 {
00073 this->index=index;
00074 this->value=value;
00075 this->dummy=dummy;
00076 }
00077
00078
00079 inline D operator+ (ArrayElement& el2) { return value+el2.value; }
00080 inline D operator+ (D el2) { return value+el2; }
00081
00082 inline bool operator> (D el2) { return value>el2; }
00083
00084 inline bool operator> (ArrayElement& el2) { return value>el2.value; }
00085 inline D& operator= (D value)
00086 {
00087 if (dummy==0)
00088 {
00089 dummy = (D*) malloc(sizeof(D));
00090 (*hashData)[index]=dummy;
00091 }
00092 *dummy = value;
00093 return *dummy;
00094 }
00095 inline D& operator= (ArrayElement& el2) { this=el2.value; }
00096
00097 inline operator D() { return value; }
00098
00099 protected:
00100 I index;
00101 D value;
00102 __gnu_cxx::hash_map<I, D* >* hashData;
00103 D* dummy;
00104 };
00105
00106 SparseArray(I arraySize) : arraySize(arraySize), hashData(0)
00107 {
00108 allocate();
00109 }
00110
00111 virtual ~SparseArray() {
00112 freeData();
00113 }
00114
00115 virtual inline void reallocate(I arraySize)
00116 {
00117 this->arraySize=arraySize;
00118 allocate();
00119 }
00120
00121 virtual inline I size() { return this->arraySize; }
00122
00123 inline ArrayElement& operator[](const I index)
00124 {
00125 typename __gnu_cxx::hash_map<I,D*>::const_iterator iterator = hashData->find(index);
00126 if (iterator!= hashData->end())
00127 {
00128 D* dummy = (*iterator).second;
00129 elementDummy.set(index, *dummy, dummy);
00130 } else
00131 elementDummy.set(index, 0, 0);
00132 return elementDummy;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 virtual inline long getRealSize()
00147 {
00148 long sumSize = sizeof *this;
00149 sumSize += sizeof *hashData;
00150 sumSize += hashData->size() * (sizeof(D*)+sizeof(D));
00151 return sumSize;
00152 }
00153
00154
00155 protected:
00156 ArrayElement elementDummy;
00157
00158 I arraySize;
00159 __gnu_cxx::hash_map<I, D* >* hashData;
00160
00161 virtual void inline allocate()
00162 {
00163 if (hashData)
00164 freeData();
00165 hashData = new __gnu_cxx::hash_map<I, D* >();
00166 elementDummy.reallocate(hashData);
00167 }
00168
00169 virtual void inline freeData()
00170 {
00171
00172
00173
00174 if (hashData)
00175 {
00176 delete hashData;
00177 hashData = 0;
00178 }
00179 }
00180
00181 private:
00182 SparseArray() {}
00183
00184 };
00185
00186
00187 }
00188
00189 #endif