flaw 0.6.1

Embedded signal filtering, no-std and no-alloc compatible.
Documentation
//! Butterworth filters: pre-calculated Second Order Sections coefficients for order 4 lowpass filters.
//! This file is autogenerated.
use crate::sos::SisoSosFilter;
use core::ops::Neg;
use num_traits::{FromPrimitive, MulAdd, Num, ToPrimitive};

pub const NUM_SECTIONS: usize = 2;
const NUM_INTERP_POINTS: usize = 100;
pub const MIN_CUTOFF_RATIO_F32: f64 = 0.005;
pub const MAX_CUTOFF_RATIO_F32: f64 = 0.4;
pub const MIN_CUTOFF_RATIO_F64: f64 = 0.0005;
pub const MAX_CUTOFF_RATIO_F64: f64 = 0.4;

// [dimensionless] Log base-10 of cutoff ratios, to improve float precision during interpolation
#[rustfmt::skip]
static LOG10_CUTOFF_RATIOS: [f64; NUM_INTERP_POINTS] = [-4.0, -3.963615555643152, -3.9272311112863036, -3.8908466669294555, -3.8544622225726077, -3.8180777782157596, -3.7816933338589114, -3.745308889502063, -3.708924445145215, -3.672540000788367, -3.636155556431519, -3.599771112074671, -3.5633866677178228, -3.5270022233609746, -3.4906177790041264, -3.454233334647278, -3.41784889029043, -3.3814644459335823, -3.345080001576734, -3.308695557219886, -3.2723111128630378, -3.2359266685061896, -3.199542224149342, -3.1631577797924937, -3.1267733354356455, -3.0903888910787973, -3.054004446721949, -3.017620002365101, -2.981235558008253, -2.9448511136514046, -2.9084666692945564, -2.8720822249377087, -2.8356977805808605, -2.7993133362240123, -2.7629288918671646, -2.7265444475103164, -2.6901600031534683, -2.65377555879662, -2.617391114439772, -2.5810066700829237, -2.5446222257260755, -2.5082377813692274, -2.471853337012379, -2.435468892655531, -2.3990844482986833, -2.362700003941835, -2.326315559584987, -2.289931115228139, -2.253546670871291, -2.217162226514443, -2.1807777821575947, -2.1443933378007465, -2.1080088934438983, -2.07162444908705, -2.035240004730202, -1.9988555603733542, -1.962471116016506, -1.9260866716596579, -1.8897022273028097, -1.8533177829459615, -1.8169333385891133, -1.7805488942322656, -1.7441644498754174, -1.7077800055185692, -1.671395561161721, -1.6350111168048729, -1.5986266724480247, -1.5622422280911765, -1.5258577837343288, -1.4894733393774806, -1.4530888950206324, -1.4167044506637843, -1.380320006306936, -1.343935561950088, -1.3075511175932402, -1.271166673236392, -1.2347822288795438, -1.1983977845226956, -1.1620133401658475, -1.1256288958089993, -1.089244451452151, -1.0528600070953034, -1.0164755627384552, -0.980091118381607, -0.9437066740247588, -0.9073222296679107, -0.8709377853110625, -0.8345533409542147, -0.7981688965973666, -0.7617844522405184, -0.7254000078836702, -0.689015563526822, -0.6526311191699739, -0.6162466748131261, -0.5798622304562779, -0.5434777860994298, -0.5070933417425816, -0.4707088973857334, -0.4343244530288852, -0.3979400086720376];

