GammaLib  2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GResponseVectorCache.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GResponseVectorCache.cpp - Response vector cache class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2020 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GResponseVectorCache.cpp
23  * @brief Response vector cache class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "GTools.hpp"
32 #include "GVector.hpp"
33 #include "GResponseVectorCache.hpp"
34 
35 /* __ Method name definitions ____________________________________________ */
36 
37 /* __ Macros _____________________________________________________________ */
38 
39 /* __ Coding definitions _________________________________________________ */
40 
41 /* __ Debug definitions __________________________________________________ */
42 //#define G_DEBUG_VECTOR_CACHE //!< Debug vector cache
43 
44 
45 /*==========================================================================
46  = =
47  = Constructors/destructors =
48  = =
49  ==========================================================================*/
50 
51 /***********************************************************************//**
52  * @brief Void constructor
53  ***************************************************************************/
55 {
56  // Initialise class members
57  init_members();
58 
59  // Return
60  return;
61 }
62 
63 
64 /***********************************************************************//**
65  * @brief Copy constructor
66  *
67  * @param[in] cache Response vector cache.
68  ***************************************************************************/
70 {
71  // Initialise class members
72  init_members();
73 
74  // Copy members
75  copy_members(cache);
76 
77  // Return
78  return;
79 }
80 
81 
82 /***********************************************************************//**
83  * @brief Destructor
84  ***************************************************************************/
86 {
87  // Free members
88  free_members();
89 
90  // Return
91  return;
92 }
93 
94 
95 /*==========================================================================
96  = =
97  = Operators =
98  = =
99  ==========================================================================*/
100 
101 /***********************************************************************//**
102  * @brief Assignment operator
103  *
104  * @param[in] cache Response vector cache.
105  * @return Response vector cache.
106  ***************************************************************************/
108 {
109  // Execute only if object is not identical
110  if (this != &cache) {
111 
112  // Free members
113  free_members();
114 
115  // Initialise private members
116  init_members();
117 
118  // Copy members
119  copy_members(cache);
120 
121  } // endif: object was not identical
122 
123  // Return this object
124  return *this;
125 }
126 
127 
128 /*==========================================================================
129  = =
130  = Public methods =
131  = =
132  ==========================================================================*/
133 
134 /***********************************************************************//**
135  * @brief Clear response vector cache
136  ***************************************************************************/
138 {
139  // Free members
140  free_members();
141 
142  // Initialise private members
143  init_members();
144 
145  // Return
146  return;
147 }
148 
149 
150 /***********************************************************************//**
151  * @brief Clone response cache
152  *
153  * @return Pointer to deep copy of response cache.
154  ***************************************************************************/
156 {
157  return new GResponseVectorCache(*this);
158 }
159 
160 
161 /***********************************************************************//**
162  * @brief Set cache value
163  *
164  * @param[in] cache_id Cache identifier.
165  * @param[in] vector Cache vector.
166  *
167  * Set cache vector for a given @p cache_id.
168  ***************************************************************************/
169 void GResponseVectorCache::set(const std::string& cache_id,
170  const GVector& vector)
171 {
172  // Debug vector cache
173  #if defined(G_DEBUG_VECTOR_CACHE)
174  std::cout << "GResponseVectorCache::set(";
175  std::cout << cache_id << "," << vector.size() << "):";
176  #endif
177 
178  // Initialise pointers to values and indices
179  double* values = NULL;
180  int* indices = NULL;
181 
182  // Find cache index
183  int index = find_cache(cache_id);
184 
185  // Determine size of vector cache
186  int entries = vector.non_zeros();
187 
188  // Debug vector cache
189  #if defined(G_DEBUG_VECTOR_CACHE)
190  if (index != -1) {
191  std::cout << " entry found at index " << index;
192  std::cout << " with " << m_cache_entries[index] << " elements.";
193  std::cout << " Require " << entries << " elements.";
194  std::cout << std::endl;
195  }
196  else {
197  std::cout << " no entry found.";
198  std::cout << " Require " << entries << " elements.";
199  std::cout << std::endl;
200  }
201  #endif
202 
203  // If cache identifier does not yet exist then create new cache entry
204  // and allocate memory to hold cache values and indices
205  if (index == -1) {
206  if (entries > 0) {
207  values = new double[entries];
208  indices = new int[entries];
209  }
210  m_cache_ids.push_back(cache_id);
211  m_cache_entries.push_back(entries);
212  m_cache_values.push_back(values);
213  m_cache_indices.push_back(indices);
214  }
215 
216  // ... otherwise update cache existing entry by allocating new memory
217  // to hold cache values and indices in case that the number of entries
218  // have changed
219  else {
220  if (m_cache_entries[index] != entries) {
221  if (entries > 0) {
222  values = new double[entries];
223  indices = new int[entries];
224  }
225  if (m_cache_values[index] != NULL) delete [] m_cache_values[index];
226  if (m_cache_indices[index] != NULL) delete [] m_cache_indices[index];
227  m_cache_entries[index] = entries;
228  m_cache_values[index] = values;
229  m_cache_indices[index] = indices;
230  }
231  else {
232  values = m_cache_values[index];
233  indices = m_cache_indices[index];
234  }
235  }
236 
237  // Set cache vector
238  for (int i = 0; i < vector.size(); ++i) {
239  if (vector[i] != 0.0) {
240  *values++ = vector[i];
241  *indices++ = i;
242  }
243  }
244 
245  // Return
246  return;
247 }
248 
249 
250 /***********************************************************************//**
251  * @brief Remove cache
252  *
253  * @param[in] cache_id Cache identifier.
254  *
255  * Remove cache for a given @p cache_id.
256  ***************************************************************************/
257 void GResponseVectorCache::remove(const std::string& cache_id)
258 {
259  // Find cache index
260  int index = find_cache(cache_id);
261 
262  // If cache index is valid then remove corresponding cache
263  if (index != -1) {
264 
265  // Free memory
266  if (m_cache_values[index] != NULL) delete [] m_cache_values[index];
267  if (m_cache_indices[index] != NULL) delete [] m_cache_indices[index];
268 
269  // Erase entry
270  m_cache_ids.erase(m_cache_ids.begin() + index);
271  m_cache_entries.erase(m_cache_entries.begin() + index);
272  m_cache_values.erase(m_cache_values.begin() + index);
273  m_cache_indices.erase(m_cache_indices.begin() + index);
274 
275  } // endif: cache index was valid
276 
277  // Return
278  return;
279 }
280 
281 
282 /***********************************************************************//**
283  * @brief Check if cache contains a value for specific parameters
284  *
285  * @param[in] cache_id Cache identifier.
286  * @param[in,out] vector Pointer to cached vector (only if found).
287  * @return True if cached value was found, otherwise false.
288  *
289  * Check if the cache contains a value for a given @p name, reconstructed
290  * energy @p ereco, and true energy @p etrue.
291  *
292  * If the @p value pointer argument is not NULL, the method will return the
293  * cached value through this argument in case that the value exists.
294  ***************************************************************************/
295 bool GResponseVectorCache::contains(const std::string& cache_id,
296  GVector* vector) const
297 {
298  // Debug vector cache
299  #if defined(G_DEBUG_VECTOR_CACHE)
300  std::cout << "GResponseVectorCache::contains(" << cache_id;
301  if (vector == NULL) {
302  std::cout << ", NULL):";
303  }
304  else {
305  std::cout << "," << vector->size() << "):";
306  }
307  #endif
308 
309  // Find cache index
310  int index = find_cache(cache_id);
311 
312  // Set contains flag
313  bool contains = (index != -1);
314 
315  // Debug vector cache
316  #if defined(G_DEBUG_VECTOR_CACHE)
317  if (contains) {
318  std::cout << " entry found at index " << index;
319  std::cout << " with " << m_cache_entries[index] << " elements.";
320  std::cout << std::endl;
321  }
322  else {
323  std::cout << " no entry found." << std::endl;
324  }
325  #endif
326 
327  // If cache contains the identifier and a pointer to a vector was
328  // provided then fill the vector
329  if (contains && vector != NULL) {
330 
331  // Get pointer to values and indices
332  double* values = m_cache_values[index];
333  int* indices = m_cache_indices[index];
334 
335  // Fill vector
336  for (int i = 0; i < m_cache_entries[index]; ++i, ++values, ++indices) {
337  (*vector)[*indices] = *values;
338  }
339 
340  } // endif: filled vector
341 
342  // Return containment flag
343  return contains;
344 }
345 
346 
347 /***********************************************************************//**
348  * @brief Print response cache
349  *
350  * @param[in] chatter Chattiness.
351  * @return String containing response cache information.
352  ***************************************************************************/
353 std::string GResponseVectorCache::print(const GChatter& chatter) const
354 {
355  // Initialise result string
356  std::string result;
357 
358  // Continue only if chatter is not silent
359  if (chatter != SILENT) {
360 
361  // Append header
362  result.append("=== GResponseVectorCache ===");
363 
364  // Append total cache size
365  result.append("\n"+gammalib::parformat("Number of cached vectors"));
366  result.append(gammalib::str(size()));
367 
368  // Append cache information
369  for (int i = 0; i < size(); ++i) {
370  result.append("\n"+gammalib::parformat("Identifier"));
371  result.append(m_cache_ids[i]);
372  result.append(" ("+gammalib::str(m_cache_entries[i])+" values");
373  }
374 
375  } // endif: chatter was not silent
376 
377  // Return result
378  return result;
379 }
380 
381 
382 /*==========================================================================
383  = =
384  = Private methods =
385  = =
386  ==========================================================================*/
387 
388 /***********************************************************************//**
389  * @brief Initialise class members
390  ***************************************************************************/
392 {
393  // Initialise members
394  m_cache_ids.clear();
395  m_cache_entries.clear();
396  m_cache_values.clear();
397  m_cache_indices.clear();
398 
399  // Return
400  return;
401 }
402 
403 
404 /***********************************************************************//**
405  * @brief Copy class members
406  *
407  * @param[in] cache Response cache.
408  ***************************************************************************/
410 {
411  // Copy members
412  m_cache_ids = cache.m_cache_ids;
414 
415  // Copy values and indices
416  for (int i = 0; i < size(); ++i) {
417  double* values = NULL;
418  int* indices = NULL;
419  if (m_cache_entries[i] > 0) {
420  values = new double[m_cache_entries[i]];
421  indices = new int[m_cache_entries[i]];
422  for (int k = 0; k < m_cache_entries[i]; ++k) {
423  values[k] = cache.m_cache_values[i][k];
424  indices[k] = cache.m_cache_indices[i][k];
425  }
426  }
427  m_cache_values.push_back(values);
428  m_cache_indices.push_back(indices);
429  }
430 
431  // Return
432  return;
433 }
434 
435 
436 /***********************************************************************//**
437  * @brief Delete class members
438  ***************************************************************************/
440 {
441  // Loop over entries
442  for (int i = 0; i < size(); ++i) {
443  if (m_cache_values[i] != NULL) delete [] m_cache_values[i];
444  if (m_cache_indices[i] != NULL) delete [] m_cache_indices[i];
445  m_cache_values[i] = NULL;
446  m_cache_indices[i] = NULL;
447  }
448 
449  // Return
450  return;
451 }
452 
453 
454 /***********************************************************************//**
455  * @brief Find cache
456  *
457  * @param[in] cache_id Cache identifier.
458  * @return Cache index (-1 if no cache was found)
459  *
460  * Find cache for a given @p cache_id. If no cache was found the method
461  * returns -1.
462  ***************************************************************************/
463 int GResponseVectorCache::find_cache(const std::string& cache_id) const
464 {
465  // Initialise cache index
466  int index = -1;
467 
468  // Loop over cache
469  for (int i = 0; i < m_cache_ids.size(); ++i) {
470  if (m_cache_ids[i] == cache_id) {
471  index = i;
472  break;
473  }
474  }
475 
476  // Return index
477  return index;
478 }
479 
480 
GResponseVectorCache(void)
Void constructor.
Response vector cache class.
std::vector< int > m_cache_entries
std::string print(const GChatter &chatter=NORMAL) const
Print response cache.
void set(const std::string &cache_id, const GVector &vector)
Set cache value.
virtual ~GResponseVectorCache(void)
Destructor.
Gammalib tools definition.
void init_members(void)
Initialise class members.
std::vector< double * > m_cache_values
int size(void) const
Returns size of vector chache.
int find_cache(const std::string &cache_id) const
Find cache.
void free_members(void)
Delete class members.
GResponseVectorCache * clone(void) const
Clone response cache.
int non_zeros(void) const
Returns number of non-zero elements in vector.
Definition: GVector.cpp:559
GResponseVectorCache & operator=(const GResponseVectorCache &cache)
Assignment operator.
Response vector cache class definition.
void remove(const std::string &cache_id)
Remove cache.
GChatter
Definition: GTypemaps.hpp:33
Vector class interface definition.
void copy_members(const GResponseVectorCache &cache)
Copy class members.
void clear(void)
Clear response vector cache.
bool contains(const std::string &cache_id, GVector *irfs=NULL) const
Check if cache contains a value for specific parameters.
std::vector< int * > m_cache_indices
const int & size(void) const
Return size of vector.
Definition: GVector.hpp:178
Vector class.
Definition: GVector.hpp:46
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
std::vector< std::string > m_cache_ids
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489