Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
positioncollapse2d.cpp
Go to the documentation of this file.
1/**
2 * @file positioncollapse2d.cpp
3 * @brief Implements the positioncollapse2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/positioncollapse2d.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
12#include "positioncollapse2d.h"
13
17
18#include <cmath>
19#include <random>
20#include <vector>
21
22namespace qpe {
23namespace {
24
25/**
26 * @brief Performs collapse with seed.
27 * @param field Field data to read or modify.
28 * @param resolution The resolution value used by the operation.
29 * @param seed The seed value used by the operation.
30 */
32 double resolution,
33 std::uint32_t seed)
34{
36 result.resolution = resolution;
37 result.normBefore = field.norm2();
38
39 if (field.empty() || !(resolution > 0.0) || !std::isfinite(resolution) ||
40 !(result.normBefore > 0.0) || !std::isfinite(result.normBefore)) {
41 return result;
42 }
43
44 // For a Gaussian position POVM, the outcome distribution is the Born
45 // density convolved with a Gaussian of standard deviation 'resolution'.
46 // Sampling x~|psi|^2 and then adding Gaussian readout noise is an exact
47 // Monte-Carlo draw from that convolution.
48 const std::vector<PositionMeasurement2DPoint> latent =
50 if (latent.empty()) {
51 return result;
52 }
53
54 std::mt19937 engine(seed ^ 0x9e3779b9u);
55 std::normal_distribution<double> noise(0.0, resolution);
56 result.outcome.x = static_cast<float>(static_cast<double>(latent.front().x) + noise(engine));
57 result.outcome.y = static_cast<float>(static_cast<double>(latent.front().y) + noise(engine));
58
59 const double invFourSigma2 = 1.0 / (4.0 * resolution * resolution);
60 for (std::size_t y = 0u; y < field.height(); ++y) {
61 const double py = GaussianPacket2D::yCoordinate(field, y);
62 const double dy = py - static_cast<double>(result.outcome.y);
63 for (std::size_t x = 0u; x < field.width(); ++x) {
64 const double px = GaussianPacket2D::xCoordinate(field, x);
65 const double dx = px - static_cast<double>(result.outcome.x);
66 const double exponent = -(dx * dx + dy * dy) * invFourSigma2;
67 const float weight = static_cast<float>(std::exp(exponent));
68 field(x, y) *= weight;
69 }
70 }
71
72 if (!field.normalize()) {
73 return result;
74 }
75
76 result.normAfter = field.norm2();
77 result.valid = result.normAfter > 0.0 && std::isfinite(result.normAfter);
78 return result;
79}
80
81} // namespace
82
84 double resolution)
85{
86 std::random_device rd;
87 std::seed_seq seedSequence{rd(), rd(), rd(), rd(),
88 static_cast<unsigned int>(field.width()),
89 static_cast<unsigned int>(field.height())};
90 std::uint32_t seed = 0u;
91 seedSequence.generate(&seed, &seed + 1);
92 return collapseWithSeed(field, resolution, seed);
93}
94
96 double resolution,
97 std::uint32_t seed)
98{
99 return collapseWithSeed(field, resolution, seed);
100}
101
102} // namespace qpe
Owning Cartesian grid of complex scalar samples.
double norm2() const noexcept
Returns the discrete integral of |psi|^2 including dx*dy.
bool empty() const noexcept
Returns whether the field contains no samples.
std::size_t height() const noexcept
Returns the number of samples along Y.
bool normalize() noexcept
Scales the field to unit discrete probability norm.
std::size_t width() const noexcept
Returns the number of samples along X.
static double yCoordinate(const ComplexField2D &field, std::size_t y) noexcept
Performs y coordinate.
static double xCoordinate(const ComplexField2D &field, std::size_t x) noexcept
Performs x coordinate.
static PositionCollapse2DResult collapse(ComplexField2D &field, double resolution)
Performs collapse.
static PositionCollapse2DResult collapseSeeded(ComplexField2D &field, double resolution, std::uint32_t seed)
Performs collapse seeded.
static std::vector< PositionMeasurement2DPoint > sampleSeeded(const ComplexField2D &field, std::size_t shots, std::uint32_t seed)
Samples seeded.
Declares the complex scalar field container representing two-dimensional wave functions.
Declares the gaussianpacket2d physics/numerical component used by QPE experiments.
PositionCollapse2DResult collapseWithSeed(ComplexField2D &field, double resolution, std::uint32_t seed)
Performs collapse with seed.
Declares the positioncollapse2d physics/numerical component used by QPE experiments.
Declares the positionmeasurement2d physics/numerical component used by QPE experiments.
Data record containing Position Collapse2D Result.
PositionMeasurement2DPoint outcome