LOOS  v2.3.2
MatrixStorage.hpp
1 /*
2  MatrixStorage.hpp
3 
4  Storage policies for loos::Matrix
5 */
6 
7 /*
8  This file is part of LOOS.
9 
10  LOOS (Lightweight Object-Oriented Structure library)
11  Copyright (c) 2008, Tod D. Romo, Alan Grossfield
12  Department of Biochemistry and Biophysics
13  School of Medicine & Dentistry, University of Rochester
14 
15  This package (LOOS) is free software: you can redistribute it and/or modify
16  it under the terms of the GNU General Public License as published by
17  the Free Software Foundation under version 3 of the License.
18 
19  This package is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <http://www.gnu.org/licenses/>.
26 */
27 
28 
29 #if !defined(LOOS_MATRIX_STORAGE_HPP)
30 #define LOOS_MATRIX_STORAGE_HPP
31 
32 
33 #include <string>
34 #include <stdexcept>
35 #include <boost/shared_array.hpp>
36 #include <vector>
37 
38 #if __GNUC__ == 4 && __GNUC_MINOR__ < 1
39 #include <ext/hash_map>
40 #else
41 #include <boost/unordered_map.hpp>
42 #endif
43 
44 #include <loos_defs.hpp>
45 
46 namespace loos {
47  namespace Math {
48 
50 
58  template<typename T>
59  class SharedArray {
60  public:
61  typedef const T* const_iterator;
62  typedef T* iterator;
63 
64  SharedArray(const ulong n) : dim_(n) { allocate(n); }
65  SharedArray(T* p, const ulong n) : dim_(n), dptr(p) { }
66 
67  // In some cases, BOOST makes dptr(0) a shared_array<int> which
68  // will cause subsequent type problems. So, we force it to be a NULL
69  // pointer but with type T and wrap that...
70  SharedArray() : dim_(0), dptr(static_cast<T*>(0)) { }
71 
72  T* get(void) const { return(dptr.get()); }
73 
74 
75  T& operator[](const ulong i) {
76 #if defined(DEBUG)
77  if (i >= dim_)
78  throw(std::out_of_range("Matrix index out of range"));
79 #endif
80  return(dptr[i]);
81  }
82 
83  const T& operator[](const ulong i) const {
84 #if defined(DEBUG)
85  if (i >= dim_)
86  throw(std::out_of_range("Matrix index out of range"));
87 #endif
88  return(dptr[i]);
89  }
90 
91 
92  iterator begin(void) { return(dptr.get()); }
93  iterator end(void) { return(dptr.get() + dim_); }
94 
95  const_iterator begin(void) const { return(dptr.get()); }
96  const_iterator end(void) const { return(dptr.get() + dim_); }
97 
98 
99 
100  protected:
101 
102  void set(const SharedArray<T>& s) {
103  dim_ = s.dim_;
104  dptr = s.dptr;
105  }
106 
107  void copyData(const SharedArray<T>& s) {
108  allocate(s.dim_);
109  for (ulong i=0; i<dim_; ++i)
110  dptr[i] = s.dptr[i];
111  };
112 
113  void resize(const ulong n) {
114  dim_ = n;
115  allocate(n);
116  }
117 
118  void reset(void) {
119  dim_ = 0;
120  dptr.reset();
121  }
122 
123 
124  private:
125 
126  void allocate(const ulong n) {
127  dptr = boost::shared_array<T>(new T[n]);
128  for (ulong i=0; i<n; ++i)
129  dptr[i] = 0;
130  }
131 
132  ulong dim_;
133  boost::shared_array<T> dptr;
134 
135  };
136 
137 
139 
148  template<class T>
149  class SparseArray {
150  public:
151 
152 #if __GNUC__ == 4 && __GNUC_MINOR__ < 1
153  typedef typename __gnu_cxx::hash_map<ulong, T>::const_iterator const_iterator;
154  typedef typename __gnu_cxx::hash_map<ulong, T>::iterator iterator;
155 #else
156  typedef typename boost::unordered_map<ulong, T>::const_iterator const_iterator;
157  typedef typename boost::unordered_map<ulong, T>::iterator iterator;
158 #endif
159 
160  SparseArray(const ulong n) : dim_(n) { }
161  SparseArray() : dim_(0) { }
162 
163 
164  T& operator[](const ulong i) {
165  if (i >= dim_)
166  throw(std::out_of_range("Matrix index out of range"));
167  return(dmap[i]);
168  }
169 
170 
171  // Since unordered_set::operator[] will create an entry if none
172  // exists, we have to use the find m.f. to check whether or not
173  // this entry has been set. If not, then we return a const-ref to
174  // a default-initialize object of type T. This is so we can read
175  // through all indices of a sparse matrix without it then
176  // ballooning out to the max possible storage...
177 
178  const T& operator[](const ulong i) const {
179  static T null_value;
180  if (i >= dim_)
181  throw(std::out_of_range("Matrix index out of range"));
182 
183 #if __GNUC__ == 4 && __GNUC_MINOR__ < 1
184  typename __gnu_cxx::hash_map<ulong, T>::const_iterator ci;
185 #else
186  typename boost::unordered_map<ulong, T>::const_iterator ci;
187 #endif
188 
189  ci = dmap.find(i);
190  if (ci == dmap.end()) {
191  return(null_value);
192  }
193 
194  return((*ci).second);
195  }
196 
198  ulong actualSize(void) const { return(dmap.size()); }
199 
200  // NOTE: No get() function here since it makes no sense...
201 
202  iterator begin(void) { return(dmap.begin()); }
203  iterator end(void) { return(dmap.end()); }
204 
205  const_iterator begin(void) const { return(dmap.begin()); }
206  const_iterator end(void) const { return(dmap.end()); }
207 
209  double density(void) const {
210  return( (static_cast<double>(dmap.size())) / dim_ );
211  }
212 
213 
214  protected:
215  void set(const SparseArray<T>& s) {
216  dim_ = s.dim_;
217  dmap = s.dmap;
218  }
219 
220  void copyData(const SparseArray<T>& s) {
221  set(s);
222  }
223 
224  void resize(const ulong n) {
225  dim_ = n;
226  dmap.clear();
227  };
228 
229  void reset(void) {
230  resize(0);
231  }
232 
233  private:
234  ulong dim_;
235 
236 
237 #if __GNUC__ == 4 && __GNUC_MINOR__ < 1
238  __gnu_cxx::hash_map<ulong, T> dmap;
239 #else
240  boost::unordered_map<ulong, T> dmap;
241 #endif
242 
243 
244  };
245  }
246 
247 }
248 
249 #endif
Storage policy for a block of memory wrapped in a boost::shared_array pointer.
ulong actualSize(void) const
The actual size (# of elements) set.
double density(void) const
Degree of sparseness...
Storage policy for a sparse matrix (see important note in the detailed documentation).
Namespace for most things not already encapsulated within a class.