#!/usr/bin/python

import unittest
from numpy import *
from scipy.io import loadmat
from rwt import *

class TestRWT(unittest.TestCase):

  def setUp(self):
      pass

  def test_dwt(self):
    x = makesig('LinChirp', 8)
    h = daubcqf(4, 'min')[0]
    L = 2
    y, L = dwt(x, h, L)
    y_corr = array([1.109692262737501,0.876661822959323,0.820391852106669,-0.520074093642583,-0.033927668247206,0.100110695461285,0.220088240246095,-0.140081604397608])
    self.assertTrue(allclose(y, y_corr, 0.0001))

  def test_dwt_2d(self):
    x = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16.0]])
    h = daubcqf(4)[0]
    L = 2
    y, L = dwt(x, h, L)
    y_corr = array([[34.0000, -3.4641, 0.0000, -2.0000], [-13.8564, 0.0000, 0.0000, -2.0000], [-0.0000, 0.0000, -0.0000, -0.0000], [-8.0000, -8.0000, 0.0000, -0.0000]])
    self.assertTrue(allclose(y, y_corr, 0.0000005))

  def test_idwt(self):
    x = makesig('LinChirp', 8)
    h = daubcqf(4, 'min')[0]
    L = 2
    y, L = dwt(x, h, L)
    x_new, L = idwt(y, h, L)
    self.assertTrue(allclose(x, x_new, 0.0005))

  def test_idwt_2d(self):
    x = loadmat('../tests/lena512.mat')['lena512'] * 1.0
    h = daubcqf(6)[0]
    L = 9
    y, L = dwt(x, h, L)
    x_new, L = idwt(y, h, L)
    self.assertTrue(allclose(x, x_new, 0.0005))

  def test_rdwt(self):
    x = makesig('Leopold', 8)
    h = daubcqf(4, 'min')[0]
    L = 1
    (yl, yh, L) = rdwt(x, h, L)
    yl_corr = [0.8365,  0.4830, 0, 0, 0, 0, -0.1294, 0.2241]
    yh_corr = [-0.2241, -0.1294, 0, 0, 0, 0, -0.4830, 0.8365]
    L_corr = 1
    self.assertTrue(allclose(yl, yl_corr, 0.0005))
    self.assertTrue(allclose(yh, yh_corr, 0.0005))
    self.assertTrue(allclose(L, L_corr, 0.0005))

  def test_rdwt_2(self):
    x = array([[1.0,3,5,2],[3,4,8,1],[3,9,2,0],[1,2,3,0]])
    h = daubcqf(4, 'min')[0]
    yl, yh, L = rdwt(x, h, 1)
    yl_corr = array([
      [9.0111, 10.7799, 5.8795, 4.1107],
      [11.1393, 8.7766, 2.5502, 4.9130],
      [6.9465, 5.7578, 1.6630, 2.8517],
      [4.8182, 7.7611, 4.9922, 2.0494]])
    yh_corr = array([
      [4.5724, 0.4285, -1.8828, 2.2611, 4.8714, -3.1026, -1.7978, 0.0290, -2.9620, -1.1818, -1.1295, 5.2733],
      [-2.4441, -2.4318, -1.4465, -1.4587, 1.8861, -4.2488, -1.9776, 4.3403, -0.0233, 0.0356, 0.9498, -0.9620],
      [-1.7488, -0.5870, 0.5592, -0.6026, 1.1663, -2.3550, -1.7398, 2.9285, -0.6965, 1.8583, -0.7120, -0.4498],
      [-0.3795, 2.5903, 2.7700, -0.1998, 4.1516, -1.2087, -1.5601, -1.3828, 3.6818, -0.7120, 0.8917, -3.8615]])
    self.assertTrue(allclose(yl, yl_corr, 0.001))
    self.assertTrue(allclose(yh, yh_corr, 0.001))

  def test_rdwt_2L2(self):
    x = array([[1.0,3,5,2],[3,4,8,1],[3,9,2,0],[1,2,3,0]])
    h = daubcqf(4, 'min')[0]
    yl, yh, L = rdwt(x, h, 2)
    yl_corr = array([
      [11.7500,  11.7500,  11.7500,  11.7500],
      [11.7500,  11.7500,  11.7500,  11.7500],
      [11.7500,  11.7500,  11.7500,  11.7500],
      [11.7500,  11.7500,  11.7500,  11.7500]])
    yh_corr = array([
       [4.5724,   0.4285,  -1.8828,   2.2611,   4.8714,  -3.1026,  -1.7978,   0.0290,  -2.9620,  -1.1818,  -1.1295,   5.2733,
       3.1405,   3.1405,   3.1405,   3.1405,   4.2075,   4.7877,  -4.2075,  -4.7877,  -1.0760,   1.8816,   1.0760,  -1.8816],
       [-2.4441,  -2.4318,  -1.4465,  -1.4587,   1.8861,  -4.2488,  -1.9776,   4.3403,  -0.0233,   0.0356,   0.9498,  -0.9620,
       1.9396,   1.9396,   1.9396,   1.9396,   4.2075,   4.7877,  -4.2075,  -4.7877,   4.3816,  -0.9240,  -4.3816,   0.9240],
       [-1.7488,  -0.5870,   0.5592,  -0.6026,   1.1663,  -2.3550,  -1.7398,   2.9285,  -0.6965,   1.8583,  -0.7120,  -0.4498,
       -3.1405,  -3.1405,  -3.1405,  -3.1405,   4.2075,   4.7877,  -4.2075,  -4.7877,   1.0760,  -1.8816,  -1.0760,   1.8816],
       [-0.3795,   2.5903,   2.7700,  -0.1998,   4.1516,  -1.2087,  -1.5601,  -1.3828,   3.6818,  -0.7120,   0.8917,  -3.8615,
       -1.9396,  -1.9396,  -1.9396,  -1.9396,   4.2075,   4.7877,  -4.2075,  -4.7877,  -4.3816,   0.9240,   4.3816,  -0.9240]])
    self.assertTrue(allclose(yl, yl_corr, 0.001))
    self.assertTrue(allclose(yh, yh_corr, 0.001))

  def test_irdwt(self):
    xin = makesig('Leopold',8)
    h = daubcqf(4, 'min')[0]
    Lin = 1
    (yl, yh, L) = rdwt(xin, h, Lin) 
    (x, L) = irdwt(yl, yh, h, L)
    self.assertTrue(allclose(x, xin, 0.0005))
       
  def test_irdwt_2d(self):
    x = loadmat('../tests/lena512.mat')['lena512'] * 1.0
    h = daubcqf(6)[0]
    L = 9 
    yl, yh, L = rdwt(x, h, L)
    x_new, L = irdwt(yl, yh, h, L)
    self.assertTrue(allclose(x, x_new, 0.0005))

  def test_makesig_heavisine(self):
    x = makesig('HeaviSine', 8)
    y = array([4.0000, 0.0000, -6.0000, -2.0000, 2.0000, 0.0000, -4.0000, -0.0000])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_bumps(self):
    x = around(makesig('Bumps', 8), 4)
    y = array([0.3206, 5.0527, 0.3727, 0.0129, 0.0295, 0.0489, 0.0004, 0.0000])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_blocks(self):
    x = makesig('Blocks', 8)
    y = array([4.0000, 0.5000, 3.0000, 0.9000, 0.9000, 5.2000, -0.0000, -0.0000])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_doppler(self):
    x = makesig('Doppler', 12)
    y = array([-0.1954, -0.3067, 0.0000, -0.4703, 0.4930, -0.2703, -0.4127, 0.1025, 0.4001, 0.3454, 0.1425, 0])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_ramp(self):
    x = makesig('Ramp', 8)
    y = array([0.1250, 0.2500, -0.6250, -0.5000, -0.3750, -0.2500, -0.1250, 0])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_cusp(self):
    x = makesig('Cusp', 8)
    y = array([0.4950, 0.3464, 0.0707, 0.3606, 0.5050, 0.6164, 0.7106, 0.7937])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_sing(self):
    x = makesig('Sing', 8)
    y = array([5.3333, 16.0000, 16.0000, 5.3333, 3.2000, 2.2857, 1.7778, 1.4545])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_hisine(self):
    x = makesig('HiSine', 8)
    y = array([0.8267, -0.9302, 0.2200, 0.6827, -0.9882, 0.4292, 0.5053, -0.9977])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_losine(self):
    x = makesig('LoSine', 8)
    y = array([0.865973039158459,0.866130104544730,0.000314159260191,-0.865815888304075,-0.866287084447387,-0.000628318489377,0.865658651997088,0.866443978850937])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_linchirp(self):
    x = makesig('LinChirp', 8)
    y = array([0.049067674327418,0.195090322016128,0.427555093430282,0.707106781186547,0.941544065183021,0.980785280403230,0.671558954847019,0.000000000000000])
    self.assertTrue(allclose(x, y, 0.0001))
  
  def test_makesig_twochirp(self):
    x = makesig('TwoChirp', 8)
    y = array([0.5132, 1.5000, 0.5412, 0.8660, -0.5132, 0, 0.5132, 0.8660])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_quadchirp(self):
    x = makesig('QuadChirp', 8)
    y = array([0.016361731626487,0.130526192220052,0.427555093430282,0.866025403784439,0.889516075421856,-0.382683432365090,-0.621660573370077,0.866025403784439])
    self.assertTrue(allclose(x, y, 0.0001))
  
  def test_makesig_mishmash(self):
    x = makesig('MishMash', 8)
    y = array([0.8922, -0.6046, 1.0751, 2.2558, 0.8429, 1.0273, 0.5551, -0.1317])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_wernersorrows(self):
    x = makesig('WernerSorrows', 8)
    y = array([1.5545, 5.3175, 0.8252, 1.6956, -1.2678, 0.6466, 1.7332, -0.9977])
    self.assertTrue(allclose(x, y, 0.0005))
  
  def test_makesig_leopold(self):
    x = makesig('Leopold', 8)
    y = array([0, 1, 0, 0, 0, 0, 0, 0])
    self.assertTrue(allclose(x, y, 0.0005))

  def test_denoise_default(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h)
    signal_denoised_corr = array([0.0741827688375062,0.0791701902526268,0.0760842615272340,0.0750476831774179,0.111279774779568,0.163475053283544,-0.0498263815350539,0.0946073088237311,0.135126562486911,-0.0186090620958193,-0.0748812479991294,-0.103470206059426,0.0234254843251780,0.239772540836257,0.0920583398962312,-0.152180640366891,-0.116682073306156,-0.0459389850762785,-0.00245240039778375,0.0755739164104836,0.102548333512214,0.121099911744184,0.177390507921620,0.240386041553093,0.231105933317157,0.198210924493273,0.175672812990725,0.138822049613034,0.127491615387826,0.121409597186325,0.0994935320130783,0.0760019340865427])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))

  def test_denoise_2d(self):
    x = array([[1,2,3,4],[5,6,7,8],[9,10.09,11,12],[13,13.91,15,16]])
    h = daubcqf(4)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(x, h)
    signal_denoised_corr = array([[1.093495801587334,2.052784169768518,3.036985129109070,4.014510779767102],[5.037416383975946,6.006178652683398,6.994963120759174,7.978382656683513],[9.047593546684929,10.003998510025589,10.977825887256145,11.94698494275469],[13.009489364401729,13.937038667522501,14.939852728547271,15.9224996584731398]])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))

  def test_denoise_udwt(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1)
    signal_denoised_corr = array([0.126244615385152,0.0952319712425300,0.0671343607152503,0.0513902979722585,0.0430402732682634,0.0586932575131794,0.0861069751902698,0.0989949047763016,0.0908418658128637,-0.0141454670119059,-0.144791527437026,-0.0185533166035902,0.278351613782131,0.279033706376659,-0.0205012032054263,-0.212367658407976,-0.241484343697995,-0.248582298831059,-0.213374214781743,-0.101963712141109,0.0454248851310567,0.181104333949749,0.275294407293259,0.309076259882059,0.298600450385073,0.259080737796607,0.211123535801718,0.183021783525739,0.171966340866576,0.171616812586097,0.168720006300193,0.151066428184072])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))

  def test_denoise_udwt_2d(self):
    x = array([[1,2,3,4],[5,6,7,8],[9,10.09,11,12],[13,13.91,15,16]])
    h = daubcqf(4)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(x, h, 1)
    signal_denoised_corr = array([[1.007040488866197,1.993405274521765,3.006268404030089,3.996424654030090],[4.995935171857875,6.002401216530091,7.001252328142127,8.005847881693983],[9.009508189685661,10.059981743374523,11.001190131625481,11.999030274521770],[12.987516149590270,13.944211765573623,14.991289136202310,15.998697189754166]])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_threshold_low(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [1,3.0,0,2,0,0])
    signal_denoised_corr = array([0.0187742354278351,0.0237616568429558,0.0206757281175629,0.0196391497677469,0.0558712413698966,0.108066519873873,-0.105234914944725,0.0391987754140600,0.0797180290772401,-0.0740175955054904,-0.130289781408801,-0.158878739469097,-0.0319830490844931,0.184364007426586,0.0366498064865601,-0.207589173776562,-0.172090606715827,-0.101347518485950,-0.0578609338074549,0.0201653830008125,0.0471398001025425,0.0656913783345127,0.121981974511949,0.184977508143422,0.175697399907486,0.142802391083602,0.120264279581054,0.0834135162033633,0.0720830819781554,0.0660010637766539,0.0440849986034073,0.0205934006768717])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_thresh_multiplier(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [1,3.5,0,2,0,0])
    signal_denoised_corr = array([0.00563527074803461,0.0110853052404048,0.0101590193471916,0.0116789518546074,0.0354625658443208,0.0691904606426981,-0.0647010252187970,0.0393485097012034,0.0302297746478269,-0.0658230296401878,-0.0947938063374137,-0.147943151851009,-0.0355607514547514,0.143027827800490,0.0126752977970079,-0.200577663821584,-0.149059259007655,-0.0564432101940217,-0.0281365070661950,0.0201021371871464,0.0438412772787373,0.0596866399869512,0.0967101937989458,0.136451641917565,0.130716307107088,0.109146914388131,0.0925200849653435,0.0657607417363412,0.0550584910898860,0.0469636231448182,0.0277268486177313,0.00667135407398081])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_std(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [0,3.0,1,2,0,0])
    signal_denoised_corr = array([0.0686926069658060,0.0706216045196474,0.0719769032529757,0.0743568305131058,0.0754251996534692,0.0763549103855611,0.0783972750744446,0.0807092136475563,0.0763109954998047,0.0693017683604205,0.0628697537191382,0.0547492531677562,0.0755519478401559,0.107931256046656,0.0859959791464885,0.0494376118339224,0.0602059364595448,0.0785077229738383,0.0791999606842265,0.0809410605777517,0.0844652184548917,0.0873749084881920,0.0911535278085727,0.0952027332951270,0.0936316016468421,0.0898878427420561,0.0866734185917041,0.0820709685744921,0.0793481432323076,0.0768306965269240,0.0727995727792393,0.0684196591566048])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_hard(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [0,3.0,0,1,0,0])
    signal_denoised_corr = array([0.0977394160103721,0.0994161560983385,0.0832447407807381,0.0666983311697188,0.177420971595413,0.340230583897110,-0.354597069671295,0.0250017872275015,0.394418485343238,-0.0595745304374512,-0.452401570793399,-0.175707560852101,-0.00622320325130765,0.437867065411816,0.187485346584306,-0.241060664687049,-0.306285896120773,-0.373946536466370,-0.246165924475657,0.00210496326791051,0.0528629966064817,0.0967383656953347,0.275410693617439,0.487298926169970,0.454985253718689,0.348603331393631,0.288205743942248,0.186806596496260,0.172147260405660,0.180050851714681,0.142136445826288,0.104484725401481])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_levels(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [0,3.0,0,2,4,0])
    signal_denoised_corr = array([0.164259992817262,0.156379071218712,0.142212685671703,0.125038963573761,0.150297815252073,0.191536767978636,-0.0381639580765735,0.0881092032192094,0.119629284458486,-0.0406090725365491,-0.105645426731493,-0.141820831994602,-0.0280318977202704,0.173171960129832,0.0117537437282443,-0.247115729957293,-0.206759297285911,-0.123147866042363,-0.0685808245422524,0.0255826360141400,0.0635302930397082,0.0930381970490923,0.165728084463140,0.246884147157615,0.246603211345582,0.220210934934003,0.206436991723089,0.177172675548210,0.178948997433275,0.188010177892750,0.179798128181065,0.170937023676945])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_actual_thresh(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 0, [0,3.0,0,2,0,0.5])
    signal_denoised_corr = array([0.0607099183942295,0.0654351521193524,0.0684154759800610,0.0742018934148454,0.0758845005390013,0.0769511530643110,0.0810856606730252,0.0858023375316036,0.0704706443350518,0.0472060906047587,0.0254329679518446,-0.00154590940405266,0.0598455182579352,0.156556707841878,0.0864272987162393,-0.0287835335280487,0.00606017120154721,0.0659592575432934,0.0713958080495586,0.0812891735076492,0.0953701981347179,0.107554576791239,0.123739146895592,0.141180422640726,0.137085044622601,0.124838366760086,0.114852957437233,0.0997294000571788,0.0922174665178409,0.0857758976557685,0.0737052631031342,0.0605470542090229])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))

  def test_denoise_udwt_threshold_low(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [1,3,0,1,0,0])
    signal_denoised_corr = array([0.135039400483741,0.117805175604609,0.0967709584177031,0.0142060292567307,-0.0239840294603812,0.323425861331697,-0.212285200125643,0.166066657685731,0.136653739821785,-0.0361708285655289,-0.244622217319313,-0.0751486112344819,0.279128997196628,0.299915294672821,0.00822389077239383,-0.232180770499244,-0.330137263335199,-0.293955318206172,-0.175538926380835,-0.0733568677543535,0.049241196655251,0.200165899490694,0.304615650610263,0.337325376378116,0.325593984310807,0.282048956150932,0.228861081870546,0.196656880842149,0.180959366486141,0.175210410022406,0.169828050229736,0.155033256209497])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_udwt_thresh_multiplier(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [1,3.5,0,1,0,0])
    signal_denoised_corr = array([0.0479478506866607,0.0160653046305043,-0.012660890293452,-0.0292521383561941,-0.0383355043751224,-0.0239494802109215,0.00200042536526626,0.0135636610003902,0.00399637041195728,-0.100521378500944,-0.229923524965501,-0.102614225576592,0.195850596270724,0.197593413336102,-0.100882406775293,-0.291163630119251,-0.318524834100706,-0.324752887320235,-0.288916218874243,-0.176658530913858,-0.028536592326759,0.108409816572649,0.204063702017061,0.239170248556769,0.230108690684778,0.190119394184444,0.14091827822899,0.11174543739754,0.0991301032767805,0.0977198505254529,0.0937639547688583,0.0745251447941448])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_udwt_std(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [0,3.0,1,1,0,0])
    signal_denoised_corr = array([0.0847626939447046,0.0648669375488877,0.0505127048998841,0.0431477690668965,0.0443458995091662,0.0638361516754724,0.0926698200065443,0.122716357496751,0.135591683864019,0.0377466753027189,-0.0889166586897228,-0.0310700016943258,0.16530654803759,0.237349858169585,0.0577692051497442,-0.137751577705709,-0.18354744395111,-0.188205427540335,-0.157902857480421,-0.055391323576937,0.0791892398460303,0.198068185997372,0.271471422836112,0.282275886815228,0.246689293630916,0.205546705496588,0.16546007731141,0.145130898382968,0.1471329636038,0.142472749823065,0.132163448290946,0.111958195551385])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_udwt_soft(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [0,3.0,0,2,0,0])
    signal_denoised_corr = array([0.086668016749428,0.078090652632278,0.070455842749544,0.062824684205684,0.064249795534642,0.086899924318641,0.053549539548214,0.100644175366308,0.100726560037458,0.051479406046214,-0.011299945211104,0.036115394710961,0.147624998547612,0.159516308766960,0.059119062682569,-0.020817294484415,-0.042170912413038,-0.046825168298822,-0.027179285827824,0.017379645805457,0.071225126011476,0.123532780238470,0.153926034241219,0.160138755049699,0.153562168658336,0.138748019440599,0.123707805352361,0.115223425612607,0.110890877355381,0.107909648973443,0.103630954238181,0.095849084980685])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_udwt_levels(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [0,3.0,0,1,4,0])
    signal_denoised_corr = array([0.137633389000662,0.120676804147327,0.0997827582151432,0.0156985740202669,-0.0251180988153785,0.319788331991522,-0.217919217670089,0.160238201773756,0.131270340429534,-0.0414158027972923,-0.249853610380694,-0.0801267408837784,0.275034335985338,0.296982831400265,0.00620014657281041,-0.234309647934845,-0.33273125185212,-0.296826946748889,-0.178550726178275,-0.0748494125178897,0.0503752660102483,0.203803428830869,0.310249668154709,0.343153832290091,0.330977383703058,0.287293930382695,0.234092474931927,0.201635010491445,0.185054027697432,0.178142873294961,0.171851794429319,0.157162133645098])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))
  
  def test_denoise_udwt_actual_thresh(self):
    signal = makesig('Doppler', 32)
    noise = array([1.54421189550395,0.0859311331754255,-1.49159031063761,-0.742301837259857,-1.06158173331999,2.35045722400204,-0.615601881466894,0.748076783703985,-0.192418510588264,0.888610425420721,-0.764849236567874,-1.40226896933876,-1.42237592509150,0.488193909859941,-0.177375156618825,-0.196053487807333,1.41931015064255,0.291584373984183,0.197811053464361,1.58769908997406,-0.804465956349547,0.696624415849607,0.835088165072682,-0.243715140377952,0.215670086403744,-1.16584393148205,-1.14795277889859,0.104874716016494,0.722254032225002,2.58549125261624,-0.666890670701386,0.187331024578940])
    with_noise = signal + noise / 10
    h = daubcqf(6)[0]
    signal_denoised, subtracted_noise, actual_options = denoise(with_noise, h, 1, [0,3.0,0,1,0,0.5])
    signal_denoised_corr = array([0.126244615385152,0.09523197124253,0.0671343607152503,0.0513902979722585,0.0430402732682634,0.0586932575131794,0.0861069751902698,0.0989949047763016,0.0908418658128637,-0.0141454670119059,-0.144791527437026,-0.0185533166035902,0.278351613782131,0.279033706376659,-0.0205012032054263,-0.212367658407976,-0.241484343697995,-0.248582298831059,-0.213374214781743,-0.101963712141109,0.0454248851310567,0.181104333949749,0.275294407293258,0.309076259882059,0.298600450385073,0.259080737796607,0.211123535801717,0.183021783525739,0.171966340866576,0.171616812586097,0.168720006300193,0.151066428184072])
    self.assertTrue(allclose(signal_denoised, signal_denoised_corr, 0.01))

  def test_daubcqf_min(self):
    (a, b) = daubcqf(4)
    ax = [0.482962913144534,0.836516303737808,0.224143868042013,-0.129409522551260]
    bx = [0.129409522551260,0.224143868042013,-0.836516303737808,0.482962913144534]
    self.assertTrue(allclose(a, ax, 0.000001))
    self.assertTrue(allclose(b, bx, 0.000001))
    
  def test_daubcqf_max(self):
    (a, b) = daubcqf(4, 'max')
    ax = [-0.129409522551260,0.224143868042013,0.836516303737808,0.482962913144534]
    bx = [-0.482962913144534,0.836516303737808,-0.224143868042013,-0.129409522551260]
    self.assertTrue(allclose(a, ax, 0.000001))
    self.assertTrue(allclose(b, bx, 0.000001))
    
  def test_daubcqf_mid_even_k(self):
    (a, b) = daubcqf(4, 'mid')
    ax = [0.482962913144534,0.836516303737808,0.224143868042013,-0.129409522551260]
    bx = [0.129409522551260,0.224143868042013,-0.836516303737808,0.482962913144534]
    self.assertTrue(allclose(a, ax, 0.000001))
    self.assertTrue(allclose(b, bx, 0.000001))
    
  def test_daubcqf_mid_odd_k(self):
    (a, b) = daubcqf(6, 'mid')
    ax = [0.332670552950083,0.806891509311093,0.459877502118491,-0.135011020010255,-0.085441273882027,0.035226291885710]
    bx = [-0.035226291885710,-0.085441273882027,0.135011020010255,0.459877502118491,-0.806891509311093,0.332670552950083]
    self.assertTrue(allclose(a, ax, 0.000001))
    self.assertTrue(allclose(b, bx, 0.000001))
  
if __name__ == '__main__':
    unittest.main()
