#
# = Discrete Wavelet Transforms
# This chapter describes functions for performing Discrete Wavelet Transforms 
# (DWTs). 
# The library includes wavelets for real data in both one and two dimensions. 
#
# Contents:
# 1. {Definitions}[link:files/rdoc/rdoc/wavelet_rdoc.html#1]
# 1. {Initialization}[link:files/rdoc/rdoc/wavelet_rdoc.html#2]
# 1. {Transform methods}[link:files/rdoc/rdoc/wavelet_rdoc.html#3]
#    1. {Wavelet transforms in one dimension}[link:files/rdoc/rdoc/wavelet_rdoc.html#3.1]
#    1. {Wavelet transforms in two dimension}[link:files/rdoc/rdoc/wavelet_rdoc.html#3.2]
# 1. {Examples}[link:files/rdoc/rdoc/wavelet_rdoc.html#4]
#
# == {}[link:index.html"name="1] Definitions
#
# The continuous wavelet transform and its inverse are defined by the relations,
# and,
# where the basis functionspsi_{s,tau} are obtained by scaling and translation 
# from a single function, referred to as the mother wavelet.
#
# The discrete version of the wavelet transform acts on evenly sampled data, 
# with fixed scaling and translation steps (s, tau). The frequency and time 
# axes are sampled dyadically on scales of 2^j through a level parameter j. 
# The resulting family of functions {psi_{j,n}} constitutes an orthonormal 
# basis for square-integrable signals.
#
# The discrete wavelet transform is an O(N) algorithm, and is also referred to as 
# the fast wavelet transform.
#
# == {}[link:index.html"name="2] Initialization
#
# ---
# * GSL::Wavelet.alloc(type, k)
# * GSL::Wavelet.alloc(type, k)
#
#   This function allocates and initializes a wavelet object of type <tt>type</tt>. 
#   The parameter <tt>k</tt> selects the specific member of the wavelet family. 
#
#   The wavelet types are given by a constant (Fixnum) or a string as followings.
#
#   * <tt>GSL::Wavelet::DAUBECHIES</tt>, or <tt>"daubechies"</tt>
#   * <tt>GSL::Wavelet::DAUBECHIES_CENTERED</tt>, or <tt>"daubechies_centered"</tt>
#   * <tt>GSL::Wavelet::HAAR</tt>, or <tt>"haar"</tt>
#   * <tt>GSL::Wavelet::HAAR_CENTERED</tt>, or <tt>"haar_centered"</tt>
#   * <tt>GSL::Wavelet::BSPLINE</tt>, or <tt>"bspline"</tt>
#   * <tt>GSL::Wavelet::BSPLINE_CENTERED</tt>, or <tt>"bspline_centered"</tt>
#
#   The centered forms of the wavelets align the coefficients of the various 
#   sub-bands on edges. Thus the resulting visualization of the coefficients 
#   of the wavelet transform in the phase plane is easier to understand.
#
# ---
# * GSL::Wavelet#name
#
#   This method returns a String of the name of the wavelet family for <tt>self</tt>.
#
# ---
# * GSL::Wavelet::Workspace.alloc(n)
#
#   The GSL::Wavelet::Workspace object contains scratch space of the same size as 
#   the input data, for holding intermediate results during the transform.
#   This method allocates a workspace for the discrete wavelet transform. 
#   To perform a one-dimensional transform on <tt>n</tt> elements, a workspace of 
#   size <tt>n</tt> must be provided. For two-dimensional transforms of n-by-n 
#   matrices it is sufficient to allocate a workspace of size <tt>n</tt>, 
#   since the transform operates on individual rows and columns.
#
# == {}[link:index.html"name="3] Transform Methods
# === {}[link:index.html"name="3.1] Wavelet transforms in one dimension
#
# ---
# * GSL::Wavelet.transform(w, v, dir = GSL::Wavelet::FORWARD, work)
# * GSL::Wavelet.transform(w, v, dir)
# * GSL::Wavelet.transform(w, v, work)
# * GSL::Wavelet.transform(w, v)
# * GSL::Wavelet#transform(v, dir = GSL::Wavelet::FORWARD, work)
# * GSL::Wavelet#transform(v, dir)
# * GSL::Wavelet#transform(v, work)
# * GSL::Wavelet#transform(v)
# * GSL::Wavelet.transform_forward(w, v, work)
# * GSL::Wavelet.transform_forward(w, v)
# * GSL::Wavelet#transform_forward(v, work)
# * GSL::Wavelet#transform_forward(v)
# * GSL::Wavelet.transform_inverse(w, v, work)
# * GSL::Wavelet.transform_inverse(w, v)
# * GSL::Wavelet#transform_inverse(v, work)
# * GSL::Wavelet#transform_inverse(v)
# * GSL::Vector#wavelet_transform(w, ...)
# * GSL::Vector#wavelet_transform_forward(w, ...)
# * GSL::Vector#wavelet_transform_inverse(w, ...)
#
#   These methods compute forward and inverse discrete wavelet transforms 
#   of the vector <tt>v</tt>. The length of the transform is restricted to powers 
#   of two. For the transform version of the function the argument dir can be 
#   either GSL::Wavelet::FORWARD (+1) or GSL::Wavelet::BACKWARD (-1). 
#   A workspace <tt>work</tt> can be omitted.
#   
#   If <tt>v</tt> is a <tt>GSL::Matrix</tt> object, methods for 2d-transforms
#   are called.
#
#   For the forward transform, the elements of the original vector are replaced by 
#   the discrete wavelet transform f_i -> w_{j,k} in a packed triangular storage 
#   layout, where j is the index of the level j = 0 ... J-1 and k is the index of 
#   the coefficient within each level, k = 0 ... (2^j)-1. The total number of 
#   levels is J = log_2(n). 
#
#   These methods return a transformed data, and the input vector is not changed.
#
# === {}[link:index.html"name="3.2] Wavelet transforms in two dimension
# ---
# * GSL::Wavelet.transform(same as the methods for one dimensional transforms)
# * GSL::Wavelet.transform_matrix()
# * GSL::Wavelet2d.transform()
# * GSL::Wavelet#transform(same as the methods for one dimensional transforms)
# * GSL::Wavelet#transform_matrix()
# * GSL::Wavelet2d#transform()
#
#
# ---
# * GSL::Wavelet.transform_forward()
# * GSL::Wavelet.transform_matrix_forward()
# * GSL::Wavelet2d.transform_forward()
# * GSL::Wavelet#transform_forward()
# * GSL::Wavelet#transform_matrix_forward()
# * GSL::Wavelet2d#transform_forward()
#
#
# ---
# * GSL::Wavelet.transform_inverse()
# * GSL::Wavelet.transform_matrix_inverse()
# * GSL::Wavelet2d.transform_inverse()
# * GSL::Wavelet#transform_inverse()
# * GSL::Wavelet#transform_matrix_inverse()
# * GSL::Wavelet2d#transform_inverse()
#
#
# ---
# * GSL::Wavelet.nstransform(same as the methods for one dimensional nstransforms)
# * GSL::Wavelet.nstransform_matrix()
# * GSL::Wavelet2d.nstransform()
# * GSL::Wavelet#nstransform(same as the methods for one dimensional nstransforms)
# * GSL::Wavelet#nstransform_matrix()
# * GSL::Wavelet2d#nstransform()
#
#
# ---
# * GSL::Wavelet.nstransform_forward()
# * GSL::Wavelet.nstransform_matrix_forward()
# * GSL::Wavelet2d.nstransform_forward()
# * GSL::Wavelet#nstransform_forward()
# * GSL::Wavelet#nstransform_matrix_forward()
# * GSL::Wavelet2d#nstransform_forward()
#
#
# ---
# * GSL::Wavelet.nstransform_inverse()
# * GSL::Wavelet.nstransform_matrix_inverse()
# * GSL::Wavelet2d.nstransform_inverse()
# * GSL::Wavelet#nstransform_inverse()
# * GSL::Wavelet#nstransform_matrix_inverse()
# * GSL::Wavelet2d#nstransform_inverse()
#
#
# == {}[link:index.html"name="4] Example
#   #!/usr/bin/env ruby
#   require("gsl")
#
#   n = 256
#   nc = 20
#  
#   data = Vector.alloc(n)
#   data.fscanf("ecg.dat")
#
#   w = GSL::Wavelet.alloc("daubechies", 4)
#   work = GSL::Wavelet::Workspace.alloc(n)
#
#   ##### Choose as you like...
#   data2 = w.transform(data, Wavelet::FORWARD, work)
#   #data2 = w.transform(data, work)
#   #data2 = w.transform(data)
#   #data2 = w.transform(data, Wavelet::FORWARD)
#   #data2 = w.transform_forward(data, work)
#   #data2 = w.transform_forward(data)
#   #data2 = Wavelet.transform(w, data, Wavelet::FORWARD, work)
#   #data2 = Wavelet.transform(w, data, Wavelet::FORWARD)
#   #data2 = Wavelet.transform(w, data, work)
#   #data2 = Wavelet.transform_forward(w, data)
#   #data2 = data.wavelet_transform(w, Wavelet::FORWARD, work)
#   #data2 = data.wavelet_transform_forward(w, work)
#
#   perm = data2.abs.sort_index
#
#   i = 0
#   while (i + nc) < n
#     data2[perm[i]] = 0.0
#     i += 1  
#   end
#
#   #data3 = w.transform(data2, Wavelet::BACKWARD, work)
#   #data3 = w.transform(data2, Wavelet::BACKWARD)
#   #data3 = w.transform_inverse(data2, work)
#   #data3 = w.transform_inverse(data2)
#   #data3 = Wavelet.transform(w, data2, Wavelet::BACKWARD, work)
#   #data3 = Wavelet.transform(w, data2, Wavelet::BACKWARD)
#   #data3 = Wavelet.transform_inverse(w, data2, work)
#   data3 = Wavelet.transform_inverse(w, data2)
#   #data3 = data2.wavelet_transform(w, Wavelet::BACKWARD, work)
#   #data3 = data2.wavelet_transform_inverse(w, work)
#
#   #If you have GNU graph utility...
#   GSL::graph(nil, data, data3, "-T X -C -g 3")
#   
# {prev}[link:files/rdoc/rdoc/fft_rdoc.html]
# {next}[link:files/rdoc/rdoc/integration_rdoc.html]
#
# {back}[link:files/rdoc/rdoc/index_rdoc.html]
#
