|
| 1 | +//----------------------------------*-C++-*----------------------------------// |
| 2 | +// Copyright 2025 UT-Battelle, LLC, and other QIR-EE developers. |
| 3 | +// See the top-level COPYRIGHT file for details. |
| 4 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 5 | +//---------------------------------------------------------------------------// |
| 6 | +//! \file qiree/ResultDistribution.cc |
| 7 | +//---------------------------------------------------------------------------// |
| 8 | +#include "ResultDistribution.hh" |
| 9 | + |
| 10 | +#include <algorithm> |
| 11 | + |
| 12 | +#include "RecordedResult.hh" |
| 13 | +#include "qiree/Assert.hh" |
| 14 | + |
| 15 | +namespace qiree |
| 16 | +{ |
| 17 | +namespace |
| 18 | +{ |
| 19 | +//---------------------------------------------------------------------------// |
| 20 | +/*! |
| 21 | + * Convert bits to a bit string key ("0" for false, "1" for true). |
| 22 | + */ |
| 23 | +std::string to_key(std::vector<bool> const& bits) |
| 24 | +{ |
| 25 | + std::string key; |
| 26 | + key.reserve(bits.size()); |
| 27 | + for (bool bit : bits) |
| 28 | + { |
| 29 | + key.push_back(bit ? '1' : '0'); |
| 30 | + } |
| 31 | + return key; |
| 32 | +} |
| 33 | + |
| 34 | +} // namespace |
| 35 | + |
| 36 | +//---------------------------------------------------------------------------// |
| 37 | +/*! |
| 38 | + * Accumulate a single shot. |
| 39 | + */ |
| 40 | +void ResultDistribution::accumulate(RecordedResult const& result) |
| 41 | +{ |
| 42 | + auto const& bits = result.bits(); |
| 43 | + |
| 44 | + if (QIREE_UNLIKELY(key_length_ == 0)) |
| 45 | + { |
| 46 | + // This is the first result: store the key length |
| 47 | + key_length_ = bits.size(); |
| 48 | + } |
| 49 | + else |
| 50 | + { |
| 51 | + QIREE_VALIDATE(bits.size() == key_length_, |
| 52 | + << "RecordedResult bit length " << bits.size() |
| 53 | + << " does not match distribution key length " |
| 54 | + << key_length_); |
| 55 | + } |
| 56 | + |
| 57 | + ++distribution_[to_key(bits)]; |
| 58 | +} |
| 59 | + |
| 60 | +//---------------------------------------------------------------------------// |
| 61 | +/*! |
| 62 | + * Access the number of shots that resulted in this bit string. |
| 63 | + */ |
| 64 | +std::size_t ResultDistribution::count(std::string const& key) const |
| 65 | +{ |
| 66 | + QIREE_VALIDATE(key.length() == key_length_, |
| 67 | + << "invalid key length: expected " << key_length_ |
| 68 | + << " but got " << key.length()); |
| 69 | + QIREE_VALIDATE(std::all_of(key.begin(), |
| 70 | + key.end(), |
| 71 | + [](char c) { return c == '0' || c == '1'; }), |
| 72 | + << "invalid key: expected only '0' or '1'"); |
| 73 | + |
| 74 | + auto it = distribution_.find(key); |
| 75 | + return (it != distribution_.end()) ? it->second : 0; |
| 76 | +} |
| 77 | + |
| 78 | +//---------------------------------------------------------------------------// |
| 79 | +/*! |
| 80 | + * Build a JSON string of the distribution. |
| 81 | + */ |
| 82 | +std::string ResultDistribution::to_json() const |
| 83 | +{ |
| 84 | + std::ostringstream oss; |
| 85 | + oss << "{"; |
| 86 | + bool first = true; |
| 87 | + for (auto const& kv : distribution_) |
| 88 | + { |
| 89 | + if (!first) |
| 90 | + oss << ","; |
| 91 | + first = false; |
| 92 | + oss << "\"" << kv.first << "\":" << kv.second; |
| 93 | + } |
| 94 | + oss << "}"; |
| 95 | + return oss.str(); |
| 96 | +} |
| 97 | + |
| 98 | +//---------------------------------------------------------------------------// |
| 99 | +} // namespace qiree |
0 commit comments