SkylineStorage.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef EIGEN_SKYLINE_STORAGE_H
26 #define EIGEN_SKYLINE_STORAGE_H
27 
28 namespace Eigen {
29 
36 template<typename Scalar>
38  typedef typename NumTraits<Scalar>::Real RealScalar;
39  typedef SparseIndex Index;
40 public:
41 
43  : m_diag(0),
44  m_lower(0),
45  m_upper(0),
46  m_lowerProfile(0),
47  m_upperProfile(0),
48  m_diagSize(0),
49  m_upperSize(0),
50  m_lowerSize(0),
51  m_upperProfileSize(0),
52  m_lowerProfileSize(0),
53  m_allocatedSize(0) {
54  }
55 
56  SkylineStorage(const SkylineStorage& other)
57  : m_diag(0),
58  m_lower(0),
59  m_upper(0),
60  m_lowerProfile(0),
61  m_upperProfile(0),
62  m_diagSize(0),
63  m_upperSize(0),
64  m_lowerSize(0),
65  m_upperProfileSize(0),
66  m_lowerProfileSize(0),
67  m_allocatedSize(0) {
68  *this = other;
69  }
70 
71  SkylineStorage & operator=(const SkylineStorage& other) {
72  resize(other.diagSize(), other.m_upperProfileSize, other.m_lowerProfileSize, other.upperSize(), other.lowerSize());
73  memcpy(m_diag, other.m_diag, m_diagSize * sizeof (Scalar));
74  memcpy(m_upper, other.m_upper, other.upperSize() * sizeof (Scalar));
75  memcpy(m_lower, other.m_lower, other.lowerSize() * sizeof (Scalar));
76  memcpy(m_upperProfile, other.m_upperProfile, m_upperProfileSize * sizeof (Index));
77  memcpy(m_lowerProfile, other.m_lowerProfile, m_lowerProfileSize * sizeof (Index));
78  return *this;
79  }
80 
81  void swap(SkylineStorage& other) {
82  std::swap(m_diag, other.m_diag);
83  std::swap(m_upper, other.m_upper);
84  std::swap(m_lower, other.m_lower);
85  std::swap(m_upperProfile, other.m_upperProfile);
86  std::swap(m_lowerProfile, other.m_lowerProfile);
87  std::swap(m_diagSize, other.m_diagSize);
88  std::swap(m_upperSize, other.m_upperSize);
89  std::swap(m_lowerSize, other.m_lowerSize);
90  std::swap(m_allocatedSize, other.m_allocatedSize);
91  }
92 
93  ~SkylineStorage() {
94  delete[] m_diag;
95  delete[] m_upper;
96  if (m_upper != m_lower)
97  delete[] m_lower;
98  delete[] m_upperProfile;
99  delete[] m_lowerProfile;
100  }
101 
102  void reserve(Index size, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize) {
103  Index newAllocatedSize = size + upperSize + lowerSize;
104  if (newAllocatedSize > m_allocatedSize)
105  reallocate(size, upperProfileSize, lowerProfileSize, upperSize, lowerSize);
106  }
107 
108  void squeeze() {
109  if (m_allocatedSize > m_diagSize + m_upperSize + m_lowerSize)
110  reallocate(m_diagSize, m_upperProfileSize, m_lowerProfileSize, m_upperSize, m_lowerSize);
111  }
112 
113  void resize(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize, float reserveSizeFactor = 0) {
114  if (m_allocatedSize < diagSize + upperSize + lowerSize)
115  reallocate(diagSize, upperProfileSize, lowerProfileSize, upperSize + Index(reserveSizeFactor * upperSize), lowerSize + Index(reserveSizeFactor * lowerSize));
116  m_diagSize = diagSize;
117  m_upperSize = upperSize;
118  m_lowerSize = lowerSize;
119  m_upperProfileSize = upperProfileSize;
120  m_lowerProfileSize = lowerProfileSize;
121  }
122 
123  inline Index diagSize() const {
124  return m_diagSize;
125  }
126 
127  inline Index upperSize() const {
128  return m_upperSize;
129  }
130 
131  inline Index lowerSize() const {
132  return m_lowerSize;
133  }
134 
135  inline Index upperProfileSize() const {
136  return m_upperProfileSize;
137  }
138 
139  inline Index lowerProfileSize() const {
140  return m_lowerProfileSize;
141  }
142 
143  inline Index allocatedSize() const {
144  return m_allocatedSize;
145  }
146 
147  inline void clear() {
148  m_diagSize = 0;
149  }
150 
151  inline Scalar& diag(Index i) {
152  return m_diag[i];
153  }
154 
155  inline const Scalar& diag(Index i) const {
156  return m_diag[i];
157  }
158 
159  inline Scalar& upper(Index i) {
160  return m_upper[i];
161  }
162 
163  inline const Scalar& upper(Index i) const {
164  return m_upper[i];
165  }
166 
167  inline Scalar& lower(Index i) {
168  return m_lower[i];
169  }
170 
171  inline const Scalar& lower(Index i) const {
172  return m_lower[i];
173  }
174 
175  inline Index& upperProfile(Index i) {
176  return m_upperProfile[i];
177  }
178 
179  inline const Index& upperProfile(Index i) const {
180  return m_upperProfile[i];
181  }
182 
183  inline Index& lowerProfile(Index i) {
184  return m_lowerProfile[i];
185  }
186 
187  inline const Index& lowerProfile(Index i) const {
188  return m_lowerProfile[i];
189  }
190 
191  static SkylineStorage Map(Index* upperProfile, Index* lowerProfile, Scalar* diag, Scalar* upper, Scalar* lower, Index size, Index upperSize, Index lowerSize) {
192  SkylineStorage res;
193  res.m_upperProfile = upperProfile;
194  res.m_lowerProfile = lowerProfile;
195  res.m_diag = diag;
196  res.m_upper = upper;
197  res.m_lower = lower;
198  res.m_allocatedSize = res.m_diagSize = size;
199  res.m_upperSize = upperSize;
200  res.m_lowerSize = lowerSize;
201  return res;
202  }
203 
204  inline void reset() {
205  memset(m_diag, 0, m_diagSize * sizeof (Scalar));
206  memset(m_upper, 0, m_upperSize * sizeof (Scalar));
207  memset(m_lower, 0, m_lowerSize * sizeof (Scalar));
208  memset(m_upperProfile, 0, m_diagSize * sizeof (Index));
209  memset(m_lowerProfile, 0, m_diagSize * sizeof (Index));
210  }
211 
212  void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) {
213  //TODO
214  }
215 
216 protected:
217 
218  inline void reallocate(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize) {
219 
220  Scalar* diag = new Scalar[diagSize];
221  Scalar* upper = new Scalar[upperSize];
222  Scalar* lower = new Scalar[lowerSize];
223  Index* upperProfile = new Index[upperProfileSize];
224  Index* lowerProfile = new Index[lowerProfileSize];
225 
226  Index copyDiagSize = (std::min)(diagSize, m_diagSize);
227  Index copyUpperSize = (std::min)(upperSize, m_upperSize);
228  Index copyLowerSize = (std::min)(lowerSize, m_lowerSize);
229  Index copyUpperProfileSize = (std::min)(upperProfileSize, m_upperProfileSize);
230  Index copyLowerProfileSize = (std::min)(lowerProfileSize, m_lowerProfileSize);
231 
232  // copy
233  memcpy(diag, m_diag, copyDiagSize * sizeof (Scalar));
234  memcpy(upper, m_upper, copyUpperSize * sizeof (Scalar));
235  memcpy(lower, m_lower, copyLowerSize * sizeof (Scalar));
236  memcpy(upperProfile, m_upperProfile, copyUpperProfileSize * sizeof (Index));
237  memcpy(lowerProfile, m_lowerProfile, copyLowerProfileSize * sizeof (Index));
238 
239 
240 
241  // delete old stuff
242  delete[] m_diag;
243  delete[] m_upper;
244  delete[] m_lower;
245  delete[] m_upperProfile;
246  delete[] m_lowerProfile;
247  m_diag = diag;
248  m_upper = upper;
249  m_lower = lower;
250  m_upperProfile = upperProfile;
251  m_lowerProfile = lowerProfile;
252  m_allocatedSize = diagSize + upperSize + lowerSize;
253  m_upperSize = upperSize;
254  m_lowerSize = lowerSize;
255  }
256 
257 public:
258  Scalar* m_diag;
259  Scalar* m_upper;
260  Scalar* m_lower;
261  Index* m_upperProfile;
262  Index* m_lowerProfile;
263  Index m_diagSize;
264  Index m_upperSize;
265  Index m_lowerSize;
266  Index m_upperProfileSize;
267  Index m_lowerProfileSize;
268  Index m_allocatedSize;
269 
270 };
271 
272 } // end namespace Eigen
273 
274 #endif // EIGEN_COMPRESSED_STORAGE_H