GammaLib 2.0.0
Loading...
Searching...
No Matches
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"
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
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
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
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 ***************************************************************************/
169void 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 ***************************************************************************/
257void 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 ***************************************************************************/
295bool 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 ***************************************************************************/
353std::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 ***************************************************************************/
463int 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
Response vector cache class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Vector class interface definition.
Response vector cache class.
std::string print(const GChatter &chatter=NORMAL) const
Print response cache.
bool contains(const std::string &cache_id, GVector *irfs=NULL) const
Check if cache contains a value for specific parameters.
void free_members(void)
Delete class members.
int size(void) const
Returns size of vector chache.
std::vector< int > m_cache_entries
virtual ~GResponseVectorCache(void)
Destructor.
std::vector< int * > m_cache_indices
GResponseVectorCache(void)
Void constructor.
std::vector< double * > m_cache_values
void remove(const std::string &cache_id)
Remove cache.
void copy_members(const GResponseVectorCache &cache)
Copy class members.
void init_members(void)
Initialise class members.
void clear(void)
Clear response vector cache.
int find_cache(const std::string &cache_id) const
Find cache.
std::vector< std::string > m_cache_ids
void set(const std::string &cache_id, const GVector &vector)
Set cache value.
GResponseVectorCache * clone(void) const
Clone response cache.
GResponseVectorCache & operator=(const GResponseVectorCache &cache)
Assignment operator.
Vector class.
Definition GVector.hpp:46
const int & size(void) const
Return size of vector.
Definition GVector.hpp:178
int non_zeros(void) const
Returns number of non-zero elements in vector.
Definition GVector.cpp:559
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489