Monte Carlo Integration Library 1.0
High-performance Monte Carlo methods for numerical integration and optimization
hypercylinder.tpp
Go to the documentation of this file.
1/**
2 * @file hypercylinder.tpp
3 * @brief HyperCylinder template implementation.
4 * @details Contains the inline implementations of `HyperCylinder` methods
5 * for hypersphere-base extrusion volume and point containment testing.
6 */
7
8#include <cmath>
9#include <algorithm> // For std::pow
10#include "../geometry.hpp"
11#include "integration_domain.hpp"
12
13#ifndef M_PI
14#define M_PI 3.14159265358979323846
15#endif
16
17namespace mc::domains {
18
19/**
20 * @brief Construct a hypercylinder with given base radius and height.
21 * @tparam dim Dimensionality (must be ≥ 2).
22 * @param rad Radius of the (N-1)-dimensional hypersphere base (must be > 0).
23 * @param h Height along the last dimension (must be ≥ 0).
24 *
25 * @details A hypercylinder is an (N-1)-dimensional hypersphere of radius `rad`
26 * extruded along the last dimension by height `h`. The region is:
27 * {x ∈ ℝⁿ : x₁² + ... + x_{n-1}² ≤ r², 0 ≤ xₙ ≤ h}
28 */
29template <size_t dim>
30HyperCylinder<dim>::HyperCylinder(double rad, double h)
31 : radius(rad), height(h)
32{
33 static_assert(dim >= 2, "HyperCylinder requires at least 2 dimensions");
34}
35
36/**
37 * @brief Get the axis-aligned bounding box enclosing the hypercylinder.
38 * @tparam dim Dimensionality parameter.
39 * @return Bounds [-radius, radius] for first N-1 dimensions; [0, height] for last.
40 *
41 * @details Returns a hypercube that minimally encloses the cylinder:
42 * [-r, r]^(N-1) × [0, h]
43 */
44template <size_t dim>
45auto HyperCylinder<dim>::getBounds() const -> mc::geom::Bounds<dim> {
46 mc::geom::Bounds<dim> bounds;
47
48 // Set bounds for the hypersphere base dimensions (0 to n-2)
49 for (size_t i = 0; i < dim - 1; ++i) {
50 bounds[i] = std::make_pair(-radius, radius);
51 }
52
53 // Set bounds for the height dimension (last dimension, n-1)
54 bounds[dim - 1] = std::make_pair(0.0, height);
55
56 return bounds;
57}
58
59/**
60 * @brief Compute the volume of the bounding hypercube.
61 * @tparam dim Dimensionality parameter.
62 * @return (2*radius)^(dim-1) * height
63 *
64 * @details Computes the volume of the minimal axis-aligned bounding hypercube.
65 * This is used for normalization in Monte Carlo acceptance-rejection sampling.
66 */
67template <size_t dim>
68double HyperCylinder<dim>::getBoxVolume() const {
69 // Volume of the bounding hypercube: (2*r)^(dim-1) * height
70 return std::pow(2.0 * radius, static_cast<double>(dim - 1)) * height;
71}
72
73/**
74 * @brief Test whether a point lies inside the hypercylinder.
75 * @tparam dim Dimensionality parameter.
76 * @param point Point to test.
77 * @return true if radial distance² ≤ radius² AND 0 ≤ point[last] ≤ height.
78 *
79 * @details Two-part check:
80 * 1. Height constraint: 0 ≤ xₙ ≤ h
81 * 2. Radial constraint: x₁² + ... + x_{n-1}² ≤ r²
82 * Time complexity: O(dim).
83 */
84template <size_t dim>
85bool HyperCylinder<dim>::isInside(const mc::geom::Point<dim> &point) const {
86 // 1. Check the height constraint (last dimension)
87 double h_val = point[dim - 1];
88 if (h_val < 0.0 || h_val > height) {
89 return false;
90 }
91
92 // 2. Check the radial constraint (hypersphere base)
93 // Sum of squares of the first (n-1) coordinates
94 double radial_dist_squared = 0.0;
95 for (size_t i = 0; i < dim - 1; ++i) {
96 double coord = point[i];
97 radial_dist_squared += coord * coord;
98 }
99
100 return radial_dist_squared <= (radius * radius);
101}
102
103} // namespace mc::domains