如何计算函数的小波逼近?

计算科学 Python 傅立叶分析 小波
2021-12-16 14:22:58

对于函数f(x)=x,如何使用 Haar 基计算小波逼近?

我是小波的新手,我正在寻找一个可以做这样的事情的包

from mpmath import *
mp.dps = 15; mp.pretty = True
nb_coeff = 3
interval = [0, 10]
fct = lambda x : x
fourier_coef = fourier(fct, interval, nb_coeff)
fourier_series_apx = lambda x: fourierval(fourier_coef, interval, x)

这可以在 Haar 的基础上用pywavelets完成吗?
或者,是否有另一个库可以为 Haar 小波生成上述功能?

编辑
怀疑他们可能没有提供上述功能的包,我试图自己推出。
我的实现目前不起作用,我在这里问了一个问题。

2个回答

这是纯粹的哈尔缩放函数逼近f(t)

f(t)=k=akϕ(2jtk)
在哪里
ϕ(t)={1;0t<1,0;otherwise.
是哈尔缩放函数,j缩放参数,k平移参数和系数
ak=f(t)ϕ(2jtk)dt
所以在我们的情况下,如果f(t)=t, 为了kZ并且对于j=0我们必须计算ak=f(t)ϕ(tk)dt. 我们知道ϕ(tk)=1为了t[k,k+1)其他地方为零。所以我们只整合[k,k+1).
ak=kk+1tϕ(tk)dt=2k+12
因此我们有
f(t)=12k=(2k+1)ϕ(tk)
以下脚本绘制了 haar 近似与给定函数的关系f(x)=x

import numpy as np
import matplotlib.pyplot as plt

def init(x,j,k):
    y=np.piecewise(x,[x < 0, x > 1],[lambda x: 0, lambda x: 0, lambda x:1]) 
    t=(x+k)/2**j
    ii=np.where(y==1)
    return y[ii], t[ii]

a=-4 #lower limit of sum
b=4 #upper limit of sum
j=0
k=np.arange(a*2**j,b*2**j)
y=(2*k+1)/2 # the coefficients a_k
T=np.arange(0,2,0.01)
[p,dummy]=init(T*2**j,j,0)
phi=np.ones((len(k),len(p)))
t=np.zeros((len(k),len(p)))

for i in range (1,len(k)+1):
    [p,t1]=init(T*2**j,j,i-1)
    t[i-1,:]=t1+a

for l in range (1,len(k)+1):
    plt.plot(t[l-1,:],2**j*y[l-1]*phi[l-1,:],'r') 

在此处输入图像描述

哈尔近似f(x)=cos(x)为了j=2
在此处输入图像描述

感谢 Jan。我完成了我的实施工作。
下面的代码比较:Haar vs Fourier vs Chebyshev。
在此处输入图像描述

from __future__ import division
from mpmath import *

# --------- Haar wavelet approximation of a function
# algorithm from : http://fourier.eng.hmc.edu/e161/lectures/wavelets/node5.html
# implementation only handle [0,1] for the moment: scaling and wavelet fcts need to be periodice

phi = lambda x : (0 <= x < 1) #scaling fct
psi = lambda x : (0 <= x < .5) - (.5 <= x < 1) #wavelet fct
phi_j_k = lambda x, j, k : 2**(j/2) * phi(2**j * x - k)
psi_j_k = lambda x, j, k : 2**(j/2) * psi(2**j * x - k)

def haar(f, interval, level):
    c0 = quadgl(  lambda t : f(t) * phi_j_k(t, 0, 0), interval  )

    coef = []
    for j in xrange(0, level):
        for k in xrange(0, 2**j):
                djk = quadgl(  lambda t: f(t) * psi_j_k(t, j, k), interval  )
                coef.append( (j, k, djk) )

    return c0, coef

def haarval(haar_coef, x):
    c0, coef = haar_coef
    s = c0 * phi_j_k(x, 0, 0)
    for j, k ,djk in coef:
            s += djk * psi_j_k(x, j, k)
    return s

# --------- to plot an Haar wave
interval = [0, 1]
plot([lambda x : phi_j_k(x,1,1)],interval)

# ---------- main
# below is code to compate : Haar vs Fourier vs Chebyshev

nb_coeff = 5
interval = [0, 1] # haar only handle [0,1] for the moment: scaling and wavelet fcts need to be periodice

fct = lambda x : x

haar_coef = haar(fct, interval, nb_coeff)
haar_series_apx = lambda x : haarval(haar_coef, x)

fourier_coef = fourier(fct, interval, nb_coeff)
fourier_series_apx = lambda x: fourierval(fourier_coef, interval, x)
chebyshev_coef = chebyfit(fct, interval, nb_coeff)
chebyshev_series_apx = lambda x : polyval(chebyshev_coef, x)


print 'fourier %d chebyshev %d haar %d' % ( len(fourier_coef[0]) + len(fourier_coef[1]),len(chebyshev_coef), 1 + len(haar_coef[1]))
print 'error:'
print 'fourier', quadgl(  lambda x : abs( fct(x) - fourier_series_apx(x) ), interval  )
print 'chebyshev', quadgl(  lambda x : abs( fct(x) - chebyshev_series_apx(x) ), interval  )
print 'haar', quadgl(  lambda x : abs( fct(x) - haar_series_apx(x) ), interval  )

plot([fct, fourier_series_apx, chebyshev_series_apx, haar_series_apx], interval)