def orthonormalize_wavelets(g0, g1, k): ''' USE LONGFLOATS Orthonormalize in reverse order ''' for i in range(k - 1, -1, -1): for attempt in range(1): # was 2 # Orthog to previous functions for m in range(k - 1, i, -1): dotim = dot(g0[i] + g1[i], g0[m] + g1[m]) for j in range(k): g0[i][j] = g0[i][j] - dotim * g0[m][j] g1[i][j] = g1[i][j] - dotim * g1[m][j] norm = dot(g0[i] + g1[i], g0[i] + g1[i]) rnorm = norm.rsqrt() for j in range(k): g0[i][j] = g0[i][j] * rnorm g1[i][j] = g1[i][j] * rnorm
def orthonormalize_wavelets(g0,g1,k): ''' USE LONGFLOATS Orthonormalize in reverse order ''' for i in range(k-1,-1,-1): for attempt in range(1): # was 2 # Orthog to previous functions for m in range(k-1,i,-1): dotim = dot(g0[i]+g1[i],g0[m]+g1[m]) for j in range(k): g0[i][j] = g0[i][j] - dotim*g0[m][j] g1[i][j] = g1[i][j] - dotim*g1[m][j] norm = dot(g0[i]+g1[i],g0[i]+g1[i]) rnorm = norm.rsqrt() for j in range(k): g0[i][j] = g0[i][j]*rnorm g1[i][j] = g1[i][j]*rnorm
def g0g1(k): ''' USE LONGFLOATS Compute the g0 & g1 two-scale coefficients which define the multi-wavelet in terms of the scaling functions at the finer level. psi_i(x) = sqrt(2)*sum(j) g0_ij*phi_j(2x) + g1_ij*phi_j(2x-1) Projection with sqrt(2)*phi_j(2x) and sqrt(2)*phi_j(2x-1), which are the normalized scaling functions on the finer level, yields g0_ij = sqrt(2)*int(psi_i(x)*phi_j(2x),x=0..1/2) g1_ij = sqrt(2)*int(psi_i(x)*phi_j(2x-1),x=1/2..1) With the original Alpert conditions we have g1_ij = (-1)^(i+j+k) g0_ij from symmetry properties of the psi but you only get this if you impose the condition of additional vanishing moments. The projection of the additional moments is very numerically unstable and forces the use of higher precision for k >= 6. ''' g0 = zeromatrix(k, k) g1 = zeromatrix(k, k) # Initialize the basis rroot2 = longfloat(2).rsqrt() for i in range(0, k): g0[i][i] = rroot2 g1[i][i] = -rroot2 (h0, h1) = h0h1(k) # Project out the moments == orthog to the scaling functions. # Need to use the two-scale relation for the scaling functions. for i in range(k): for attempt in range(1): # was 2 for m in range(k): dotim = dot(g0[i], h0[m]) + dot(g1[i], h1[m]) for j in range(k): g0[i][j] = g0[i][j] - dotim * h0[m][j] g1[i][j] = g1[i][j] - dotim * h1[m][j] # Orthog to x^k, x^k+1, ... , x^2k-2 first = 0 root2 = longfloat(2).sqrt() (hmom1, hmom2) = half_moments(2 * k - 2, k) test = longfloat(1).eps().sqrt() for power in range(k, 2 * k - 1): # Transform to the wavelet basis overlap = zerovector(k) for i in range(k): for j in range(k): overlap[i] = overlap[i] + root2*\ (g0[i][j]*hmom1[power][j] + g1[i][j]*hmom2[power][j]) # Put first function with non-zero overlap in front of the list for i in range(first, k): if abs(overlap[i]) > test: # Is there a better test? (g0[first], g0[i]) = (g0[i], g0[first]) (g1[first], g1[i]) = (g1[i], g1[first]) (overlap[first], overlap[i]) = (overlap[i], overlap[first]) break # Project out the first component as necessary. if abs(overlap[first]) > test: # Is there a better test? for i in range(first + 1, k): scale = overlap[i] / overlap[first] for j in range(k): g0[i][j] = g0[i][j] - scale * g0[first][j] g1[i][j] = g1[i][j] - scale * g1[first][j] first = first + 1 orthonormalize_wavelets(g0, g1, k) return (g0, g1)
def g0g1(k): ''' USE LONGFLOATS Compute the g0 & g1 two-scale coefficients which define the multi-wavelet in terms of the scaling functions at the finer level. psi_i(x) = sqrt(2)*sum(j) g0_ij*phi_j(2x) + g1_ij*phi_j(2x-1) Projection with sqrt(2)*phi_j(2x) and sqrt(2)*phi_j(2x-1), which are the normalized scaling functions on the finer level, yields g0_ij = sqrt(2)*int(psi_i(x)*phi_j(2x),x=0..1/2) g1_ij = sqrt(2)*int(psi_i(x)*phi_j(2x-1),x=1/2..1) With the original Alpert conditions we have g1_ij = (-1)^(i+j+k) g0_ij from symmetry properties of the psi but you only get this if you impose the condition of additional vanishing moments. The projection of the additional moments is very numerically unstable and forces the use of higher precision for k >= 6. ''' g0 = zeromatrix(k,k) g1 = zeromatrix(k,k) # Initialize the basis rroot2 = longfloat(2).rsqrt() for i in range(0,k): g0[i][i] = rroot2 g1[i][i] = -rroot2 (h0, h1) = h0h1(k) # Project out the moments == orthog to the scaling functions. # Need to use the two-scale relation for the scaling functions. for i in range(k): for attempt in range(1): # was 2 for m in range(k): dotim = dot(g0[i],h0[m])+dot(g1[i],h1[m]) for j in range(k): g0[i][j] = g0[i][j] - dotim*h0[m][j] g1[i][j] = g1[i][j] - dotim*h1[m][j] # Orthog to x^k, x^k+1, ... , x^2k-2 first = 0 root2 = longfloat(2).sqrt() (hmom1,hmom2) = half_moments(2*k-2,k) test = longfloat(1).eps().sqrt() for power in range(k,2*k-1): # Transform to the wavelet basis overlap = zerovector(k) for i in range(k): for j in range(k): overlap[i] = overlap[i] + root2*\ (g0[i][j]*hmom1[power][j] + g1[i][j]*hmom2[power][j]) # Put first function with non-zero overlap in front of the list for i in range(first,k): if abs(overlap[i]) > test: # Is there a better test? (g0[first],g0[i]) = (g0[i],g0[first]) (g1[first],g1[i]) = (g1[i],g1[first]) (overlap[first],overlap[i]) = (overlap[i],overlap[first]) break # Project out the first component as necessary. if abs(overlap[first]) > test: # Is there a better test? for i in range(first+1,k): scale = overlap[i]/overlap[first] for j in range(k): g0[i][j] = g0[i][j] - scale*g0[first][j] g1[i][j] = g1[i][j] - scale*g1[first][j] first = first + 1 orthonormalize_wavelets(g0,g1,k) return (g0, g1)