-
Notifications
You must be signed in to change notification settings - Fork 35
Average equivalent q-vectors in explicit structure factor #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -330,6 +330,36 @@ template <std::floating_point T> class SamplingPolicy | |||||||||||
| } | ||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * @brief Average values with equivalent keys (same rounded magnitude). | ||||||||||||
| * | ||||||||||||
| * Groups (key, value) pairs by rounded key and computes the mean value for each group. | ||||||||||||
| * Used to average intensities from equivalent q-vectors with the same |q| magnitude. | ||||||||||||
| * | ||||||||||||
| * @see Equivalent to Rust's `average_duplicates` in pripps/src/explicit.rs | ||||||||||||
| */ | ||||||||||||
| template <std::floating_point T> | ||||||||||||
| std::map<T, T> averageByMagnitude(const std::vector<std::pair<T, T>>& pairs, | ||||||||||||
| T precision = T{10000}) | ||||||||||||
| { | ||||||||||||
| struct Accumulator | ||||||||||||
| { | ||||||||||||
| T sum = T{0}; | ||||||||||||
| int count = 0; | ||||||||||||
| }; | ||||||||||||
|
Comment on lines
+345
to
+349
|
||||||||||||
| std::map<T, Accumulator> bins; | ||||||||||||
| for (const auto& [key, value] : pairs) { | ||||||||||||
| const T rounded = std::round(key * precision) / precision; | ||||||||||||
| bins[rounded].sum += value; | ||||||||||||
| bins[rounded].count++; | ||||||||||||
| } | ||||||||||||
| std::map<T, T> result; | ||||||||||||
| for (const auto& [key, acc] : bins) { | ||||||||||||
| result[key] = acc.sum / static_cast<T>(acc.count); | ||||||||||||
| } | ||||||||||||
| return result; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * @brief Calculate scattering intensity using explicit q averaging. | ||||||||||||
| * | ||||||||||||
|
|
@@ -372,16 +402,22 @@ class StructureFactorPBC : private TSamplingPolicy | |||||||||||
| template <typename Tscatterers> | ||||||||||||
| void sample(const Tscatterers& scatterers, const Point& boxlength) | ||||||||||||
| { | ||||||||||||
|
||||||||||||
| { | |
| { | |
| if (p_max <= 0) { | |
| return; | |
| } |
Copilot
AI
Mar 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as in StructureFactorPBC::sample(): p_max is an int and may be negative from configuration, but it is cast to size_t to compute n and size q_intensity. A negative p_max will underflow and can trigger an enormous allocation. Add validation (e.g., reject p_max <= 0) before casting/allocating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
averageByMagnitude()duplicates the binning/rounding logic and hard-codes a defaultprecision(10000) that is meant to matchSamplingPolicy::precision. This creates a maintainability risk: if a differentTSamplingPolicyis supplied (orSamplingPolicy's binning changes), duplicates may be grouped differently thanaddSampling()bins them, producing inconsistent results. Consider factoring the rounding/binning into a shared helper/constant, or plumb the precision/binner from the sampling policy intoaverageByMagnitude()so the grouping and accumulation always use the same binning rule.