Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
positionmeasurement2d.cpp
Go to the documentation of this file.
1/**
2 * @file positionmeasurement2d.cpp
3 * @brief Implements the positionmeasurement2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/positionmeasurement2d.cpp. This file is part of Quantum Phenomena Explorer (QPE),
7 * maintained by Officina Turini. See LICENSE_IT.txt / LICENSE.txt for the
8 * QPE freeware source-available terms and THIRD_PARTY_NOTICES.txt for
9 * third-party components.
10 */
11
13
15
16#include <cmath>
17#include <random>
18
19namespace qpe {
20namespace {
21
22std::vector<PositionMeasurement2DPoint> sampleWithEngine(
23 const ComplexField2D &field,
24 std::size_t shots,
25 std::mt19937 &engine)
26{
27 std::vector<PositionMeasurement2DPoint> result;
28 if (field.empty() || shots == 0u) {
29 return result;
30 }
31
32 std::vector<double> weights(field.size(), 0.0);
33 double total = 0.0;
34 const ComplexField2D::Value *values = field.data();
35 for (std::size_t i = 0; i < field.size(); ++i) {
36 const double re = static_cast<double>(values[i].real());
37 const double im = static_cast<double>(values[i].imag());
38 const double p = re * re + im * im;
39 if (std::isfinite(p) && p > 0.0) {
40 weights[i] = p;
41 total += p;
42 }
43 }
44
45 if (!(total > 0.0) || !std::isfinite(total)) {
46 return result;
47 }
48
49 std::discrete_distribution<std::size_t> distribution(weights.begin(), weights.end());
50 result.reserve(shots);
51
52 const double cx = 0.5 * static_cast<double>(field.width() - 1u);
53 const double cy = 0.5 * static_cast<double>(field.height() - 1u);
54 const double dx = static_cast<double>(field.dx());
55 const double dy = static_cast<double>(field.dy());
56
57 for (std::size_t shot = 0; shot < shots; ++shot) {
58 const std::size_t index = distribution(engine);
59 const std::size_t xIndex = index % field.width();
60 const std::size_t yIndex = index / field.width();
61
63 point.x = static_cast<float>((static_cast<double>(xIndex) - cx) * dx);
64 point.y = static_cast<float>((static_cast<double>(yIndex) - cy) * dy);
65 result.push_back(point);
66 }
67
68 return result;
69}
70
71} // namespace
72
73std::vector<PositionMeasurement2DPoint> PositionMeasurement2D::sample(
74 const ComplexField2D &field,
75 std::size_t shots)
76{
77 std::random_device rd;
78 std::seed_seq seed{
79 rd(), rd(), rd(), rd(),
80 static_cast<unsigned int>(field.width()),
81 static_cast<unsigned int>(field.height()),
82 static_cast<unsigned int>(shots)
83 };
84 std::mt19937 engine(seed);
85 return sampleWithEngine(field, shots, engine);
86}
87
88std::vector<PositionMeasurement2DPoint> PositionMeasurement2D::sampleSeeded(
89 const ComplexField2D &field,
90 std::size_t shots,
91 std::uint32_t seed)
92{
93 std::mt19937 engine(seed);
94 return sampleWithEngine(field, shots, engine);
95}
96
97} // namespace qpe
Owning Cartesian grid of complex scalar samples.
std::size_t size() const noexcept
Returns the total number of complex samples.
bool empty() const noexcept
Returns whether the field contains no samples.
float dx() const noexcept
Returns the X grid spacing.
std::size_t height() const noexcept
Returns the number of samples along Y.
Value * data() noexcept
Returns mutable contiguous row-major sample storage.
std::complex< float > Value
float dy() const noexcept
Returns the Y grid spacing.
std::size_t width() const noexcept
Returns the number of samples along X.
static std::vector< PositionMeasurement2DPoint > sampleSeeded(const ComplexField2D &field, std::size_t shots, std::uint32_t seed)
Samples seeded.
static std::vector< PositionMeasurement2DPoint > sample(const ComplexField2D &field, std::size_t shots)
Performs sample.
Declares the complex scalar field container representing two-dimensional wave functions.
Declares the positionmeasurement2d physics/numerical component used by QPE experiments.
Data record containing Position Measurement2D Point.