def psi(self, t): """DOG wavelet as described in Torrence and Compo (1998) The derivative of a Gaussian of order n can be determined using the probabilistic Hermite polynomials. They are explicitly written as: Hn(x) = 2 ** (-n / s) * n! * sum ((-1) ** m) * (2 ** 0.5 * x) ** (n - 2 * m) / (m! * (n - 2*m)!) or in the recursive form: Hn(x) = x * Hn(x) - nHn-1(x) Source: http://www.ask.com/wiki/Hermite_polynomials """ p = hermitenorm(self.m) return (-1) ** (self.m + 1) * polyval(p, t) * np.exp(-t ** 2 / 2) / np.sqrt(gamma(self.m + 0.5))
def psi(self, t): """DOG wavelet as described in Torrence and Compo (1998) The derivative of a Gaussian of order n can be determined using the probabilistic Hermite polynomials. They are explicitly written as: Hn(x) = 2 ** (-n / s) * n! * sum ((-1) ** m) * (2 ** 0.5 * x) ** (n - 2 * m) / (m! * (n - 2*m)!) or in the recursive form: Hn(x) = x * Hn(x) - nHn-1(x) Source: http://www.ask.com/wiki/Hermite_polynomials """ p = hermitenorm(self.m) return ((-1) ** (self.m + 1) * polyval(p, t) * exp(-t ** 2 / 2) / sqrt(gamma(self.m + 0.5)))
def test_he_roots(): rootf = orth.he_roots evalf = orth.eval_hermitenorm weightf = orth.hermitenorm(5).weight_func verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 5) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 25, atol=1e-13) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 100, atol=1e-12) x, w = orth.he_roots(5, False) y, v, m = orth.he_roots(5, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) muI, muI_err = integrate.quad(weightf, -np.inf, np.inf) assert_allclose(m, muI, rtol=muI_err) assert_raises(ValueError, orth.he_roots, 0) assert_raises(ValueError, orth.he_roots, 3.3)
def test_roots_hermitenorm(): rootf = sc.roots_hermitenorm evalf = orth.eval_hermitenorm weightf = orth.hermitenorm(5).weight_func verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 5) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 25, atol=1e-13) verify_gauss_quad(rootf, evalf, weightf, -np.inf, np.inf, 100, atol=1e-12) x, w = sc.roots_hermitenorm(5, False) y, v, m = sc.roots_hermitenorm(5, True) assert_allclose(x, y, 1e-14, 1e-14) assert_allclose(w, v, 1e-14, 1e-14) muI, muI_err = integrate.quad(weightf, -np.inf, np.inf) assert_allclose(m, muI, rtol=muI_err) assert_raises(ValueError, sc.roots_hermitenorm, 0) assert_raises(ValueError, sc.roots_hermitenorm, 3.3)
def test_hermitenorm(self): # He_n(x) = 2**(-n/2) H_n(x/sqrt(2)) psub = np.poly1d([1.0 / sqrt(2), 0]) H0 = orth.hermitenorm(0) H1 = orth.hermitenorm(1) H2 = orth.hermitenorm(2) H3 = orth.hermitenorm(3) H4 = orth.hermitenorm(4) H5 = orth.hermitenorm(5) he0 = orth.hermite(0)(psub) he1 = orth.hermite(1)(psub) / sqrt(2) he2 = orth.hermite(2)(psub) / 2.0 he3 = orth.hermite(3)(psub) / (2 * sqrt(2)) he4 = orth.hermite(4)(psub) / 4.0 he5 = orth.hermite(5)(psub) / (4.0 * sqrt(2)) assert_array_almost_equal(H0.c, he0.c, 13) assert_array_almost_equal(H1.c, he1.c, 13) assert_array_almost_equal(H2.c, he2.c, 13) assert_array_almost_equal(H3.c, he3.c, 13) assert_array_almost_equal(H4.c, he4.c, 13) assert_array_almost_equal(H5.c, he5.c, 13)
def test_hermitenorm(self): # He_n(x) = 2**(-n/2) H_n(x/sqrt(2)) psub = np.poly1d([1.0/sqrt(2),0]) H0 = orth.hermitenorm(0) H1 = orth.hermitenorm(1) H2 = orth.hermitenorm(2) H3 = orth.hermitenorm(3) H4 = orth.hermitenorm(4) H5 = orth.hermitenorm(5) he0 = orth.hermite(0)(psub) he1 = orth.hermite(1)(psub) / sqrt(2) he2 = orth.hermite(2)(psub) / 2.0 he3 = orth.hermite(3)(psub) / (2*sqrt(2)) he4 = orth.hermite(4)(psub) / 4.0 he5 = orth.hermite(5)(psub) / (4.0*sqrt(2)) assert_array_almost_equal(H0.c,he0.c,13) assert_array_almost_equal(H1.c,he1.c,13) assert_array_almost_equal(H2.c,he2.c,13) assert_array_almost_equal(H3.c,he3.c,13) assert_array_almost_equal(H4.c,he4.c,13) assert_array_almost_equal(H5.c,he5.c,13)
def wavelet_inverse(wave, scale, dt, dj=0.25, mother="MORLET", param=-1): """Inverse continuous wavelet transform Torrence and Compo (1998), eq. (11) INPUTS waves (array like): WAVE is the WAVELET transform. This is a complex array. scale (array like): the vector of scale indices dt (float) : amount of time between each original value, i.e. the sampling time. dj (float, optional) : the spacing between discrete scales. Default is 0.25. A smaller # will give better scale resolution, but be slower to plot. mother (string, optional) : the mother wavelet function. The choices are 'MORLET', 'PAUL', or 'DOG' PARAM = the mother wavelet parameter. For 'MORLET' this is k0 (wavenumber), default is 6. For 'PAUL' this is m (order), default is 4. For 'DOG' this is m (m-th derivative), default is 2. OUTPUTS iwave (array like) : Inverse wavelet transform. """ import numpy as np j1, n = wave.shape J1 = len(scale) if not j1 == J1: print j1, n, J1 raise Exception("Input array are inconsistent") sj = np.dot(scale.reshape(len(scale), 1), np.ones((1, n))) # mother = mother.upper() # psi0 comes from Table 1,2 Torrence and Compo (1998) # Cdelta comes from Table 2 Torrence and Compo (1998) if mother == 'MORLET': #----------------------------------- Morlet if (param == -1): param = 6. psi0 = np.pi**(-0.25) if param == 6.: Cdelta = 0.776 elif mother == 'PAUL': #-------------------------------- Paul if (param == -1): param = 4. m = param psi0 = np.real(2.**m * 1j**m * np.prod(np.arange(2, m + 1)) / np.sqrt(np.pi * np.prod(np.arange(2, 2 * m + 1))) * (1**(-(m + 1)))) if m == 4.: Cdelta = 1.132 elif mother == 'DOG': #-------------------------------- DOG if (param == -1): param = 2. m = param from scipy.special import gamma from numpy.lib.polynomial import polyval from scipy.special.orthogonal import hermitenorm p = hermitenorm(m) psi0 = (-1)**(m + 1) / np.sqrt(gamma(m + 0.5)) * polyval(p, 0) print psi0 if m == 2.: Cdelta = 3.541 if m == 6.: Cdelta = 1.966 else: raise Exception("Mother must be one of MORLET,PAUL,DOG") #eq. (11) in Torrence and Compo (1998) iwave = dj * np.sqrt(dt) / Cdelta / psi0 * (np.real(wave) / sj**0.5).sum(axis=0) return iwave
def wavelet_inverse(wave, scale, dt, dj=0.25, mother="MORLET",param=-1): """Inverse continuous wavelet transform Torrence and Compo (1998), eq. (11) INPUTS waves (array like): WAVE is the WAVELET transform. This is a complex array. scale (array like): the vector of scale indices dt (float) : amount of time between each original value, i.e. the sampling time. dj (float, optional) : the spacing between discrete scales. Default is 0.25. A smaller # will give better scale resolution, but be slower to plot. mother (string, optional) : the mother wavelet function. The choices are 'MORLET', 'PAUL', or 'DOG' PARAM = the mother wavelet parameter. For 'MORLET' this is k0 (wavenumber), default is 6. For 'PAUL' this is m (order), default is 4. For 'DOG' this is m (m-th derivative), default is 2. OUTPUTS iwave (array like) : Inverse wavelet transform. """ import numpy as np j1, n = wave.shape J1 = len(scale) if not j1 == J1: print j1,n,J1 raise Exception("Input array are inconsistent") sj = np.dot(scale.reshape(len(scale),1),np.ones((1,n))) # mother = mother.upper() # psi0 comes from Table 1,2 Torrence and Compo (1998) # Cdelta comes from Table 2 Torrence and Compo (1998) if mother=='MORLET': #----------------------------------- Morlet if (param == -1): param = 6. psi0=np.pi**(-0.25) if param==6.: Cdelta = 0.776 elif mother=='PAUL': #-------------------------------- Paul if (param == -1): param = 4. m = param psi0=np.real(2.**m*1j**m*np.prod(np.arange(2, m + 1))/np.sqrt(np.pi*np.prod(np.arange(2,2*m+1)))*(1**(-(m+1)))) if m==4.: Cdelta = 1.132 elif mother=='DOG': #-------------------------------- DOG if (param == -1): param = 2. m = param from scipy.special import gamma from numpy.lib.polynomial import polyval from scipy.special.orthogonal import hermitenorm p = hermitenorm(m) psi0=(-1)**(m+1)/np.sqrt(gamma(m+0.5))*polyval(p, 0) print psi0 if m==2.: Cdelta=3.541 if m==6.: Cdelta=1.966 else: raise Exception("Mother must be one of MORLET,PAUL,DOG") #eq. (11) in Torrence and Compo (1998) iwave = dj * np.sqrt(dt) / Cdelta /psi0 * (np.real(wave) / sj**0.5).sum(axis=0) return iwave