Skip to main content

complex_bessel/
types.rs

1//! Core types for Bessel and Airy function computation.
2
3#[cfg(feature = "std")]
4use alloc::vec::Vec;
5use core::fmt;
6
7use num_complex::Complex;
8
9use crate::machine::BesselFloat;
10
11/// Status of the computation result.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum Accuracy {
14    /// No significant precision loss detected during computation.
15    Normal,
16    /// Result computed but may have lost more than half of significant digits.
17    ///
18    /// Triggered when:
19    /// - Bessel functions: |z| or |ν| exceeds ~32767 (f64)
20    /// - Airy functions: |z| exceeds ~1024 (f64)
21    Reduced,
22}
23
24/// Result of an Airy function computation, returned by `_raw` functions
25/// (e.g., [`airy_raw`](crate::airy_raw)).
26///
27/// Simplified convenience functions (`airy`, `biry`, …) do not expose
28/// this type; they return only the computed value and discard the status.
29#[derive(Debug, Clone, Copy, PartialEq)]
30pub struct AiryResult<T: BesselFloat> {
31    /// Computed function value.
32    pub value: Complex<T>,
33    /// Accuracy of the computation result.
34    ///
35    /// See [`Accuracy`] for possible values and their meaning.
36    pub status: Accuracy,
37}
38
39/// Result of a sequence computation into a caller-provided slice, returned by
40/// `_seq_into` functions (e.g., [`besselk_seq_into`](crate::besselk_seq_into)).
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42pub struct SeqInfo {
43    /// Number of components set to zero due to underflow.
44    pub underflow_count: usize,
45    /// Accuracy of the computation result.
46    ///
47    /// See [`Accuracy`] for possible values and their meaning.
48    pub status: Accuracy,
49}
50
51/// Result of a sequence computation, returned by `_seq` functions
52/// (e.g., [`besselk_seq`](crate::besselk_seq)).
53///
54/// Single-value convenience functions (`besselj`, `besselk`, …) do not expose
55/// this type; they return only the computed value and discard the status.
56#[cfg(feature = "std")]
57#[derive(Debug, Clone, PartialEq)]
58pub struct BesselResult<T: BesselFloat> {
59    /// Computed function values for orders ν, ν+1, ..., ν+n-1.
60    pub values: Vec<Complex<T>>,
61    /// Number of components set to zero due to underflow.
62    pub underflow_count: usize,
63    /// Accuracy of the computation result.
64    ///
65    /// See [`Accuracy`] for possible values and their meaning.
66    pub status: Accuracy,
67}
68
69/// Scaling option for Bessel and Airy function computation.
70///
71/// When [`Exponential`](Scaling::Exponential) is selected, the result is
72/// multiplied by an exponential factor to prevent overflow or underflow.
73/// The factor depends on the function type:
74/// - J, Y: exp(−|Im(z)|)
75/// - I: exp(−|Re(z)|)
76/// - K: exp(z)
77/// - H<sup>(1)</sup>: exp(−iz)
78/// - H<sup>(2)</sup>: exp(iz)
79/// - Ai, Ai′: exp(ζ)
80/// - Bi, Bi′: exp(−|Re(ζ)|)
81///
82/// where ζ = (2/3) · z · √z.
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
84pub enum Scaling {
85    /// No scaling applied.
86    Unscaled,
87    /// Exponential scaling to prevent overflow/underflow.
88    Exponential,
89}
90
91/// Kind of Hankel function.
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub(crate) enum HankelKind {
94    /// H^(1), Hankel function of the first kind.
95    First,
96    /// H^(2), Hankel function of the second kind.
97    Second,
98}
99
100/// Selects I or K function path in uniform asymptotic expansion.
101///
102/// Controls the prefactor (1/sqrt(2π) vs sqrt(π/2)) and whether the
103/// asymptotic sum uses straight or alternating signs.
104#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub(crate) enum IkFlag {
106    /// I function (Fortran ikflg=1): straight sum, sqrt(1/2π) prefactor.
107    I,
108    /// K function (Fortran ikflg=2): alternating sum, sqrt(π/2) prefactor.
109    K,
110}
111
112/// Controls whether the full asymptotic sum is computed or only phi/zeta.
113///
114/// When only the leading-order overflow/underflow test is needed (e.g. in
115/// ZUOIK), the expensive sum computation can be skipped.
116#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117pub(crate) enum SumOption {
118    /// Compute all parameters including the asymptotic sum (Fortran ipmtr=0).
119    Full,
120    /// Compute phi/zeta only, skip the sum (Fortran ipmtr=1, for overflow pre-check).
121    SkipSum,
122}
123
124/// Selects Airy function value or its derivative.
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub(crate) enum AiryDerivative {
127    /// Ai(z) or Bi(z).
128    Value,
129    /// Ai'(z) or Bi'(z).
130    Derivative,
131}
132
133/// Unrecoverable error during Bessel or Airy function computation.
134///
135/// Returned as the `Err` variant of all public functions. For computations
136/// that succeed but with reduced accuracy, see [`Accuracy`].
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
138pub enum Error {
139    /// Invalid input (e.g., non-finite z or ν, z=0 for K, H, Y (except at
140    /// negative half-integer orders), and J, I of negative non-integer order,
141    /// n < 1 in sequence functions).
142    InvalidInput,
143    /// Overflow: |z| or |ν| too large, or |z| too small.
144    Overflow,
145    /// |z| or |ν| too large for meaningful computation.
146    TotalPrecisionLoss,
147    /// Algorithm did not meet termination criteria.
148    ConvergenceFailure,
149}
150
151impl fmt::Display for Error {
152    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153        match self {
154            Error::InvalidInput => {
155                write!(f, "invalid input: check z and nu constraints")
156            }
157            Error::Overflow => {
158                write!(f, "overflow: result magnitude exceeds representable range")
159            }
160            Error::TotalPrecisionLoss => {
161                write!(f, "total precision loss: no significant digits remain")
162            }
163            Error::ConvergenceFailure => {
164                write!(
165                    f,
166                    "convergence failure: algorithm did not meet termination criteria"
167                )
168            }
169        }
170    }
171}
172
173impl core::error::Error for Error {}