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