Crates.io | scientific-cal |
lib.rs | scientific-cal |
version | 0.2.0 |
created_at | 2025-07-30 08:16:31.428083+00 |
updated_at | 2025-08-06 05:18:37.831749+00 |
description | scientific cal |
homepage | |
repository | https://gitee.com/bruchen/scientific-cal.git |
max_upload_size | |
id | 1773244 |
size | 120,421 |
模块类型 | 功能 | 状态 |
---|---|---|
数字滤波器 | Butterworth(低通 / 高通) | ✅ 已完成 |
Bessel(低通 / 高通) | ✅ 已完成 | |
Chebyshev I(低通 / 高通) | ✅ 已完成 | |
Chebyshev II(低通 / 高通) | ✅ 已完成 | |
Gaussian(低通) | ✅ 已完成 | |
带通 / 带阻支持 | 🚧 规划中 | |
平滑算法 | 中值滤波(Median filter) | ✅ 已完成 |
SMA(Simple Moving Average) | ✅ 已完成 | |
EMA(Exponential Moving Average) | ✅ 已完成 | |
RMA(Running Moving Average) | ✅ 已完成 | |
频域分析 | FFT / IFFT | ✅ 已完成 |
RFFT / IRFFT | 🚧 待实现 | |
Hilbert 变换 | 🚧 规划中 | |
模态分解 | EMD(经验模态分解) | 🚧 规划中 |
EEMD(集合经验模态分解) | 🚧 规划中 | |
CEEMD(完全集合 EMD) | 🚧 规划中 | |
实用函数 | 极值点检测(find_peaks) | 🚧 规划中 |
样条插值器(Spline interpolation) | 🚧 规划中 |
当前所有滤波器仅实现了低通 / 高通功能,带通与带阻支持将于后续版本添加。
use std::{f32::consts::PI, time::Instant};
// use scientific_cal::{bessel, butter_worth, FilterBand, FilterSelect, Sosfit};
use scientific_cal::{filters::{filter_factory, BesselCriterion, FilterBand, FilterType}, ScientificError};
#[test]
fn bessel_filter_test() -> Result<(), ScientificError>{
// 参数输入
let order = 4;
let fs = 1000.0;
let cutoff = 5.0;
// 仿真数据
let dt = 1.0 / fs as f32;
let mut raw_data: Vec<f32> = (0..fs as i32)
.map(|i| {
let t = i as f32 * dt;
(2.0 * PI * 2.0 * t).sin() + 0.5 * (2.0 * PI * 20.0 * t).sin()
})
.collect();
// 定义低通滤波器
let mut start = Instant::now();
let ftype = FilterType::Bessel {
order: order,
cutoff: vec![cutoff],
band: FilterBand::LowPass,
analog: false,
criterion: BesselCriterion::Delay,
fs: Some(fs),
};
let filter = filter_factory::<f32>().create(ftype)?;
println!("滤波初始化参数耗时: {:?}", start.elapsed());
start = Instant::now();
// 开始计算
println!("滤波前:{:?}", &raw_data[0..10]);
let _ = filter.apply_inplase(&mut raw_data)?;
println!("滤波运行耗时: {:?}", start.elapsed());
println!("滤波后:{:?}", &raw_data[0..10]);
Ok(())
}
use std::{f32::consts::PI, time::Instant};
use scientific_cal::{smooth::{sma, ema, rma, sma_inplase,}, ScientificError};
#[test]
fn move_ema_filter_test() -> Result<(), ScientificError>{
// 参数输入
let window_size = 5;
let fs = 100000;
// 仿真数据
let dt = 1.0 / fs as f32;
let mut raw_data: Vec<f32> = (0..fs as i32)
.map(|i| {
let t = i as f32 * dt;
(2.0 * PI * 2.0 * t).sin() + 0.5 * (2.0 * PI * 20.0 * t).sin()
})
.collect();
// 开始计算
let start = Instant::now();
let output = sma(&raw_data, window_size)?; // ema rma用法一样
// sma_inplase(&mut raw_data, window_size)?; // ema rma 没有实现 inplase
println!("滤波运行耗时: {:?}", start.elapsed());
println!("{:?}", &output[0..10]);
Ok(())
}
use std::{f32::consts::PI, time::Instant};
use scientific_cal::{spectrum::{fft, ifft}, ScientificError};
#[test]
fn fft_test() -> Result<(), ScientificError>{
// 参数输入
let n = 1024;
// 仿真数据
let raw_data: Vec<f32> = (0..n as i64)
.map(|i| {
(2.0 * PI * i as f32 / n as f32).sin()
})
.collect();
// 开始计算
let start = Instant::now();
let mut fft_result = fft(&raw_data)?;
println!("fft_result: {:?}", &fft_result[0..10]);
// 幅值需要除以 N
let n = raw_data.len();
for f in fft_result.iter_mut(){
*f = *f / (n as f32)
}
// 可以自定义滤波
// 略
// 反fft
let ifft_result = ifft(&mut fft_result)?;
println!("fft运行耗时: {:?}", start.elapsed());
println!("ifft_result: {:?}", &ifft_result[0..10]);
Ok(())
}
Add this to your Cargo.toml
:
cargo add scientific-cal