pub use crate::daubechies::*;
use ndwt_macros::implement_dwt_orthogonal;
implement_dwt_orthogonal! {
Daubechies1,
[
7.071067811865475244008443621048490392848359376884740365883399e-1,
7.071067811865475244008443621048490392848359376884740365883399e-1
]
}
implement_dwt_orthogonal! {
Daubechies2,
[
-1.294095225512603811744494188120241641745344506599652569070016e-1,
2.241438680420133810259727622404003554678835181842717613871683e-1,
8.365163037378079055752937809168732034593703883484392934953415e-1,
4.829629131445341433748715998644486838169524195042022752011715e-1
]
}
implement_dwt_orthogonal! {
Daubechies3,
[
3.522629188570953660274066471551002932775838791743161039893406e-2,
-8.544127388202666169281916918177331153619763898808662976351749e-2,
-1.350110200102545886963899066993744805622198452237811919756863e-1,
4.598775021184915700951519421476167208081101774314923066433868e-1,
8.068915093110925764944936040887134905192973949948236181650921e-1,
3.326705529500826159985115891390056300129233992450683597084706e-1
]
}
implement_dwt_orthogonal! {
Daubechies4,
[
-1.059740178506903210488320852402722918109996490637641983484974e-2,
3.288301166688519973540751354924438866454194113754971259727278e-2,
3.084138183556076362721936253495905017031482172003403341821219e-2,
-1.870348117190930840795706727890814195845441743745800912057771e-1,
-2.798376941685985421141374718007538541198732022449175284003358e-2,
6.308807679298589078817163383006152202032229226771951174057473e-1,
7.148465705529156470899219552739926037076084010993081758450110e-1,
2.303778133088965008632911830440708500016152482483092977910968e-1
]
}
implement_dwt_orthogonal! {
Daubechies5,
[
3.335725285473771277998183415817355747636524742305315099706429e-3,
-1.258075199908199946850973993177579294920459162609785020169233e-2,
-6.241490212798274274190519112920192970763557165687607323417435e-3,
7.757149384004571352313048938860181980623099452012527983210146e-2,
-3.224486958463837464847975506213492831356498416379847225434268e-2,
-2.422948870663820318625713794746163619914908080626185983913727e-1,
1.384281459013207315053971463390246973141057911739561022694652e-1,
7.243085284377729277280712441022186407687562182320073725767335e-1,
6.038292697971896705401193065250621075074221631016986987969283e-1,
1.601023979741929144807237480204207336505441246250578327725699e-1
]
}
implement_dwt_orthogonal! {
Daubechies6,
[
-1.077301085308479564852621609587200035235233609334419689818581e-3,
4.777257510945510639635975246820707050230501216581434297593255e-3,
5.538422011614961392519183980465012206110262773864964295476525e-4,
-3.158203931748602956507908069984866905747953237314842337511465e-2,
2.752286553030572862554083950419321365738758783043454321494203e-2,
9.750160558732304910234355253812534233983074749525514279893193e-2,
-1.297668675672619355622896058765854608452337492235814701599311e-1,
-2.262646939654398200763145006609034656705401539728969940143488e-1,
3.152503517091976290859896548109263966495199235172945244404164e-1,
7.511339080210953506789344984397316855802547833382612009730421e-1,
4.946238903984530856772041768778555886377863828962743623531835e-1,
1.115407433501094636213239172409234390425395919844216759082360e-1
]
}
implement_dwt_orthogonal! {
Daubechies7,
[
3.537137999745202484462958363064254310959060059520040012524276e-4,
-1.801640704047490915268262912739550962585651469641090625323865e-3,
4.295779729213665211321291228197322228235350396942409742946367e-4,
1.255099855609984061298988603418777957289474046048710038411818e-2,
-1.657454163066688065410767489170265479204504394820713705239273e-2,
-3.802993693501441357959206160185803585446196938467869898283123e-2,
8.061260915108307191292248035938190585823820965629489058139218e-2,
7.130921926683026475087657050112904822711327451412314659575113e-2,
-2.240361849938749826381404202332509644757830896773246552665095e-1,
-1.439060039285649754050683622130460017952735705499084834401753e-1,
4.697822874051931224715911609744517386817913056787359532392529e-1,
7.291320908462351199169430703392820517179660611901363782697716e-1,
3.965393194819173065390003909368428563587151149333287401110500e-1,
7.785205408500917901996352195789374837918305292795568438702937e-2
]
}
implement_dwt_orthogonal! {
Daubechies8,
[
-1.174767841247695337306282316988909444086693950311503927620014e-4,
6.754494064505693663695475738792991218489630013558432103617077e-4,
-3.917403733769470462980803573237762675229350073890493724492695e-4,
-4.870352993451574310422181557109824016634978512157003764736209e-3,
8.746094047405776716382743246475640180402147081140676742686747e-3,
1.398102791739828164872293057263345144239559532934347169146368e-2,
-4.408825393079475150676372323896350189751839190110996472750392e-2,
-1.736930100180754616961614886809598311413086529488394316977315e-2,
1.287474266204784588570292875097083843022601575556488795577000e-1,
4.724845739132827703605900098258949861948011288770074644084096e-4,
-2.840155429615469265162031323741647324684350124871451793599205e-1,
-1.582910525634930566738054787646630415774471154502826559735336e-2,
5.853546836542067127712655200450981944303266678053369055707175e-1,
6.756307362972898068078007670471831499869115906336364227766760e-1,
3.128715909142999706591623755057177219497319740370229185698712e-1,
5.441584224310400995500940520299935503599554294733050397729281e-2
]
}
implement_dwt_orthogonal! {
Daubechies9,
[
3.934732031627159948068988306589150707782477055517013507359938e-5,
-2.519631889427101369749886842878606607282181543478028214134265e-4,
2.303857635231959672052163928245421692940662052463711972260007e-4,
1.847646883056226476619129491125677051121081359600318160732515e-3,
-4.281503682463429834496795002314531876481181811463288374860455e-3,
-4.723204757751397277925707848242465405729514912627938018758527e-3,
2.236166212367909720537378270269095241855646688308853754721816e-2,
2.509471148314519575871897499885543315176271993709633321834165e-4,
-6.763282906132997367564227482971901592578790871353739900748331e-2,
3.072568147933337921231740072037882714105805024670744781503061e-2,
1.485407493381063801350727175060423024791258577280603060771649e-1,
-9.684078322297646051350813353769660224825458104599099679471268e-2,
-2.932737832791749088064031952421987310438961628589906825725113e-1,
1.331973858250075761909549458997955536921780768433661136154347e-1,
6.572880780513005380782126390451732140305858669245918854436034e-1,
6.048231236901111119030768674342361708959562711896117565333714e-1,
2.438346746125903537320415816492844155263611085609231361429088e-1,
3.807794736387834658869765887955118448771714496278417476647192e-2
]
}
implement_dwt_orthogonal! {
Daubechies10,
[
-1.326420289452124481243667531226683305749240960605829756400675e-5,
9.358867032006959133405013034222854399688456215297276443521874e-5,
-1.164668551292854509514809710258991891527461854347597362819235e-4,
-6.858566949597116265613709819265714196625043336786920516211904e-4,
1.992405295185056117158742242640643211762555365514105280067936e-3,
1.395351747052901165789318447957707567660542855688552426721118e-3,
-1.073317548333057504431811410651364448111548781143923213370334e-2,
3.606553566956169655423291417133403299517350518618994762730612e-3,
3.321267405934100173976365318215912897978337413267096043323351e-2,
-2.945753682187581285828323760141839199388200516064948779769654e-2,
-7.139414716639708714533609307605064767292611983702150917523756e-2,
9.305736460357235116035228983545273226942917998946925868063974e-2,
1.273693403357932600826772332014009770786177480422245995563098e-1,
-1.959462743773770435042992543190981318766776476382778474396782e-1,
-2.498464243273153794161018979207791000564669737132073715013122e-1,
2.811723436605774607487269984455892876243888859026150413831544e-1,
6.884590394536035657418717825492358539771364042407339537279681e-1,
5.272011889317255864817448279595081924981402680840223445318549e-1,
1.881768000776914890208929736790939942702546758640393484348595e-1,
2.667005790055555358661744877130858277192498290851289932779976e-2
]
}
#[cfg(test)]
mod test {
use super::*;
use crate::boundarys::BoundaryCondition;
use crate::dwt::{DiscreteTransform, get_outlen};
use crate::tests::{test_approx_adjoint, test_approx_equal};
use rstest::rstest;
const RTOL: f64 = 1E-13;
const ATOL: f64 = 0.0;
macro_rules! test_wavelet {
($test_name:ident, $per_test_name:ident, $adj_test_name:ident, $wvlt:ident) => {
#[rstest]
fn $test_name(
#[values(
BoundaryCondition::Zero,
BoundaryCondition::Periodic,
BoundaryCondition::Constant,
BoundaryCondition::Reflect,
BoundaryCondition::Symmetric,
BoundaryCondition::Antisymmetric,
BoundaryCondition::Smooth,
BoundaryCondition::Antireflect
)]
bc: BoundaryCondition,
#[values(1, 2, 4, 5, 20, 64, 65)] n: usize,
) {
let x: Vec<f64> = (0..n).map(|i| (i + 1) as f64).collect();
let mut x2 = vec![0.0; n];
let nsd = get_outlen($wvlt::WIDTH, n);
let mut s = vec![0.0; nsd];
let mut d = vec![0.0; nsd];
$wvlt::forward(&x, &mut s, &mut d, &bc);
$wvlt::inverse(&s, &d, &mut x2);
test_approx_equal(&x2, &x, RTOL, ATOL);
}
#[rstest]
fn $per_test_name(#[values(1, 2, 4, 5, 20, 64, 65)] n: usize) {
let x: Vec<f64> = (0..n).map(|i| (i + 1) as f64).collect();
let mut x2 = vec![0.0; n];
let nd = n / 2;
let ns = (n + 1) / 2;
let mut s = vec![0.0; ns];
let mut d = vec![0.0; nd];
$wvlt::forward_per(&x, &mut s, &mut d);
$wvlt::inverse_per(&s, &d, &mut x2);
test_approx_equal(&x2, &x, RTOL, ATOL);
}
#[rstest]
fn $adj_test_name(#[values(1, 2, 4, 5, 20, 64, 65)] n: usize) {
let x: Vec<f64> = (0..n).map(|i| (i + 1) as f64).collect();
let mut x2 = vec![0.0; n];
let nd = n / 2;
let ns = (n + 1) / 2;
let mut s = vec![0.0; ns];
let mut d = vec![0.0; nd];
$wvlt::adjoint_inverse_per(&x, &mut s, &mut d);
$wvlt::adjoint_forward_per(&s, &d, &mut x2);
test_approx_equal(&x2, &x, RTOL, ATOL);
let u = (0..n as isize).map(|i| (i + 1) as f64).collect::<Vec<_>>();
let v = (0..n as isize).map(|i| (5 - i) as f64).collect::<Vec<_>>();
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(ns);
$wvlt::adjoint_inverse_per(u, s, d);
},
|v, out| {
let (s, d) = v.split_at(ns);
$wvlt::inverse_per(s, d, out);
},
&u,
&v,
RTOL,
ATOL,
);
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(ns);
$wvlt::forward_per(u, s, d);
},
|v, out| {
let (s, d) = v.split_at(ns);
$wvlt::adjoint_forward_per(s, d, out);
},
&u,
&v,
RTOL,
ATOL,
);
}
};
}
test_wavelet!(test_db1, test_db1_per, test_db1_adj, Daubechies1);
test_wavelet!(test_db2, test_db2_per, test_db2_adj, Daubechies2);
test_wavelet!(test_db3, test_db3_per, test_db3_adj, Daubechies3);
test_wavelet!(test_db4, test_db4_per, test_db4_adj, Daubechies4);
test_wavelet!(test_db5, test_db5_per, test_db5_adj, Daubechies5);
test_wavelet!(test_db6, test_db6_per, test_db6_adj, Daubechies6);
test_wavelet!(test_db7, test_db7_per, test_db7_adj, Daubechies7);
test_wavelet!(test_db8, test_db8_per, test_db8_adj, Daubechies8);
test_wavelet!(test_db9, test_db9_per, test_db9_adj, Daubechies9);
test_wavelet!(test_db10, test_db10_per, test_db10_adj, Daubechies10);
#[rstest]
fn test_adjoint_db3(
#[values(
BoundaryCondition::Zero,
BoundaryCondition::Periodic,
BoundaryCondition::Constant,
BoundaryCondition::Reflect,
BoundaryCondition::Symmetric,
BoundaryCondition::Antisymmetric,
BoundaryCondition::Smooth,
BoundaryCondition::Antireflect
)]
bc: BoundaryCondition,
#[values(64, 65)] n: usize,
) {
type Wvlt = Daubechies3;
let nsd = get_outlen(Wvlt::WIDTH, n);
let u = (0..n as isize).map(|i| (i + 1) as f64).collect::<Vec<_>>();
let v = (0..(2 * nsd) as isize)
.map(|i| (5 - i) as f64)
.collect::<Vec<_>>();
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(nsd);
Wvlt::adjoint_inverse(u, s, d);
},
|v, out| {
let (s, d) = v.split_at(nsd);
Wvlt::inverse(s, d, out);
},
&u,
&v,
RTOL,
ATOL,
);
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(nsd);
Wvlt::forward(u, s, d, &bc);
},
|v, out| {
let (s, d) = v.split_at(nsd);
Wvlt::adjoint_forward(s, d, out, &bc);
},
&u,
&v,
RTOL,
ATOL,
);
}
#[rstest]
fn test_adjoint_db2(
#[values(
BoundaryCondition::Zero,
BoundaryCondition::Periodic,
BoundaryCondition::Constant,
BoundaryCondition::Reflect,
BoundaryCondition::Symmetric,
BoundaryCondition::Antisymmetric,
BoundaryCondition::Smooth,
BoundaryCondition::Antireflect
)]
bc: BoundaryCondition,
#[values(64, 65)] n: usize,
) {
type Wvlt = Daubechies2;
let nsd = get_outlen(Wvlt::WIDTH, n);
let u = (0..n as isize).map(|i| (i + 1) as f64).collect::<Vec<_>>();
let v = (0..(2 * nsd) as isize)
.map(|i| (5 - i) as f64)
.collect::<Vec<_>>();
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(nsd);
Wvlt::adjoint_inverse(u, s, d);
},
|v, out| {
let (s, d) = v.split_at(nsd);
Wvlt::inverse(s, d, out);
},
&u,
&v,
RTOL,
ATOL,
);
test_approx_adjoint(
|u, out| {
let (s, d) = out.split_at_mut(nsd);
Wvlt::forward(u, s, d, &bc);
},
|v, out| {
let (s, d) = v.split_at(nsd);
Wvlt::adjoint_forward(s, d, out, &bc);
},
&u,
&v,
RTOL,
ATOL,
);
}
}