extern crate splines; use splines::{Spline, Key, Interpolation}; use std::error::Error; use find_peaks::PeakFinder; pub fn interpolate_spline,>(x_t: Vec, y_t: Vec, step: f64) -> Result, Box> { let x: Vec = x_t.iter().map(|&x| x.into()).collect(); let y: Vec = y_t.iter().map(|&y| y.into()).collect(); if x.len() != y.len() { return Err("x and y must have the same length".into()); } // 创建样条曲线 let keys: Vec> = x.iter() .zip(y.iter()) .map(|(&x, &y)| Key::new(x, y, Interpolation::Linear)) .collect(); let spline = Spline::from_vec(keys); // 计算 x 的最大值和最小值 let &start = x.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap(); let &end = x.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap(); // 插值到间隔为 step 的点 let mut result = Vec::new(); let mut t = start; while t <= end { if let Some(value) = spline.clamped_sample(t) { result.push((t, value)); } t += step; } Ok(result) } pub fn interpolate_spline_at_points>(x_t: Vec, y_t: Vec, x_target: Vec) -> Result, Box> { let x: Vec = x_t.iter().map(|&x| x.into()).collect(); let y: Vec = y_t.iter().map(|&y| y.into()).collect(); if x.len() != y.len() { return Err("x and y must have the same length".into()); } // 创建样条曲线 let keys: Vec> = x.iter() .zip(y.iter()) .map(|(&x, &y)| Key::new(x, y, Interpolation::Linear)) .collect(); let spline = Spline::from_vec(keys); // 插值到 x_target 指定的点 let mut result = Vec::new(); for &t in x_target.iter() { if let Some(value) = spline.clamped_sample(t) { result.push(value); } } Ok(result) } pub fn find_peek(data:Vec,minheigh:f64)->Vec<(u32,f64)>{ let mut fp = PeakFinder::new(&data); fp.with_min_prominence(200.); fp.with_min_height(minheigh); let mut retvec=Vec::new(); let peaks = fp.find_peaks(); for p in peaks { // println!("{} {}", p.middle_position(), p.height.unwrap()); retvec.push((p.middle_position().try_into().unwrap(),p.height.unwrap())); } retvec } #[test] fn testinterpolate_spline() -> Result<(), Box> { // 示例数据 let x = vec![0.0,0.5, 0.569, 1.138, 1.707, 2.276, 2.845]; let y = vec![0.0, 0.4,0.5, 1.0, 0.5, 0.0, -0.5]; let step = 0.1; // 调用插值函数 let interpolated_values = interpolate_spline(x, y, step)?; // 输出结果 for (xi, yi) in interpolated_values { println!("x = {:.3}, y = {:.3}", xi, yi); } Ok(()) } #[test] fn tset_interpolate_spline_at_points() -> Result<(), Box> { let x = vec![0.0,0.5, 0.569, 1.138, 1.707, 2.276, 2.845]; let y = vec![0.0, 0.4,0.5, 1.0, 0.5, 0.0, -0.5]; let x_target = vec![0.1, 0.2, 0.3]; let result = interpolate_spline_at_points(x, y, x_target)?; for (yi) in result { println!("y = {:.3}", yi); } Ok(()) } use csv::ReaderBuilder; fn read_csv_to_vec(file_path: &str) -> Result, Box> { let mut rdr = ReaderBuilder::new().from_path(file_path)?; let mut values = Vec::new(); for result in rdr.records() { let record = result?; if let Some(value) = record.get(1) { values.push(value.parse::()?); } } Ok(values) } use nalgebra::{DMatrix, DVector}; pub fn compute_weave_coeff(x_data:Vec,y_data:Vec)->Vec{ assert_eq!(x_data.len(), y_data.len()); let n = x_data.len(); // 构建设计矩阵 X 和观测向量 y let mut x_matrix = DMatrix::zeros(n, 4); // 三阶多项式有 4 个系数 let y_vector = DVector::from_vec(y_data.clone()); for (i, &x) in x_data.iter().enumerate() { x_matrix[(i, 0)] = 1.0; // 常数项 x_matrix[(i, 1)] = x; // x x_matrix[(i, 2)] = x.powi(2); // x² x_matrix[(i, 3)] = x.powi(3); // x³ } // 使用正规方程求解最小二乘问题: (XᵀX)β = Xᵀy let xt = x_matrix.transpose(); let xtx = &xt * &x_matrix; let xty = &xt * &y_vector; // 求解方程 (XᵀX)β = Xᵀy let beta = xtx .lu() .solve(&xty) .expect("无法求解正规方程,可能是矩阵奇异"); // 输出拟合系数 println!("拟合的三阶多项式系数:"); println!("y = {:.4} + {:.4}x + {:.4}x² + {:.4}x³", beta[0], beta[1], beta[2], beta[3]); // 示例:使用拟合的多项式进行预测 let x_test = 6.0; let y_pred = beta[0] + beta[1]*x_test + beta[2]*x_test.powi(2) + beta[3]*x_test.powi(3); println!("对于 x = {:.2}, 预测的 y = {:.4}", x_test, y_pred); let mut retvec=Vec::new(); for i in 0..4{ retvec.push(beta[i]); } retvec } #[test] fn test_find_peek(){ let data = read_csv_to_vec("D:\\06Learn\\rust\\tarui\\myfirst_tauri\\src-tauri\\test0_UP.csv").unwrap(); let peaks = find_peek(data,10000.0); for p in peaks { println!("{} {}", p.0, p.1); } }