Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
gaussianpacket2d.cpp
Go to the documentation of this file.
1/**
2 * @file gaussianpacket2d.cpp
3 * @brief Implements the gaussianpacket2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/gaussianpacket2d.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 "gaussianpacket2d.h"
13
14#include <cmath>
15#include <stdexcept>
16
17namespace qpe {
18namespace {
19
20/**
21 * @brief Performs finite.
22 * @param v The v value used by the operation.
23 */
24bool finite(float v) noexcept
25{
26 return std::isfinite(static_cast<double>(v));
27}
28
29} // namespace
30
31double GaussianPacket2D::xCoordinate(const ComplexField2D &field, std::size_t x) noexcept
32{
33 if (field.width() == 0) {
34 return 0.0;
35 }
36 const double centre = 0.5 * static_cast<double>(field.width() - 1u);
37 return (static_cast<double>(x) - centre) * static_cast<double>(field.dx());
38}
39
40double GaussianPacket2D::yCoordinate(const ComplexField2D &field, std::size_t y) noexcept
41{
42 if (field.height() == 0) {
43 return 0.0;
44 }
45 const double centre = 0.5 * static_cast<double>(field.height() - 1u);
46 return (static_cast<double>(y) - centre) * static_cast<double>(field.dy());
47}
48
50 const GaussianPacket2DParams &params)
51{
52 if (field.empty()) {
53 throw std::invalid_argument("GaussianPacket2D: field must not be empty");
54 }
55
56 if (!(params.sigma > 0.0f) || !finite(params.sigma)) {
57 throw std::invalid_argument("GaussianPacket2D: sigma must be finite and positive");
58 }
59
60 if (!(params.hbar > 0.0f) || !finite(params.hbar)) {
61 throw std::invalid_argument("GaussianPacket2D: hbar must be finite and positive");
62 }
63
64 if (!finite(params.centerX) || !finite(params.centerY) ||
65 !finite(params.momentumX) || !finite(params.momentumY)) {
66 throw std::invalid_argument("GaussianPacket2D: all parameters must be finite");
67 }
68
69 const double sigma = static_cast<double>(params.sigma);
70 const double inv4Sigma2 = 1.0 / (4.0 * sigma * sigma);
71 const double invHbar = 1.0 / static_cast<double>(params.hbar);
72
73 for (std::size_t y = 0; y < field.height(); ++y) {
74 const double py = yCoordinate(field, y);
75 const double dy = py - static_cast<double>(params.centerY);
76
77 for (std::size_t x = 0; x < field.width(); ++x) {
78 const double px = xCoordinate(field, x);
79 const double dx = px - static_cast<double>(params.centerX);
80
81 const double envelope = std::exp(-(dx * dx + dy * dy) * inv4Sigma2);
82 const double phase =
83 (static_cast<double>(params.momentumX) * px +
84 static_cast<double>(params.momentumY) * py) * invHbar;
85
86 field(x, y) = ComplexField2D::Value(
87 static_cast<float>(envelope * std::cos(phase)),
88 static_cast<float>(envelope * std::sin(phase)));
89 }
90 }
91
92 if (!field.normalize()) {
93 throw std::runtime_error("GaussianPacket2D: normalization failed");
94 }
95}
96
97} // namespace qpe
Owning Cartesian grid of complex scalar samples.
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::complex< float > Value
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 void initialize(ComplexField2D &field, const GaussianPacket2DParams &params)
Initializes ialize.
Declares the gaussianpacket2d physics/numerical component used by QPE experiments.
Configuration values for Gaussian Packet2D Params.