Skip to main content

sparse_ir_core/
basis_trait.rs

1//! Basis trait for IR and DLR representations
2//!
3//! This module provides a common trait for different basis representations
4//! (IR basis, DLR basis, augmented basis, etc.) in imaginary-time/frequency domains.
5
6use crate::error::Error;
7use crate::freq::MatsubaraFreq;
8use crate::traits::StatisticsType;
9
10/// Common trait for basis representations in imaginary-time/frequency domains
11///
12/// This trait abstracts over different basis representations:
13/// - `FiniteTempBasis`: IR (Intermediate Representation) basis
14/// - `DiscreteLehmannRepresentation`: DLR basis
15/// - `AugmentedBasis`: IR basis with additional functions
16///
17/// Each basis provides:
18/// - Physical parameters (β, ωmax, Λ)
19/// - Basis size and accuracy information
20/// - Default sampling points for τ and Matsubara frequencies
21///
22/// # Type Parameters
23/// * `S` - Statistics type (Fermionic or Bosonic)
24pub trait Basis<S: StatisticsType> {
25    /// Inverse temperature β
26    ///
27    /// # Returns
28    /// The inverse temperature in units where ℏ = kB = 1
29    fn beta(&self) -> f64;
30
31    /// Maximum frequency ωmax
32    ///
33    /// The basis functions are designed to accurately represent
34    /// spectral functions with support in [-ωmax, ωmax].
35    ///
36    /// # Returns
37    /// The maximum frequency cutoff
38    fn wmax(&self) -> f64;
39
40    /// Kernel parameter Λ = β × ωmax
41    ///
42    /// This is the dimensionless parameter that controls the basis.
43    ///
44    /// # Returns
45    /// The dimensionless parameter Λ
46    fn lambda(&self) -> f64 {
47        self.beta() * self.wmax()
48    }
49
50    /// Number of basis functions
51    ///
52    /// # Returns
53    /// The size of the basis (number of basis functions)
54    fn size(&self) -> usize;
55
56    /// Accuracy of the basis
57    ///
58    /// Upper bound to the relative error of representing a propagator
59    /// with the given number of basis functions.
60    ///
61    /// # Returns
62    /// A number between 0 and 1 representing the accuracy
63    fn accuracy(&self) -> f64;
64
65    /// Significance of each basis function
66    ///
67    /// Returns a vector where `σ[i]` (0 ≤ σ[i] ≤ 1) is the significance
68    /// level of the i-th basis function. If ε is the desired accuracy,
69    /// then any basis function where σ[i] < ε can be neglected.
70    ///
71    /// For the IR basis: σ[i] = s[i] / s[0]
72    /// For the DLR basis: σ[i] = 1.0 (all poles equally significant)
73    ///
74    /// # Returns
75    /// Vector of significance values for each basis function
76    fn significance(&self) -> Vec<f64>;
77
78    /// Get singular values (non-normalized)
79    ///
80    /// Returns the singular values S_l of the basis in physical units; for
81    /// `FiniteTempBasis`, S_l = sqrt(β ωmax/2) ωmax^ypower s_l with s_l those of
82    /// the SVE.
83    /// These are the absolute values, not normalized by s[0].
84    ///
85    /// # Returns
86    /// Vector of singular values
87    fn svals(&self) -> Vec<f64>;
88
89    /// Get default tau sampling points
90    ///
91    /// Returns sampling points in imaginary time τ ∈ [-β/2, β/2].
92    /// These are chosen to provide near-optimal conditioning of the
93    /// sampling matrix.
94    ///
95    /// # Returns
96    /// Vector of tau sampling points
97    ///
98    /// # Errors
99    ///
100    /// [`Error::NotSupported`] if the basis has no default tau sampling points,
101    /// e.g. an IR basis whose SVE has too few singular functions (see
102    /// `FiniteTempBasis::default_tau_sampling_points`)
103    fn default_tau_sampling_points(&self) -> Result<Vec<f64>, Error>;
104
105    /// Get default Matsubara sampling points
106    ///
107    /// Returns sampling points in Matsubara frequency space.
108    /// These are chosen to provide near-optimal conditioning.
109    ///
110    /// # Arguments
111    /// * `positive_only` - If true, only return non-negative frequencies
112    ///
113    /// # Returns
114    /// Vector of Matsubara frequency sampling points
115    ///
116    /// # Errors
117    ///
118    /// [`Error::NotSupported`] if the basis is a DLR (use the points of its IR
119    /// basis), or its basis functions have no definite parity (an SVE that is
120    /// not centrosymmetric, #183)
121    fn default_matsubara_sampling_points(
122        &self,
123        positive_only: bool,
124    ) -> Result<Vec<MatsubaraFreq<S>>, Error>
125    where
126        S: 'static;
127
128    /// Evaluate basis functions at imaginary time points
129    ///
130    /// Computes the value of basis functions at given τ points.
131    /// For IR basis: u_l(τ)
132    /// For DLR basis: the pole functions u_p(τ), one column per pole
133    ///
134    /// # Arguments
135    /// * `tau` - Imaginary time points τ ∈ [-β, β]; negative τ uses the
136    ///   (anti)periodicity of the statistics
137    ///
138    /// # Returns
139    /// Matrix of shape [tau.len(), self.size()] where result[i, l] = u_l(τ_i)
140    ///
141    /// An empty `tau` gives a `[0, size]` matrix.
142    ///
143    /// # Errors
144    ///
145    /// [`Error::OutOfDomain`] if a τ is outside [-β, β] or NaN; no value is
146    /// computed then.
147    fn evaluate_tau(&self, tau: &[f64]) -> Result<crate::Matrix<f64>, Error>;
148
149    /// Evaluate basis functions at Matsubara frequencies
150    ///
151    /// Computes the value of basis functions at given Matsubara frequencies.
152    /// For IR basis: û_l(iν)
153    /// For DLR basis: basis functions in Matsubara space
154    ///
155    /// # Arguments
156    /// * `freqs` - Matsubara frequencies
157    ///
158    /// # Returns
159    /// Matrix of shape [freqs.len(), self.size()] where result[i, l] = û_l(iν_i)
160    ///
161    /// An empty `freqs` gives a `[0, size]` matrix.
162    ///
163    /// # Errors
164    ///
165    /// Implementors may return errors. The bases of this crate
166    /// (`FiniteTempBasis` and `DiscreteLehmannRepresentation`)
167    /// never do: every `MatsubaraFreq<S>` has the parity of the statistics, so
168    /// every frequency can be evaluated.
169    fn evaluate_matsubara(
170        &self,
171        freqs: &[MatsubaraFreq<S>],
172    ) -> Result<crate::Matrix<num_complex::Complex<f64>>, Error>
173    where
174        S: 'static;
175
176    /// Evaluate spectral basis functions at real frequencies
177    ///
178    /// Computes the value of spectral basis functions at given real frequencies.
179    /// For IR basis: V_l(ω)
180    /// Not supported for the DLR basis (see Errors)
181    ///
182    /// # Arguments
183    /// * `omega` - Real frequency points in [-ωmax, ωmax]
184    ///
185    /// # Returns
186    /// Matrix of shape [omega.len(), self.size()] where result[i, l] = V_l(ω_i)
187    ///
188    /// An empty `omega` gives a `[0, size]` matrix.
189    ///
190    /// # Errors
191    ///
192    /// * [`Error::OutOfDomain`] if an ω is outside [-ωmax, ωmax] or NaN
193    /// * [`Error::NotSupported`] for the DLR basis
194    fn evaluate_omega(&self, omega: &[f64]) -> Result<crate::Matrix<f64>, Error>;
195
196    /// Get default omega (real frequency) sampling points
197    ///
198    /// Returns sampling points on the real-frequency axis ω ∈ [-ωmax, ωmax].
199    /// These are used as pole locations for the Discrete Lehmann Representation (DLR).
200    ///
201    /// The sampling points are chosen as the roots/extrema of the L-th basis function
202    /// in the spectral domain, providing near-optimal conditioning.
203    ///
204    /// # Returns
205    /// Vector of real-frequency sampling points in [-ωmax, ωmax]
206    ///
207    /// # Errors
208    ///
209    /// [`Error::NotSupported`] if the basis is an IR basis whose SVE has too
210    /// few singular functions (the DLR returns its poles)
211    fn default_omega_sampling_points(&self) -> Result<Vec<f64>, Error>;
212}