#[rustfmt::skip]
static SOS_TABLES: [[[f64; NUM_INTERP_POINTS]; 5]; NUM_SECTIONS] = [    [
        [9.732916985803468e-15, 1.360660103371991e-14, 1.9021885432640173e-14, 2.659221504122345e-14, 3.717510894180601e-14, 5.1969254653792084e-14, 7.265021830356645e-14, 1.0156012441892176e-13, 1.4197276126578564e-13, 1.9846409398466525e-13, 2.774300805363836e-13, 3.8781032864984714e-13, 5.420993825175367e-13, 7.577599068156705e-13, 1.0591974021087391e-12, 1.480519448534309e-12, 2.069390964993145e-12, 2.892420541731133e-12, 4.042685444142945e-12, 5.650243773366653e-12, 7.896818537751913e-12, 1.1036307742174598e-11, 1.5423429614525036e-11, 2.1553726055994697e-11, 3.011942248045726e-11, 4.2087420741244583e-11, 5.880818211036204e-11, 8.216771538387709e-11, 1.147997054894844e-10, 1.603815352940665e-10, 2.240473115528605e-10, 3.1296403935229466e-10, 4.3713523517553623e-10, 6.105215229466906e-10, 8.52602890772976e-10, 1.1905561420504021e-09, 1.662288981010593e-09, 2.3206665097667656e-09, 3.2393968959134933e-09, 4.521224721498587e-09, 6.309332558781059e-09, 8.803200564079052e-09, 1.2280657457338146e-08, 1.7128525264058264e-08, 2.3885184894781535e-08, 3.329966647302377e-08, 4.641362948239142e-08, 6.467502413763038e-08, 9.009556384309048e-08, 1.2546872568777832e-07, 1.7467128911540467e-07, 2.430800425864799e-07, 3.3814707322843215e-07, 4.701931364465552e-07, 6.535005016880049e-07, 9.078164232026752e-07, 1.2604187070233036e-06, 1.7489493456900177e-06, 2.4252956412356184e-06, 3.36089691063394e-06, 4.6539869768874746e-06, 6.439458870011638e-06, 8.902272288078673e-06, 1.2295634090005293e-05, 1.696558992387263e-05, 2.3384199452644937e-05, 3.219416406447425e-05, 4.4268678480022345e-05, 6.079144030879221e-05, 8.336323995771415e-05, 0.00011414344625718829, 0.00015603709484323703, 0.00021294128829226007, 0.0002900683613606186, 0.00039436790880491144, 0.0005350755076954225, 0.0007244230284117436, 0.0009785541272720438, 0.001318699270333886, 0.0017726780564427257, 0.0023768135906518137, 0.0031783655947841905, 0.004238618001903086, 0.005636796391497631, 0.0074750462009749285, 0.00988478277324189, 0.013034842559373401, 0.017142042795247007, 0.02248502930216196, 0.029422714730332523, 0.03841927468618437, 0.05007873129396481, 0.06519387819817665, 0.08481715553524309, 0.11036591621066028, 0.143782922271076, 0.18778794020747866, 0.24628412498154922, 0.3250363950839906, 0.43284664499029174],
        [1.9465833971606937e-14, 2.721320206743982e-14, 3.8043770865280345e-14, 5.31844300824469e-14, 7.435021788361202e-14, 1.0393850930758417e-13, 1.453004366071329e-13, 2.0312024883784352e-13, 2.839455225315713e-13, 3.969281879693305e-13, 5.548601610727672e-13, 7.756206572996943e-13, 1.0841987650350734e-12, 1.515519813631341e-12, 2.1183948042174783e-12, 2.961038897068618e-12, 4.13878192998629e-12, 5.784841083462266e-12, 8.08537088828589e-12, 1.1300487546733306e-11, 1.5793637075503825e-11, 2.2072615484349195e-11, 3.084685922905007e-11, 4.3107452111989395e-11, 6.023884496091452e-11, 8.417484148248917e-11, 1.1761636422072407e-10, 1.6433543076775418e-10, 2.295994109789688e-10, 3.20763070588133e-10, 4.48094623105721e-10, 6.259280787045893e-10, 8.742704703510725e-10, 1.2210430458933813e-09, 1.705205781545952e-09, 2.3811122841008042e-09, 3.324577962021186e-09, 4.641333019533531e-09, 6.478793791826987e-09, 9.042449442997174e-09, 1.2618665117562118e-08, 1.7606401128158104e-08, 2.4561314914676292e-08, 3.425705052811653e-08, 4.777036978956307e-08, 6.659933294604754e-08, 9.282725896478285e-08, 1.2935004827526077e-07, 1.8019112768618095e-07, 2.5093745137555663e-07, 3.4934257823080934e-07, 4.861600851729598e-07, 6.762941464568643e-07, 9.403862728931104e-07, 1.3070010033760099e-06, 1.8156328464053503e-06, 2.520837414046607e-06, 3.4978986913800353e-06, 4.850591282471237e-06, 6.72179382126788e-06, 9.307973953774949e-06, 1.2878917740023276e-05, 1.7804544576157346e-05, 2.4591268180010587e-05, 3.393117984774526e-05, 4.676839890528987e-05, 6.43883281289485e-05, 8.853735696004469e-05, 0.00012158288061758442, 0.0001667264799154283, 0.00022828689251437658, 0.00031207418968647407, 0.00042588257658452013, 0.0005801367227212372, 0.0007887358176098229, 0.001070151015390845, 0.0014488460568234873, 0.0019571082545440876, 0.002637398540667772, 0.0035453561128854514, 0.004753627181303627, 0.006356731189568381, 0.008477236003806171, 0.011273592782995261, 0.014950092401949857, 0.01976956554648378, 0.026069685118746803, 0.034284085590494014, 0.04497005860432392, 0.058845429460665045, 0.07683854937236874, 0.10015746258792962, 0.1303877563963533, 0.16963431107048618, 0.22073183242132055, 0.287565844542152, 0.3755758804149573, 0.49256824996309845, 0.6500727901679813, 0.8656932899805835],
        [9.732916985803468e-15, 1.360660103371991e-14, 1.9021885432640173e-14, 2.659221504122345e-14, 3.717510894180601e-14, 5.1969254653792084e-14, 7.265021830356645e-14, 1.0156012441892176e-13, 1.4197276126578564e-13, 1.9846409398466525e-13, 2.774300805363836e-13, 3.8781032864984714e-13, 5.420993825175367e-13, 7.577599068156705e-13, 1.0591974021087391e-12, 1.480519448534309e-12, 2.069390964993145e-12, 2.892420541731133e-12, 4.042685444142945e-12, 5.650243773366653e-12, 7.896818537751913e-12, 1.1036307742174598e-11, 1.5423429614525036e-11, 2.1553726055994697e-11, 3.011942248045726e-11, 4.2087420741244583e-11, 5.880818211036204e-11, 8.216771538387709e-11, 1.147997054894844e-10, 1.603815352940665e-10, 2.240473115528605e-10, 3.1296403935229466e-10, 4.3713523517553623e-10, 6.105215229466906e-10, 8.52602890772976e-10, 1.1905561420504021e-09, 1.662288981010593e-09, 2.3206665097667656e-09, 3.2393968959134933e-09, 4.521224721498587e-09, 6.309332558781059e-09, 8.803200564079052e-09, 1.2280657457338146e-08, 1.7128525264058264e-08, 2.3885184894781535e-08, 3.329966647302377e-08, 4.641362948239142e-08, 6.467502413763038e-08, 9.009556384309048e-08, 1.2546872568777832e-07, 1.7467128911540467e-07, 2.430800425864799e-07, 3.3814707322843215e-07, 4.701931364465552e-07, 6.535005016880049e-07, 9.078164232026752e-07, 1.2604187070233036e-06, 1.7489493456900177e-06, 2.4252956412356184e-06, 3.36089691063394e-06, 4.6539869768874746e-06, 6.439458870011638e-06, 8.902272288078673e-06, 1.2295634090005293e-05, 1.696558992387263e-05, 2.3384199452644937e-05, 3.219416406447425e-05, 4.4268678480022345e-05, 6.079144030879221e-05, 8.336323995771415e-05, 0.00011414344625718829, 0.00015603709484323703, 0.00021294128829226007, 0.0002900683613606186, 0.00039436790880491144, 0.0005350755076954225, 0.0007244230284117436, 0.0009785541272720438, 0.001318699270333886, 0.0017726780564427257, 0.0023768135906518137, 0.0031783655947841905, 0.004238618001903086, 0.005636796391497631, 0.0074750462009749285, 0.00988478277324189, 0.013034842559373401, 0.017142042795247007, 0.02248502930216196, 0.029422714730332523, 0.03841927468618437, 0.05007873129396481, 0.06519387819817665, 0.08481715553524309, 0.11036591621066028, 0.143782922271076, 0.18778794020747866, 0.24628412498154922, 0.3250363950839906, 0.43284664499029174],
        [-1.9988392978080736, -1.998737893140717, -1.9986276317794558, -1.9985077406388165, -1.998377379235719, -1.9982356338290062, -1.9980815110521668, -1.9979139309959255, -1.997731719693776, -1.9975336009596267, -1.997318187522544, -1.9970839713990447, -1.9968293134385406, -1.9965524319723098, -1.996251390490752, -1.9959240842676818, -1.9955682258439646, -1.9951813292759344, -1.994760693046662, -1.994303381530345, -1.9938062048917613, -1.9932656972939353, -1.9926780932778283, -1.9920393021680753, -1.9913448803484814, -1.990590001240214, -1.9897694228044465, -1.988877452379602, -1.987907908651479, -1.9868540805423769, -1.9857086827931494, -1.9844638079999066, -1.9831108748551474, -1.981640572331599, -1.9800427995363328, -1.9783066009530696, -1.9764200967824725, -1.9743704080841462, -1.9721435764205433, -1.9697244777028475, -1.9670967299428233, -1.9642425946237057, -1.9611428714184216, -1.957776786006141, -1.9541218707697043, -1.9501538381985697, -1.945846446876259, -1.941171359999911, -1.9360979964645697, -1.930593374648523, -1.9246219491607208, -1.918145440959398, -1.9111226614247914, -1.9035093311702274, -1.8952578946064904, -1.886317331534958, -1.876632967335261, -1.8661462836312603, -1.8547947316607782, -1.8425115509328305, -1.8292255961200745, -1.814861175488018, -1.7993379044839888, -1.782570578367965, -1.7644690679243815, -1.7449382422976956, -1.7238779227796102, -1.7011828708610397, -1.6767428129470638, -1.6504425026969634, -1.6221618198488208, -1.5917759014478683, -1.559155297419201, -1.5241661371763482, -1.4866702871681028, -1.4465254706244195, -1.4035853098995033, -1.3576992382818693, -1.308712211390317, -1.2564641275730277, -1.2007888410759435, -1.1415126197193337, -1.0784518583110496, -1.0114098068469604, -0.9401720038167095, -0.8645000120695375, -0.7841229258570664, -0.6987259341915358, -0.6079349578238639, -0.5112959770432993, -0.4082470566206675, -0.2980801213777357, -0.17988801678201824, -0.05248991003669645, 0.08567606276128167, 0.23671114505493918, 0.40349625074739637, 0.5900685358584165, 0.802233330594955, 1.0485995763626115],
        [0.9988396923632011, 0.9987383596438452, 0.9986281833480194, 0.9985083927811003, 0.9983781502864275, 0.998236545464129, 0.9980825888975597, 0.9979152053466436, 0.9977332263642898, 0.997535382288698, 0.9973202935608517, 0.9970864613127411, 0.9968322571679225, 0.9965559121918812, 0.9962555049253249, 0.9959289484290306, 0.9955739762642, 0.9951881273274974, 0.9947687294550405, 0.9943128817047084, 0.993817435221218, 0.9932789725836373, 0.9926937855303831, 0.9920578509525073, 0.9913668050422784, 0.9906159154809334, 0.9898000515472655, 0.9889136520276155, 0.9879506908082926, 0.9869046400336968, 0.9857684307180864, 0.9845344107064175, 0.9831942998907253, 0.9817391426037908, 0.9801592571322976, 0.9784441823182588, 0.9765826212514035, 0.9745623820978254, 0.9723703161629502, 0.969992253351666, 0.9674129352670826, 0.9646159462842002, 0.9615836430480905, 0.9582970829807979, 0.9547359525398739, 0.9508784961574734, 0.946701447005413, 0.9421799609819322, 0.9372875556034023, 0.9319960558119869, 0.9262755490811113, 0.9200943526166017, 0.9134189959137595, 0.9062142224391786, 0.8984430147587907, 0.8900666480258257, 0.8810447773664062, 0.8713355653446574, 0.8608958563368816, 0.8496814052732995, 0.8376471687870424, 0.82474766730718, 0.8109374270012562, 0.7961715106607837, 0.7804061465706681, 0.7635994640450368, 0.7457123435789405, 0.7267093883912111, 0.706560022460586, 0.6852397179459497, 0.6627313521248992, 0.6390266907246008, 0.6141279908667062, 0.5880497130117452, 0.5608203276015039, 0.5324841990556992, 0.5031035280784387, 0.4727603338163895, 0.4415584615361012, 0.4096256107856713, 0.3771153955971516, 0.34420947494629756, 0.3111198321182167, 0.27809134092377225, 0.24540484215016947, 0.21338107604891157, 0.182385992854959, 0.1528382202154807, 0.12521984844988143, 0.10009227712597968, 0.078119780404543, 0.06010492706590599, 0.047042460733170595, 0.040202512009014764, 0.04126165231566124, 0.05251451686082635, 0.07722636177516791, 0.12024335878472586, 0.18909943257210599, 0.2961403575616695],
    ],
    [
        [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
        [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0],
        [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
        [-1.9995188267602697, -1.9994767515966752, -1.9994309947451783, -1.9993812335902308, -1.9993271171630838, -1.9992682636348227, -1.9992042575850097, -1.9991346470253473, -1.9990589401558219, -1.9989766018285944, -1.99888704969251, -1.9987896499884317, -1.998683712962666, -1.998568487862485, -1.9984431574741208, -1.9983068321596114, -1.9981585433443692, -1.9979972364024052, -1.9978217628805512, -1.997630871996839, -1.9974232013412603, -1.9971972666993476, -1.9969514509103317, -1.99668399166181, -1.9963929681119061, -1.9960762862174637, -1.9957316626328756, -1.9953566070283626, -1.9949484026586641, -1.9945040849929154, -1.9940204181935992, -1.993493869206445, -1.9929205791936928, -1.9922963320095406, -1.9916165193784476, -1.9908761023934836, -1.9900695689023868, -1.9891908862925531, -1.9882334491217981, -1.9871900209683573, -1.9860526697899028, -1.9848126959860104, -1.983460552249816, -1.9819857541709747, -1.980376780411375, -1.9786209611153849, -1.976704353035374, -1.9746115996484959, -1.9723257743096672, -1.9698282042258028, -1.9670982727451272, -1.964113197130426, -1.960847778624424, -1.9572741212176552, -1.9533613150937068, -1.9490750802543322, -1.944377365320323, -1.9392258959682005, -1.9335736669062953, -1.927368370729227, -1.9205517564354804, -1.913058909873775, -1.9048174479337994, -1.8957466179593503, -1.8857562936926358, -1.8747458591266948, -1.8626029720328012, -1.849202199741067, -1.8344035211002263, -1.8180506905543437, -1.7999694630851915, -1.779965682513251, -1.757823240446407, -1.7333019190964372, -1.7061351382688883, -1.6760276349921, -1.6426531132633282, -1.6056519108412932, -1.5646287392561764, -1.519150561324804, -1.4687446762738228, -1.412897084724616, -1.3510512029297306, -1.2826069868332741, -1.2069205119558801, -1.123304037357941, -1.031026568050744, -0.9293149351638516, -0.8173554656707014, -0.6942964661593539, -0.5592520926433457, -0.4113088906806122, -0.2495376754143744, -0.07301604834060116, 0.11912821343113168, 0.32763335716453645, 0.5529422396726733, 0.7948921842147931, 1.05211932749665, 1.3209134308194261],
        [0.999519221449531, 0.9994772182722521, 0.9994315465354489, 0.9993818860175481, 0.9993278885802376, 0.999269175741052, 0.9992053360360572, 0.9991359221546877, 0.999060447827313, 0.9989783844444823, 0.9988891573850778, 0.998792142028725, 0.9986866594258069, 0.9985719715962725, 0.9984472764261015, 0.9983117021278294, 0.9981643012288515, 0.9980040440484254, 0.9978298116212398, 0.9976403880222208, 0.9974344520438414, 0.9972105681735782, 0.9969671768153904, 0.9967025836950594, 0.9964149483851155, 0.9961022718806808, 0.9957623831531178, 0.9953929246037614, 0.994991336335333, 0.9945548391539585, 0.9940804162100764, 0.9935647931819851, 0.9930044169015746, 0.9923954323178784, 0.9917336576908037, 0.9910145579048577, 0.9902332157911976, 0.9893843013462088, 0.9884620387364128, 0.9874601709833538, 0.9863719222287318, 0.9851899574901878, 0.9839063398325264, 0.982512484898951, 0.9809991127730913, 0.9793561971767873, 0.9775729120523805, 0.975637575633695, 0.9735375921793563, 0.9712593916283963, 0.9687883675445915, 0.96610881384656, 0.9632038609798679, 0.9600554123806311, 0.9566440823134792, 0.9529491364474068, 0.9489484368691897, 0.9446183936348423, 0.9399339254356381, 0.9348684325180172, 0.929393785659104, 0.9234803357753765, 0.9170969496458073, 0.9102110782775564, 0.9027888656467945, 0.8947953069231998, 0.8861944668457704, 0.8769497706677778, 0.8670243820328891, 0.8563816842783969, 0.8449858839718547, 0.8328027579506591, 0.8198005677158019, 0.8059511676877836, 0.7912313365177065, 0.7756243633216853, 0.7591219233634798, 0.7417262804065943, 0.7234528558736054, 0.704333208477063, 0.6844184728479795, 0.6637833131251747, 0.6425304594889341, 0.6207959153474814, 0.5987549550276239, 0.5766290833432984, 0.5546942094468716, 0.5332904125185648, 0.5128338671357234, 0.4938317818860569, 0.47690162986689216, 0.4627965781186012, 0.4524399478377001, 0.44697289150936254, 0.4478214375972732, 0.4567918402975392, 0.47620691892699124, 0.5091004454610859, 0.559489549501248, 0.6327387928852765],
    ],
];

pub trait CutoffRatioBounds {
    const MIN_CUTOFF_RATIO: f64;
    const MAX_CUTOFF_RATIO: f64;

    fn is_within_bounds(cutoff_ratio: f64) -> bool {
        cutoff_ratio >= Self::MIN_CUTOFF_RATIO && cutoff_ratio <= Self::MAX_CUTOFF_RATIO
    }
}

impl CutoffRatioBounds for f32 {
    const MIN_CUTOFF_RATIO: f64 = MIN_CUTOFF_RATIO_F32;
    const MAX_CUTOFF_RATIO: f64 = MAX_CUTOFF_RATIO_F32;
}

impl CutoffRatioBounds for f64 {
    const MIN_CUTOFF_RATIO: f64 = MIN_CUTOFF_RATIO_F64;
    const MAX_CUTOFF_RATIO: f64 = MAX_CUTOFF_RATIO_F64;
}

/// Butterworth order 4 lowpass filter, second order sections (SOS) implementation.
/// The filter is created by interpolating the SOS coefficients from stored tables.
///
/// `cutoff_ratio` (dimensionless) is the cutoff frequency divided by the sample frequency.
///
/// Region of validity for `cutoff_ratio` depends on the float type `T`:
/// * f32: 0.0050 to 0.4000
/// * f64: 0.0005 to 0.4000
pub fn butter4<T>(cutoff_ratio: f64) -> Result<SisoSosFilter<NUM_SECTIONS, T>, &'static str>
where
    T: Num
        + Copy
        + MulAdd<Output = T>
        + Neg<Output = T>
        + FromPrimitive
        + ToPrimitive
        + CutoffRatioBounds,
{
    if !T::is_within_bounds(cutoff_ratio) {
        return Err("cutoff_ratio out of bounds for provided float type");
    }
    // Convert SOS tables from static arrays to slices because new_interpolated expects slices.
    let sos_tables = SOS_TABLES
        .each_ref()
        .map(|sec| sec.each_ref().map(|coeffs| &coeffs[..]));
    SisoSosFilter::new_interpolated(cutoff_ratio, &LOG10_CUTOFF_RATIOS, sos_tables)
}

#[cfg(test)]
mod tests {
    use super::super::super::test_helpers::test_filter;
    use super::{
        MAX_CUTOFF_RATIO_F32, MAX_CUTOFF_RATIO_F64, MIN_CUTOFF_RATIO_F32, MIN_CUTOFF_RATIO_F64,
        NUM_SECTIONS, butter4,
    };
    #[test]
    fn test_butter4_f32() {
        test_filter::<NUM_SECTIONS, f32>(MIN_CUTOFF_RATIO_F32, MAX_CUTOFF_RATIO_F32, butter4);
    }

    #[test]
    fn test_butter4_f64() {
        test_filter::<NUM_SECTIONS, f64>(MIN_CUTOFF_RATIO_F64, MAX_CUTOFF_RATIO_F64, butter4);
    }
}