scirs2_fft/sparse_fft/config.rs
1//! Configuration types and utilities for Sparse FFT algorithms
2//!
3//! This module contains the configuration structures, enums, and utility functions
4//! used to configure and control sparse FFT computations.
5
6use num_complex::Complex64;
7use std::fmt::Debug;
8
9/// Helper function to extract complex values from various types (for doctests)
10#[allow(dead_code)]
11pub fn try_as_complex<T: 'static + Copy>(val: T) -> Option<Complex64> {
12 use std::any::Any;
13
14 // Try to use runtime type checking with Any for complex types
15 if let Some(complex) = (&val as &dyn Any).downcast_ref::<Complex64>() {
16 return Some(*complex);
17 }
18
19 // Try to handle f32 complex numbers
20 if let Some(complex32) = (&val as &dyn Any).downcast_ref::<num_complex::Complex<f32>>() {
21 return Some(Complex64::new(complex32.re as f64, complex32.im as f64));
22 }
23
24 None
25}
26
27/// Sparsity estimation method
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum SparsityEstimationMethod {
30 /// Manual estimation (user provides the sparsity)
31 Manual,
32 /// Automatic estimation based on thresholding
33 Threshold,
34 /// Adaptive estimation based on signal properties
35 Adaptive,
36 /// Frequency domain pruning for high accuracy estimation
37 FrequencyPruning,
38 /// Spectral flatness measure for noise vs signal discrimination
39 SpectralFlatness,
40}
41
42/// Sparse FFT algorithm variant
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum SparseFFTAlgorithm {
45 /// Sublinear Sparse FFT
46 Sublinear,
47 /// Compressed Sensing-based Sparse FFT
48 CompressedSensing,
49 /// Iterative Method for Sparse FFT
50 Iterative,
51 /// Deterministic Sparse FFT
52 Deterministic,
53 /// Frequency-domain pruning approach
54 FrequencyPruning,
55 /// Advanced pruning using spectral flatness measure
56 SpectralFlatness,
57}
58
59/// Window function to apply before FFT
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum WindowFunction {
62 /// No windowing (rectangular window)
63 None,
64 /// Hann window (reduces spectral leakage)
65 Hann,
66 /// Hamming window (good for speech)
67 Hamming,
68 /// Blackman window (excellent sidelobe suppression)
69 Blackman,
70 /// Flat top window (best amplitude accuracy)
71 FlatTop,
72 /// Kaiser window with adjustable parameter
73 Kaiser,
74}
75
76/// Sparse FFT configuration
77#[derive(Debug, Clone)]
78pub struct SparseFFTConfig {
79 /// The sparsity estimation method
80 pub estimation_method: SparsityEstimationMethod,
81 /// Expected sparsity (k) - number of significant frequency components
82 pub sparsity: usize,
83 /// Algorithm variant to use
84 pub algorithm: SparseFFTAlgorithm,
85 /// Threshold for frequency coefficient significance (when using threshold method)
86 pub threshold: f64,
87 /// Number of iterations for iterative methods
88 pub iterations: usize,
89 /// Random seed for probabilistic algorithms
90 pub seed: Option<u64>,
91 /// Maximum signal size to process (to prevent test timeouts)
92 pub max_signal_size: usize,
93 /// Adaptivity parameter (controls how aggressive adaptivity is)
94 pub adaptivity_factor: f64,
95 /// Pruning parameter (controls sensitivity of frequency pruning)
96 pub pruning_sensitivity: f64,
97 /// Spectral flatness threshold (0-1, lower values = more selective)
98 pub flatness_threshold: f64,
99 /// Analysis window size for spectral flatness calculations
100 pub window_size: usize,
101 /// Window function to apply before FFT
102 pub window_function: WindowFunction,
103 /// Kaiser window beta parameter (when using Kaiser window)
104 pub kaiser_beta: f64,
105}
106
107impl Default for SparseFFTConfig {
108 fn default() -> Self {
109 Self {
110 estimation_method: SparsityEstimationMethod::Threshold,
111 sparsity: 10,
112 algorithm: SparseFFTAlgorithm::Sublinear,
113 threshold: 0.01,
114 iterations: 3,
115 seed: None,
116 max_signal_size: 1024, // Default max size to avoid test timeouts
117 adaptivity_factor: 0.25,
118 pruning_sensitivity: 0.05,
119 flatness_threshold: 0.3,
120 window_size: 16,
121 window_function: WindowFunction::None,
122 kaiser_beta: 14.0, // Default beta for Kaiser window
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_default_config() {
133 let config = SparseFFTConfig::default();
134 assert_eq!(config.sparsity, 10);
135 assert_eq!(config.threshold, 0.01);
136 assert_eq!(config.max_signal_size, 1024);
137 }
138
139 #[test]
140 fn test_try_as_complex() {
141 let val = Complex64::new(1.0, 2.0);
142 assert_eq!(try_as_complex(val), Some(val));
143
144 let val32 = num_complex::Complex::new(1.0f32, 2.0f32);
145 assert_eq!(try_as_complex(val32), Some(Complex64::new(1.0, 2.0)));
146 }
147}