#[derive(Debug, PartialEq)]
pub enum MedianMissingMode {
IncludeNaN,
OmitNaN,
}
#[derive(Debug, PartialEq)]
pub enum MedianPaddingMode {
ZeroPad,
Truncate,
}
pub fn medianfilter_default(x: &[f64], n: usize) -> Vec<f64> {
moving_median_filter(
x,
n,
MedianPaddingMode::ZeroPad,
MedianMissingMode::IncludeNaN,
)
}
pub fn moving_median_filter(
x: &[f64],
n: usize,
padding: MedianPaddingMode,
missing: MedianMissingMode,
) -> Vec<f64> {
let len = x.len();
let mut y = vec![0.0; len];
for (i, y_value) in y.iter_mut().enumerate() {
let mut segment: Vec<f64> = vec![];
let mut segment_start: i64 = i as i64 - (n as i64 - 1) / 2;
if n.is_multiple_of(2) {
segment_start = i as i64 - n as i64 / 2;
}
for j in 0..n {
let index = segment_start + j as i64;
if index < 0 || index >= len as i64 {
match padding {
MedianPaddingMode::ZeroPad => segment.push(0.0),
MedianPaddingMode::Truncate => continue,
}
} else {
segment.push(x[index as usize]);
}
}
if missing == MedianMissingMode::OmitNaN {
segment = remove_nan(&segment);
}
if segment.iter().any(|x| x.is_nan()) {
*y_value = f64::NAN;
continue;
}
segment.sort_by(|a, b| a.partial_cmp(b).unwrap());
if segment.len() % 2 == 1 {
*y_value = segment[segment.len() / 2];
} else {
let middle = segment.len() / 2;
*y_value = (segment[middle - 1] + segment[middle]) / 2.0;
}
}
y
}
fn remove_nan(segment: &[f64]) -> Vec<f64> {
segment.iter().filter(|x| !x.is_nan()).copied().collect()
}
#[cfg(test)]
mod tests {
use crate::median_filter::*;
#[test]
fn remove_nan_test_nan_array() {
let nan_array = vec![f64::NAN; 50];
assert_eq!(50, nan_array.len());
let result = remove_nan(&nan_array);
assert_eq!(0, result.len());
}
#[test]
fn remove_nan_test_non_nan_array() {
let nan_array = vec![2.0_f64; 50];
assert_eq!(50, nan_array.len());
let result = remove_nan(&nan_array);
assert_eq!(50, result.len());
}
#[test]
fn omit_nan_test_odd_window() {
let nan_array = vec![
4.0,
8.0,
f64::NAN,
-1.0,
-2.0,
-3.0,
f64::NAN,
3.0,
4.0,
5.0,
];
let expected = vec![
6.0000, 6.0000, 3.5000, -1.5000, -2.0000, -2.5000, 0.0, 3.5000, 4.0000, 4.5000,
];
let result = moving_median_filter(
&nan_array,
3,
MedianPaddingMode::Truncate,
MedianMissingMode::OmitNaN,
);
assert_eq!(expected, result);
}
#[test]
fn omit_nan_test_even_window() {
let nan_array = vec![
4.0,
8.0,
f64::NAN,
-1.0,
-2.0,
-3.0,
f64::NAN,
3.0,
4.0,
5.0,
];
let expected = vec![
6.0000, 6.0000, 4.0000, -1.0, -2.0000, -2.0000, -2.0, 3.000, 4.0000, 4.0000,
];
let result = moving_median_filter(
&nan_array,
4,
MedianPaddingMode::Truncate,
MedianMissingMode::OmitNaN,
);
assert_eq!(expected, result);
}
#[test]
fn include_nan_test_odd_window() {
let nan_array = vec![
4.0,
8.0,
f64::NAN,
-1.0,
-2.0,
-3.0,
f64::NAN,
3.0,
4.0,
5.0,
];
let expected = vec![
6.0000,
f64::NAN,
f64::NAN,
f64::NAN,
-2.0000,
f64::NAN,
f64::NAN,
f64::NAN,
4.0000,
4.5000,
];
let result = moving_median_filter(
&nan_array,
3,
MedianPaddingMode::Truncate,
MedianMissingMode::IncludeNaN,
);
for (idx, &value) in expected.iter().enumerate() {
if value.is_nan() {
assert!(result[idx].is_nan());
continue;
}
assert_eq!(
(value * 100.0_f64).round() / 100.0,
(result[idx] * 100.0).round() / 100.0
);
}
}
#[test]
fn include_nan_test_even_window() {
let nan_array = vec![
4.0,
8.0,
f64::NAN,
-1.0,
-2.0,
-3.0,
f64::NAN,
3.0,
4.0,
5.0,
];
let expected = vec![
6.0000,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
4.0000,
];
let result = moving_median_filter(
&nan_array,
4,
MedianPaddingMode::Truncate,
MedianMissingMode::IncludeNaN,
);
for (idx, &value) in expected.iter().enumerate() {
if value.is_nan() {
assert!(result[idx].is_nan());
continue;
}
assert_eq!(
(value * 100.0_f64).round() / 100.0,
(result[idx] * 100.0).round() / 100.0
);
}
}
#[test]
fn median_test() {
let data = vec![
0.0, 0.3343, 0.1304, 0.7736, 0.5376, 0.8090, 1.0518, 0.7308, 1.2358, 0.8452, 0.9511,
1.0233, 0.5327, 0.8752, 0.3348, 0.3090, 0.2723, -0.3006, -0.0109, -0.5727, -0.5878,
-0.5820, -1.0821, -0.6920, -1.1292, -1.0000, -0.8353, -1.1675, -0.6066, -0.8759,
-0.5878, -0.2788, -0.4865, 0.1750, -0.0216, 0.3090, 0.6287, 0.3997, 1.0083, 0.7294,
0.9511, 1.1391, 0.7603, 1.2063, 0.7579, 0.8090, 0.8315, 0.2981, 0.6059, 0.0404,
-0.0000, -0.0404, -0.6059, -0.2981, -0.8315, -0.8090, -0.7579, -1.2063, -0.7603,
-1.1391, -0.9511, -0.7294, -1.0083, -0.3997, -0.6287, -0.3090, 0.0216, -0.1750, 0.4865,
0.2788, 0.5878, 0.8759, 0.6066, 1.1675, 0.8353, 1.0000, 1.1292, 0.6920, 1.0821, 0.5820,
0.5878, 0.5727, 0.0109, 0.3006, -0.2723, -0.3090, -0.3348, -0.8752, -0.5327, -1.0233,
-0.9511, -0.8452, -1.2358, -0.7308, -1.0518, -0.8090, -0.5376, -0.7736, -0.1304,
-0.3343, -0.0000,
];
let expected_outcome = vec![
0.0, 0.0652, 0.2324, 0.4359, 0.6342, 0.7522, 0.7913, 0.8271, 0.8271, 0.8602, 0.8602,
0.8602, 0.788, 0.6889, 0.4338, 0.3219, 0.2906, 0.1307, -0.1557, -0.4366, -0.5773,
-0.5849, -0.6399, -0.7636, -0.7636, -0.8556, -0.8556, -0.8556, -0.7636, -0.7209,
-0.5972, -0.5371, -0.3826, -0.1502, 0.0767, 0.242, 0.3544, 0.5142, 0.6791, 0.7449,
0.7591, 0.7847, 0.8203, 0.8203, 0.7847, 0.7847, 0.7591, 0.6819, 0.452, 0.1692, 0.0202,
-0.0202, -0.1692, -0.452, -0.6819, -0.7591, -0.7847, -0.7847, -0.8202, -0.8202,
-0.7847, -0.7591, -0.7448, -0.679, -0.5142, -0.3543, -0.242, -0.0767, 0.1502, 0.3827,
0.5372, 0.5972, 0.721, 0.7636, 0.8556, 0.8556, 0.8556, 0.7636, 0.7636, 0.6399, 0.5849,
0.5774, 0.4367, 0.1558, -0.1307, -0.2906, -0.3219, -0.4337, -0.6889, -0.788, -0.8602,
-0.8602, -0.8602, -0.8271, -0.8271, -0.7913, -0.7522, -0.6342, -0.4359, -0.2323,
-0.0652,
];
let filtered_data = medianfilter_default(&data, 10);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 100.0_f64).round() / 100.0,
(filtered_data[idx] * 100.0).round() / 100.0
);
}
}
#[test]
fn median_test2() {
let data = vec![
1.25000000000000,
0.780033002134952,
1.00703073448199,
0.921582174095752,
0.526714378827675,
0.837785252292473,
0.223525042971336,
0.325944135758592,
0.140044768123050,
-0.327587482158041,
-0.0590169943749473,
-0.684007922695452,
-0.560169741154953,
-0.693258994182052,
-1.07856092863760,
-0.701056516295154,
-1.19436894990821,
-0.920772479834533,
-0.891328912534894,
-1.10708130105976,
-0.559016994374948,
-0.886801354522425,
-0.458572546385261,
-0.290870304090940,
-0.389635563179463,
0.250000000000000,
-0.0148729340080113,
0.445378801278418,
0.613081043572731,
0.482292857334951,
1.05901699437495,
0.702572803872283,
1.04583740972237,
1.07528097702201,
0.789860452720743,
1.20105651629515,
0.674052431450127,
0.847767491369528,
0.714678238342428,
0.279499425507979,
0.559016994374948,
-0.0769210150294324,
0.0144637290644198,
-0.171435638571114,
-0.628033540158809,
-0.337785252292473,
-0.931222876015148,
-0.767073676908276,
-0.852522237294513,
-1.18454149932243,
-0.750000000000000,
-1.18454149932243,
-0.852522237294515,
-0.767073676908280,
-0.931222876015144,
-0.337785252292472,
-0.628033540158813,
-0.171435638571117,
0.0144637290644248,
-0.0769210150294367,
0.559016994374947,
0.279499425507977,
0.714678238342426,
0.847767491369531,
0.674052431450126,
1.20105651629515,
0.789860452720746,
1.07528097702200,
1.04583740972237,
0.702572803872281,
1.05901699437495,
0.482292857334956,
0.613081043572731,
0.445378801278420,
-0.0148729340080096,
0.250000000000001,
-0.389635563179459,
-0.290870304090939,
-0.458572546385256,
-0.886801354522425,
-0.559016994374947,
-1.10708130105976,
-0.891328912534896,
-0.920772479834529,
-1.19436894990822,
-0.701056516295154,
-1.07856092863760,
-0.693258994182052,
-0.560169741154952,
-0.684007922695451,
-0.0590169943749481,
-0.327587482158040,
0.140044768123049,
0.325944135758597,
0.223525042971329,
0.837785252292474,
0.526714378827674,
0.921582174095753,
1.00703073448199,
0.780033002134953,
1.25000000000000,
];
let expected_outcome = vec![
0.263357189413837,
0.653373690481313,
0.653373690481313,
0.653373690481313,
0.653373690481313,
0.653373690481313,
0.426329257293134,
0.274734589364964,
0.181784905547193,
0.0405138868740515,
-0.193302238266494,
-0.443878611656497,
-0.622088831925202,
-0.688633458438752,
-0.697157755238603,
-0.796192714415024,
-0.796192714415024,
-0.889065133528659,
-0.889065133528659,
-0.889065133528659,
-0.793928935408789,
-0.722909174448686,
-0.508794770380104,
-0.424104054782362,
-0.340252933635202,
-0.152871619049476,
0.117563532995994,
0.347689400639209,
0.463835829306684,
0.547686950453841,
0.657826923722507,
0.746216628296513,
0.746216628296513,
0.818813972045136,
0.818813972045136,
0.818813972045136,
0.752269345531585,
0.752269345531585,
0.694365334896278,
0.616534712912537,
0.419258209941463,
0.146981577286199,
-0.0312286429825063,
-0.124178326800273,
-0.254610445431793,
-0.482909396225641,
-0.689016770079405,
-0.758536838454138,
-0.809797957101394,
-0.809797957101397,
-0.852522237294514,
-0.852522237294514,
-0.809797957101397,
-0.809797957101397,
-0.758536838454140,
-0.689016770079406,
-0.482909396225642,
-0.254610445431794,
-0.124178326800277,
-0.0312286429825060,
0.146981577286201,
0.419258209941462,
0.616534712912537,
0.694365334896276,
0.752269345531586,
0.752269345531586,
0.818813972045138,
0.818813972045138,
0.818813972045138,
0.746216628296513,
0.746216628296513,
0.657826923722506,
0.547686950453844,
0.463835829306688,
0.347689400639210,
0.117563532995995,
-0.152871619049474,
-0.340252933635199,
-0.424104054782358,
-0.508794770380102,
-0.722909174448686,
-0.793928935408790,
-0.889065133528661,
-0.889065133528661,
-0.889065133528661,
-0.796192714415025,
-0.796192714415025,
-0.697157755238603,
-0.688633458438751,
-0.622088831925202,
-0.443878611656496,
-0.193302238266494,
0.0405138868740504,
0.181784905547189,
0.274734589364963,
0.426329257293135,
0.653373690481313,
0.653373690481313,
0.653373690481313,
0.653373690481313,
0.653373690481313,
];
let filtered_data = medianfilter_default(&data, 10);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
#[test]
fn median_test3() {
let data = vec![
1.25000000000000,
0.776009551905249,
1.01758948841404,
0.900193266708538,
0.537417925686131,
0.828045612778897,
0.193206150838156,
0.353826704202598,
0.0752914657989951,
-0.306030021759606,
-0.0850807879683331,
-0.734923155196478,
-0.509846506552486,
-0.790019585701491,
-1.02731546462145,
-0.727400990360479,
-1.23932936929444,
-0.825844569683800,
-0.995071683182819,
-0.999852101806367,
-0.567590750475342,
-0.903728714588556,
-0.308488889220254,
-0.393686416739931,
-0.224081829102642,
0.248899480206506,
-0.0141152000863687,
0.625728396209682,
0.483470628147915,
0.672532371088771,
1.02218704235745,
0.681508210846974,
1.20766033183436,
0.874999999999997,
0.962116208048515,
1.08600609978720,
0.601380289427557,
0.961251817540307,
0.428654487786782,
0.427310491957822,
0.367565302412047,
-0.181445198534276,
0.103167336042392,
-0.502436685244003,
-0.456587955583265,
-0.551006980694814,
-1.00054894805153,
-0.639338779536952,
-1.15600624730019,
-0.921241828741014,
-0.921241828741009,
-1.15600624730020,
-0.639338779536952,
-1.00054894805153,
-0.551006980694820,
-0.456587955583269,
-0.502436685244005,
0.103167336042391,
-0.181445198534276,
0.367565302412046,
0.427310491957825,
0.428654487786777,
0.961251817540306,
0.601380289427558,
1.08600609978720,
0.962116208048510,
0.874999999999994,
1.20766033183436,
0.681508210846975,
1.02218704235745,
0.672532371088775,
0.483470628147911,
0.625728396209682,
-0.0141152000863688,
0.248899480206507,
-0.224081829102638,
-0.393686416739931,
-0.308488889220254,
-0.903728714588555,
-0.567590750475340,
-0.999852101806364,
-0.995071683182821,
-0.825844569683801,
-1.23932936929444,
-0.727400990360479,
-1.02731546462145,
-0.790019585701486,
-0.509846506552483,
-0.734923155196479,
-0.0850807879683352,
-0.306030021759605,
0.0752914657989951,
0.353826704202600,
0.193206150838158,
0.828045612778898,
0.537417925686131,
0.900193266708532,
1.01758948841404,
0.776009551905250,
1.25000000000000,
];
let expected_outcome = vec![
0.268708962843066,
0.656713738795690,
0.656713738795690,
0.656713738795690,
0.656713738795690,
0.656713738795690,
0.445622314944365,
0.273516427520377,
0.134248808318575,
-0.00489466108466900,
-0.195555404863970,
-0.407938264156046,
-0.618623748456483,
-0.731162072778478,
-0.762471370448984,
-0.807932077692645,
-0.807932077692645,
-0.864786642136178,
-0.864786642136178,
-0.864786642136178,
-0.776622780022140,
-0.696717660079571,
-0.480638583607636,
-0.351087652980092,
-0.266285359161448,
-0.119098514594505,
0.117392140060069,
0.366185054177211,
0.554599512178799,
0.649130383649227,
0.677020290967873,
0.778254105423486,
0.778254105423486,
0.918125908770152,
0.918125908770152,
0.918125908770152,
0.778254105423486,
0.738190144713777,
0.515017388607170,
0.427982489872302,
0.397437897184935,
0.235366319227220,
-0.0391389312459419,
-0.319016577058771,
-0.479512320413634,
-0.526721832969409,
-0.595172880115883,
-0.780290304138980,
-0.780290304138981,
-0.921241828741011,
-0.921241828741011,
-0.921241828741011,
-0.780290304138981,
-0.780290304138981,
-0.595172880115886,
-0.526721832969413,
-0.479512320413637,
-0.319016577058773,
-0.0391389312459427,
0.235366319227218,
0.397437897184936,
0.427982489872301,
0.515017388607167,
0.738190144713776,
0.778254105423485,
0.918125908770150,
0.918125908770150,
0.918125908770150,
0.778254105423485,
0.778254105423485,
0.677020290967875,
0.649130383649229,
0.554599512178797,
0.366185054177209,
0.117392140060069,
-0.119098514594504,
-0.266285359161446,
-0.351087652980093,
-0.480638583607636,
-0.696717660079570,
-0.776622780022140,
-0.864786642136178,
-0.864786642136178,
-0.864786642136178,
-0.807932077692644,
-0.807932077692644,
-0.762471370448983,
-0.731162072778479,
-0.618623748456481,
-0.407938264156044,
-0.195555404863970,
-0.00489466108467005,
0.134248808318576,
0.273516427520379,
0.445622314944365,
0.656713738795690,
0.656713738795690,
0.656713738795690,
0.656713738795690,
0.656713738795690,
];
let filtered_data = medianfilter_default(&data, 10);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
#[test]
fn median_test4() {
let data = vec![
0.0,
0.331016210326103,
0.138125490594051,
0.783593709536483,
0.523386761353039,
0.846224065443774,
1.02418862578637,
0.751448227461646,
1.24732695529832,
0.800884048292368,
1.00778781550994,
0.951530439615855,
0.552105586341674,
0.868127518139074,
0.250084058068717,
0.374648170756512,
0.150133676500818,
-0.278703970468565,
-0.0342771963711963,
-0.682224965300244,
-0.496609802195486,
-0.731985563528213,
-1.02672230620607,
-0.704040279074683,
-1.22607164655960,
-0.850640356919347,
-0.979743551698061,
-1.04479219971842,
-0.583987378524191,
-0.934779623035807,
-0.368121064585069,
-0.411162804653666,
-0.296699972382703,
0.216506350946108,
-0.0599624496275750,
0.565699071733269,
0.470207678245239,
0.612070650057492,
1.01351641218304,
0.659915160558767,
1.18424292581092,
0.898634705331355,
0.942508630790831,
1.12317436155938,
0.619823465531387,
0.983157573192888,
0.489739638327251,
0.442370541813275,
0.436272303396584,
-0.143669517056834,
0.143669517056835,
-0.436272303396578,
-0.442370541813277,
-0.489739638327244,
-0.983157573192890,
-0.619823465531386,
-1.12317436155938,
-0.942508630790833,
-0.898634705331353,
-1.18424292581092,
-0.659915160558768,
-1.01351641218304,
-0.612070650057487,
-0.470207678245238,
-0.565699071733275,
0.0599624496275739,
-0.216506350946107,
0.296699972382696,
0.411162804653669,
0.368121064585067,
0.934779623035806,
0.583987378524192,
1.04479219971842,
0.979743551698064,
0.850640356919345,
1.22607164655960,
0.704040279074684,
1.02672230620607,
0.731985563528220,
0.496609802195490,
0.682224965300246,
0.0342771963711990,
0.278703970468564,
-0.150133676500818,
-0.374648170756510,
-0.250084058068714,
-0.868127518139074,
-0.552105586341676,
-0.951530439615854,
-1.00778781550995,
-0.800884048292364,
-1.24732695529832,
-0.751448227461648,
-1.02418862578638,
-0.846224065443774,
-0.523386761353040,
-0.783593709536485,
-0.138125490594055,
-0.331016210326108,
-3.18408167778312e-15,
];
let expected_outcome = vec![
0.0,
0.0690627452970254,
0.234570850460077,
0.427201485839571,
0.637417494407343,
0.767520968499065,
0.792238878914426,
0.823554056868071,
0.823554056868071,
0.857175791791424,
0.857175791791424,
0.834505783215721,
0.776166137877007,
0.676494817317021,
0.463376878549093,
0.312366114412614,
0.200108867284767,
0.0579282400648109,
-0.156490583419880,
-0.387656886332025,
-0.589417383747865,
-0.693132622187464,
-0.718012921301448,
-0.791312960223780,
-0.791312960223780,
-0.892709989977577,
-0.892709989977577,
-0.892709989977577,
-0.777340317997015,
-0.717313867721769,
-0.497575091588928,
-0.389641934619368,
-0.332410518483886,
-0.178331211005139,
0.0782719506592667,
0.343357014595674,
0.517953374989254,
0.588884860895380,
0.635992905308130,
0.779274932945061,
0.779274932945061,
0.920571668061093,
0.920571668061093,
0.920571668061093,
0.779274932945061,
0.759229085431371,
0.554781551929319,
0.466055090070263,
0.439321422604929,
0.289970910226709,
3.60822483003176e-16,
-0.289970910226706,
-0.439321422604928,
-0.466055090070261,
-0.554781551929315,
-0.759229085431370,
-0.779274932945061,
-0.920571668061093,
-0.920571668061093,
-0.920571668061093,
-0.779274932945061,
-0.779274932945061,
-0.635992905308128,
-0.588884860895381,
-0.517953374989256,
-0.343357014595672,
-0.0782719506592666,
0.178331211005135,
0.332410518483881,
0.389641934619368,
0.497575091588930,
0.717313867721768,
0.777340317997014,
0.892709989977575,
0.892709989977575,
0.892709989977575,
0.791312960223782,
0.791312960223782,
0.718012921301452,
0.693132622187465,
0.589417383747868,
0.387656886332027,
0.156490583419882,
-0.0579282400648092,
-0.200108867284765,
-0.312366114412612,
-0.463376878549093,
-0.676494817317020,
-0.776166137877006,
-0.834505783215719,
-0.857175791791424,
-0.857175791791424,
-0.823554056868069,
-0.823554056868069,
-0.792238878914424,
-0.767520968499067,
-0.637417494407344,
-0.427201485839574,
-0.234570850460081,
-0.0690627452970292,
];
let filtered_data = medianfilter_default(&data, 10);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
#[test]
fn median_test5() {
let data = vec![
0.0,
0.334327627658843,
0.130360423610890,
0.773590924052785,
0.537600792855571,
0.809016994374947,
1.05177336553914,
0.730819032054843,
1.23579085750206,
0.845168388241360,
0.951056516295153,
1.02325299311698,
0.532749113702001,
0.875188118822478,
0.334807361028596,
0.309016994374947,
0.272279546637423,
-0.300554648603102,
-0.0109257580910668,
-0.572725604638190,
-0.587785252292474,
-0.582022314348291,
-1.08209205457580,
-0.692012356814463,
-1.12923356380181,
-1.00000000000000,
-0.835340937655570,
-1.16754061496204,
-0.606563796428226,
-0.875914940494530,
-0.587785252292474,
-0.278832978491953,
-0.486454016238643,
0.174973609544476,
-0.0216130795088154,
0.309016994374946,
0.628699987174835,
0.399659860674902,
1.00827737184958,
0.729360366970746,
0.951056516295153,
1.13906101438760,
0.760262599354482,
1.20634729020242,
0.757880739392903,
0.809016994374947,
0.831493419001808,
0.298062665905210,
0.605888681758468,
0.0404350015126084,
-8.57252759403147e-16,
-0.0404350015126085,
-0.605888681758468,
-0.298062665905207,
-0.831493419001812,
-0.809016994374946,
-0.757880739392906,
-1.20634729020242,
-0.760262599354484,
-1.13906101438759,
-0.951056516295155,
-0.729360366970747,
-1.00827737184958,
-0.399659860674903,
-0.628699987174832,
-0.309016994374962,
0.0216130795088196,
-0.174973609544479,
0.486454016238641,
0.278832978491956,
0.587785252292471,
0.875914940494533,
0.606563796428227,
1.16754061496204,
0.835340937655566,
0.999999999999995,
1.12923356380181,
0.692012356814464,
1.08209205457580,
0.582022314348292,
0.587785252292472,
0.572725604638188,
0.0109257580910650,
0.300554648603100,
-0.272279546637414,
-0.309016994374944,
-0.334807361028590,
-0.875188118822477,
-0.532749113702000,
-1.02325299311698,
-0.951056516295156,
-0.845168388241361,
-1.23579085750206,
-0.730819032054845,
-1.05177336553913,
-0.809016994374953,
-0.537600792855571,
-0.773590924052786,
-0.130360423610892,
-0.334327627658844,
-3.18408167778312e-15,
];
let expected_outcome = vec![
0.0, 0.1304, 0.3343, 0.5376, 0.7308, 0.7736, 0.809, 0.8452, 0.8452, 0.8752, 0.8752,
0.8452, 0.8452, 0.5327, 0.3348, 0.309, 0.2723, -0.0109, -0.3006, -0.5727, -0.582,
-0.5878, -0.692, -0.8353, -0.8353, -0.8759, -0.8759, -0.8353, -0.8353, -0.6066,
-0.5878, -0.4865, -0.2788, -0.0216, 0.175, 0.309, 0.3997, 0.6287, 0.7294, 0.7603,
0.7603, 0.809, 0.8315, 0.809, 0.809, 0.7603, 0.7579, 0.6059, 0.2981, 0.0404, 0.0,
-0.0404, -0.2981, -0.6059, -0.7579, -0.7603, -0.809, -0.809, -0.8315, -0.809, -0.7603,
-0.7603, -0.7294, -0.6287, -0.3997, -0.309, -0.175, 0.0216, 0.2788, 0.4865, 0.5878,
0.6066, 0.8353, 0.8353, 0.8759, 0.8759, 0.8353, 0.8353, 0.692, 0.5878, 0.582, 0.5727,
0.3006, 0.0109, -0.2723, -0.309, -0.3348, -0.5327, -0.8452, -0.8452, -0.8752, -0.8752,
-0.8452, -0.8452, -0.809, -0.7736, -0.7308, -0.5376, -0.3343, -0.1304, 0.0,
];
let filtered_data = medianfilter_default(&data, 9);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
#[test]
fn median_test6() {
let data = vec![
1.25000000000000,
0.776009551905249,
1.01758948841404,
0.900193266708538,
0.537417925686131,
0.828045612778897,
0.193206150838156,
0.353826704202598,
0.0752914657989951,
-0.306030021759606,
-0.0850807879683331,
-0.734923155196478,
-0.509846506552486,
-0.790019585701491,
-1.02731546462145,
-0.727400990360479,
-1.23932936929444,
-0.825844569683800,
-0.995071683182819,
-0.999852101806367,
-0.567590750475342,
-0.903728714588556,
-0.308488889220254,
-0.393686416739931,
-0.224081829102642,
0.248899480206506,
-0.0141152000863687,
0.625728396209682,
0.483470628147915,
0.672532371088771,
1.02218704235745,
0.681508210846974,
1.20766033183436,
0.874999999999997,
0.962116208048515,
1.08600609978720,
0.601380289427557,
0.961251817540307,
0.428654487786782,
0.427310491957822,
0.367565302412047,
-0.181445198534276,
0.103167336042392,
-0.502436685244003,
-0.456587955583265,
-0.551006980694814,
-1.00054894805153,
-0.639338779536952,
-1.15600624730019,
-0.921241828741014,
-0.921241828741009,
-1.15600624730020,
-0.639338779536952,
-1.00054894805153,
-0.551006980694820,
-0.456587955583269,
-0.502436685244005,
0.103167336042391,
-0.181445198534276,
0.367565302412046,
0.427310491957825,
0.428654487786777,
0.961251817540306,
0.601380289427558,
1.08600609978720,
0.962116208048510,
0.874999999999994,
1.20766033183436,
0.681508210846975,
1.02218704235745,
0.672532371088775,
0.483470628147911,
0.625728396209682,
-0.0141152000863688,
0.248899480206507,
-0.224081829102638,
-0.393686416739931,
-0.308488889220254,
-0.903728714588555,
-0.567590750475340,
-0.999852101806364,
-0.995071683182821,
-0.825844569683801,
-1.23932936929444,
-0.727400990360479,
-1.02731546462145,
-0.790019585701486,
-0.509846506552483,
-0.734923155196479,
-0.0850807879683352,
-0.306030021759605,
0.0752914657989951,
0.353826704202600,
0.193206150838158,
0.828045612778898,
0.537417925686131,
0.900193266708532,
1.01758948841404,
0.776009551905250,
1.25000000000000,
];
let expected_outcome = vec![
0.5374, 0.776, 0.776, 0.776, 0.776, 0.5374, 0.3538, 0.1932, 0.0753, -0.0851, -0.306,
-0.5098, -0.7274, -0.7349, -0.79, -0.8258, -0.8258, -0.9037, -0.9037, -0.8258, -0.8258,
-0.5676, -0.3937, -0.3085, -0.2241, -0.0141, 0.2489, 0.4835, 0.6257, 0.6725, 0.6815,
0.875, 0.875, 0.9613, 0.9613, 0.875, 0.875, 0.6014, 0.4287, 0.4273, 0.3676, 0.1032,
-0.1814, -0.4566, -0.5024, -0.551, -0.6393, -0.9212, -0.9212, -0.9212, -0.9212,
-0.9212, -0.9212, -0.6393, -0.551, -0.5024, -0.4566, -0.1814, 0.1032, 0.3676, 0.4273,
0.4287, 0.6014, 0.875, 0.875, 0.9613, 0.9613, 0.875, 0.875, 0.6815, 0.6725, 0.6257,
0.4835, 0.2489, -0.0141, -0.2241, -0.3085, -0.3937, -0.5676, -0.8258, -0.8258, -0.9037,
-0.9037, -0.8258, -0.8258, -0.79, -0.7349, -0.7274, -0.5098, -0.306, -0.0851, 0.0753,
0.1932, 0.3538, 0.5374, 0.776, 0.776, 0.776, 0.776, 0.5374,
];
let filtered_data = medianfilter_default(&data, 9);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
#[test]
fn median_test7() {
let data = vec![
1.25000000000000,
0.780033002134952,
1.00703073448199,
0.921582174095752,
0.526714378827675,
0.837785252292473,
0.223525042971336,
0.325944135758592,
0.140044768123050,
-0.327587482158041,
-0.0590169943749473,
-0.684007922695452,
-0.560169741154953,
-0.693258994182052,
-1.07856092863760,
-0.701056516295154,
-1.19436894990821,
-0.920772479834533,
-0.891328912534894,
-1.10708130105976,
-0.559016994374948,
-0.886801354522425,
-0.458572546385261,
-0.290870304090940,
-0.389635563179463,
0.250000000000000,
-0.0148729340080113,
0.445378801278418,
0.613081043572731,
0.482292857334951,
1.05901699437495,
0.702572803872283,
1.04583740972237,
1.07528097702201,
0.789860452720743,
1.20105651629515,
0.674052431450127,
0.847767491369528,
0.714678238342428,
0.279499425507979,
0.559016994374948,
-0.0769210150294324,
0.0144637290644198,
-0.171435638571114,
-0.628033540158809,
-0.337785252292473,
-0.931222876015148,
-0.767073676908276,
-0.852522237294513,
-1.18454149932243,
-0.750000000000000,
-1.18454149932243,
-0.852522237294515,
-0.767073676908280,
-0.931222876015144,
-0.337785252292472,
-0.628033540158813,
-0.171435638571117,
0.0144637290644248,
-0.0769210150294367,
0.559016994374947,
0.279499425507977,
0.714678238342426,
0.847767491369531,
0.674052431450126,
1.20105651629515,
0.789860452720746,
1.07528097702200,
1.04583740972237,
0.702572803872281,
1.05901699437495,
0.482292857334956,
0.613081043572731,
0.445378801278420,
-0.0148729340080096,
0.250000000000001,
-0.389635563179459,
-0.290870304090939,
-0.458572546385256,
-0.886801354522425,
-0.559016994374947,
-1.10708130105976,
-0.891328912534896,
-0.920772479834529,
-1.19436894990822,
-0.701056516295154,
-1.07856092863760,
-0.693258994182052,
-0.560169741154952,
-0.684007922695451,
-0.0590169943749481,
-0.327587482158040,
0.140044768123049,
0.325944135758597,
0.223525042971329,
0.837785252292474,
0.526714378827674,
0.921582174095753,
1.00703073448199,
0.780033002134953,
1.25000000000000,
];
let expected_outcome = vec![
0.921582174095752,
0.879683713194113,
0.837785252292473,
0.808909127213713,
0.780033002134952,
0.653373690481313,
0.426329257293134,
0.274734589364964,
0.181784905547193,
0.0405138868740515,
-0.193302238266494,
-0.443878611656497,
-0.622088831925202,
-0.688633458438752,
-0.697157755238603,
-0.796192714415024,
-0.796192714415024,
-0.889065133528659,
-0.889065133528659,
-0.889065133528659,
-0.793928935408789,
-0.722909174448686,
-0.508794770380104,
-0.424104054782362,
-0.340252933635202,
-0.152871619049476,
0.117563532995994,
0.347689400639209,
0.463835829306684,
0.547686950453841,
0.657826923722507,
0.746216628296513,
0.746216628296513,
0.818813972045136,
0.818813972045136,
0.818813972045136,
0.752269345531585,
0.752269345531585,
0.694365334896278,
0.616534712912537,
0.419258209941463,
0.146981577286199,
-0.0312286429825063,
-0.124178326800273,
-0.254610445431793,
-0.482909396225641,
-0.689016770079405,
-0.758536838454138,
-0.809797957101394,
-0.809797957101397,
-0.852522237294514,
-0.852522237294514,
-0.809797957101397,
-0.809797957101397,
-0.758536838454140,
-0.689016770079406,
-0.482909396225642,
-0.254610445431794,
-0.124178326800277,
-0.0312286429825060,
0.146981577286201,
0.419258209941462,
0.616534712912537,
0.694365334896276,
0.752269345531586,
0.752269345531586,
0.818813972045138,
0.818813972045138,
0.818813972045138,
0.746216628296513,
0.746216628296513,
0.657826923722506,
0.547686950453844,
0.463835829306688,
0.347689400639210,
0.117563532995995,
-0.152871619049474,
-0.340252933635199,
-0.424104054782358,
-0.508794770380102,
-0.722909174448686,
-0.793928935408790,
-0.889065133528661,
-0.889065133528661,
-0.889065133528661,
-0.796192714415025,
-0.796192714415025,
-0.697157755238603,
-0.688633458438751,
-0.622088831925202,
-0.443878611656496,
-0.193302238266494,
0.0405138868740504,
0.181784905547189,
0.274734589364963,
0.426329257293135,
0.653373690481313,
0.780033002134953,
0.808909127213713,
0.837785252292474,
0.879683713194113,
];
let filtered_data = moving_median_filter(
&data,
10,
MedianPaddingMode::Truncate,
MedianMissingMode::IncludeNaN,
);
assert_eq!(expected_outcome.len(), filtered_data.len());
for (idx, &value) in expected_outcome.iter().enumerate() {
assert_eq!(
(value * 10000.0_f64).round() / 10000.0,
(filtered_data[idx] * 10000.0).round() / 10000.0
);
}
}
}