1 /**
2  * This code is part of Qiskit.
3  *
4  * (C) Copyright IBM 2018, 2019.
5  *
6  * This code is licensed under the Apache License, Version 2.0. You may
7  * obtain a copy of this license in the LICENSE.txt file in the root directory
8  * of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
9  *
10  * Any modifications or derivative works of this code must retain this
11  * copyright notice, and modified files need to carry a notice indicating
12  * that they have been altered from the originals.
13  */
14 
15 #ifndef _aer_framework_results_data_average_snapshot_hpp_
16 #define _aer_framework_results_data_average_snapshot_hpp_
17 
18 #include "framework/json.hpp"
19 #include "framework/results/data/average_data.hpp"
20 #include "framework/types.hpp"
21 
22 namespace AER {
23 
24 //------------------------------------------------------------------------------
25 // Average Snapshot data storage class
26 //------------------------------------------------------------------------------
27 
28 template <typename T>
29 class AverageSnapshot {
30   // Inner snapshot data map type
31 
32  public:
33   // Add a new datum to the snapshot at the specified key
34   // Uses copy semantics
35   void add_data(const std::string &key, const std::string &memory,
36                 const T &datum, bool variance = false);
37 
38   // Add a new datum to the snapshot at the specified key
39   // Uses move semantics
40   void add_data(const std::string &key, const std::string &memory,
41                 T &&datum, bool variance = false) noexcept;
42 
43   // Combine with another average snapshot container
44   // Uses copy semantics
45   void combine(const AverageSnapshot<T> &other);
46 
47   // Combine with another average snapshot container
48   // Uses move semantics
49   void combine(AverageSnapshot<T> &&other) noexcept;
50 
51   // Clear all data from current snapshot
clear()52   void clear() { data_.clear(); }
53 
54   // Clear all snapshot data for a given label
erase(const std::string & label)55   void erase(const std::string &label) { data_.erase(label); }
56 
57   // Return true if snapshot container is empty
empty() const58   bool empty() const { return data_.empty(); }
59 
60   // Return data reference
data()61   stringmap_t<stringmap_t<AverageData<T>>> data() { return data_; }
62 
63   // Return const data reference
data() const64   const stringmap_t<stringmap_t<AverageData<T>>> &data() const { return data_; }
65 
66  protected:
67   // Internal Storage
68   // Outer map key is the snapshot label string
69   // Inner map key is the memory value string
70   stringmap_t<stringmap_t<AverageData<T>>> data_;
71 };
72 
73 //------------------------------------------------------------------------------
74 // Implementation: AverageSnapshot class methods
75 //------------------------------------------------------------------------------
76 
77 template <typename T>
add_data(const std::string & key,const std::string & memory,const T & datum,bool variance)78 void AverageSnapshot<T>::add_data(const std::string &key,
79                                   const std::string &memory, const T &datum,
80                                   bool variance) {
81   data_[key][memory].add_data(datum, variance);
82 }
83 
84 template <typename T>
add_data(const std::string & key,const std::string & memory,T && datum,bool variance)85 void AverageSnapshot<T>::add_data(const std::string &key,
86                                   const std::string &memory, T &&datum,
87                                   bool variance) noexcept {
88   data_[key][memory].add_data(std::move(datum), variance);
89 }
90 
91 template <typename T>
combine(const AverageSnapshot<T> & other)92 void AverageSnapshot<T>::combine(const AverageSnapshot<T> &other) {
93   for (const auto &outer : other.data_) {
94     for (const auto &inner : outer.second) {
95       data_[outer.first][inner.first].combine(inner.second);
96     }
97   }
98 }
99 
100 template <typename T>
combine(AverageSnapshot<T> && other)101 void AverageSnapshot<T>::combine(AverageSnapshot<T> &&other) noexcept {
102   for (auto &outer : other.data_) {
103     for (auto &inner : outer.second) {
104       data_[outer.first][inner.first].combine(std::move(inner.second));
105     }
106   }
107   // Clear moved snapshot
108   other.clear();
109 }
110 
111 //------------------------------------------------------------------------------
112 // JSON serialization
113 //------------------------------------------------------------------------------
114 template <typename T>
to_json(json_t & js,const AverageSnapshot<T> & snapshot)115 void to_json(json_t &js, const AverageSnapshot<T> &snapshot) {
116   js = json_t::object();
117   for (const auto &outer_pair : snapshot.data()) {
118     for (const auto &inner_pair : outer_pair.second) {
119       // Store mean and variance for snapshot
120       json_t datum = inner_pair.second;
121       // Add memory key if there are classical registers
122       auto memory = inner_pair.first;
123       if (memory.empty() == false) datum["memory"] = inner_pair.first;
124       // Add to list of output
125       js[outer_pair.first].push_back(datum);
126     }
127   }
128 }
129 
130 //------------------------------------------------------------------------------
131 }  // end namespace AER
132 //------------------------------------------------------------------------------
133 #endif
134