Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
detectorscreenmeasurement2d.cpp
Go to the documentation of this file.
1/**
2 * @file detectorscreenmeasurement2d.cpp
3 * @brief Implements the detectorscreenmeasurement2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/detectorscreenmeasurement2d.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 <algorithm>
17#include <cmath>
18#include <random>
19
20namespace qpe {
21namespace {
22
23std::vector<PositionMeasurement2DPoint> sampleWithEngine(
24 const ComplexField2D &field,
26 std::size_t shots,
27 std::mt19937 &engine)
28{
29 std::vector<PositionMeasurement2DPoint> result;
30 if (field.empty() || shots == 0u || !(params.thickness > 0.0f)) {
31 return result;
32 }
33
34 const double cx = 0.5 * static_cast<double>(field.width() - 1u);
35 const double cy = 0.5 * static_cast<double>(field.height() - 1u);
36 const double dx = static_cast<double>(field.dx());
37 const double dy = static_cast<double>(field.dy());
38 const double halfThickness = 0.5 * static_cast<double>(params.thickness);
39
40 std::vector<double> weights(field.height(), 0.0);
41 double total = 0.0;
42 bool selectedAnyColumn = false;
43
44 for (std::size_t x = 0; x < field.width(); ++x) {
45 const double physicalX = (static_cast<double>(x) - cx) * dx;
46 if (std::fabs(physicalX - static_cast<double>(params.detectorX)) > halfThickness) {
47 continue;
48 }
49 selectedAnyColumn = true;
50 for (std::size_t y = 0; y < field.height(); ++y) {
51 const ComplexField2D::Value v = field(x, y);
52 const double re = static_cast<double>(v.real());
53 const double im = static_cast<double>(v.imag());
54 const double p = re * re + im * im;
55 if (std::isfinite(p) && p > 0.0) {
56 weights[y] += p;
57 total += p;
58 }
59 }
60 }
61
62 // For a strip thinner than one grid cell, use the nearest detector column.
63 if (!selectedAnyColumn) {
64 const double gridX = static_cast<double>(params.detectorX) / dx + cx;
65 long nearest = static_cast<long>(std::lround(gridX));
66 nearest = std::max<long>(0, std::min<long>(static_cast<long>(field.width()) - 1, nearest));
67 const std::size_t x = static_cast<std::size_t>(nearest);
68 for (std::size_t y = 0; y < field.height(); ++y) {
69 const ComplexField2D::Value v = field(x, y);
70 const double re = static_cast<double>(v.real());
71 const double im = static_cast<double>(v.imag());
72 const double p = re * re + im * im;
73 if (std::isfinite(p) && p > 0.0) {
74 weights[y] += p;
75 total += p;
76 }
77 }
78 }
79
80 if (!(total > 0.0) || !std::isfinite(total)) {
81 return result;
82 }
83
84 std::discrete_distribution<std::size_t> distribution(weights.begin(), weights.end());
85 result.reserve(shots);
86 for (std::size_t shot = 0; shot < shots; ++shot) {
87 const std::size_t yIndex = distribution(engine);
89 point.x = params.detectorX;
90 point.y = static_cast<float>((static_cast<double>(yIndex) - cy) * dy);
91 result.push_back(point);
92 }
93
94 return result;
95}
96
97} // namespace
98
99std::vector<PositionMeasurement2DPoint> DetectorScreenMeasurement2D::sample(
100 const ComplexField2D &field,
102 std::size_t shots)
103{
104 std::random_device rd;
105 std::seed_seq seed{rd(), rd(), rd(), rd(),
106 static_cast<unsigned int>(field.width()),
107 static_cast<unsigned int>(field.height()),
108 static_cast<unsigned int>(shots)};
109 std::mt19937 engine(seed);
110 return sampleWithEngine(field, params, shots, engine);
111}
112
113std::vector<PositionMeasurement2DPoint> DetectorScreenMeasurement2D::sampleSeeded(
114 const ComplexField2D &field,
116 std::size_t shots,
117 std::uint32_t seed)
118{
119 std::mt19937 engine(seed);
120 return sampleWithEngine(field, params, shots, engine);
121}
122
124 const std::vector<PositionMeasurement2DPoint> &hits,
125 float yMin,
126 float yMax,
127 std::size_t bins)
128{
129 std::vector<std::size_t> histogram;
130 if (!(yMax > yMin) || bins == 0u) {
131 return histogram;
132 }
133 histogram.assign(bins, 0u);
134 const double span = static_cast<double>(yMax - yMin);
135 for (std::size_t i = 0; i < hits.size(); ++i) {
136 const double u = (static_cast<double>(hits[i].y) - static_cast<double>(yMin)) / span;
137 if (u < 0.0 || u > 1.0) {
138 continue;
139 }
140 std::size_t index = static_cast<std::size_t>(u * static_cast<double>(bins));
141 if (index >= bins) {
142 index = bins - 1u;
143 }
144 ++histogram[index];
145 }
146 return histogram;
147}
148
149} // namespace qpe
Owning Cartesian grid of complex scalar 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.
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 > sample(const ComplexField2D &field, const DetectorScreenMeasurement2DParams &params, std::size_t shots)
Performs sample.
static std::vector< PositionMeasurement2DPoint > sampleSeeded(const ComplexField2D &field, const DetectorScreenMeasurement2DParams &params, std::size_t shots, std::uint32_t seed)
Samples seeded.
static std::vector< std::size_t > histogramY(const std::vector< PositionMeasurement2DPoint > &hits, float yMin, float yMax, std::size_t bins)
Performs histogram y.
Declares the complex scalar field container representing two-dimensional wave functions.
Declares the detectorscreenmeasurement2d physics/numerical component used by QPE experiments.
std::vector< PositionMeasurement2DPoint > sampleWithEngine(const ComplexField2D &field, const DetectorScreenMeasurement2DParams &params, std::size_t shots, std::mt19937 &engine)
Configuration values for Detector Screen Measurement2D Params.
Data record containing Position Measurement2D Point.