1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! Basis trait for IR and DLR representations
//!
//! This module provides a common trait for different basis representations
//! (IR basis, DLR basis, augmented basis, etc.) in imaginary-time/frequency domains.
use crate::freq::MatsubaraFreq;
use crate::kernel::KernelProperties;
use crate::traits::StatisticsType;
/// Common trait for basis representations in imaginary-time/frequency domains
///
/// This trait abstracts over different basis representations:
/// - `FiniteTempBasis`: IR (Intermediate Representation) basis
/// - `DiscreteLehmannRepresentation`: DLR basis
/// - `AugmentedBasis`: IR basis with additional functions
///
/// Each basis provides:
/// - Physical parameters (β, ωmax, Λ)
/// - Basis size and accuracy information
/// - Default sampling points for τ and Matsubara frequencies
///
/// # Type Parameters
/// * `S` - Statistics type (Fermionic or Bosonic)
pub trait Basis<S: StatisticsType> {
/// Associated kernel type
type Kernel: KernelProperties;
/// Get reference to the kernel
///
/// # Returns
/// Reference to the kernel used to construct this basis
fn kernel(&self) -> &Self::Kernel;
/// Inverse temperature β
///
/// # Returns
/// The inverse temperature in units where ℏ = kB = 1
fn beta(&self) -> f64;
/// Maximum frequency ωmax
///
/// The basis functions are designed to accurately represent
/// spectral functions with support in [-ωmax, ωmax].
///
/// # Returns
/// The maximum frequency cutoff
fn wmax(&self) -> f64;
/// Kernel parameter Λ = β × ωmax
///
/// This is the dimensionless parameter that controls the basis.
///
/// # Returns
/// The dimensionless parameter Λ
fn lambda(&self) -> f64 {
self.beta() * self.wmax()
}
/// Number of basis functions
///
/// # Returns
/// The size of the basis (number of basis functions)
fn size(&self) -> usize;
/// Accuracy of the basis
///
/// Upper bound to the relative error of representing a propagator
/// with the given number of basis functions.
///
/// # Returns
/// A number between 0 and 1 representing the accuracy
fn accuracy(&self) -> f64;
/// Significance of each basis function
///
/// Returns a vector where `σ[i]` (0 ≤ σ[i] ≤ 1) is the significance
/// level of the i-th basis function. If ε is the desired accuracy,
/// then any basis function where σ[i] < ε can be neglected.
///
/// For the IR basis: σ[i] = s[i] / s[0]
/// For the DLR basis: σ[i] = 1.0 (all poles equally significant)
///
/// # Returns
/// Vector of significance values for each basis function
fn significance(&self) -> Vec<f64>;
/// Get singular values (non-normalized)
///
/// Returns the singular values s[i] from the SVE decomposition.
/// These are the absolute values, not normalized by s[0].
///
/// # Returns
/// Vector of singular values
fn svals(&self) -> Vec<f64>;
/// Get default tau sampling points
///
/// Returns sampling points in imaginary time τ ∈ [-β/2, β/2].
/// These are chosen to provide near-optimal conditioning of the
/// sampling matrix.
///
/// # Returns
/// Vector of tau sampling points
fn default_tau_sampling_points(&self) -> Vec<f64>;
/// Get default Matsubara sampling points
///
/// Returns sampling points in Matsubara frequency space.
/// These are chosen to provide near-optimal conditioning.
///
/// # Arguments
/// * `positive_only` - If true, only return non-negative frequencies
///
/// # Returns
/// Vector of Matsubara frequency sampling points
fn default_matsubara_sampling_points(&self, positive_only: bool) -> Vec<MatsubaraFreq<S>>
where
S: 'static;
/// Evaluate basis functions at imaginary time points
///
/// Computes the value of basis functions at given τ points.
/// For IR basis: u_l(τ)
/// For DLR basis: sum over poles weighted by basis coefficients
///
/// # Arguments
/// * `tau` - Imaginary time points where τ ∈ [0, β] (or extended range for DLR)
///
/// # Returns
/// Matrix of shape [tau.len(), self.size()] where result[i, l] = u_l(τ_i)
fn evaluate_tau(&self, tau: &[f64]) -> mdarray::DTensor<f64, 2>;
/// Evaluate basis functions at Matsubara frequencies
///
/// Computes the value of basis functions at given Matsubara frequencies.
/// For IR basis: û_l(iωn)
/// For DLR basis: basis functions in Matsubara space
///
/// # Arguments
/// * `freqs` - Matsubara frequencies
///
/// # Returns
/// Matrix of shape [freqs.len(), self.size()] where result[i, l] = û_l(iωn_i)
fn evaluate_matsubara(
&self,
freqs: &[MatsubaraFreq<S>],
) -> mdarray::DTensor<num_complex::Complex<f64>, 2>
where
S: 'static;
/// Evaluate spectral basis functions at real frequencies
///
/// Computes the value of spectral basis functions at given real frequencies.
/// For IR basis: V_l(ω)
/// For DLR basis: may return identity or specific representation
///
/// # Arguments
/// * `omega` - Real frequency points in [-ωmax, ωmax]
///
/// # Returns
/// Matrix of shape [omega.len(), self.size()] where result[i, l] = V_l(ω_i)
fn evaluate_omega(&self, omega: &[f64]) -> mdarray::DTensor<f64, 2>;
/// Get default omega (real frequency) sampling points
///
/// Returns sampling points on the real-frequency axis ω ∈ [-ωmax, ωmax].
/// These are used as pole locations for the Discrete Lehmann Representation (DLR).
///
/// The sampling points are chosen as the roots/extrema of the L-th basis function
/// in the spectral domain, providing near-optimal conditioning.
///
/// # Returns
/// Vector of real-frequency sampling points in [-ωmax, ωmax]
fn default_omega_sampling_points(&self) -> Vec<f64>;
}
#[cfg(test)]
#[path = "basis_trait_tests.rs"]
mod tests;