Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/gsl/dwt.pyx
4068 views
1
"""
2
Wavelet transform wrapper. Wraps GSL's gsl_wavelet_transform_forward,
3
and gsl_wavelet_transform_inverse and creates plot methods.
4
5
AUTHOR:
6
Josh Kantor (2006-10-07) - initial version
7
David Joyner (2006-10-09) - minor changes to docstrings and examples.
8
9
"""
10
11
#*****************************************************************************
12
# Copyright (C) 2006 Joshua Kantor <[email protected]>
13
#
14
# Distributed under the terms of the GNU General Public License (GPL)
15
#
16
# This code is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
# General Public License for more details.
20
#
21
# The full text of the GPL is available at:
22
#
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
#include 'gsl.pxi'
27
28
import sage.plot.all
29
30
#import gsl_array
31
#cimport gsl_array
32
33
def WaveletTransform(n, wavelet_type, wavelet_k):
34
"""
35
This function initializes an GSLDoubleArray of length n which
36
can perform a discrete wavelet transform.
37
38
INPUT:
39
n -- a power of 2.
40
T -- the data in the GSLDoubleArray must be real.
41
wavelet_type -- the name of the type of wavelet,
42
valid choices are:
43
'daubechies','daubechies_centered',
44
'haar','haar_centered','bspline', and
45
'bspline_centered'.
46
47
For daubechies wavelets, wavelet_k specifies a daubechie wavelet
48
with k/2 vanishing moments. k = 4,6,...,20 for k even are the
49
only ones implemented.
50
For Haar wavelets, wavelet_k must be 2.
51
For bspline wavelets, wavelet_k = 103,105,202,204,206,208,301,305,
52
307,309 will give biorthogonal B-spline wavelets of order (i,j) where
53
wavelet_k=100*i+j.
54
The wavelet transform uses J=log_2(n) levels.
55
56
OUTPUT:
57
58
An array of the form
59
(s_{-1,0},d_{0,0},d_{1,0},d_{1,1}, d_{2,0}...,d_{J-1,2^{J-1}-1})
60
for d_{j,k} the detail coefficients of level j.
61
The centered forms align the coefficients of the sub-bands on edges.
62
63
EXAMPLES::
64
65
sage: a = WaveletTransform(128,'daubechies',4)
66
sage: for i in range(1, 11):
67
... a[i] = 1
68
... a[128-i] = 1
69
sage: a.plot().show(ymin=0)
70
sage: a.forward_transform()
71
sage: a.plot().show()
72
sage: a = WaveletTransform(128,'haar',2)
73
sage: for i in range(1, 11): a[i] = 1; a[128-i] = 1
74
sage: a.forward_transform()
75
sage: a.plot().show(ymin=0)
76
sage: a = WaveletTransform(128,'bspline_centered',103)
77
sage: for i in range(1, 11): a[i] = 1; a[100+i] = 1
78
sage: a.forward_transform()
79
sage: a.plot().show(ymin=0)
80
81
This example gives a simple example of wavelet compression::
82
83
sage: a = DWT(2048,'daubechies',6)
84
sage: for i in range(2048): a[i]=float(sin((i*5/2048)**2))
85
sage: a.plot().show() # long time (7s on sage.math, 2011)
86
sage: a.forward_transform()
87
sage: for i in range(1800): a[2048-i-1] = 0
88
sage: a.backward_transform()
89
sage: a.plot().show() # long time (7s on sage.math, 2011)
90
"""
91
cdef size_t _n, _k
92
_n = int(n)
93
if _n < 0:
94
raise ValueError, "n must be nonnegative."
95
_k = int(wavelet_k)
96
if not is2pow(_n):
97
raise NotImplementedError,"discrete wavelet transform only implemented when n is a 2-power"
98
return DiscreteWaveletTransform(_n,1,wavelet_type,_k)
99
100
DWT = WaveletTransform
101
102
cdef class DiscreteWaveletTransform(gsl_array.GSLDoubleArray):
103
def __cinit__(self,size_t n,size_t stride, wavelet_type, size_t wavelet_k):
104
self.wavelet = NULL
105
self.workspace = NULL
106
107
def __init__(self,size_t n,size_t stride, wavelet_type, size_t wavelet_k):
108
if not is2pow(n):
109
raise NotImplementedError,"discrete wavelet transform only implemented when n is a 2-power"
110
gsl_array.GSLDoubleArray.__init__(self,n,stride)
111
if wavelet_type=="daubechies":
112
self.wavelet = <gsl_wavelet*> gsl_wavelet_alloc(gsl_wavelet_daubechies, wavelet_k)
113
elif wavelet_type == "daubechies_centered":
114
self.wavelet = <gsl_wavelet*> gsl_wavelet_alloc(gsl_wavelet_daubechies_centered,wavelet_k)
115
elif wavelet_type == "haar":
116
self.wavelet = <gsl_wavelet *> gsl_wavelet_alloc(gsl_wavelet_haar,wavelet_k)
117
elif wavelet_type == "haar_centered":
118
self.wavelet = <gsl_wavelet*> gsl_wavelet_alloc(gsl_wavelet_haar_centered,wavelet_k)
119
elif wavelet_type == "bspline":
120
self.wavelet = <gsl_wavelet*> gsl_wavelet_alloc(gsl_wavelet_bspline,wavelet_k)
121
elif wavelet_type == "bspline_centered":
122
self.wavelet = <gsl_wavelet*> gsl_wavelet_alloc(gsl_wavelet_bspline_centered,wavelet_k)
123
self.workspace = <gsl_wavelet_workspace*> gsl_wavelet_workspace_alloc(n)
124
125
def __dealloc__(self):
126
if self.wavelet != NULL:
127
gsl_wavelet_free(self.wavelet)
128
gsl_wavelet_workspace_free(self.workspace)
129
130
def forward_transform(self):
131
gsl_wavelet_transform_forward(self.wavelet,self.data,self.stride,self.n,self.workspace)
132
133
def backward_transform(self):
134
gsl_wavelet_transform_inverse(self.wavelet,self.data,self.stride,self.n,self.workspace)
135
136
def plot(self,xmin=None,xmax=None,**args):
137
cdef int i
138
cdef double x
139
v = []
140
point = sage.plot.all.point
141
if xmin == None:
142
x_min = 0
143
if xmax == None:
144
x_max=self.n
145
for i from x_min <=i < x_max:
146
x = self.data[i]
147
if i >0:
148
v.append(point([(i,x)],hue=(1,1,1),**args))
149
return sum(v)
150
151
152
def is2pow(unsigned int n):
153
while n != 0 and n%2 == 0:
154
n = n >> 1
155
return n == 1
156
157