#pragma once
// Copyright (c) 2024-2026 Tarik Moussa.
// SPDX-License-Identifier: MIT

// constants.hpp
//
// Single source of truth for mathematical constants used throughout
// conformallab++.  Include this header instead of defining π locally.
//
// All constants are in the conformallab namespace and are constexpr double.

namespace conformallab {

/// π to 30 significant digits (well beyond double precision of ~15-16 digits).
constexpr double PI     = 3.14159265358979323846264338328;

/// 2π (full turn).
constexpr double TWO_PI = 2.0 * PI;

// ── Numerical thresholds and bounds (N4/N6 audit) ──────────────────────────

/// Edge length floor for log-scale functionals (euclidean_functional, spherical_functional).
/// exp(-30.0) ≈ 3e-7: edges below this length are treated as degenerate/zero.
/// Rationale: avoids log(tiny) overflow and enforces a minimum edge scale.
constexpr double LOG_EDGE_LENGTH_FLOOR = -30.0;

/// Hyper-ideal scale factor lower bound (hyper_ideal_functional:179-181).
/// If b (scale) becomes negative (infeasible), clamp to 0.01 to keep geometry valid.
/// Rationale: ensures b > 0 maintains the Lorentzian model's causal structure.
constexpr double HYPER_IDEAL_SCALE_FLOOR = 0.01;

/// Sharpness β of the optional C¹ smooth-barrier scale floor (N3 audit).
/// Only used when the hyper-ideal clamp mode is `SmoothBarrier`; larger β
/// makes the softplus transition tighter around `HYPER_IDEAL_SCALE_FLOOR`
/// (β·floor ≈ 1, so β ≈ 100 keeps the barrier ≈ identity for b ≳ 0.05 while
/// staying C¹ across b = 0).  See `clamp_hyper_ideal_scale`.
constexpr double HYPER_IDEAL_SCALE_SHARPNESS = 100.0;

/// Domain guard for asin in spherical_l (spherical_geometry:34).
/// Clamps exp(λ/2) to slightly below 1.0 so asin stays in [−π/2, π/2].
/// Rationale: asin(x) is undefined for |x| > 1; this prevents IEEE Inf/NaN.
constexpr double ASIN_DOMAIN_GUARD = 1.0 - 1e-15;

} // namespace conformallab
