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 #ifndef EIGEN_COMPRESSED_STORAGE_H
00026 #define EIGEN_COMPRESSED_STORAGE_H
00027
00031 template<typename Scalar>
00032 class CompressedStorage
00033 {
00034 typedef typename NumTraits<Scalar>::Real RealScalar;
00035 public:
00036 CompressedStorage()
00037 : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
00038 {}
00039
00040 CompressedStorage(std::size_t size)
00041 : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
00042 {
00043 resize(size);
00044 }
00045
00046 CompressedStorage(const CompressedStorage& other)
00047 : m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
00048 {
00049 *this = other;
00050 }
00051
00052 CompressedStorage& operator=(const CompressedStorage& other)
00053 {
00054 resize(other.size());
00055 std::memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
00056 std::memcpy(m_indices, other.m_indices, m_size * sizeof(int));
00057 return *this;
00058 }
00059
00060 void swap(CompressedStorage& other)
00061 {
00062 std::swap(m_values, other.m_values);
00063 std::swap(m_indices, other.m_indices);
00064 std::swap(m_size, other.m_size);
00065 std::swap(m_allocatedSize, other.m_allocatedSize);
00066 }
00067
00068 ~CompressedStorage()
00069 {
00070 delete[] m_values;
00071 delete[] m_indices;
00072 }
00073
00074 void reserve(std::size_t size)
00075 {
00076 std::size_t newAllocatedSize = m_size + size;
00077 if (newAllocatedSize > m_allocatedSize)
00078 reallocate(newAllocatedSize);
00079 }
00080
00081 void squeeze()
00082 {
00083 if (m_allocatedSize>m_size)
00084 reallocate(m_size);
00085 }
00086
00087 void resize(std::size_t size, float reserveSizeFactor = 0)
00088 {
00089 if (m_allocatedSize<size)
00090 reallocate(size + std::size_t(reserveSizeFactor*size));
00091 m_size = size;
00092 }
00093
00094 void append(const Scalar& v, int i)
00095 {
00096 int id = m_size;
00097 resize(m_size+1, 1);
00098 m_values[id] = v;
00099 m_indices[id] = i;
00100 }
00101
00102 inline std::size_t size() const { return m_size; }
00103 inline std::size_t allocatedSize() const { return m_allocatedSize; }
00104 inline void clear() { m_size = 0; }
00105
00106 inline Scalar& value(std::size_t i) { return m_values[i]; }
00107 inline const Scalar& value(std::size_t i) const { return m_values[i]; }
00108
00109 inline int& index(std::size_t i) { return m_indices[i]; }
00110 inline const int& index(std::size_t i) const { return m_indices[i]; }
00111
00112 static CompressedStorage Map(int* indices, Scalar* values, std::size_t size)
00113 {
00114 CompressedStorage res;
00115 res.m_indices = indices;
00116 res.m_values = values;
00117 res.m_allocatedSize = res.m_size = size;
00118 return res;
00119 }
00120
00122 inline int searchLowerIndex(int key) const
00123 {
00124 return searchLowerIndex(0, m_size, key);
00125 }
00126
00128 inline int searchLowerIndex(std::size_t start, std::size_t end, int key) const
00129 {
00130 while(end>start)
00131 {
00132 std::size_t mid = (end+start)>>1;
00133 if (m_indices[mid]<key)
00134 start = mid+1;
00135 else
00136 end = mid;
00137 }
00138 return start;
00139 }
00140
00143 inline Scalar at(int key, Scalar defaultValue = Scalar(0)) const
00144 {
00145 if (m_size==0)
00146 return defaultValue;
00147 else if (key==m_indices[m_size-1])
00148 return m_values[m_size-1];
00149
00150
00151 const std::size_t id = searchLowerIndex(0,m_size-1,key);
00152 return ((id<m_size) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
00153 }
00154
00156 inline Scalar atInRange(std::size_t start, std::size_t end, int key, Scalar defaultValue = Scalar(0)) const
00157 {
00158 if (start==end)
00159 return Scalar(0);
00160 else if (end>start && key==m_indices[end-1])
00161 return m_values[end-1];
00162
00163
00164 const std::size_t id = searchLowerIndex(start,end-1,key);
00165 return ((id<end) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
00166 }
00167
00171 inline Scalar& atWithInsertion(int key, Scalar defaultValue = Scalar(0))
00172 {
00173 std::size_t id = searchLowerIndex(0,m_size,key);
00174 if (id>=m_size || m_indices[id]!=key)
00175 {
00176 resize(m_size+1,1);
00177 for (std::size_t j=m_size-1; j>id; --j)
00178 {
00179 m_indices[j] = m_indices[j-1];
00180 m_values[j] = m_values[j-1];
00181 }
00182 m_indices[id] = key;
00183 m_values[id] = defaultValue;
00184 }
00185 return m_values[id];
00186 }
00187
00188 void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
00189 {
00190 std::size_t k = 0;
00191 std::size_t n = size();
00192 for (std::size_t i=0; i<n; ++i)
00193 {
00194 if (!ei_isMuchSmallerThan(value(i), reference, epsilon))
00195 {
00196 value(k) = value(i);
00197 index(k) = index(i);
00198 ++k;
00199 }
00200 }
00201 resize(k,0);
00202 }
00203
00204 protected:
00205
00206 inline void reallocate(std::size_t size)
00207 {
00208 Scalar* newValues = new Scalar[size];
00209 int* newIndices = new int[size];
00210 std::size_t copySize = std::min(size, m_size);
00211
00212 std::memcpy(newValues, m_values, copySize * sizeof(Scalar));
00213 std::memcpy(newIndices, m_indices, copySize * sizeof(int));
00214
00215 delete[] m_values;
00216 delete[] m_indices;
00217 m_values = newValues;
00218 m_indices = newIndices;
00219 m_allocatedSize = size;
00220 }
00221
00222 protected:
00223 Scalar* m_values;
00224 int* m_indices;
00225 std::size_t m_size;
00226 std::size_t m_allocatedSize;
00227
00228 };
00229
00230 #endif // EIGEN_COMPRESSED_STORAGE_H