Here we calculate the 3-term connection coefficients. I glued pycco and MathJax together. This gives a nice documentation of the code in form of literate scientific programming.
However, there is a bug in my code: The value this programm computes, are not equal to the ones from Resnikov and Wells, 1998. Except for l=m. Find the raw python code in my Github repository. Please let me know if you find the issue!
with
import itertools
import warnings
import numpy as np
from scipy.misc import factorial
from moments import moment
from scaling_coefficients import db3, daubechies_wavelets
def threeterm_connection_coefficients(a, d1, d2, d3):
The 3-term connection coefficients are defined as which can be transformed by a change of variables with and to
if d1 == 0:
idx, indices, Λ = fundamental_threeterm_connection_coefficients(a, d1, d2, d3)
idx2 = lambda i,j,k: idx(j-i, k-i)
return idx2, indices, Λ
else:
Using integration by parts we can focus on the case
idx1, indices1, Λ1 = threeterm_connection_coefficients(a, d1-1, d2+1, d3)
idx2, indices2, Λ2 = threeterm_connection_coefficients(a, d1-1, d2, d3+1)
assert indices1 == indices2
return idx1, indices1, -Λ1 - Λ2
def fundamental_threeterm_connection_coefficients(a, d1, d2, d3):
Our wavelet has non-zero scaling coefficients where is the genus.
N = a.size
aindices = range(N)
d = d1 + d2 + d3
The fundamental connection coefficients are just non-zero for
Tindices = list(set((l,m) for l,m in itertools.product(range(-(N-2), (N-2)+1), repeat=2)
if abs(l-m) < (N-1)))
idx = lambda l,m: Tindices.index((l,m))
M = 3*N**2 - 9*N + 7
assert len(Tindices)
The Daubechies wavelet of genus has just as many vanishing moments and we must not calculate higher derivatives than !
if np.amax([d1,d2,d3]) >= N/2:
msg = 'Calculation of connection coefficients for {},{},{} > g = N/2 is invalid!'.format(d1,d2,d3)
warnings.warn(msg)
We exploit the fact that which means for the connection coefficients using the chain rule with .
Using a change of variables and remembering we find
This gives a system of equations of the form where .
T = np.zeros([len(Tindices), len(Tindices)])
for l,m in Tindices:
for i,j,k in itertools.product(range(N), repeat=3):
if (2*l+j-i, 2*m+k-i) not in Tindices:
continue # skip the Λ which are zero anyway
T[idx(l,m), idx(2*l+j-i, 2*m+k-i)] += a[i]*a[j]*a[k]
T -= 2**(1-d)*np.eye(len(Tindices))
b = np.zeros([len(Tindices)])
If we differentiate the moment equation times with , we yield the equation Then multiplying by for some fixed , and integrating, we gain Finally, we perform a change of variables Similar equations hold for and .
M = np.zeros([d1, len(Tindices)])
j = 0 if (d2 % 2) == 0 else 1
k = 0 if (d3 % 2) == 0 else 1
for q in range(d1):
for i in range(-(N-2), (N-2)+1):
if (j-i, k-i) in Tindices:
M[q, idx(j-i, k-i)] += moment(a, i, q)
A = np.vstack([T,M])
b = np.hstack([b, np.zeros([d1])])
M = np.zeros([d2, len(Tindices)])
i = 0 if (d1 % 2) == 0 else 1
k = 0 if (d3 % 2) == 0 else 1
for q in range(d2):
for j in range(-(N-2), (N-2)+1):
if (j-i, k-i) in Tindices:
M[q, idx(j-i, k-i)] += moment(a, j, q)
A = np.vstack([A,M])
b = np.hstack([b, np.zeros([d2])])
M = np.zeros([d3, len(Tindices)])
i = 0 if (d1 % 2) == 0 else 1
j = 0 if (d2 % 2) == 0 else 1
for q in range(d3):
for k in range(-(N-2), (N-2)+1):
if (j-i, k-i) in Tindices:
M[q, idx(j-i, k-i)] += moment(a, k, q)
A = np.vstack([A,M])
b = np.hstack([b, np.zeros([d3])])
Finally we differentiate the moment equation times, yielding Similar equations hold for and . Multiplying these equations and integrating gains Again with a change of variables this yields
M = np.zeros([1, len(Tindices)])
i = 0
for j,k in itertools.product(range(-(N-2), (N-2)+1), repeat=2):
if (j-i, k-i) in Tindices:
M[0, idx(j-i, k-i)] += moment(a, j, d2)*moment(a, k, d3)
A = np.vstack([A,M])
b = np.hstack([b, [factorial(d1)*factorial(d2)*factorial(d3)]])
Λ, residuals, rank, singular_values = np.linalg.lstsq(A, b)
if (residuals > 1e-30).any():
msg = 'Residuals {} of connection coefficients exceed 10**-30!'.format(residuals)
warnings.warn(msg)
return idx, Tindices, Λ
def test():
from test_cc3 import cc3_100
idx, Tindices, Λ = threeterm_connection_coefficients(db3, 1, 0, 0)
N = len(db3)
for l,m in itertools.product(range(-(N-2), (N-2)+1), repeat=2):
a = Λ[idx(0,l,m)] if abs(l-m) < (N-1) else 0
b = cc3_100[(l,m)]
print(l,m, a, b, (a-b)/(b if b != 0 else 1))
if __name__ == '__main__':
test()