././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/0000755000175000017500000000000000000000000012550 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/LICENSE0000644000175000017500000000271400000000000013561 0ustar00pierrepierre# Copyright 2016 Pierre Paleo # License: BSD # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of ESRF nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061201.0 pycudwt-1.0.2/MANIFEST.in0000644000175000017500000000006400000000000014306 0ustar00pierrepierreinclude pdwt/src/*.h recursive-include pdwt/src/*.h ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/PKG-INFO0000644000175000017500000000050700000000000013647 0ustar00pierrepierreMetadata-Version: 2.1 Name: pycudwt Version: 1.0.2 Summary: UNKNOWN Home-page: UNKNOWN Author: Pierre Paleo Author-email: pierre.paleo@esrf.fr Maintainer: Pierre Paleo Maintainer-email: pierre.paleo@esrf.fr License: UNKNOWN Platform: UNKNOWN License-File: LICENSE Python Wrapper for Cuda Discrete Wavelet Transform ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061329.0 pycudwt-1.0.2/README.md0000644000175000017500000000347400000000000014037 0ustar00pierrepierre## pycudwt pycudwt is a python module for parallel Discrete Wavelet Transform. This is a wrapper of [PDWT](https://github.com/pierrepaleo/PDWT). **Note:** this project was formerly named `pypwt`. It has been renamed `pycudwt` to have a spot on [pypi](https://pypi.org/project/pycudwt). ## Installation ### Requirements You need cython and nvcc (the Nvidia CUDA compiler, available in the [NVIDIA CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit)). For the tests, you need pywavelets. `python-pywt` is packaged for Debian-like distributions, more recent changes are available on [the new repository](https://github.com/PyWavelets/pywt). ### Stable version (from pypi) ```bash pip install pycudwt ``` ### From conda recipe Conda build for a specific *cudatoolkit* version that matches one in your conda environment, e.g.: ``` export CUDA_VERSION="10.1.243" conda build conda-recipe/ ``` ### Development version (from github) ```bash git clone https://github.com/pierrepaleo/pypwt cd pypwt pip install . ``` You can specify the compute capability when building the library: ```bash PYCUDWT_CC=86 pip install . ``` ### Testing If `pywt` is available, you can check if pycudwt gives consistent results : ```bash cd test python test_all.py ``` the results are stored in `results.log`. ## Getting started Computing a Wavelet Transform wity pycudwt is simple. In `ipython`: ```python from pycudwt import Wavelets from scipy.misc import lena l = lena() W = Wavelets(l, "db2", 3) W ------------- Wavelet transform infos ------------ Wavelet name : db2 Number of levels : 3 Stationary WT : no Cycle spinning : no Separable transform : yes Estimated memory footprint : 5.2 MB Running on device : GeForce GTX TITAN X -------------------------------------------------- W.forward() W.soft_threshold(10) W.inverse() imshow(W.image) ``` ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/pdwt/0000755000175000017500000000000000000000000013526 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/pdwt/src/0000755000175000017500000000000000000000000014315 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/common.cu0000644000175000017500000004773400000000000016155 0ustar00pierrepierre/// **************************************************************************** /// ***************** Common utilities and CUDA Kernels ********************** /// **************************************************************************** //~ #include "utils.h" #include "common.h" #define W_SIGN(a) ((a > 0) ? (1.0f) : (-1.0f)) #define SQRT_2 1.4142135623730951 #include /// soft thresholding of the detail coefficients (2D) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_soft_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_h[gidy*Nc + gidx]; c_h[gidy*Nc + gidx] = copysignf(max(fabsf(val)-beta, 0.0f), val); val = c_v[gidy*Nc + gidx]; c_v[gidy*Nc + gidx] = copysignf(max(fabsf(val)-beta, 0.0f), val); val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = copysignf(max(fabsf(val)-beta, 0.0f), val); } } /// soft thresholding of the detail coefficients (1D) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector // CHECKME: consider merging this kernel with the previous kernel __global__ void w_kern_soft_thresh_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = copysignf(max(fabsf(val)-beta, 0.0f), val); } } /// soft thresholding of the approximation coefficients (2D and 1D) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_soft_thresh_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_a[gidy*Nc + gidx]; c_a[gidy*Nc + gidx] = copysignf(max(fabsf(val)-beta, 0.0f), val); } } /// Hard thresholding of the detail coefficients (2D) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_hard_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_h[gidy*Nc + gidx]; c_h[gidy*Nc + gidx] = max(W_SIGN(fabsf(val)-beta), 0.0f)*val; val = c_v[gidy*Nc + gidx]; c_v[gidy*Nc + gidx] = max(W_SIGN(fabsf(val)-beta), 0.0f)*val; val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = max(W_SIGN(fabsf(val)-beta), 0.0f)*val; } } /// Hard thresholding of the detail coefficients (1D) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector // CHECKME: consider merging this kernel with the previous kernel __global__ void w_kern_hard_thresh_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = max(W_SIGN(fabsf(val)-beta), 0.0f)*val; } } /// Hard thresholding of the approximation coefficients (2D and 1D) __global__ void w_kern_hard_thresh_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_a[gidy*Nc + gidx]; c_a[gidy*Nc + gidx] = max(W_SIGN(fabsf(val)-beta), 0.0f)*val; } } /// Projection of the coefficients onto the L-infinity ball of radius "beta" (2D). /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_proj_linf(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_h[gidy*Nc + gidx]; c_h[gidy*Nc + gidx] = copysignf(min(fabsf(val), beta), val); val = c_v[gidy*Nc + gidx]; c_v[gidy*Nc + gidx] = copysignf(min(fabsf(val), beta), val); val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = copysignf(min(fabsf(val), beta), val); } } __global__ void w_kern_proj_linf_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_a[gidy*Nc + gidx]; c_a[gidy*Nc + gidx] = copysignf(min(fabsf(val), beta), val); } } /// Projection of the coefficients onto the L-infinity ball of radius "beta" (1D). /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_proj_linf_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; DTYPE val = 0.0f; if (gidx < Nc && gidy < Nr) { val = c_d[gidy*Nc + gidx]; c_d[gidy*Nc + gidx] = copysignf(min(fabsf(val), beta), val); } } /// group soft thresholding the detail coefficients (2D) /// If do_thresh_appcoeffs, the appcoeff (A) is only used at the last scale: /// - At any scale, c_a == NULL /// - At the last scale, c_a != NULL (i.e its size is the same as c_h, c_v, c_d) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_group_soft_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* c_a, DTYPE beta, int Nr, int Nc, int do_thresh_appcoeffs) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidx < Nc && gidy < Nr) { int tid = gidy*Nc + gidx; DTYPE val_h = 0.0f, val_v = 0.0f, val_d = 0.0f, val_a = 0.0f; DTYPE norm = 0, res = 0; val_h = c_h[tid]; val_v = c_v[tid]; val_d = c_d[tid]; norm = val_h*val_h + val_v*val_v + val_d*val_d; if (c_a != NULL) { // SWT val_a = c_a[tid]; norm += val_a*val_a; } norm = sqrtf(norm); if (norm == 0) res = 0; else res = max(1 - beta/norm, 0.0); c_h[tid] *= res; c_v[tid] *= res; c_d[tid] *= res; if (c_a != NULL) c_a[tid] *= res; } } /// group soft thresholding of the coefficients (1D) /// If do_thresh_appcoeffs, the appcoeff (A) is only used at the last scale: /// - At any scale, c_a == NULL /// - At the last scale, c_a != NULL (i.e its size is the same as c_d) /// Must be lanched with block size (Nc, Nr) : the size of the current coefficient vector __global__ void w_kern_group_soft_thresh_1d(DTYPE* c_d, DTYPE* c_a, DTYPE beta, int Nr, int Nc, int do_thresh_appcoeffs) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidx < Nc && gidy < Nr) { int tid = gidy*Nc + gidx; DTYPE val_d = 0.0f, val_a = 0.0f; DTYPE norm = 0, res = 0; val_d = c_d[tid]; norm = val_d*val_d; // does not make much sense to use DWT_1D + group_soft_thresh (use soft_tresh) if (c_a != NULL) { // SWT val_a = c_a[tid]; norm += val_a*val_a; } norm = sqrtf(norm); if (norm == 0) res = 0; else res = max(1 - beta/norm, 0.0); c_d[tid] *= res; if (c_a != NULL) c_a[tid] *= res; } } /// Circular shift of the image (2D and 1D) __global__ void w_kern_circshift(DTYPE* d_image, DTYPE* d_out, int Nr, int Nc, int sr, int sc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidx < Nc && gidy < Nr) { int r = gidy - sr, c = gidx - sc; if (r < 0) r += Nr; if (c < 0) c += Nc; d_out[gidy*Nc + gidx] = d_image[r*Nc + c]; } } /// **************************************************************************** /// ******************** Common CUDA Kernels calls ***************************** /// **************************************************************************** void w_call_soft_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize) { int tpb = 16; // Threads per block dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels, ndims = winfos.ndims; int Nr2 = Nr, Nc2 = Nc; if (!do_swt) { if (ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } if (do_thresh_appcoeffs) { DTYPE beta2 = beta; if (normalize > 0) { // beta2 = beta/sqrt(2)^nlevels int nlevels2 = nlevels/2; beta2 /= (1 << nlevels2); if (nlevels2 *2 != nlevels) beta2 /= SQRT_2; } n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); w_kern_soft_thresh_appcoeffs<<>>(d_coeffs[0], beta2, Nr2, Nc2); } for (int i = 0; i < nlevels; i++) { if (!do_swt) { if (ndims > 1) w_div2(&Nr); w_div2(&Nc); } if (normalize > 0) beta /= SQRT_2; n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); if (ndims > 1) w_kern_soft_thresh<<>>(d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], beta, Nr, Nc); else w_kern_soft_thresh_1d<<>>(d_coeffs[i+1], beta, Nr, Nc); } } void w_call_hard_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize) { int tpb = 16; // Threads per block dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels, ndims = winfos.ndims; int Nr2 = Nr, Nc2 = Nc; if (!do_swt) { if (ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } DTYPE beta2 = beta; if (do_thresh_appcoeffs) { if (normalize > 0) { // beta2 = beta/sqrt(2)^nlevels int nlevels2 = nlevels/2; beta2 /= (1 << nlevels2); if (nlevels2 *2 != nlevels) beta2 /= SQRT_2; } n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); w_kern_hard_thresh_appcoeffs<<>>(d_coeffs[0], beta, Nr2, Nc2); } for (int i = 0; i < nlevels; i++) { if (!do_swt) { if (ndims > 1) w_div2(&Nr); w_div2(&Nc); } if (normalize > 0) beta /= SQRT_2; n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); if (ndims > 1) w_kern_hard_thresh<<>>(d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], beta, Nr, Nc); else w_kern_hard_thresh_1d<<>>(d_coeffs[i+1], beta, Nr, Nc); } } void w_call_proj_linf(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs) { int tpb = 16; // Threads per block dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels, ndims = winfos.ndims; int Nr2 = Nr, Nc2 = Nc; if (!do_swt) { if (ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } if (do_thresh_appcoeffs) { n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); w_kern_proj_linf_appcoeffs<<>>(d_coeffs[0], beta, Nr2, Nc2); } for (int i = 0; i < nlevels; i++) { if (!do_swt) { if (ndims > 1) w_div2(&Nr); w_div2(&Nc); } n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); if (ndims > 1) w_kern_proj_linf<<>>(d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], beta, Nr, Nc); else w_kern_proj_linf_1d<<>>(d_coeffs[i+1], beta, Nr, Nc); } } void w_call_group_soft_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize) { int tpb = 16; // Threads per block dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels, ndims = winfos.ndims; int Nr2 = Nr, Nc2 = Nc; if (!do_swt) { if (ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } //~ if (do_thresh_appcoeffs) { //~ DTYPE beta2 = beta; //~ if (normalize > 0) { // beta2 = beta/sqrt(2)^nlevels //~ int nlevels2 = nlevels/2; //~ beta2 /= (1 << nlevels2); //~ if (nlevels2 *2 != nlevels) beta2 /= SQRT_2; //~ } //~ n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); //~ w_kern_soft_thresh_appcoeffs<<>>(d_coeffs[0], beta2, Nr2, Nc2); //~ } for (int i = 0; i < nlevels; i++) { if (!do_swt) { if (ndims > 1) w_div2(&Nr); w_div2(&Nc); } if (normalize > 0) beta /= SQRT_2; n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); if (ndims > 1) w_kern_group_soft_thresh<<>>(d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], ((do_thresh_appcoeffs && i == nlevels-1) ? d_coeffs[0]: NULL), beta, Nr, Nc, do_thresh_appcoeffs); else w_kern_group_soft_thresh_1d<<>>(d_coeffs[i+1], ((do_thresh_appcoeffs && i == nlevels-1) ? d_coeffs[0]: NULL), beta, Nr, Nc, do_thresh_appcoeffs); } } void w_shrink(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs) { int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels, ndims = winfos.ndims; int Nr2 = Nr, Nc2 = Nc; if (!do_swt) { if (ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } if (do_thresh_appcoeffs) { cublas_scal(Nr2*Nc2, 1.0f/(1.0f + beta), d_coeffs[0], 1); } for (int i = 0; i < nlevels; i++) { if (!do_swt) { if (ndims > 1) w_div2(&Nr); w_div2(&Nc); } if (ndims == 2) { cublas_scal(Nr*Nc, 1.0f/(1.0f + beta), d_coeffs[3*i+1], 1); cublas_scal(Nr*Nc, 1.0f/(1.0f + beta), d_coeffs[3*i+2], 1); cublas_scal(Nr*Nc, 1.0f/(1.0f + beta), d_coeffs[3*i+3], 1); } else { // 1D cublas_scal(Nr*Nc, 1.0f/(1.0f + beta), d_coeffs[i+1], 1); } } } // if inplace = 1, the result is in "d_image" ; otherwise result is in "d_image2". void w_call_circshift(DTYPE* d_image, DTYPE* d_image2, w_info winfos, int sr, int sc, int inplace) { int Nr = winfos.Nr, Nc = winfos.Nc, ndims = winfos.ndims; // Modulus in C can be negative if (sr < 0) sr += Nr; // or do while loops to ensure positive numbers if (sc < 0) sc += Nc; int tpb = 16; // Threads per block sr = sr % Nr; sc = sc % Nc; if (ndims == 1) sr = 0; dim3 n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); if (inplace) { cudaMemcpy(d_image2, d_image, Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); w_kern_circshift<<>>(d_image2, d_image, Nr, Nc, sr, sc); } else { w_kern_circshift<<>>(d_image, d_image2, Nr, Nc, sr, sc); } } /// Creates an allocated/padded device array : [ An, H1, V1, D1, ..., Hn, Vn, Dn] DTYPE** w_create_coeffs_buffer(w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels; int Nr0 = Nr, Nc0 = Nc; if (!do_swt) { w_div2(&Nr0); w_div2(&Nc0); } DTYPE** res = (DTYPE**) calloc(3*nlevels+1, sizeof(DTYPE*)); // Coeffs (H, V, D) for (int i = 1; i < 3*nlevels+1; i += 3) { if (!do_swt) { w_div2(&Nr); w_div2(&Nc); } cudaMalloc(&(res[i]), Nr*Nc*sizeof(DTYPE)); cudaMemset(res[i], 0, Nr*Nc*sizeof(DTYPE)); cudaMalloc(&(res[i+1]), Nr*Nc*sizeof(DTYPE)); cudaMemset(res[i+1], 0, Nr*Nc*sizeof(DTYPE)); cudaMalloc(&(res[i+2]), Nr*Nc*sizeof(DTYPE)); cudaMemset(res[i+2], 0, Nr*Nc*sizeof(DTYPE)); } // App coeff (last scale). They are also useful as a temp. buffer for the reconstruction, hence a bigger size cudaMalloc(&(res[0]), Nr0*Nc0*sizeof(DTYPE)); cudaMemset(res[0], 0, Nr0*Nc0*sizeof(DTYPE)); return res; } /// Creates an allocated/padded device array : [ An, D1, ..., Dn] DTYPE** w_create_coeffs_buffer_1d(w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels; int Nc0 = Nc; if (!do_swt) w_div2(&Nc0); DTYPE** res = (DTYPE**) calloc(nlevels+1, sizeof(DTYPE*)); // Det coeffs for (int i = 1; i < nlevels+1; i++) { if (!do_swt) w_div2(&Nc); cudaMalloc(&(res[i]), Nr*Nc*sizeof(DTYPE)); cudaMemset(res[i], 0, Nr*Nc*sizeof(DTYPE)); } // App coeff (last scale). They are also useful as a temp. buffer for the reconstruction, hence a bigger size cudaMalloc(&(res[0]), Nr*Nc0*sizeof(DTYPE)); cudaMemset(res[0], 0, Nr*Nc0*sizeof(DTYPE)); return res; } /// Deep free of wavelet coefficients void w_free_coeffs_buffer(DTYPE** coeffs, int nlevels) { for (int i = 0; i < 3*nlevels+1; i++) cudaFree(coeffs[i]); free(coeffs); } void w_free_coeffs_buffer_1d(DTYPE** coeffs, int nlevels) { for (int i = 0; i < nlevels+1; i++) cudaFree(coeffs[i]); free(coeffs); } /// Deep copy of wavelet coefficients. All structures must be allocated. void w_copy_coeffs_buffer(DTYPE** dst, DTYPE** src, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, nlevels = winfos.nlevels, do_swt = winfos.do_swt; // Coeffs (H, V, D) for (int i = 1; i < 3*nlevels+1; i += 3) { if (!do_swt) { w_div2(&Nr); w_div2(&Nc); } cudaMemcpy(dst[i], src[i], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); cudaMemcpy(dst[i+1], src[i+1], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); cudaMemcpy(dst[i+2], src[i+2], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); } // App coeff (last scale) cudaMemcpy(dst[0], src[0], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); } void w_copy_coeffs_buffer_1d(DTYPE** dst, DTYPE** src, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, nlevels = winfos.nlevels, do_swt = winfos.do_swt; // Det Coeffs for (int i = 1; i < nlevels+1; i++) { if (!do_swt) w_div2(&Nc); cudaMemcpy(dst[i], src[i], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); } // App coeff (last scale) cudaMemcpy(dst[0], src[0], Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); } /// /// ---------------------------------------------------------------------------- /// void w_add_coeffs(DTYPE** dst, DTYPE** src, w_info winfos, DTYPE alpha) { int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels; // Coeffs (H, V, D) for (int i = 1; i < 3*nlevels+1; i += 3) { if (!do_swt) { w_div2(&Nr); w_div2(&Nc); } cublas_axpy(Nr*Nc, alpha, src[i], 1, dst[i], 1); cublas_axpy(Nr*Nc, alpha, src[i+1], 1, dst[i+1], 1); cublas_axpy(Nr*Nc, alpha, src[i+2], 1, dst[i+2], 1); } // App coeff (last scale) cublas_axpy(Nr*Nc, alpha, src[0], 1, dst[0], 1); } /// dst = dst + alpha*src void w_add_coeffs_1d(DTYPE** dst, DTYPE** src, w_info winfos, DTYPE alpha) { int Nr = winfos.Nr, Nc = winfos.Nc, do_swt = winfos.do_swt, nlevels = winfos.nlevels; // Det Coeffs for (int i = 1; i < nlevels+1; i++) { if (!do_swt) Nc /= 2; cublas_axpy(Nr*Nc, alpha, src[i], 1, dst[i], 1); } // App coeff (last scale) cublas_axpy(Nr*Nc, alpha, src[0], 1, dst[0], 1); } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/common.h0000644000175000017500000000772000000000000015764 0ustar00pierrepierre#ifndef COMMON_H #define COMMON_H #include "utils.h" // For all architectures, constant mem is limited to 64 KB. // Here we limit the filter size to 40x40 coefficients => 25.6KB // If you know the max width of filters used in practice, it might be interesting to define it here // since MAX_FILTER_WIDTH * MAX_FILTER_WIDTH * 4 elements are transfered at each transform scale // // There are two approaches for inversion : // - compute the inverse filters into the previous constant arrays, before W.inverse(). It is a little slower. // - pre-compute c_kern_inv_XX once for all... faster, but twice more memory is used #define MAX_FILTER_WIDTH 40 #ifdef SEPARATE_COMPILATION extern __constant__ DTYPE c_kern_L[MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_H[MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_IL[MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_IH[MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_LL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_LH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_HL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; extern __constant__ DTYPE c_kern_HH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; #else __constant__ DTYPE c_kern_L[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_H[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_IL[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_IH[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_LL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_LH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_HL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_HH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; #endif __global__ void w_kern_soft_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_soft_thresh_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_soft_thresh_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc); __global__ void w_kern_proj_linf(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_proj_linf_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_proj_linf_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc); __global__ void w_kern_hard_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_hard_thresh_appcoeffs(DTYPE* c_a, DTYPE beta, int Nr, int Nc); __global__ void w_kern_group_soft_thresh(DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* c_a, DTYPE beta, int Nr, int Nc, int do_thresh_appcoeffs); __global__ void w_kern_group_soft_thresh_1d(DTYPE* c_d, DTYPE* c_a, DTYPE beta, int Nr, int Nc, int do_thresh_appcoeffs); __global__ void w_kern_circshift(DTYPE* d_image, DTYPE* d_out, int Nr, int Nc, int sr, int sc); void w_call_soft_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize); void w_call_hard_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize); void w_call_proj_linf(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs); void w_call_group_soft_thresh(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs, int normalize); void w_shrink(DTYPE** d_coeffs, DTYPE beta, w_info winfos, int do_thresh_appcoeffs); void w_call_circshift(DTYPE* d_image, DTYPE* d_image2, w_info winfos, int sr, int sc, int inplace = 1); DTYPE** w_create_coeffs_buffer(w_info winfos); void w_free_coeffs_buffer(DTYPE** coeffs, int nlevels); void w_copy_coeffs_buffer(DTYPE** dst, DTYPE** src, w_info winfos); DTYPE** w_create_coeffs_buffer_1d(w_info winfos); void w_free_coeffs_buffer_1d(DTYPE** coeffs, int nlevels); void w_copy_coeffs_buffer_1d(DTYPE** dst, DTYPE** src, w_info winfos); __global__ void w_kern_hard_thresh_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc); __global__ void w_kern_soft_thresh_1d(DTYPE* c_d, DTYPE beta, int Nr, int Nc); void w_add_coeffs(DTYPE** dst, DTYPE** src, w_info winfos, DTYPE alpha=1.0f); void w_add_coeffs_1d(DTYPE** dst, DTYPE** src, w_info winfos, DTYPE alpha=1.0f); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/filters.cpp0000644000175000017500000041315700000000000016504 0ustar00pierrepierre/// /// Wavelets coefficients, extracted from http://wavelets.pybytes.com /// #include "filters.h" DTYPE DB2_L[4] = { -0.12940952255092145, 0.22414386804185735, 0.836516303737469, 0.48296291314469025 }; DTYPE DB2_H[4] = { -0.48296291314469025, 0.836516303737469, -0.22414386804185735, -0.12940952255092145 }; DTYPE DB2_I_L[4] = { 0.48296291314469025, 0.836516303737469, 0.22414386804185735, -0.12940952255092145 }; DTYPE DB2_I_H[4] = { -0.12940952255092145, -0.22414386804185735, 0.836516303737469, -0.48296291314469025 }; DTYPE DB3_L[6] = { 0.035226291882100656, -0.08544127388224149, -0.13501102001039084, 0.4598775021193313, 0.8068915093133388, 0.3326705529509569 }; DTYPE DB3_H[6] = { -0.3326705529509569, 0.8068915093133388, -0.4598775021193313, -0.13501102001039084, 0.08544127388224149, 0.035226291882100656 }; DTYPE DB3_I_L[6] = { 0.3326705529509569, 0.8068915093133388, 0.4598775021193313, -0.13501102001039084, -0.08544127388224149, 0.035226291882100656 }; DTYPE DB3_I_H[6] = { 0.035226291882100656, 0.08544127388224149, -0.13501102001039084, -0.4598775021193313, 0.8068915093133388, -0.3326705529509569 }; DTYPE DB4_L[8] = { -0.010597401784997278, 0.032883011666982945 , 0.030841381835986965 , -0.18703481171888114 , -0.02798376941698385 , 0.6308807679295904 , 0.7148465705525415 , 0.23037781330885523 }; DTYPE DB4_H[8] = { -0.23037781330885523 , 0.7148465705525415 , -0.6308807679295904 , -0.02798376941698385 , 0.18703481171888114 , 0.030841381835986965 , -0.032883011666982945, -0.010597401784997278 }; DTYPE DB4_I_L[8] = { 0.23037781330885523 , 0.7148465705525415 , 0.6308807679295904 , -0.02798376941698385 , -0.18703481171888114 , 0.030841381835986965 , 0.032883011666982945 , -0.010597401784997278 }; DTYPE DB4_I_H[8] = { -0.010597401784997278, -0.032883011666982945, 0.030841381835986965 , 0.18703481171888114 , -0.02798376941698385 , -0.6308807679295904 , 0.7148465705525415 , -0.23037781330885523 }; DTYPE DB5_L[10] = { 0.003335725285001549, -0.012580751999015526, -0.006241490213011705, 0.07757149384006515, -0.03224486958502952, -0.24229488706619015, 0.13842814590110342, 0.7243085284385744, 0.6038292697974729, 0.160102397974125 }; DTYPE DB5_H[10] = { -0.160102397974125, 0.6038292697974729, -0.7243085284385744, 0.13842814590110342, 0.24229488706619015, -0.03224486958502952, -0.07757149384006515, -0.006241490213011705, 0.012580751999015526, 0.003335725285001549 }; DTYPE DB5_I_L[10] = { 0.160102397974125, 0.6038292697974729, 0.7243085284385744, 0.13842814590110342, -0.24229488706619015, -0.03224486958502952, 0.07757149384006515, -0.006241490213011705, -0.012580751999015526, 0.003335725285001549 }; DTYPE DB5_I_H[10] = { 0.003335725285001549, 0.012580751999015526, -0.006241490213011705, -0.07757149384006515, -0.03224486958502952, 0.24229488706619015, 0.13842814590110342, -0.7243085284385744, 0.6038292697974729, -0.160102397974125 }; DTYPE DB6_L[12] = { -0.00107730108499558, 0.004777257511010651, 0.0005538422009938016, -0.031582039318031156, 0.02752286553001629, 0.09750160558707936, -0.12976686756709563, -0.22626469396516913, 0.3152503517092432, 0.7511339080215775, 0.4946238903983854, 0.11154074335008017 }; DTYPE DB6_H[12] = { -0.11154074335008017, 0.4946238903983854, -0.7511339080215775, 0.3152503517092432, 0.22626469396516913, -0.12976686756709563, -0.09750160558707936, 0.02752286553001629, 0.031582039318031156, 0.0005538422009938016, -0.004777257511010651, -0.00107730108499558 }; DTYPE DB6_I_L[12] = { 0.11154074335008017, 0.4946238903983854, 0.7511339080215775, 0.3152503517092432, -0.22626469396516913, -0.12976686756709563, 0.09750160558707936, 0.02752286553001629, -0.031582039318031156, 0.0005538422009938016, 0.004777257511010651, -0.00107730108499558 }; DTYPE DB6_I_H[12] = { -0.00107730108499558, -0.004777257511010651, 0.0005538422009938016, 0.031582039318031156, 0.02752286553001629, -0.09750160558707936, -0.12976686756709563, 0.22626469396516913, 0.3152503517092432, -0.7511339080215775, 0.4946238903983854, -0.11154074335008017 }; DTYPE DB7_L[14] = { 0.0003537138000010399, -0.0018016407039998328, 0.00042957797300470274, 0.012550998556013784, -0.01657454163101562, -0.03802993693503463, 0.0806126091510659, 0.07130921926705004, -0.22403618499416572, -0.14390600392910627, 0.4697822874053586, 0.7291320908465551, 0.39653931948230575, 0.07785205408506236, }; DTYPE DB7_I_L[14] = { 0.07785205408506236, 0.39653931948230575, 0.7291320908465551, 0.4697822874053586, -0.14390600392910627, -0.22403618499416572, 0.07130921926705004, 0.0806126091510659, -0.03802993693503463, -0.01657454163101562, 0.012550998556013784, 0.00042957797300470274, -0.0018016407039998328, 0.0003537138000010399, }; DTYPE DB7_H[14] = { -0.07785205408506236, 0.39653931948230575, -0.7291320908465551, 0.4697822874053586, 0.14390600392910627, -0.22403618499416572, -0.07130921926705004, 0.0806126091510659, 0.03802993693503463, -0.01657454163101562, -0.012550998556013784, 0.00042957797300470274, 0.0018016407039998328, 0.0003537138000010399, }; DTYPE DB7_I_H[14] = { 0.0003537138000010399, 0.0018016407039998328, 0.00042957797300470274, -0.012550998556013784, -0.01657454163101562, 0.03802993693503463, 0.0806126091510659, -0.07130921926705004, -0.22403618499416572, 0.14390600392910627, 0.4697822874053586, -0.7291320908465551, 0.39653931948230575, -0.07785205408506236, }; DTYPE DB8_L[16] = { -0.00011747678400228192, 0.0006754494059985568, -0.0003917403729959771, -0.00487035299301066, 0.008746094047015655, 0.013981027917015516, -0.04408825393106472, -0.01736930100202211, 0.128747426620186, 0.00047248457399797254, -0.2840155429624281, -0.015829105256023893, 0.5853546836548691, 0.6756307362980128, 0.3128715909144659, 0.05441584224308161, }; DTYPE DB8_I_L[16] = { 0.05441584224308161, 0.3128715909144659, 0.6756307362980128, 0.5853546836548691, -0.015829105256023893, -0.2840155429624281, 0.00047248457399797254, 0.128747426620186, -0.01736930100202211, -0.04408825393106472, 0.013981027917015516, 0.008746094047015655, -0.00487035299301066, -0.0003917403729959771, 0.0006754494059985568, -0.00011747678400228192, }; DTYPE DB8_H[16] = { -0.05441584224308161, 0.3128715909144659, -0.6756307362980128, 0.5853546836548691, 0.015829105256023893, -0.2840155429624281, -0.00047248457399797254, 0.128747426620186, 0.01736930100202211, -0.04408825393106472, -0.013981027917015516, 0.008746094047015655, 0.00487035299301066, -0.0003917403729959771, -0.0006754494059985568, -0.00011747678400228192, }; DTYPE DB8_I_H[16] = { -0.00011747678400228192, -0.0006754494059985568, -0.0003917403729959771, 0.00487035299301066, 0.008746094047015655, -0.013981027917015516, -0.04408825393106472, 0.01736930100202211, 0.128747426620186, -0.00047248457399797254, -0.2840155429624281, 0.015829105256023893, 0.5853546836548691, -0.6756307362980128, 0.3128715909144659, -0.05441584224308161, }; DTYPE DB9_L[18] = { 3.9347319995026124e-05, -0.0002519631889981789, 0.00023038576399541288, 0.0018476468829611268, -0.004281503681904723, -0.004723204757894831, 0.022361662123515244, 0.00025094711499193845, -0.06763282905952399, 0.030725681478322865, 0.14854074933476008, -0.09684078322087904, -0.29327378327258685, 0.13319738582208895, 0.6572880780366389, 0.6048231236767786, 0.24383467463766728, 0.03807794736316728, }; DTYPE DB9_I_L[18] = { 0.03807794736316728, 0.24383467463766728, 0.6048231236767786, 0.6572880780366389, 0.13319738582208895, -0.29327378327258685, -0.09684078322087904, 0.14854074933476008, 0.030725681478322865, -0.06763282905952399, 0.00025094711499193845, 0.022361662123515244, -0.004723204757894831, -0.004281503681904723, 0.0018476468829611268, 0.00023038576399541288, -0.0002519631889981789, 3.9347319995026124e-05, }; DTYPE DB9_H[18] = { -0.03807794736316728, 0.24383467463766728, -0.6048231236767786, 0.6572880780366389, -0.13319738582208895, -0.29327378327258685, 0.09684078322087904, 0.14854074933476008, -0.030725681478322865, -0.06763282905952399, -0.00025094711499193845, 0.022361662123515244, 0.004723204757894831, -0.004281503681904723, -0.0018476468829611268, 0.00023038576399541288, 0.0002519631889981789, 3.9347319995026124e-05, }; DTYPE DB9_I_H[18] = { 3.9347319995026124e-05, 0.0002519631889981789, 0.00023038576399541288, -0.0018476468829611268, -0.004281503681904723, 0.004723204757894831, 0.022361662123515244, -0.00025094711499193845, -0.06763282905952399, -0.030725681478322865, 0.14854074933476008, 0.09684078322087904, -0.29327378327258685, -0.13319738582208895, 0.6572880780366389, -0.6048231236767786, 0.24383467463766728, -0.03807794736316728, }; DTYPE DB10_L[20] = { -1.326420300235487e-05, 9.358867000108985e-05, -0.0001164668549943862, -0.0006858566950046825, 0.00199240529499085, 0.0013953517469940798, -0.010733175482979604, 0.0036065535669883944, 0.03321267405893324, -0.02945753682194567, -0.07139414716586077, 0.09305736460380659, 0.12736934033574265, -0.19594627437659665, -0.24984642432648865, 0.2811723436604265, 0.6884590394525921, 0.5272011889309198, 0.18817680007762133, 0.026670057900950818, }; DTYPE DB10_I_L[20] = { 0.026670057900950818, 0.18817680007762133, 0.5272011889309198, 0.6884590394525921, 0.2811723436604265, -0.24984642432648865, -0.19594627437659665, 0.12736934033574265, 0.09305736460380659, -0.07139414716586077, -0.02945753682194567, 0.03321267405893324, 0.0036065535669883944, -0.010733175482979604, 0.0013953517469940798, 0.00199240529499085, -0.0006858566950046825, -0.0001164668549943862, 9.358867000108985e-05, -1.326420300235487e-05, }; DTYPE DB10_H[20] = { -0.026670057900950818, 0.18817680007762133, -0.5272011889309198, 0.6884590394525921, -0.2811723436604265, -0.24984642432648865, 0.19594627437659665, 0.12736934033574265, -0.09305736460380659, -0.07139414716586077, 0.02945753682194567, 0.03321267405893324, -0.0036065535669883944, -0.010733175482979604, -0.0013953517469940798, 0.00199240529499085, 0.0006858566950046825, -0.0001164668549943862, -9.358867000108985e-05, -1.326420300235487e-05, }; DTYPE DB10_I_H[20] = { -1.326420300235487e-05, -9.358867000108985e-05, -0.0001164668549943862, 0.0006858566950046825, 0.00199240529499085, -0.0013953517469940798, -0.010733175482979604, -0.0036065535669883944, 0.03321267405893324, 0.02945753682194567, -0.07139414716586077, -0.09305736460380659, 0.12736934033574265, 0.19594627437659665, -0.24984642432648865, -0.2811723436604265, 0.6884590394525921, -0.5272011889309198, 0.18817680007762133, -0.026670057900950818, }; DTYPE DB11_L[22] = { 4.494274277236352e-06, -3.463498418698379e-05, 5.443907469936638e-05, 0.00024915252355281426, -0.0008930232506662366, -0.00030859285881515924, 0.004928417656058778, -0.0033408588730145018, -0.015364820906201324, 0.02084090436018004, 0.03133509021904531, -0.06643878569502022, -0.04647995511667613, 0.14981201246638268, 0.06604358819669089, -0.27423084681792875, -0.16227524502747828, 0.41196436894789695, 0.6856867749161785, 0.44989976435603013, 0.1440670211506196, 0.01869429776147044, }; DTYPE DB11_I_L[22] = { 0.01869429776147044, 0.1440670211506196, 0.44989976435603013, 0.6856867749161785, 0.41196436894789695, -0.16227524502747828, -0.27423084681792875, 0.06604358819669089, 0.14981201246638268, -0.04647995511667613, -0.06643878569502022, 0.03133509021904531, 0.02084090436018004, -0.015364820906201324, -0.0033408588730145018, 0.004928417656058778, -0.00030859285881515924, -0.0008930232506662366, 0.00024915252355281426, 5.443907469936638e-05, -3.463498418698379e-05, 4.494274277236352e-06, }; DTYPE DB11_H[22] = { -0.01869429776147044, 0.1440670211506196, -0.44989976435603013, 0.6856867749161785, -0.41196436894789695, -0.16227524502747828, 0.27423084681792875, 0.06604358819669089, -0.14981201246638268, -0.04647995511667613, 0.06643878569502022, 0.03133509021904531, -0.02084090436018004, -0.015364820906201324, 0.0033408588730145018, 0.004928417656058778, 0.00030859285881515924, -0.0008930232506662366, -0.00024915252355281426, 5.443907469936638e-05, 3.463498418698379e-05, 4.494274277236352e-06, }; DTYPE DB11_I_H[22] = { 4.494274277236352e-06, 3.463498418698379e-05, 5.443907469936638e-05, -0.00024915252355281426, -0.0008930232506662366, 0.00030859285881515924, 0.004928417656058778, 0.0033408588730145018, -0.015364820906201324, -0.02084090436018004, 0.03133509021904531, 0.06643878569502022, -0.04647995511667613, -0.14981201246638268, 0.06604358819669089, 0.27423084681792875, -0.16227524502747828, -0.41196436894789695, 0.6856867749161785, -0.44989976435603013, 0.1440670211506196, -0.01869429776147044, }; DTYPE DB12_L[24] = { -1.5290717580684923e-06, 1.2776952219379579e-05, -2.4241545757030318e-05, -8.850410920820318e-05, 0.0003886530628209267, 6.5451282125215034e-06, -0.0021795036186277044, 0.0022486072409952287, 0.006711499008795549, -0.012840825198299882, -0.01221864906974642, 0.04154627749508764, 0.010849130255828966, -0.09643212009649671, 0.0053595696743599965, 0.18247860592758275, -0.023779257256064865, -0.31617845375277914, -0.04476388565377762, 0.5158864784278007, 0.6571987225792911, 0.3773551352142041, 0.10956627282118277, 0.013112257957229239, }; DTYPE DB12_I_L[24] = { 0.013112257957229239, 0.10956627282118277, 0.3773551352142041, 0.6571987225792911, 0.5158864784278007, -0.04476388565377762, -0.31617845375277914, -0.023779257256064865, 0.18247860592758275, 0.0053595696743599965, -0.09643212009649671, 0.010849130255828966, 0.04154627749508764, -0.01221864906974642, -0.012840825198299882, 0.006711499008795549, 0.0022486072409952287, -0.0021795036186277044, 6.5451282125215034e-06, 0.0003886530628209267, -8.850410920820318e-05, -2.4241545757030318e-05, 1.2776952219379579e-05, -1.5290717580684923e-06, }; DTYPE DB12_H[24] = { -0.013112257957229239, 0.10956627282118277, -0.3773551352142041, 0.6571987225792911, -0.5158864784278007, -0.04476388565377762, 0.31617845375277914, -0.023779257256064865, -0.18247860592758275, 0.0053595696743599965, 0.09643212009649671, 0.010849130255828966, -0.04154627749508764, -0.01221864906974642, 0.012840825198299882, 0.006711499008795549, -0.0022486072409952287, -0.0021795036186277044, -6.5451282125215034e-06, 0.0003886530628209267, 8.850410920820318e-05, -2.4241545757030318e-05, -1.2776952219379579e-05, -1.5290717580684923e-06, }; DTYPE DB12_I_H[24] = { -1.5290717580684923e-06, -1.2776952219379579e-05, -2.4241545757030318e-05, 8.850410920820318e-05, 0.0003886530628209267, -6.5451282125215034e-06, -0.0021795036186277044, -0.0022486072409952287, 0.006711499008795549, 0.012840825198299882, -0.01221864906974642, -0.04154627749508764, 0.010849130255828966, 0.09643212009649671, 0.0053595696743599965, -0.18247860592758275, -0.023779257256064865, 0.31617845375277914, -0.04476388565377762, -0.5158864784278007, 0.6571987225792911, -0.3773551352142041, 0.10956627282118277, -0.013112257957229239, }; DTYPE DB13_L[26] = { 5.2200350984548e-07, -4.700416479360808e-06, 1.0441930571407941e-05, 3.067853757932436e-05, -0.0001651289885565057, 4.9251525126285676e-05, 0.000932326130867249, -0.0013156739118922766, -0.002761911234656831, 0.007255589401617119, 0.003923941448795577, -0.02383142071032781, 0.002379972254052227, 0.056139477100276156, -0.026488406475345658, -0.10580761818792761, 0.07294893365678874, 0.17947607942935084, -0.12457673075080665, -0.31497290771138414, 0.086985726179645, 0.5888895704312119, 0.6110558511587811, 0.3119963221604349, 0.08286124387290195, 0.009202133538962279, }; DTYPE DB13_I_L[26] = { 0.009202133538962279, 0.08286124387290195, 0.3119963221604349, 0.6110558511587811, 0.5888895704312119, 0.086985726179645, -0.31497290771138414, -0.12457673075080665, 0.17947607942935084, 0.07294893365678874, -0.10580761818792761, -0.026488406475345658, 0.056139477100276156, 0.002379972254052227, -0.02383142071032781, 0.003923941448795577, 0.007255589401617119, -0.002761911234656831, -0.0013156739118922766, 0.000932326130867249, 4.9251525126285676e-05, -0.0001651289885565057, 3.067853757932436e-05, 1.0441930571407941e-05, -4.700416479360808e-06, 5.2200350984548e-07, }; DTYPE DB13_H[26] = { -0.009202133538962279, 0.08286124387290195, -0.3119963221604349, 0.6110558511587811, -0.5888895704312119, 0.086985726179645, 0.31497290771138414, -0.12457673075080665, -0.17947607942935084, 0.07294893365678874, 0.10580761818792761, -0.026488406475345658, -0.056139477100276156, 0.002379972254052227, 0.02383142071032781, 0.003923941448795577, -0.007255589401617119, -0.002761911234656831, 0.0013156739118922766, 0.000932326130867249, -4.9251525126285676e-05, -0.0001651289885565057, -3.067853757932436e-05, 1.0441930571407941e-05, 4.700416479360808e-06, 5.2200350984548e-07, }; DTYPE DB13_I_H[26] = { 5.2200350984548e-07, 4.700416479360808e-06, 1.0441930571407941e-05, -3.067853757932436e-05, -0.0001651289885565057, -4.9251525126285676e-05, 0.000932326130867249, 0.0013156739118922766, -0.002761911234656831, -0.007255589401617119, 0.003923941448795577, 0.02383142071032781, 0.002379972254052227, -0.056139477100276156, -0.026488406475345658, 0.10580761818792761, 0.07294893365678874, -0.17947607942935084, -0.12457673075080665, 0.31497290771138414, 0.086985726179645, -0.5888895704312119, 0.6110558511587811, -0.3119963221604349, 0.08286124387290195, -0.009202133538962279, }; DTYPE DB14_L[28] = { -1.7871399683109222e-07, 1.7249946753674012e-06, -4.389704901780418e-06, -1.0337209184568496e-05, 6.875504252695734e-05, -4.177724577037067e-05, -0.00038683194731287514, 0.0007080211542354048, 0.001061691085606874, -0.003849638868019787, -0.0007462189892638753, 0.01278949326634007, -0.0056150495303375755, -0.030185351540353976, 0.02698140830794797, 0.05523712625925082, -0.0715489555039835, -0.0867484115681106, 0.13998901658445695, 0.13839521386479153, -0.2180335299932165, -0.27168855227867705, 0.21867068775886594, 0.6311878491047198, 0.5543056179407709, 0.25485026779256437, 0.062364758849384874, 0.0064611534600864905, }; DTYPE DB14_I_L[28] = { 0.0064611534600864905, 0.062364758849384874, 0.25485026779256437, 0.5543056179407709, 0.6311878491047198, 0.21867068775886594, -0.27168855227867705, -0.2180335299932165, 0.13839521386479153, 0.13998901658445695, -0.0867484115681106, -0.0715489555039835, 0.05523712625925082, 0.02698140830794797, -0.030185351540353976, -0.0056150495303375755, 0.01278949326634007, -0.0007462189892638753, -0.003849638868019787, 0.001061691085606874, 0.0007080211542354048, -0.00038683194731287514, -4.177724577037067e-05, 6.875504252695734e-05, -1.0337209184568496e-05, -4.389704901780418e-06, 1.7249946753674012e-06, -1.7871399683109222e-07, }; DTYPE DB14_H[28] = { -0.0064611534600864905, 0.062364758849384874, -0.25485026779256437, 0.5543056179407709, -0.6311878491047198, 0.21867068775886594, 0.27168855227867705, -0.2180335299932165, -0.13839521386479153, 0.13998901658445695, 0.0867484115681106, -0.0715489555039835, -0.05523712625925082, 0.02698140830794797, 0.030185351540353976, -0.0056150495303375755, -0.01278949326634007, -0.0007462189892638753, 0.003849638868019787, 0.001061691085606874, -0.0007080211542354048, -0.00038683194731287514, 4.177724577037067e-05, 6.875504252695734e-05, 1.0337209184568496e-05, -4.389704901780418e-06, -1.7249946753674012e-06, -1.7871399683109222e-07, }; DTYPE DB14_I_H[28] = { -1.7871399683109222e-07, -1.7249946753674012e-06, -4.389704901780418e-06, 1.0337209184568496e-05, 6.875504252695734e-05, 4.177724577037067e-05, -0.00038683194731287514, -0.0007080211542354048, 0.001061691085606874, 0.003849638868019787, -0.0007462189892638753, -0.01278949326634007, -0.0056150495303375755, 0.030185351540353976, 0.02698140830794797, -0.05523712625925082, -0.0715489555039835, 0.0867484115681106, 0.13998901658445695, -0.13839521386479153, -0.2180335299932165, 0.27168855227867705, 0.21867068775886594, -0.6311878491047198, 0.5543056179407709, -0.25485026779256437, 0.062364758849384874, -0.0064611534600864905, }; DTYPE DB15_L[30] = { 6.133359913303714e-08, -6.316882325879451e-07, 1.8112704079399406e-06, 3.3629871817363823e-06, -2.8133296266037558e-05, 2.579269915531323e-05, 0.00015589648992055726, -0.00035956524436229364, -0.0003734823541372647, 0.0019433239803823459, -0.00024175649075894543, -0.0064877345603061454, 0.005101000360422873, 0.015083918027862582, -0.020810050169636805, -0.02576700732836694, 0.054780550584559995, 0.033877143923563204, -0.11112093603713753, -0.0396661765557336, 0.19014671400708816, 0.06528295284876569, -0.28888259656686216, -0.19320413960907623, 0.33900253545462167, 0.6458131403572103, 0.4926317717079753, 0.20602386398692688, 0.04674339489275062, 0.004538537361577376, }; DTYPE DB15_I_L[30] = { 0.004538537361577376, 0.04674339489275062, 0.20602386398692688, 0.4926317717079753, 0.6458131403572103, 0.33900253545462167, -0.19320413960907623, -0.28888259656686216, 0.06528295284876569, 0.19014671400708816, -0.0396661765557336, -0.11112093603713753, 0.033877143923563204, 0.054780550584559995, -0.02576700732836694, -0.020810050169636805, 0.015083918027862582, 0.005101000360422873, -0.0064877345603061454, -0.00024175649075894543, 0.0019433239803823459, -0.0003734823541372647, -0.00035956524436229364, 0.00015589648992055726, 2.579269915531323e-05, -2.8133296266037558e-05, 3.3629871817363823e-06, 1.8112704079399406e-06, -6.316882325879451e-07, 6.133359913303714e-08, }; DTYPE DB15_H[30] = { -0.004538537361577376, 0.04674339489275062, -0.20602386398692688, 0.4926317717079753, -0.6458131403572103, 0.33900253545462167, 0.19320413960907623, -0.28888259656686216, -0.06528295284876569, 0.19014671400708816, 0.0396661765557336, -0.11112093603713753, -0.033877143923563204, 0.054780550584559995, 0.02576700732836694, -0.020810050169636805, -0.015083918027862582, 0.005101000360422873, 0.0064877345603061454, -0.00024175649075894543, -0.0019433239803823459, -0.0003734823541372647, 0.00035956524436229364, 0.00015589648992055726, -2.579269915531323e-05, -2.8133296266037558e-05, -3.3629871817363823e-06, 1.8112704079399406e-06, 6.316882325879451e-07, 6.133359913303714e-08, }; DTYPE DB15_I_H[30] = { 6.133359913303714e-08, 6.316882325879451e-07, 1.8112704079399406e-06, -3.3629871817363823e-06, -2.8133296266037558e-05, -2.579269915531323e-05, 0.00015589648992055726, 0.00035956524436229364, -0.0003734823541372647, -0.0019433239803823459, -0.00024175649075894543, 0.0064877345603061454, 0.005101000360422873, -0.015083918027862582, -0.020810050169636805, 0.02576700732836694, 0.054780550584559995, -0.033877143923563204, -0.11112093603713753, 0.0396661765557336, 0.19014671400708816, -0.06528295284876569, -0.28888259656686216, 0.19320413960907623, 0.33900253545462167, -0.6458131403572103, 0.4926317717079753, -0.20602386398692688, 0.04674339489275062, -0.004538537361577376, }; DTYPE DB16_L[32] = { -2.1093396300980412e-08, 2.3087840868545578e-07, -7.363656785441815e-07, -1.0435713423102517e-06, 1.133660866126152e-05, -1.394566898819319e-05, -6.103596621404321e-05, 0.00017478724522506327, 0.00011424152003843815, -0.0009410217493585433, 0.00040789698084934395, 0.00312802338120381, -0.0036442796214883506, -0.006990014563390751, 0.013993768859843242, 0.010297659641009963, -0.036888397691556774, -0.007588974368642594, 0.07592423604445779, -0.006239722752156254, -0.13238830556335474, 0.027340263752899923, 0.21119069394696974, -0.02791820813292813, -0.3270633105274758, -0.08975108940236352, 0.44029025688580486, 0.6373563320829833, 0.43031272284545874, 0.1650642834886438, 0.03490771432362905, 0.0031892209253436892, }; DTYPE DB16_I_L[32] = { 0.0031892209253436892, 0.03490771432362905, 0.1650642834886438, 0.43031272284545874, 0.6373563320829833, 0.44029025688580486, -0.08975108940236352, -0.3270633105274758, -0.02791820813292813, 0.21119069394696974, 0.027340263752899923, -0.13238830556335474, -0.006239722752156254, 0.07592423604445779, -0.007588974368642594, -0.036888397691556774, 0.010297659641009963, 0.013993768859843242, -0.006990014563390751, -0.0036442796214883506, 0.00312802338120381, 0.00040789698084934395, -0.0009410217493585433, 0.00011424152003843815, 0.00017478724522506327, -6.103596621404321e-05, -1.394566898819319e-05, 1.133660866126152e-05, -1.0435713423102517e-06, -7.363656785441815e-07, 2.3087840868545578e-07, -2.1093396300980412e-08, }; DTYPE DB16_H[32] = { -0.0031892209253436892, 0.03490771432362905, -0.1650642834886438, 0.43031272284545874, -0.6373563320829833, 0.44029025688580486, 0.08975108940236352, -0.3270633105274758, 0.02791820813292813, 0.21119069394696974, -0.027340263752899923, -0.13238830556335474, 0.006239722752156254, 0.07592423604445779, 0.007588974368642594, -0.036888397691556774, -0.010297659641009963, 0.013993768859843242, 0.006990014563390751, -0.0036442796214883506, -0.00312802338120381, 0.00040789698084934395, 0.0009410217493585433, 0.00011424152003843815, -0.00017478724522506327, -6.103596621404321e-05, 1.394566898819319e-05, 1.133660866126152e-05, 1.0435713423102517e-06, -7.363656785441815e-07, -2.3087840868545578e-07, -2.1093396300980412e-08, }; DTYPE DB16_I_H[32] = { -2.1093396300980412e-08, -2.3087840868545578e-07, -7.363656785441815e-07, 1.0435713423102517e-06, 1.133660866126152e-05, 1.394566898819319e-05, -6.103596621404321e-05, -0.00017478724522506327, 0.00011424152003843815, 0.0009410217493585433, 0.00040789698084934395, -0.00312802338120381, -0.0036442796214883506, 0.006990014563390751, 0.013993768859843242, -0.010297659641009963, -0.036888397691556774, 0.007588974368642594, 0.07592423604445779, 0.006239722752156254, -0.13238830556335474, -0.027340263752899923, 0.21119069394696974, 0.02791820813292813, -0.3270633105274758, 0.08975108940236352, 0.44029025688580486, -0.6373563320829833, 0.43031272284545874, -0.1650642834886438, 0.03490771432362905, -0.0031892209253436892, }; DTYPE DB17_L[34] = { 7.26749296856637e-09, -8.423948446008154e-08, 2.9577009333187617e-07, 3.0165496099963414e-07, -4.505942477225963e-06, 6.990600985081294e-06, 2.318681379876164e-05, -8.204803202458212e-05, -2.5610109566546042e-05, 0.0004394654277689454, -0.00032813251941022427, -0.001436845304805, 0.0023012052421511474, 0.002967996691518064, -0.008602921520347815, -0.0030429899813869555, 0.022733676583919053, -0.0032709555358783646, -0.04692243838937891, 0.022312336178011833, 0.08110598665408082, -0.05709141963185808, -0.12681569177849797, 0.10113548917744287, 0.19731058956508457, -0.12659975221599248, -0.32832074836418546, 0.027314970403312946, 0.5183157640572823, 0.6109966156850273, 0.3703507241528858, 0.13121490330791097, 0.025985393703623173, 0.00224180700103879, }; DTYPE DB17_I_L[34] = { 0.00224180700103879, 0.025985393703623173, 0.13121490330791097, 0.3703507241528858, 0.6109966156850273, 0.5183157640572823, 0.027314970403312946, -0.32832074836418546, -0.12659975221599248, 0.19731058956508457, 0.10113548917744287, -0.12681569177849797, -0.05709141963185808, 0.08110598665408082, 0.022312336178011833, -0.04692243838937891, -0.0032709555358783646, 0.022733676583919053, -0.0030429899813869555, -0.008602921520347815, 0.002967996691518064, 0.0023012052421511474, -0.001436845304805, -0.00032813251941022427, 0.0004394654277689454, -2.5610109566546042e-05, -8.204803202458212e-05, 2.318681379876164e-05, 6.990600985081294e-06, -4.505942477225963e-06, 3.0165496099963414e-07, 2.9577009333187617e-07, -8.423948446008154e-08, 7.26749296856637e-09, }; DTYPE DB17_H[34] = { -0.00224180700103879, 0.025985393703623173, -0.13121490330791097, 0.3703507241528858, -0.6109966156850273, 0.5183157640572823, -0.027314970403312946, -0.32832074836418546, 0.12659975221599248, 0.19731058956508457, -0.10113548917744287, -0.12681569177849797, 0.05709141963185808, 0.08110598665408082, -0.022312336178011833, -0.04692243838937891, 0.0032709555358783646, 0.022733676583919053, 0.0030429899813869555, -0.008602921520347815, -0.002967996691518064, 0.0023012052421511474, 0.001436845304805, -0.00032813251941022427, -0.0004394654277689454, -2.5610109566546042e-05, 8.204803202458212e-05, 2.318681379876164e-05, -6.990600985081294e-06, -4.505942477225963e-06, -3.0165496099963414e-07, 2.9577009333187617e-07, 8.423948446008154e-08, 7.26749296856637e-09, }; DTYPE DB17_I_H[34] = { 7.26749296856637e-09, 8.423948446008154e-08, 2.9577009333187617e-07, -3.0165496099963414e-07, -4.505942477225963e-06, -6.990600985081294e-06, 2.318681379876164e-05, 8.204803202458212e-05, -2.5610109566546042e-05, -0.0004394654277689454, -0.00032813251941022427, 0.001436845304805, 0.0023012052421511474, -0.002967996691518064, -0.008602921520347815, 0.0030429899813869555, 0.022733676583919053, 0.0032709555358783646, -0.04692243838937891, -0.022312336178011833, 0.08110598665408082, 0.05709141963185808, -0.12681569177849797, -0.10113548917744287, 0.19731058956508457, 0.12659975221599248, -0.32832074836418546, -0.027314970403312946, 0.5183157640572823, -0.6109966156850273, 0.3703507241528858, -0.13121490330791097, 0.025985393703623173, -0.00224180700103879, }; DTYPE DB18_L[36] = { -2.507934454941929e-09, 3.06883586303703e-08, -1.1760987670250871e-07, -7.691632689865049e-08, 1.768712983622886e-06, -3.3326344788769603e-06, -8.520602537423464e-06, 3.741237880730847e-05, -1.535917123021341e-07, -0.00019864855231101547, 0.0002135815619103188, 0.0006284656829644715, -0.0013405962983313922, -0.0011187326669886426, 0.004943343605456594, 0.00011863003387493042, -0.013051480946517112, 0.006262167954438661, 0.026670705926689853, -0.023733210395336858, -0.04452614190225633, 0.05705124773905827, 0.0648872162123582, -0.10675224665906288, -0.09233188415030412, 0.16708131276294505, 0.14953397556500755, -0.21648093400458224, -0.2936540407357981, 0.14722311196952223, 0.571801654887122, 0.5718268077650818, 0.31467894133619284, 0.10358846582214751, 0.01928853172409497, 0.0015763102184365595, }; DTYPE DB18_I_L[36] = { 0.0015763102184365595, 0.01928853172409497, 0.10358846582214751, 0.31467894133619284, 0.5718268077650818, 0.571801654887122, 0.14722311196952223, -0.2936540407357981, -0.21648093400458224, 0.14953397556500755, 0.16708131276294505, -0.09233188415030412, -0.10675224665906288, 0.0648872162123582, 0.05705124773905827, -0.04452614190225633, -0.023733210395336858, 0.026670705926689853, 0.006262167954438661, -0.013051480946517112, 0.00011863003387493042, 0.004943343605456594, -0.0011187326669886426, -0.0013405962983313922, 0.0006284656829644715, 0.0002135815619103188, -0.00019864855231101547, -1.535917123021341e-07, 3.741237880730847e-05, -8.520602537423464e-06, -3.3326344788769603e-06, 1.768712983622886e-06, -7.691632689865049e-08, -1.1760987670250871e-07, 3.06883586303703e-08, -2.507934454941929e-09, }; DTYPE DB18_H[36] = { -0.0015763102184365595, 0.01928853172409497, -0.10358846582214751, 0.31467894133619284, -0.5718268077650818, 0.571801654887122, -0.14722311196952223, -0.2936540407357981, 0.21648093400458224, 0.14953397556500755, -0.16708131276294505, -0.09233188415030412, 0.10675224665906288, 0.0648872162123582, -0.05705124773905827, -0.04452614190225633, 0.023733210395336858, 0.026670705926689853, -0.006262167954438661, -0.013051480946517112, -0.00011863003387493042, 0.004943343605456594, 0.0011187326669886426, -0.0013405962983313922, -0.0006284656829644715, 0.0002135815619103188, 0.00019864855231101547, -1.535917123021341e-07, -3.741237880730847e-05, -8.520602537423464e-06, 3.3326344788769603e-06, 1.768712983622886e-06, 7.691632689865049e-08, -1.1760987670250871e-07, -3.06883586303703e-08, -2.507934454941929e-09, }; DTYPE DB18_I_H[36] = { -2.507934454941929e-09, -3.06883586303703e-08, -1.1760987670250871e-07, 7.691632689865049e-08, 1.768712983622886e-06, 3.3326344788769603e-06, -8.520602537423464e-06, -3.741237880730847e-05, -1.535917123021341e-07, 0.00019864855231101547, 0.0002135815619103188, -0.0006284656829644715, -0.0013405962983313922, 0.0011187326669886426, 0.004943343605456594, -0.00011863003387493042, -0.013051480946517112, -0.006262167954438661, 0.026670705926689853, 0.023733210395336858, -0.04452614190225633, -0.05705124773905827, 0.0648872162123582, 0.10675224665906288, -0.09233188415030412, -0.16708131276294505, 0.14953397556500755, 0.21648093400458224, -0.2936540407357981, -0.14722311196952223, 0.571801654887122, -0.5718268077650818, 0.31467894133619284, -0.10358846582214751, 0.01928853172409497, -0.0015763102184365595, }; DTYPE DB19_L[38] = { 8.666848839034483e-10, -1.1164020670405678e-08, 4.636937775802368e-08, 1.447088298804088e-08, -6.86275565779811e-07, 1.531931476697877e-06, 3.0109643163099385e-06, -1.664017629722462e-05, 5.105950487090694e-06, 8.711270467250443e-05, -0.00012460079173506306, -0.0002606761356811995, 0.0007358025205041731, 0.00034180865344939543, -0.002687551800734441, 0.0007689543592242488, 0.007040747367080495, -0.005866922281112195, -0.013988388678695632, 0.019375549889114482, 0.021623767409452484, -0.04567422627778492, -0.026501236250778635, 0.0869067555554507, 0.02758435062488713, -0.14278569504021468, -0.03351854190320226, 0.21234974330662043, 0.07465226970806647, -0.28583863175723145, -0.22809139421653665, 0.2608949526521201, 0.6017045491300916, 0.5244363774668862, 0.26438843174202237, 0.08127811326580564, 0.01428109845082521, 0.0011086697631864314, }; DTYPE DB19_I_L[38] = { 0.0011086697631864314, 0.01428109845082521, 0.08127811326580564, 0.26438843174202237, 0.5244363774668862, 0.6017045491300916, 0.2608949526521201, -0.22809139421653665, -0.28583863175723145, 0.07465226970806647, 0.21234974330662043, -0.03351854190320226, -0.14278569504021468, 0.02758435062488713, 0.0869067555554507, -0.026501236250778635, -0.04567422627778492, 0.021623767409452484, 0.019375549889114482, -0.013988388678695632, -0.005866922281112195, 0.007040747367080495, 0.0007689543592242488, -0.002687551800734441, 0.00034180865344939543, 0.0007358025205041731, -0.0002606761356811995, -0.00012460079173506306, 8.711270467250443e-05, 5.105950487090694e-06, -1.664017629722462e-05, 3.0109643163099385e-06, 1.531931476697877e-06, -6.86275565779811e-07, 1.447088298804088e-08, 4.636937775802368e-08, -1.1164020670405678e-08, 8.666848839034483e-10, }; DTYPE DB19_H[38] = { -0.0011086697631864314, 0.01428109845082521, -0.08127811326580564, 0.26438843174202237, -0.5244363774668862, 0.6017045491300916, -0.2608949526521201, -0.22809139421653665, 0.28583863175723145, 0.07465226970806647, -0.21234974330662043, -0.03351854190320226, 0.14278569504021468, 0.02758435062488713, -0.0869067555554507, -0.026501236250778635, 0.04567422627778492, 0.021623767409452484, -0.019375549889114482, -0.013988388678695632, 0.005866922281112195, 0.007040747367080495, -0.0007689543592242488, -0.002687551800734441, -0.00034180865344939543, 0.0007358025205041731, 0.0002606761356811995, -0.00012460079173506306, -8.711270467250443e-05, 5.105950487090694e-06, 1.664017629722462e-05, 3.0109643163099385e-06, -1.531931476697877e-06, -6.86275565779811e-07, -1.447088298804088e-08, 4.636937775802368e-08, 1.1164020670405678e-08, 8.666848839034483e-10, }; DTYPE DB19_I_H[38] = { 8.666848839034483e-10, 1.1164020670405678e-08, 4.636937775802368e-08, -1.447088298804088e-08, -6.86275565779811e-07, -1.531931476697877e-06, 3.0109643163099385e-06, 1.664017629722462e-05, 5.105950487090694e-06, -8.711270467250443e-05, -0.00012460079173506306, 0.0002606761356811995, 0.0007358025205041731, -0.00034180865344939543, -0.002687551800734441, -0.0007689543592242488, 0.007040747367080495, 0.005866922281112195, -0.013988388678695632, -0.019375549889114482, 0.021623767409452484, 0.04567422627778492, -0.026501236250778635, -0.0869067555554507, 0.02758435062488713, 0.14278569504021468, -0.03351854190320226, -0.21234974330662043, 0.07465226970806647, 0.28583863175723145, -0.22809139421653665, -0.2608949526521201, 0.6017045491300916, -0.5244363774668862, 0.26438843174202237, -0.08127811326580564, 0.01428109845082521, -0.0011086697631864314, }; DTYPE DB20_L[40] = { -2.998836489615753e-10, 4.05612705554717e-09, -1.814843248297622e-08, 2.0143220235374613e-10, 2.633924226266962e-07, -6.847079596993149e-07, -1.0119940100181473e-06, 7.241248287663791e-06, -4.376143862182197e-06, -3.710586183390615e-05, 6.774280828373048e-05, 0.00010153288973669777, -0.0003851047486990061, -5.349759844340453e-05, 0.0013925596193045254, -0.0008315621728772474, -0.003581494259744107, 0.00442054238676635, 0.0067216273018096935, -0.013810526137727442, -0.008789324924555765, 0.03229429953011916, 0.0058746818113949465, -0.061722899624668884, 0.005632246857685454, 0.10229171917513397, -0.024716827337521424, -0.1554587507060453, 0.039850246458519104, 0.22829105082013823, -0.016727088308801888, -0.3267868004335376, -0.13921208801128787, 0.36150229873889705, 0.6104932389378558, 0.4726961853103315, 0.21994211355113222, 0.06342378045900529, 0.010549394624937735, 0.0007799536136659112, }; DTYPE DB20_I_L[40] = { 0.0007799536136659112, 0.010549394624937735, 0.06342378045900529, 0.21994211355113222, 0.4726961853103315, 0.6104932389378558, 0.36150229873889705, -0.13921208801128787, -0.3267868004335376, -0.016727088308801888, 0.22829105082013823, 0.039850246458519104, -0.1554587507060453, -0.024716827337521424, 0.10229171917513397, 0.005632246857685454, -0.061722899624668884, 0.0058746818113949465, 0.03229429953011916, -0.008789324924555765, -0.013810526137727442, 0.0067216273018096935, 0.00442054238676635, -0.003581494259744107, -0.0008315621728772474, 0.0013925596193045254, -5.349759844340453e-05, -0.0003851047486990061, 0.00010153288973669777, 6.774280828373048e-05, -3.710586183390615e-05, -4.376143862182197e-06, 7.241248287663791e-06, -1.0119940100181473e-06, -6.847079596993149e-07, 2.633924226266962e-07, 2.0143220235374613e-10, -1.814843248297622e-08, 4.05612705554717e-09, -2.998836489615753e-10, }; DTYPE DB20_H[40] = { -0.0007799536136659112, 0.010549394624937735, -0.06342378045900529, 0.21994211355113222, -0.4726961853103315, 0.6104932389378558, -0.36150229873889705, -0.13921208801128787, 0.3267868004335376, -0.016727088308801888, -0.22829105082013823, 0.039850246458519104, 0.1554587507060453, -0.024716827337521424, -0.10229171917513397, 0.005632246857685454, 0.061722899624668884, 0.0058746818113949465, -0.03229429953011916, -0.008789324924555765, 0.013810526137727442, 0.0067216273018096935, -0.00442054238676635, -0.003581494259744107, 0.0008315621728772474, 0.0013925596193045254, 5.349759844340453e-05, -0.0003851047486990061, -0.00010153288973669777, 6.774280828373048e-05, 3.710586183390615e-05, -4.376143862182197e-06, -7.241248287663791e-06, -1.0119940100181473e-06, 6.847079596993149e-07, 2.633924226266962e-07, -2.0143220235374613e-10, -1.814843248297622e-08, -4.05612705554717e-09, -2.998836489615753e-10, }; DTYPE DB20_I_H[40] = { -2.998836489615753e-10, -4.05612705554717e-09, -1.814843248297622e-08, -2.0143220235374613e-10, 2.633924226266962e-07, 6.847079596993149e-07, -1.0119940100181473e-06, -7.241248287663791e-06, -4.376143862182197e-06, 3.710586183390615e-05, 6.774280828373048e-05, -0.00010153288973669777, -0.0003851047486990061, 5.349759844340453e-05, 0.0013925596193045254, 0.0008315621728772474, -0.003581494259744107, -0.00442054238676635, 0.0067216273018096935, 0.013810526137727442, -0.008789324924555765, -0.03229429953011916, 0.0058746818113949465, 0.061722899624668884, 0.005632246857685454, -0.10229171917513397, -0.024716827337521424, 0.1554587507060453, 0.039850246458519104, -0.22829105082013823, -0.016727088308801888, 0.3267868004335376, -0.13921208801128787, -0.36150229873889705, 0.6104932389378558, -0.4726961853103315, 0.21994211355113222, -0.06342378045900529, 0.010549394624937735, -0.0007799536136659112, }; DTYPE SYM2_L[4] = { -0.12940952255092145, 0.22414386804185735, 0.836516303737469, 0.48296291314469025, }; DTYPE SYM2_I_L[4] = { 0.48296291314469025, 0.836516303737469, 0.22414386804185735, -0.12940952255092145, }; DTYPE SYM2_H[4] = { -0.48296291314469025, 0.836516303737469, -0.22414386804185735, -0.12940952255092145, }; DTYPE SYM2_I_H[4] = { -0.12940952255092145, -0.22414386804185735, 0.836516303737469, -0.48296291314469025, }; DTYPE SYM3_L[6] = { 0.035226291882100656, -0.08544127388224149, -0.13501102001039084, 0.4598775021193313, 0.8068915093133388, 0.3326705529509569, }; DTYPE SYM3_I_L[6] = { 0.3326705529509569, 0.8068915093133388, 0.4598775021193313, -0.13501102001039084, -0.08544127388224149, 0.035226291882100656, }; DTYPE SYM3_H[6] = { -0.3326705529509569, 0.8068915093133388, -0.4598775021193313, -0.13501102001039084, 0.08544127388224149, 0.035226291882100656, }; DTYPE SYM3_I_H[6] = { 0.035226291882100656, 0.08544127388224149, -0.13501102001039084, -0.4598775021193313, 0.8068915093133388, -0.3326705529509569, }; DTYPE SYM4_L[8] = { -0.07576571478927333, -0.02963552764599851, 0.49761866763201545, 0.8037387518059161, 0.29785779560527736, -0.09921954357684722, -0.012603967262037833, 0.0322231006040427, }; DTYPE SYM4_I_L[8] = { 0.0322231006040427, -0.012603967262037833, -0.09921954357684722, 0.29785779560527736, 0.8037387518059161, 0.49761866763201545, -0.02963552764599851, -0.07576571478927333, }; DTYPE SYM4_H[8] = { -0.0322231006040427, -0.012603967262037833, 0.09921954357684722, 0.29785779560527736, -0.8037387518059161, 0.49761866763201545, 0.02963552764599851, -0.07576571478927333, }; DTYPE SYM4_I_H[8] = { -0.07576571478927333, 0.02963552764599851, 0.49761866763201545, -0.8037387518059161, 0.29785779560527736, 0.09921954357684722, -0.012603967262037833, -0.0322231006040427, }; DTYPE SYM5_L[10] = { 0.027333068345077982, 0.029519490925774643, -0.039134249302383094, 0.1993975339773936, 0.7234076904024206, 0.6339789634582119, 0.01660210576452232, -0.17532808990845047, -0.021101834024758855, 0.019538882735286728, }; DTYPE SYM5_I_L[10] = { 0.019538882735286728, -0.021101834024758855, -0.17532808990845047, 0.01660210576452232, 0.6339789634582119, 0.7234076904024206, 0.1993975339773936, -0.039134249302383094, 0.029519490925774643, 0.027333068345077982, }; DTYPE SYM5_H[10] = { -0.019538882735286728, -0.021101834024758855, 0.17532808990845047, 0.01660210576452232, -0.6339789634582119, 0.7234076904024206, -0.1993975339773936, -0.039134249302383094, -0.029519490925774643, 0.027333068345077982, }; DTYPE SYM5_I_H[10] = { 0.027333068345077982, -0.029519490925774643, -0.039134249302383094, -0.1993975339773936, 0.7234076904024206, -0.6339789634582119, 0.01660210576452232, 0.17532808990845047, -0.021101834024758855, -0.019538882735286728, }; DTYPE SYM6_L[12] = { 0.015404109327027373, 0.0034907120842174702, -0.11799011114819057, -0.048311742585633, 0.4910559419267466, 0.787641141030194, 0.3379294217276218, -0.07263752278646252, -0.021060292512300564, 0.04472490177066578, 0.0017677118642428036, -0.007800708325034148, }; DTYPE SYM6_I_L[12] = { -0.007800708325034148, 0.0017677118642428036, 0.04472490177066578, -0.021060292512300564, -0.07263752278646252, 0.3379294217276218, 0.787641141030194, 0.4910559419267466, -0.048311742585633, -0.11799011114819057, 0.0034907120842174702, 0.015404109327027373, }; DTYPE SYM6_H[12] = { 0.007800708325034148, 0.0017677118642428036, -0.04472490177066578, -0.021060292512300564, 0.07263752278646252, 0.3379294217276218, -0.787641141030194, 0.4910559419267466, 0.048311742585633, -0.11799011114819057, -0.0034907120842174702, 0.015404109327027373, }; DTYPE SYM6_I_H[12] = { 0.015404109327027373, -0.0034907120842174702, -0.11799011114819057, 0.048311742585633, 0.4910559419267466, -0.787641141030194, 0.3379294217276218, 0.07263752278646252, -0.021060292512300564, -0.04472490177066578, 0.0017677118642428036, 0.007800708325034148, }; DTYPE SYM7_L[14] = { 0.002681814568257878, -0.0010473848886829163, -0.01263630340325193, 0.03051551316596357, 0.0678926935013727, -0.049552834937127255, 0.017441255086855827, 0.5361019170917628, 0.767764317003164, 0.2886296317515146, -0.14004724044296152, -0.10780823770381774, 0.004010244871533663, 0.010268176708511255, }; DTYPE SYM7_I_L[14] = { 0.010268176708511255, 0.004010244871533663, -0.10780823770381774, -0.14004724044296152, 0.2886296317515146, 0.767764317003164, 0.5361019170917628, 0.017441255086855827, -0.049552834937127255, 0.0678926935013727, 0.03051551316596357, -0.01263630340325193, -0.0010473848886829163, 0.002681814568257878, }; DTYPE SYM7_H[14] = { -0.010268176708511255, 0.004010244871533663, 0.10780823770381774, -0.14004724044296152, -0.2886296317515146, 0.767764317003164, -0.5361019170917628, 0.017441255086855827, 0.049552834937127255, 0.0678926935013727, -0.03051551316596357, -0.01263630340325193, 0.0010473848886829163, 0.002681814568257878, }; DTYPE SYM7_I_H[14] = { 0.002681814568257878, 0.0010473848886829163, -0.01263630340325193, -0.03051551316596357, 0.0678926935013727, 0.049552834937127255, 0.017441255086855827, -0.5361019170917628, 0.767764317003164, -0.2886296317515146, -0.14004724044296152, 0.10780823770381774, 0.004010244871533663, -0.010268176708511255, }; DTYPE SYM8_L[16] = { -0.0033824159510061256, -0.0005421323317911481, 0.03169508781149298, 0.007607487324917605, -0.1432942383508097, -0.061273359067658524, 0.4813596512583722, 0.7771857517005235, 0.3644418948353314, -0.05194583810770904, -0.027219029917056003, 0.049137179673607506, 0.003808752013890615, -0.01495225833704823, -0.0003029205147213668, 0.0018899503327594609, }; DTYPE SYM8_I_L[16] = { 0.0018899503327594609, -0.0003029205147213668, -0.01495225833704823, 0.003808752013890615, 0.049137179673607506, -0.027219029917056003, -0.05194583810770904, 0.3644418948353314, 0.7771857517005235, 0.4813596512583722, -0.061273359067658524, -0.1432942383508097, 0.007607487324917605, 0.03169508781149298, -0.0005421323317911481, -0.0033824159510061256, }; DTYPE SYM8_H[16] = { -0.0018899503327594609, -0.0003029205147213668, 0.01495225833704823, 0.003808752013890615, -0.049137179673607506, -0.027219029917056003, 0.05194583810770904, 0.3644418948353314, -0.7771857517005235, 0.4813596512583722, 0.061273359067658524, -0.1432942383508097, -0.007607487324917605, 0.03169508781149298, 0.0005421323317911481, -0.0033824159510061256, }; DTYPE SYM8_I_H[16] = { -0.0033824159510061256, 0.0005421323317911481, 0.03169508781149298, -0.007607487324917605, -0.1432942383508097, 0.061273359067658524, 0.4813596512583722, -0.7771857517005235, 0.3644418948353314, 0.05194583810770904, -0.027219029917056003, -0.049137179673607506, 0.003808752013890615, 0.01495225833704823, -0.0003029205147213668, -0.0018899503327594609, }; DTYPE SYM9_L[18] = { 0.0014009155259146807, 0.0006197808889855868, -0.013271967781817119, -0.01152821020767923, 0.03022487885827568, 0.0005834627461258068, -0.05456895843083407, 0.238760914607303, 0.717897082764412, 0.6173384491409358, 0.035272488035271894, -0.19155083129728512, -0.018233770779395985, 0.06207778930288603, 0.008859267493400484, -0.010264064027633142, -0.0004731544986800831, 0.0010694900329086053, }; DTYPE SYM9_I_L[18] = { 0.0010694900329086053, -0.0004731544986800831, -0.010264064027633142, 0.008859267493400484, 0.06207778930288603, -0.018233770779395985, -0.19155083129728512, 0.035272488035271894, 0.6173384491409358, 0.717897082764412, 0.238760914607303, -0.05456895843083407, 0.0005834627461258068, 0.03022487885827568, -0.01152821020767923, -0.013271967781817119, 0.0006197808889855868, 0.0014009155259146807, }; DTYPE SYM9_H[18] = { -0.0010694900329086053, -0.0004731544986800831, 0.010264064027633142, 0.008859267493400484, -0.06207778930288603, -0.018233770779395985, 0.19155083129728512, 0.035272488035271894, -0.6173384491409358, 0.717897082764412, -0.238760914607303, -0.05456895843083407, -0.0005834627461258068, 0.03022487885827568, 0.01152821020767923, -0.013271967781817119, -0.0006197808889855868, 0.0014009155259146807, }; DTYPE SYM9_I_H[18] = { 0.0014009155259146807, -0.0006197808889855868, -0.013271967781817119, 0.01152821020767923, 0.03022487885827568, -0.0005834627461258068, -0.05456895843083407, -0.238760914607303, 0.717897082764412, -0.6173384491409358, 0.035272488035271894, 0.19155083129728512, -0.018233770779395985, -0.06207778930288603, 0.008859267493400484, 0.010264064027633142, -0.0004731544986800831, -0.0010694900329086053, }; DTYPE SYM10_L[20] = { 0.0007701598091144901, 9.563267072289475e-05, -0.008641299277022422, -0.0014653825813050513, 0.0459272392310922, 0.011609893903711381, -0.15949427888491757, -0.07088053578324385, 0.47169066693843925, 0.7695100370211071, 0.38382676106708546, -0.03553674047381755, -0.0319900568824278, 0.04999497207737669, 0.005764912033581909, -0.02035493981231129, -0.0008043589320165449, 0.004593173585311828, 5.7036083618494284e-05, -0.0004593294210046588, }; DTYPE SYM10_I_L[20] = { -0.0004593294210046588, 5.7036083618494284e-05, 0.004593173585311828, -0.0008043589320165449, -0.02035493981231129, 0.005764912033581909, 0.04999497207737669, -0.0319900568824278, -0.03553674047381755, 0.38382676106708546, 0.7695100370211071, 0.47169066693843925, -0.07088053578324385, -0.15949427888491757, 0.011609893903711381, 0.0459272392310922, -0.0014653825813050513, -0.008641299277022422, 9.563267072289475e-05, 0.0007701598091144901, }; DTYPE SYM10_H[20] = { 0.0004593294210046588, 5.7036083618494284e-05, -0.004593173585311828, -0.0008043589320165449, 0.02035493981231129, 0.005764912033581909, -0.04999497207737669, -0.0319900568824278, 0.03553674047381755, 0.38382676106708546, -0.7695100370211071, 0.47169066693843925, 0.07088053578324385, -0.15949427888491757, -0.011609893903711381, 0.0459272392310922, 0.0014653825813050513, -0.008641299277022422, -9.563267072289475e-05, 0.0007701598091144901, }; DTYPE SYM10_I_H[20] = { 0.0007701598091144901, -9.563267072289475e-05, -0.008641299277022422, 0.0014653825813050513, 0.0459272392310922, -0.011609893903711381, -0.15949427888491757, 0.07088053578324385, 0.47169066693843925, -0.7695100370211071, 0.38382676106708546, 0.03553674047381755, -0.0319900568824278, -0.04999497207737669, 0.005764912033581909, 0.02035493981231129, -0.0008043589320165449, -0.004593173585311828, 5.7036083618494284e-05, 0.0004593294210046588, }; DTYPE SYM11_L[22] = { 0.00017172195069934854, -3.8795655736158566e-05, -0.0017343662672978692, 0.0005883527353969915, 0.00651249567477145, -0.009857934828789794, -0.024080841595864003, 0.0370374159788594, 0.06997679961073414, -0.022832651022562687, 0.09719839445890947, 0.5720229780100871, 0.7303435490883957, 0.23768990904924897, -0.2046547944958006, -0.1446023437053156, 0.03526675956446655, 0.04300019068155228, -0.0020034719001093887, -0.006389603666454892, 0.00011053509764272153, 0.0004892636102619239, }; DTYPE SYM11_I_L[22] = { 0.0004892636102619239, 0.00011053509764272153, -0.006389603666454892, -0.0020034719001093887, 0.04300019068155228, 0.03526675956446655, -0.1446023437053156, -0.2046547944958006, 0.23768990904924897, 0.7303435490883957, 0.5720229780100871, 0.09719839445890947, -0.022832651022562687, 0.06997679961073414, 0.0370374159788594, -0.024080841595864003, -0.009857934828789794, 0.00651249567477145, 0.0005883527353969915, -0.0017343662672978692, -3.8795655736158566e-05, 0.00017172195069934854, }; DTYPE SYM11_H[22] = { -0.0004892636102619239, 0.00011053509764272153, 0.006389603666454892, -0.0020034719001093887, -0.04300019068155228, 0.03526675956446655, 0.1446023437053156, -0.2046547944958006, -0.23768990904924897, 0.7303435490883957, -0.5720229780100871, 0.09719839445890947, 0.022832651022562687, 0.06997679961073414, -0.0370374159788594, -0.024080841595864003, 0.009857934828789794, 0.00651249567477145, -0.0005883527353969915, -0.0017343662672978692, 3.8795655736158566e-05, 0.00017172195069934854, }; DTYPE SYM11_I_H[22] = { 0.00017172195069934854, 3.8795655736158566e-05, -0.0017343662672978692, -0.0005883527353969915, 0.00651249567477145, 0.009857934828789794, -0.024080841595864003, -0.0370374159788594, 0.06997679961073414, 0.022832651022562687, 0.09719839445890947, -0.5720229780100871, 0.7303435490883957, -0.23768990904924897, -0.2046547944958006, 0.1446023437053156, 0.03526675956446655, -0.04300019068155228, -0.0020034719001093887, 0.006389603666454892, 0.00011053509764272153, -0.0004892636102619239, }; DTYPE SYM12_L[24] = { 0.00011196719424656033, -1.1353928041541452e-05, -0.0013497557555715387, 0.00018021409008538188, 0.007414965517654251, -0.0014089092443297553, -0.024220722675013445, 0.0075537806116804775, 0.04917931829966084, -0.03584883073695439, -0.022162306170337816, 0.39888597239022, 0.7634790977836572, 0.46274103121927235, -0.07833262231634322, -0.17037069723886492, 0.01530174062247884, 0.05780417944550566, -0.0026043910313322326, -0.014589836449234145, 0.00030764779631059454, 0.002350297614183465, -1.8158078862617515e-05, -0.0001790665869750869, }; DTYPE SYM12_I_L[24] = { -0.0001790665869750869, -1.8158078862617515e-05, 0.002350297614183465, 0.00030764779631059454, -0.014589836449234145, -0.0026043910313322326, 0.05780417944550566, 0.01530174062247884, -0.17037069723886492, -0.07833262231634322, 0.46274103121927235, 0.7634790977836572, 0.39888597239022, -0.022162306170337816, -0.03584883073695439, 0.04917931829966084, 0.0075537806116804775, -0.024220722675013445, -0.0014089092443297553, 0.007414965517654251, 0.00018021409008538188, -0.0013497557555715387, -1.1353928041541452e-05, 0.00011196719424656033, }; DTYPE SYM12_H[24] = { 0.0001790665869750869, -1.8158078862617515e-05, -0.002350297614183465, 0.00030764779631059454, 0.014589836449234145, -0.0026043910313322326, -0.05780417944550566, 0.01530174062247884, 0.17037069723886492, -0.07833262231634322, -0.46274103121927235, 0.7634790977836572, -0.39888597239022, -0.022162306170337816, 0.03584883073695439, 0.04917931829966084, -0.0075537806116804775, -0.024220722675013445, 0.0014089092443297553, 0.007414965517654251, -0.00018021409008538188, -0.0013497557555715387, 1.1353928041541452e-05, 0.00011196719424656033, }; DTYPE SYM12_I_H[24] = { 0.00011196719424656033, 1.1353928041541452e-05, -0.0013497557555715387, -0.00018021409008538188, 0.007414965517654251, 0.0014089092443297553, -0.024220722675013445, -0.0075537806116804775, 0.04917931829966084, 0.03584883073695439, -0.022162306170337816, -0.39888597239022, 0.7634790977836572, -0.46274103121927235, -0.07833262231634322, 0.17037069723886492, 0.01530174062247884, -0.05780417944550566, -0.0026043910313322326, 0.014589836449234145, 0.00030764779631059454, -0.002350297614183465, -1.8158078862617515e-05, 0.0001790665869750869, }; DTYPE SYM13_L[26] = { 6.820325263075319e-05, -3.573862364868901e-05, -0.0011360634389281183, -0.0001709428585302221, 0.0075262253899681, 0.005296359738725025, -0.02021676813338983, -0.017211642726299048, 0.013862497435849205, -0.0597506277179437, -0.12436246075153011, 0.19770481877117801, 0.6957391505614964, 0.6445643839011856, 0.11023022302137217, -0.14049009311363403, 0.008819757670420546, 0.09292603089913712, 0.017618296880653084, -0.020749686325515677, -0.0014924472742598532, 0.0056748537601224395, 0.00041326119884196064, -0.0007213643851362283, 3.690537342319624e-05, 7.042986690694402e-05, }; DTYPE SYM13_I_L[26] = { 7.042986690694402e-05, 3.690537342319624e-05, -0.0007213643851362283, 0.00041326119884196064, 0.0056748537601224395, -0.0014924472742598532, -0.020749686325515677, 0.017618296880653084, 0.09292603089913712, 0.008819757670420546, -0.14049009311363403, 0.11023022302137217, 0.6445643839011856, 0.6957391505614964, 0.19770481877117801, -0.12436246075153011, -0.0597506277179437, 0.013862497435849205, -0.017211642726299048, -0.02021676813338983, 0.005296359738725025, 0.0075262253899681, -0.0001709428585302221, -0.0011360634389281183, -3.573862364868901e-05, 6.820325263075319e-05, }; DTYPE SYM13_H[26] = { -7.042986690694402e-05, 3.690537342319624e-05, 0.0007213643851362283, 0.00041326119884196064, -0.0056748537601224395, -0.0014924472742598532, 0.020749686325515677, 0.017618296880653084, -0.09292603089913712, 0.008819757670420546, 0.14049009311363403, 0.11023022302137217, -0.6445643839011856, 0.6957391505614964, -0.19770481877117801, -0.12436246075153011, 0.0597506277179437, 0.013862497435849205, 0.017211642726299048, -0.02021676813338983, -0.005296359738725025, 0.0075262253899681, 0.0001709428585302221, -0.0011360634389281183, 3.573862364868901e-05, 6.820325263075319e-05, }; DTYPE SYM13_I_H[26] = { 6.820325263075319e-05, 3.573862364868901e-05, -0.0011360634389281183, 0.0001709428585302221, 0.0075262253899681, -0.005296359738725025, -0.02021676813338983, 0.017211642726299048, 0.013862497435849205, 0.0597506277179437, -0.12436246075153011, -0.19770481877117801, 0.6957391505614964, -0.6445643839011856, 0.11023022302137217, 0.14049009311363403, 0.008819757670420546, -0.09292603089913712, 0.017618296880653084, 0.020749686325515677, -0.0014924472742598532, -0.0056748537601224395, 0.00041326119884196064, 0.0007213643851362283, 3.690537342319624e-05, -7.042986690694402e-05, }; DTYPE SYM14_L[28] = { -2.5879090265397886e-05, 1.1210865808890361e-05, 0.00039843567297594335, -6.286542481477636e-05, -0.002579441725933078, 0.0003664765736601183, 0.01003769371767227, -0.002753774791224071, -0.029196217764038187, 0.004280520499019378, 0.03743308836285345, -0.057634498351326995, -0.03531811211497973, 0.39320152196208885, 0.7599762419610909, 0.4753357626342066, -0.05811182331771783, -0.15999741114652205, 0.02589858753104667, 0.06982761636180755, -0.002365048836740385, -0.019439314263626713, 0.0010131419871842082, 0.004532677471945648, -7.321421356702399e-05, -0.0006057601824664335, 1.9329016965523917e-05, 4.4618977991475265e-05, }; DTYPE SYM14_I_L[28] = { 4.4618977991475265e-05, 1.9329016965523917e-05, -0.0006057601824664335, -7.321421356702399e-05, 0.004532677471945648, 0.0010131419871842082, -0.019439314263626713, -0.002365048836740385, 0.06982761636180755, 0.02589858753104667, -0.15999741114652205, -0.05811182331771783, 0.4753357626342066, 0.7599762419610909, 0.39320152196208885, -0.03531811211497973, -0.057634498351326995, 0.03743308836285345, 0.004280520499019378, -0.029196217764038187, -0.002753774791224071, 0.01003769371767227, 0.0003664765736601183, -0.002579441725933078, -6.286542481477636e-05, 0.00039843567297594335, 1.1210865808890361e-05, -2.5879090265397886e-05, }; DTYPE SYM14_H[28] = { -4.4618977991475265e-05, 1.9329016965523917e-05, 0.0006057601824664335, -7.321421356702399e-05, -0.004532677471945648, 0.0010131419871842082, 0.019439314263626713, -0.002365048836740385, -0.06982761636180755, 0.02589858753104667, 0.15999741114652205, -0.05811182331771783, -0.4753357626342066, 0.7599762419610909, -0.39320152196208885, -0.03531811211497973, 0.057634498351326995, 0.03743308836285345, -0.004280520499019378, -0.029196217764038187, 0.002753774791224071, 0.01003769371767227, -0.0003664765736601183, -0.002579441725933078, 6.286542481477636e-05, 0.00039843567297594335, -1.1210865808890361e-05, -2.5879090265397886e-05, }; DTYPE SYM14_I_H[28] = { -2.5879090265397886e-05, -1.1210865808890361e-05, 0.00039843567297594335, 6.286542481477636e-05, -0.002579441725933078, -0.0003664765736601183, 0.01003769371767227, 0.002753774791224071, -0.029196217764038187, -0.004280520499019378, 0.03743308836285345, 0.057634498351326995, -0.03531811211497973, -0.39320152196208885, 0.7599762419610909, -0.4753357626342066, -0.05811182331771783, 0.15999741114652205, 0.02589858753104667, -0.06982761636180755, -0.002365048836740385, 0.019439314263626713, 0.0010131419871842082, -0.004532677471945648, -7.321421356702399e-05, 0.0006057601824664335, 1.9329016965523917e-05, -4.4618977991475265e-05, }; DTYPE SYM15_L[30] = { 9.712419737963348e-06, -7.35966679891947e-06, -0.00016066186637495343, 5.512254785558665e-05, 0.0010705672194623959, -0.0002673164464718057, -0.0035901654473726417, 0.003423450736351241, 0.01007997708790567, -0.01940501143093447, -0.03887671687683349, 0.021937642719753955, 0.04073547969681068, -0.04108266663538248, 0.11153369514261872, 0.5786404152150345, 0.7218430296361812, 0.2439627054321663, -0.1966263587662373, -0.1340562984562539, 0.06839331006048024, 0.06796982904487918, -0.008744788886477952, -0.01717125278163873, 0.0015261382781819983, 0.003481028737064895, -0.00010815440168545525, -0.00040216853760293483, 2.171789015077892e-05, 2.866070852531808e-05, }; DTYPE SYM15_I_L[30] = { 2.866070852531808e-05, 2.171789015077892e-05, -0.00040216853760293483, -0.00010815440168545525, 0.003481028737064895, 0.0015261382781819983, -0.01717125278163873, -0.008744788886477952, 0.06796982904487918, 0.06839331006048024, -0.1340562984562539, -0.1966263587662373, 0.2439627054321663, 0.7218430296361812, 0.5786404152150345, 0.11153369514261872, -0.04108266663538248, 0.04073547969681068, 0.021937642719753955, -0.03887671687683349, -0.01940501143093447, 0.01007997708790567, 0.003423450736351241, -0.0035901654473726417, -0.0002673164464718057, 0.0010705672194623959, 5.512254785558665e-05, -0.00016066186637495343, -7.35966679891947e-06, 9.712419737963348e-06, }; DTYPE SYM15_H[30] = { -2.866070852531808e-05, 2.171789015077892e-05, 0.00040216853760293483, -0.00010815440168545525, -0.003481028737064895, 0.0015261382781819983, 0.01717125278163873, -0.008744788886477952, -0.06796982904487918, 0.06839331006048024, 0.1340562984562539, -0.1966263587662373, -0.2439627054321663, 0.7218430296361812, -0.5786404152150345, 0.11153369514261872, 0.04108266663538248, 0.04073547969681068, -0.021937642719753955, -0.03887671687683349, 0.01940501143093447, 0.01007997708790567, -0.003423450736351241, -0.0035901654473726417, 0.0002673164464718057, 0.0010705672194623959, -5.512254785558665e-05, -0.00016066186637495343, 7.35966679891947e-06, 9.712419737963348e-06, }; DTYPE SYM15_I_H[30] = { 9.712419737963348e-06, 7.35966679891947e-06, -0.00016066186637495343, -5.512254785558665e-05, 0.0010705672194623959, 0.0002673164464718057, -0.0035901654473726417, -0.003423450736351241, 0.01007997708790567, 0.01940501143093447, -0.03887671687683349, -0.021937642719753955, 0.04073547969681068, 0.04108266663538248, 0.11153369514261872, -0.5786404152150345, 0.7218430296361812, -0.2439627054321663, -0.1966263587662373, 0.1340562984562539, 0.06839331006048024, -0.06796982904487918, -0.008744788886477952, 0.01717125278163873, 0.0015261382781819983, -0.003481028737064895, -0.00010815440168545525, 0.00040216853760293483, 2.171789015077892e-05, -2.866070852531808e-05, }; DTYPE SYM16_L[32] = { 6.230006701220761e-06, -3.113556407621969e-06, -0.00010943147929529757, 2.8078582128442894e-05, 0.0008523547108047095, -0.0001084456223089688, -0.0038809122526038786, 0.0007182119788317892, 0.012666731659857348, -0.0031265171722710075, -0.031051202843553064, 0.004869274404904607, 0.032333091610663785, -0.06698304907021778, -0.034574228416972504, 0.39712293362064416, 0.7565249878756971, 0.47534280601152273, -0.054040601387606135, -0.15959219218520598, 0.03072113906330156, 0.07803785290341991, -0.003510275068374009, -0.024952758046290123, 0.001359844742484172, 0.0069377611308027096, -0.00022211647621176323, -0.0013387206066921965, 3.656592483348223e-05, 0.00016545679579108483, -5.396483179315242e-06, -1.0797982104319795e-05, }; DTYPE SYM16_I_L[32] = { -1.0797982104319795e-05, -5.396483179315242e-06, 0.00016545679579108483, 3.656592483348223e-05, -0.0013387206066921965, -0.00022211647621176323, 0.0069377611308027096, 0.001359844742484172, -0.024952758046290123, -0.003510275068374009, 0.07803785290341991, 0.03072113906330156, -0.15959219218520598, -0.054040601387606135, 0.47534280601152273, 0.7565249878756971, 0.39712293362064416, -0.034574228416972504, -0.06698304907021778, 0.032333091610663785, 0.004869274404904607, -0.031051202843553064, -0.0031265171722710075, 0.012666731659857348, 0.0007182119788317892, -0.0038809122526038786, -0.0001084456223089688, 0.0008523547108047095, 2.8078582128442894e-05, -0.00010943147929529757, -3.113556407621969e-06, 6.230006701220761e-06, }; DTYPE SYM16_H[32] = { 1.0797982104319795e-05, -5.396483179315242e-06, -0.00016545679579108483, 3.656592483348223e-05, 0.0013387206066921965, -0.00022211647621176323, -0.0069377611308027096, 0.001359844742484172, 0.024952758046290123, -0.003510275068374009, -0.07803785290341991, 0.03072113906330156, 0.15959219218520598, -0.054040601387606135, -0.47534280601152273, 0.7565249878756971, -0.39712293362064416, -0.034574228416972504, 0.06698304907021778, 0.032333091610663785, -0.004869274404904607, -0.031051202843553064, 0.0031265171722710075, 0.012666731659857348, -0.0007182119788317892, -0.0038809122526038786, 0.0001084456223089688, 0.0008523547108047095, -2.8078582128442894e-05, -0.00010943147929529757, 3.113556407621969e-06, 6.230006701220761e-06, }; DTYPE SYM16_I_H[32] = { 6.230006701220761e-06, 3.113556407621969e-06, -0.00010943147929529757, -2.8078582128442894e-05, 0.0008523547108047095, 0.0001084456223089688, -0.0038809122526038786, -0.0007182119788317892, 0.012666731659857348, 0.0031265171722710075, -0.031051202843553064, -0.004869274404904607, 0.032333091610663785, 0.06698304907021778, -0.034574228416972504, -0.39712293362064416, 0.7565249878756971, -0.47534280601152273, -0.054040601387606135, 0.15959219218520598, 0.03072113906330156, -0.07803785290341991, -0.003510275068374009, 0.024952758046290123, 0.001359844742484172, -0.0069377611308027096, -0.00022211647621176323, 0.0013387206066921965, 3.656592483348223e-05, -0.00016545679579108483, -5.396483179315242e-06, 1.0797982104319795e-05, }; DTYPE SYM17_L[34] = { 4.297343327345983e-06, 2.7801266938414138e-06, -6.293702597554192e-05, -1.3506383399901165e-05, 0.0004759963802638669, -0.000138642302680455, -0.0027416759756816018, 0.0008567700701915741, 0.010482366933031529, -0.004819212803176148, -0.03329138349235933, 0.01790395221434112, 0.10475461484223211, 0.0172711782105185, -0.11856693261143636, 0.1423983504146782, 0.6507166292045456, 0.681488995344925, 0.18053958458111286, -0.15507600534974825, -0.08607087472073338, 0.016158808725919346, -0.007261634750928767, -0.01803889724191924, 0.009952982523509598, 0.012396988366648726, -0.001905407689852666, -0.003932325279797902, 5.8400428694052584e-05, 0.0007198270642148971, 2.520793314082878e-05, -7.607124405605129e-05, -2.4527163425833e-06, 3.7912531943321266e-06, }; DTYPE SYM17_I_L[34] = { 3.7912531943321266e-06, -2.4527163425833e-06, -7.607124405605129e-05, 2.520793314082878e-05, 0.0007198270642148971, 5.8400428694052584e-05, -0.003932325279797902, -0.001905407689852666, 0.012396988366648726, 0.009952982523509598, -0.01803889724191924, -0.007261634750928767, 0.016158808725919346, -0.08607087472073338, -0.15507600534974825, 0.18053958458111286, 0.681488995344925, 0.6507166292045456, 0.1423983504146782, -0.11856693261143636, 0.0172711782105185, 0.10475461484223211, 0.01790395221434112, -0.03329138349235933, -0.004819212803176148, 0.010482366933031529, 0.0008567700701915741, -0.0027416759756816018, -0.000138642302680455, 0.0004759963802638669, -1.3506383399901165e-05, -6.293702597554192e-05, 2.7801266938414138e-06, 4.297343327345983e-06, }; DTYPE SYM17_H[34] = { -3.7912531943321266e-06, -2.4527163425833e-06, 7.607124405605129e-05, 2.520793314082878e-05, -0.0007198270642148971, 5.8400428694052584e-05, 0.003932325279797902, -0.001905407689852666, -0.012396988366648726, 0.009952982523509598, 0.01803889724191924, -0.007261634750928767, -0.016158808725919346, -0.08607087472073338, 0.15507600534974825, 0.18053958458111286, -0.681488995344925, 0.6507166292045456, -0.1423983504146782, -0.11856693261143636, -0.0172711782105185, 0.10475461484223211, -0.01790395221434112, -0.03329138349235933, 0.004819212803176148, 0.010482366933031529, -0.0008567700701915741, -0.0027416759756816018, 0.000138642302680455, 0.0004759963802638669, 1.3506383399901165e-05, -6.293702597554192e-05, -2.7801266938414138e-06, 4.297343327345983e-06, }; DTYPE SYM17_I_H[34] = { 4.297343327345983e-06, -2.7801266938414138e-06, -6.293702597554192e-05, 1.3506383399901165e-05, 0.0004759963802638669, 0.000138642302680455, -0.0027416759756816018, -0.0008567700701915741, 0.010482366933031529, 0.004819212803176148, -0.03329138349235933, -0.01790395221434112, 0.10475461484223211, -0.0172711782105185, -0.11856693261143636, -0.1423983504146782, 0.6507166292045456, -0.681488995344925, 0.18053958458111286, 0.15507600534974825, -0.08607087472073338, -0.016158808725919346, -0.007261634750928767, 0.01803889724191924, 0.009952982523509598, -0.012396988366648726, -0.001905407689852666, 0.003932325279797902, 5.8400428694052584e-05, -0.0007198270642148971, 2.520793314082878e-05, 7.607124405605129e-05, -2.4527163425833e-06, -3.7912531943321266e-06, }; DTYPE SYM18_L[36] = { 2.6126125564836423e-06, 1.354915761832114e-06, -4.5246757874949856e-05, -1.4020992577726755e-05, 0.00039616840638254753, 7.021273459036268e-05, -0.002313871814506099, -0.00041152110923597756, 0.009502164390962365, 0.001642986397278216, -0.030325091089369604, -0.005077085160757053, 0.08421992997038655, 0.03399566710394736, -0.15993814866932407, -0.052029158983952786, 0.47396905989393956, 0.7536291401017928, 0.40148386057061813, -0.032480573290138676, -0.07379920729060717, 0.028529597039037808, 0.006277944554311694, -0.03171268473181454, -0.0032607442000749834, 0.015012356344250213, 0.001087784789595693, -0.005239789683026608, -0.00018877623940755607, 0.0014280863270832796, 4.741614518373667e-05, -0.0002658301102424104, -9.858816030140058e-06, 2.955743762093081e-05, 7.847298055831765e-07, -1.5131530692371587e-06, }; DTYPE SYM18_I_L[36] = { -1.5131530692371587e-06, 7.847298055831765e-07, 2.955743762093081e-05, -9.858816030140058e-06, -0.0002658301102424104, 4.741614518373667e-05, 0.0014280863270832796, -0.00018877623940755607, -0.005239789683026608, 0.001087784789595693, 0.015012356344250213, -0.0032607442000749834, -0.03171268473181454, 0.006277944554311694, 0.028529597039037808, -0.07379920729060717, -0.032480573290138676, 0.40148386057061813, 0.7536291401017928, 0.47396905989393956, -0.052029158983952786, -0.15993814866932407, 0.03399566710394736, 0.08421992997038655, -0.005077085160757053, -0.030325091089369604, 0.001642986397278216, 0.009502164390962365, -0.00041152110923597756, -0.002313871814506099, 7.021273459036268e-05, 0.00039616840638254753, -1.4020992577726755e-05, -4.5246757874949856e-05, 1.354915761832114e-06, 2.6126125564836423e-06, }; DTYPE SYM18_H[36] = { 1.5131530692371587e-06, 7.847298055831765e-07, -2.955743762093081e-05, -9.858816030140058e-06, 0.0002658301102424104, 4.741614518373667e-05, -0.0014280863270832796, -0.00018877623940755607, 0.005239789683026608, 0.001087784789595693, -0.015012356344250213, -0.0032607442000749834, 0.03171268473181454, 0.006277944554311694, -0.028529597039037808, -0.07379920729060717, 0.032480573290138676, 0.40148386057061813, -0.7536291401017928, 0.47396905989393956, 0.052029158983952786, -0.15993814866932407, -0.03399566710394736, 0.08421992997038655, 0.005077085160757053, -0.030325091089369604, -0.001642986397278216, 0.009502164390962365, 0.00041152110923597756, -0.002313871814506099, -7.021273459036268e-05, 0.00039616840638254753, 1.4020992577726755e-05, -4.5246757874949856e-05, -1.354915761832114e-06, 2.6126125564836423e-06, }; DTYPE SYM18_I_H[36] = { 2.6126125564836423e-06, -1.354915761832114e-06, -4.5246757874949856e-05, 1.4020992577726755e-05, 0.00039616840638254753, -7.021273459036268e-05, -0.002313871814506099, 0.00041152110923597756, 0.009502164390962365, -0.001642986397278216, -0.030325091089369604, 0.005077085160757053, 0.08421992997038655, -0.03399566710394736, -0.15993814866932407, 0.052029158983952786, 0.47396905989393956, -0.7536291401017928, 0.40148386057061813, 0.032480573290138676, -0.07379920729060717, -0.028529597039037808, 0.006277944554311694, 0.03171268473181454, -0.0032607442000749834, -0.015012356344250213, 0.001087784789595693, 0.005239789683026608, -0.00018877623940755607, -0.0014280863270832796, 4.741614518373667e-05, 0.0002658301102424104, -9.858816030140058e-06, -2.955743762093081e-05, 7.847298055831765e-07, 1.5131530692371587e-06, }; DTYPE SYM19_L[38] = { 5.487732768215838e-07, -6.463651303345963e-07, -1.1880518269823984e-05, 8.873312173729286e-06, 0.0001155392333357879, -4.612039600210587e-05, -0.000635764515004334, 0.00015915804768084938, 0.0021214250281823303, -0.0011607032572062486, -0.005122205002583014, 0.007968438320613306, 0.01579743929567463, -0.02265199337824595, -0.046635983534938946, 0.0070155738571741596, 0.008954591173043624, -0.06752505804029409, 0.10902582508127781, 0.578144945338605, 0.7195555257163943, 0.2582661692372836, -0.17659686625203097, -0.11624173010739675, 0.09363084341589714, 0.08407267627924504, -0.016908234861345205, -0.02770989693131125, 0.004319351874894969, 0.008262236955528255, -0.0006179223277983108, -0.0017049602611649971, 0.00012930767650701415, 0.0002762187768573407, -1.6821387029373716e-05, -2.8151138661550245e-05, 2.0623170632395688e-06, 1.7509367995348687e-06, }; DTYPE SYM19_I_L[38] = { 1.7509367995348687e-06, 2.0623170632395688e-06, -2.8151138661550245e-05, -1.6821387029373716e-05, 0.0002762187768573407, 0.00012930767650701415, -0.0017049602611649971, -0.0006179223277983108, 0.008262236955528255, 0.004319351874894969, -0.02770989693131125, -0.016908234861345205, 0.08407267627924504, 0.09363084341589714, -0.11624173010739675, -0.17659686625203097, 0.2582661692372836, 0.7195555257163943, 0.578144945338605, 0.10902582508127781, -0.06752505804029409, 0.008954591173043624, 0.0070155738571741596, -0.046635983534938946, -0.02265199337824595, 0.01579743929567463, 0.007968438320613306, -0.005122205002583014, -0.0011607032572062486, 0.0021214250281823303, 0.00015915804768084938, -0.000635764515004334, -4.612039600210587e-05, 0.0001155392333357879, 8.873312173729286e-06, -1.1880518269823984e-05, -6.463651303345963e-07, 5.487732768215838e-07, }; DTYPE SYM19_H[38] = { -1.7509367995348687e-06, 2.0623170632395688e-06, 2.8151138661550245e-05, -1.6821387029373716e-05, -0.0002762187768573407, 0.00012930767650701415, 0.0017049602611649971, -0.0006179223277983108, -0.008262236955528255, 0.004319351874894969, 0.02770989693131125, -0.016908234861345205, -0.08407267627924504, 0.09363084341589714, 0.11624173010739675, -0.17659686625203097, -0.2582661692372836, 0.7195555257163943, -0.578144945338605, 0.10902582508127781, 0.06752505804029409, 0.008954591173043624, -0.0070155738571741596, -0.046635983534938946, 0.02265199337824595, 0.01579743929567463, -0.007968438320613306, -0.005122205002583014, 0.0011607032572062486, 0.0021214250281823303, -0.00015915804768084938, -0.000635764515004334, 4.612039600210587e-05, 0.0001155392333357879, -8.873312173729286e-06, -1.1880518269823984e-05, 6.463651303345963e-07, 5.487732768215838e-07, }; DTYPE SYM19_I_H[38] = { 5.487732768215838e-07, 6.463651303345963e-07, -1.1880518269823984e-05, -8.873312173729286e-06, 0.0001155392333357879, 4.612039600210587e-05, -0.000635764515004334, -0.00015915804768084938, 0.0021214250281823303, 0.0011607032572062486, -0.005122205002583014, -0.007968438320613306, 0.01579743929567463, 0.02265199337824595, -0.046635983534938946, -0.0070155738571741596, 0.008954591173043624, 0.06752505804029409, 0.10902582508127781, -0.578144945338605, 0.7195555257163943, -0.2582661692372836, -0.17659686625203097, 0.11624173010739675, 0.09363084341589714, -0.08407267627924504, -0.016908234861345205, 0.02770989693131125, 0.004319351874894969, -0.008262236955528255, -0.0006179223277983108, 0.0017049602611649971, 0.00012930767650701415, -0.0002762187768573407, -1.6821387029373716e-05, 2.8151138661550245e-05, 2.0623170632395688e-06, -1.7509367995348687e-06, }; DTYPE SYM20_L[40] = { 3.695537474835221e-07, -1.9015675890554106e-07, -7.919361411976999e-06, 3.025666062736966e-06, 7.992967835772481e-05, -1.928412300645204e-05, -0.0004947310915672655, 7.215991188074035e-05, 0.002088994708190198, -0.0003052628317957281, -0.006606585799088861, 0.0014230873594621453, 0.01700404902339034, -0.003313857383623359, -0.031629437144957966, 0.008123228356009682, 0.025579349509413946, -0.07899434492839816, -0.02981936888033373, 0.4058314443484506, 0.75116272842273, 0.47199147510148703, -0.0510883429210674, -0.16057829841525254, 0.03625095165393308, 0.08891966802819956, -0.0068437019650692274, -0.035373336756604236, 0.0019385970672402002, 0.012157040948785737, -0.0006111263857992088, -0.0034716478028440734, 0.0001254409172306726, 0.0007476108597820572, -2.6615550335516086e-05, -0.00011739133516291466, 4.525422209151636e-06, 1.22872527779612e-05, -3.2567026420174407e-07, -6.329129044776395e-07, }; DTYPE SYM20_I_L[40] = { -6.329129044776395e-07, -3.2567026420174407e-07, 1.22872527779612e-05, 4.525422209151636e-06, -0.00011739133516291466, -2.6615550335516086e-05, 0.0007476108597820572, 0.0001254409172306726, -0.0034716478028440734, -0.0006111263857992088, 0.012157040948785737, 0.0019385970672402002, -0.035373336756604236, -0.0068437019650692274, 0.08891966802819956, 0.03625095165393308, -0.16057829841525254, -0.0510883429210674, 0.47199147510148703, 0.75116272842273, 0.4058314443484506, -0.02981936888033373, -0.07899434492839816, 0.025579349509413946, 0.008123228356009682, -0.031629437144957966, -0.003313857383623359, 0.01700404902339034, 0.0014230873594621453, -0.006606585799088861, -0.0003052628317957281, 0.002088994708190198, 7.215991188074035e-05, -0.0004947310915672655, -1.928412300645204e-05, 7.992967835772481e-05, 3.025666062736966e-06, -7.919361411976999e-06, -1.9015675890554106e-07, 3.695537474835221e-07, }; DTYPE SYM20_H[40] = { 6.329129044776395e-07, -3.2567026420174407e-07, -1.22872527779612e-05, 4.525422209151636e-06, 0.00011739133516291466, -2.6615550335516086e-05, -0.0007476108597820572, 0.0001254409172306726, 0.0034716478028440734, -0.0006111263857992088, -0.012157040948785737, 0.0019385970672402002, 0.035373336756604236, -0.0068437019650692274, -0.08891966802819956, 0.03625095165393308, 0.16057829841525254, -0.0510883429210674, -0.47199147510148703, 0.75116272842273, -0.4058314443484506, -0.02981936888033373, 0.07899434492839816, 0.025579349509413946, -0.008123228356009682, -0.031629437144957966, 0.003313857383623359, 0.01700404902339034, -0.0014230873594621453, -0.006606585799088861, 0.0003052628317957281, 0.002088994708190198, -7.215991188074035e-05, -0.0004947310915672655, 1.928412300645204e-05, 7.992967835772481e-05, -3.025666062736966e-06, -7.919361411976999e-06, 1.9015675890554106e-07, 3.695537474835221e-07, }; DTYPE SYM20_I_H[40] = { 3.695537474835221e-07, 1.9015675890554106e-07, -7.919361411976999e-06, -3.025666062736966e-06, 7.992967835772481e-05, 1.928412300645204e-05, -0.0004947310915672655, -7.215991188074035e-05, 0.002088994708190198, 0.0003052628317957281, -0.006606585799088861, -0.0014230873594621453, 0.01700404902339034, 0.003313857383623359, -0.031629437144957966, -0.008123228356009682, 0.025579349509413946, 0.07899434492839816, -0.02981936888033373, -0.4058314443484506, 0.75116272842273, -0.47199147510148703, -0.0510883429210674, 0.16057829841525254, 0.03625095165393308, -0.08891966802819956, -0.0068437019650692274, 0.035373336756604236, 0.0019385970672402002, -0.012157040948785737, -0.0006111263857992088, 0.0034716478028440734, 0.0001254409172306726, -0.0007476108597820572, -2.6615550335516086e-05, 0.00011739133516291466, 4.525422209151636e-06, -1.22872527779612e-05, -3.2567026420174407e-07, 6.329129044776395e-07, }; DTYPE COIF1_L[6] = { -0.01565572813546454, -0.0727326195128539, 0.38486484686420286, 0.8525720202122554, 0.3378976624578092, -0.0727326195128539, }; DTYPE COIF1_I_L[6] = { -0.0727326195128539, 0.3378976624578092, 0.8525720202122554, 0.38486484686420286, -0.0727326195128539, -0.01565572813546454, }; DTYPE COIF1_H[6] = { 0.0727326195128539, 0.3378976624578092, -0.8525720202122554, 0.38486484686420286, 0.0727326195128539, -0.01565572813546454, }; DTYPE COIF1_I_H[6] = { -0.01565572813546454, 0.0727326195128539, 0.38486484686420286, -0.8525720202122554, 0.3378976624578092, 0.0727326195128539, }; DTYPE COIF2_L[12] = { -0.0007205494453645122, -0.0018232088707029932, 0.0056114348193944995, 0.023680171946334084, -0.0594344186464569, -0.0764885990783064, 0.41700518442169254, 0.8127236354455423, 0.3861100668211622, -0.06737255472196302, -0.04146493678175915, 0.016387336463522112, }; DTYPE COIF2_I_L[12] = { 0.016387336463522112, -0.04146493678175915, -0.06737255472196302, 0.3861100668211622, 0.8127236354455423, 0.41700518442169254, -0.0764885990783064, -0.0594344186464569, 0.023680171946334084, 0.0056114348193944995, -0.0018232088707029932, -0.0007205494453645122, }; DTYPE COIF2_H[12] = { -0.016387336463522112, -0.04146493678175915, 0.06737255472196302, 0.3861100668211622, -0.8127236354455423, 0.41700518442169254, 0.0764885990783064, -0.0594344186464569, -0.023680171946334084, 0.0056114348193944995, 0.0018232088707029932, -0.0007205494453645122, }; DTYPE COIF2_I_H[12] = { -0.0007205494453645122, 0.0018232088707029932, 0.0056114348193944995, -0.023680171946334084, -0.0594344186464569, 0.0764885990783064, 0.41700518442169254, -0.8127236354455423, 0.3861100668211622, 0.06737255472196302, -0.04146493678175915, -0.016387336463522112, }; DTYPE COIF3_L[18] = { -3.459977283621256e-05, -7.098330313814125e-05, 0.0004662169601128863, 0.0011175187708906016, -0.0025745176887502236, -0.00900797613666158, 0.015880544863615904, 0.03455502757306163, -0.08230192710688598, -0.07179982161931202, 0.42848347637761874, 0.7937772226256206, 0.4051769024096169, -0.06112339000267287, -0.0657719112818555, 0.023452696141836267, 0.007782596427325418, -0.003793512864491014, }; DTYPE COIF3_I_L[18] = { -0.003793512864491014, 0.007782596427325418, 0.023452696141836267, -0.0657719112818555, -0.06112339000267287, 0.4051769024096169, 0.7937772226256206, 0.42848347637761874, -0.07179982161931202, -0.08230192710688598, 0.03455502757306163, 0.015880544863615904, -0.00900797613666158, -0.0025745176887502236, 0.0011175187708906016, 0.0004662169601128863, -7.098330313814125e-05, -3.459977283621256e-05, }; DTYPE COIF3_H[18] = { 0.003793512864491014, 0.007782596427325418, -0.023452696141836267, -0.0657719112818555, 0.06112339000267287, 0.4051769024096169, -0.7937772226256206, 0.42848347637761874, 0.07179982161931202, -0.08230192710688598, -0.03455502757306163, 0.015880544863615904, 0.00900797613666158, -0.0025745176887502236, -0.0011175187708906016, 0.0004662169601128863, 7.098330313814125e-05, -3.459977283621256e-05, }; DTYPE COIF3_I_H[18] = { -3.459977283621256e-05, 7.098330313814125e-05, 0.0004662169601128863, -0.0011175187708906016, -0.0025745176887502236, 0.00900797613666158, 0.015880544863615904, -0.03455502757306163, -0.08230192710688598, 0.07179982161931202, 0.42848347637761874, -0.7937772226256206, 0.4051769024096169, 0.06112339000267287, -0.0657719112818555, -0.023452696141836267, 0.007782596427325418, 0.003793512864491014, }; DTYPE COIF4_L[24] = { -1.7849850030882614e-06, -3.2596802368833675e-06, 3.1229875865345646e-05, 6.233903446100713e-05, -0.00025997455248771324, -0.0005890207562443383, 0.0012665619292989445, 0.003751436157278457, -0.00565828668661072, -0.015211731527946259, 0.025082261844864097, 0.03933442712333749, -0.09622044203398798, -0.06662747426342504, 0.4343860564914685, 0.782238930920499, 0.41530840703043026, -0.05607731331675481, -0.08126669968087875, 0.026682300156053072, 0.016068943964776348, -0.0073461663276420935, -0.0016294920126017326, 0.0008923136685823146, }; DTYPE COIF4_I_L[24] = { 0.0008923136685823146, -0.0016294920126017326, -0.0073461663276420935, 0.016068943964776348, 0.026682300156053072, -0.08126669968087875, -0.05607731331675481, 0.41530840703043026, 0.782238930920499, 0.4343860564914685, -0.06662747426342504, -0.09622044203398798, 0.03933442712333749, 0.025082261844864097, -0.015211731527946259, -0.00565828668661072, 0.003751436157278457, 0.0012665619292989445, -0.0005890207562443383, -0.00025997455248771324, 6.233903446100713e-05, 3.1229875865345646e-05, -3.2596802368833675e-06, -1.7849850030882614e-06, }; DTYPE COIF4_H[24] = { -0.0008923136685823146, -0.0016294920126017326, 0.0073461663276420935, 0.016068943964776348, -0.026682300156053072, -0.08126669968087875, 0.05607731331675481, 0.41530840703043026, -0.782238930920499, 0.4343860564914685, 0.06662747426342504, -0.09622044203398798, -0.03933442712333749, 0.025082261844864097, 0.015211731527946259, -0.00565828668661072, -0.003751436157278457, 0.0012665619292989445, 0.0005890207562443383, -0.00025997455248771324, -6.233903446100713e-05, 3.1229875865345646e-05, 3.2596802368833675e-06, -1.7849850030882614e-06, }; DTYPE COIF4_I_H[24] = { -1.7849850030882614e-06, 3.2596802368833675e-06, 3.1229875865345646e-05, -6.233903446100713e-05, -0.00025997455248771324, 0.0005890207562443383, 0.0012665619292989445, -0.003751436157278457, -0.00565828668661072, 0.015211731527946259, 0.025082261844864097, -0.03933442712333749, -0.09622044203398798, 0.06662747426342504, 0.4343860564914685, -0.782238930920499, 0.41530840703043026, 0.05607731331675481, -0.08126669968087875, -0.026682300156053072, 0.016068943964776348, 0.0073461663276420935, -0.0016294920126017326, -0.0008923136685823146, }; DTYPE COIF5_L[30] = { -9.517657273819165e-08, -1.6744288576823017e-07, 2.0637618513646814e-06, 3.7346551751414047e-06, -2.1315026809955787e-05, -4.134043227251251e-05, 0.00014054114970203437, 0.00030225958181306315, -0.0006381313430451114, -0.0016628637020130838, 0.0024333732126576722, 0.006764185448053083, -0.009164231162481846, -0.01976177894257264, 0.03268357426711183, 0.0412892087501817, -0.10557420870333893, -0.06203596396290357, 0.4379916261718371, 0.7742896036529562, 0.4215662066908515, -0.05204316317624377, -0.09192001055969624, 0.02816802897093635, 0.023408156785839195, -0.010131117519849788, -0.004159358781386048, 0.0021782363581090178, 0.00035858968789573785, -0.00021208083980379827, }; DTYPE COIF5_I_L[30] = { -0.00021208083980379827, 0.00035858968789573785, 0.0021782363581090178, -0.004159358781386048, -0.010131117519849788, 0.023408156785839195, 0.02816802897093635, -0.09192001055969624, -0.05204316317624377, 0.4215662066908515, 0.7742896036529562, 0.4379916261718371, -0.06203596396290357, -0.10557420870333893, 0.0412892087501817, 0.03268357426711183, -0.01976177894257264, -0.009164231162481846, 0.006764185448053083, 0.0024333732126576722, -0.0016628637020130838, -0.0006381313430451114, 0.00030225958181306315, 0.00014054114970203437, -4.134043227251251e-05, -2.1315026809955787e-05, 3.7346551751414047e-06, 2.0637618513646814e-06, -1.6744288576823017e-07, -9.517657273819165e-08, }; DTYPE COIF5_H[30] = { 0.00021208083980379827, 0.00035858968789573785, -0.0021782363581090178, -0.004159358781386048, 0.010131117519849788, 0.023408156785839195, -0.02816802897093635, -0.09192001055969624, 0.05204316317624377, 0.4215662066908515, -0.7742896036529562, 0.4379916261718371, 0.06203596396290357, -0.10557420870333893, -0.0412892087501817, 0.03268357426711183, 0.01976177894257264, -0.009164231162481846, -0.006764185448053083, 0.0024333732126576722, 0.0016628637020130838, -0.0006381313430451114, -0.00030225958181306315, 0.00014054114970203437, 4.134043227251251e-05, -2.1315026809955787e-05, -3.7346551751414047e-06, 2.0637618513646814e-06, 1.6744288576823017e-07, -9.517657273819165e-08, }; DTYPE COIF5_I_H[30] = { -9.517657273819165e-08, 1.6744288576823017e-07, 2.0637618513646814e-06, -3.7346551751414047e-06, -2.1315026809955787e-05, 4.134043227251251e-05, 0.00014054114970203437, -0.00030225958181306315, -0.0006381313430451114, 0.0016628637020130838, 0.0024333732126576722, -0.006764185448053083, -0.009164231162481846, 0.01976177894257264, 0.03268357426711183, -0.0412892087501817, -0.10557420870333893, 0.06203596396290357, 0.4379916261718371, -0.7742896036529562, 0.4215662066908515, 0.05204316317624377, -0.09192001055969624, -0.02816802897093635, 0.023408156785839195, 0.010131117519849788, -0.004159358781386048, -0.0021782363581090178, 0.00035858968789573785, 0.00021208083980379827, }; /// /// ----- /// DTYPE BIOR1_3_L[6] = { -0.08838834764831845, 0.08838834764831845, 0.7071067811865476, 0.7071067811865476, 0.08838834764831845, -0.08838834764831845, }; DTYPE BIOR1_3_I_L[6] = { 0.0, 0.0, 0.7071067811865476, 0.7071067811865476, 0.0, 0.0, }; DTYPE BIOR1_3_H[6] = { 0.0, 0.0, -0.7071067811865476, 0.7071067811865476, 0.0, 0.0, }; DTYPE BIOR1_3_I_H[6] = { -0.08838834764831845, -0.08838834764831845, 0.7071067811865476, -0.7071067811865476, 0.08838834764831845, 0.08838834764831845, }; DTYPE BIOR1_5_L[10] = { 0.01657281518405971, -0.01657281518405971, -0.12153397801643787, 0.12153397801643787, 0.7071067811865476, 0.7071067811865476, 0.12153397801643787, -0.12153397801643787, -0.01657281518405971, 0.01657281518405971, }; DTYPE BIOR1_5_I_L[10] = { 0.0, 0.0, 0.0, 0.0, 0.7071067811865476, 0.7071067811865476, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR1_5_H[10] = { 0.0, 0.0, 0.0, 0.0, -0.7071067811865476, 0.7071067811865476, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR1_5_I_H[10] = { 0.01657281518405971, 0.01657281518405971, -0.12153397801643787, -0.12153397801643787, 0.7071067811865476, -0.7071067811865476, 0.12153397801643787, 0.12153397801643787, -0.01657281518405971, -0.01657281518405971, }; DTYPE BIOR2_2_L[6] = { 0.0, -0.1767766952966369, 0.3535533905932738, 1.0606601717798214, 0.3535533905932738, -0.1767766952966369, }; DTYPE BIOR2_2_I_L[6] = { 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, }; DTYPE BIOR2_2_H[6] = { 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, }; DTYPE BIOR2_2_I_H[6] = { 0.0, 0.1767766952966369, 0.3535533905932738, -1.0606601717798214, 0.3535533905932738, 0.1767766952966369, }; DTYPE BIOR2_4_L[10] = { 0.0, 0.03314563036811942, -0.06629126073623884, -0.1767766952966369, 0.4198446513295126, 0.9943689110435825, 0.4198446513295126, -0.1767766952966369, -0.06629126073623884, 0.03314563036811942, }; DTYPE BIOR2_4_I_L[10] = { 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_4_H[10] = { 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_4_I_H[10] = { 0.0, -0.03314563036811942, -0.06629126073623884, 0.1767766952966369, 0.4198446513295126, -0.9943689110435825, 0.4198446513295126, 0.1767766952966369, -0.06629126073623884, -0.03314563036811942, }; DTYPE BIOR2_6_L[14] = { 0.0, -0.006905339660024878, 0.013810679320049757, 0.046956309688169176, -0.10772329869638811, -0.16987135563661201, 0.4474660099696121, 0.966747552403483, 0.4474660099696121, -0.16987135563661201, -0.10772329869638811, 0.046956309688169176, 0.013810679320049757, -0.006905339660024878, }; DTYPE BIOR2_6_I_L[14] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_6_H[14] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_6_I_H[14] = { 0.0, 0.006905339660024878, 0.013810679320049757, -0.046956309688169176, -0.10772329869638811, 0.16987135563661201, 0.4474660099696121, -0.966747552403483, 0.4474660099696121, 0.16987135563661201, -0.10772329869638811, -0.046956309688169176, 0.013810679320049757, 0.006905339660024878, }; DTYPE BIOR2_8_L[18] = { 0.0, 0.0015105430506304422, -0.0030210861012608843, -0.012947511862546647, 0.02891610982635418, 0.052998481890690945, -0.13491307360773608, -0.16382918343409025, 0.4625714404759166, 0.9516421218971786, 0.4625714404759166, -0.16382918343409025, -0.13491307360773608, 0.052998481890690945, 0.02891610982635418, -0.012947511862546647, -0.0030210861012608843, 0.0015105430506304422, }; DTYPE BIOR2_8_I_L[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_8_H[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR2_8_I_H[18] = { 0.0, -0.0015105430506304422, -0.0030210861012608843, 0.012947511862546647, 0.02891610982635418, -0.052998481890690945, -0.13491307360773608, 0.16382918343409025, 0.4625714404759166, -0.9516421218971786, 0.4625714404759166, 0.16382918343409025, -0.13491307360773608, -0.052998481890690945, 0.02891610982635418, 0.012947511862546647, -0.0030210861012608843, -0.0015105430506304422, }; DTYPE BIOR3_1_L[4] = { -0.3535533905932738, 1.0606601717798214, 1.0606601717798214, -0.3535533905932738, }; DTYPE BIOR3_1_I_L[4] = { 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, }; DTYPE BIOR3_1_H[4] = { -0.1767766952966369, 0.5303300858899107, -0.5303300858899107, 0.1767766952966369, }; DTYPE BIOR3_1_I_H[4] = { -0.3535533905932738, -1.0606601717798214, 1.0606601717798214, 0.3535533905932738, }; DTYPE BIOR3_3_L[8] = { 0.06629126073623884, -0.19887378220871652, -0.15467960838455727, 0.9943689110435825, 0.9943689110435825, -0.15467960838455727, -0.19887378220871652, 0.06629126073623884, }; DTYPE BIOR3_3_I_L[8] = { 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, }; DTYPE BIOR3_3_H[8] = { 0.0, 0.0, -0.1767766952966369, 0.5303300858899107, -0.5303300858899107, 0.1767766952966369, 0.0, 0.0, }; DTYPE BIOR3_3_I_H[8] = { 0.06629126073623884, 0.19887378220871652, -0.15467960838455727, -0.9943689110435825, 0.9943689110435825, 0.15467960838455727, -0.19887378220871652, -0.06629126073623884, }; DTYPE BIOR3_5_L[12] = { -0.013810679320049757, 0.04143203796014927, 0.052480581416189075, -0.26792717880896527, -0.07181553246425874, 0.966747552403483, 0.966747552403483, -0.07181553246425874, -0.26792717880896527, 0.052480581416189075, 0.04143203796014927, -0.013810679320049757, }; DTYPE BIOR3_5_I_L[12] = { 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_5_H[12] = { 0.0, 0.0, 0.0, 0.0, -0.1767766952966369, 0.5303300858899107, -0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_5_I_H[12] = { -0.013810679320049757, -0.04143203796014927, 0.052480581416189075, 0.26792717880896527, -0.07181553246425874, -0.966747552403483, 0.966747552403483, 0.07181553246425874, -0.26792717880896527, -0.052480581416189075, 0.04143203796014927, 0.013810679320049757, }; DTYPE BIOR3_7_L[16] = { 0.0030210861012608843, -0.009063258303782653, -0.01683176542131064, 0.074663985074019, 0.03133297870736289, -0.301159125922835, -0.026499240945345472, 0.9516421218971786, 0.9516421218971786, -0.026499240945345472, -0.301159125922835, 0.03133297870736289, 0.074663985074019, -0.01683176542131064, -0.009063258303782653, 0.0030210861012608843, }; DTYPE BIOR3_7_I_L[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_7_H[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1767766952966369, 0.5303300858899107, -0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_7_I_H[16] = { 0.0030210861012608843, 0.009063258303782653, -0.01683176542131064, -0.074663985074019, 0.03133297870736289, 0.301159125922835, -0.026499240945345472, -0.9516421218971786, 0.9516421218971786, 0.026499240945345472, -0.301159125922835, -0.03133297870736289, 0.074663985074019, 0.01683176542131064, -0.009063258303782653, -0.0030210861012608843, }; DTYPE BIOR3_9_L[20] = { -0.000679744372783699, 0.002039233118351097, 0.005060319219611981, -0.020618912641105536, -0.014112787930175846, 0.09913478249423216, 0.012300136269419315, -0.32019196836077857, 0.0020500227115698858, 0.9421257006782068, 0.9421257006782068, 0.0020500227115698858, -0.32019196836077857, 0.012300136269419315, 0.09913478249423216, -0.014112787930175846, -0.020618912641105536, 0.005060319219611981, 0.002039233118351097, -0.000679744372783699, }; DTYPE BIOR3_9_I_L[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_9_H[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1767766952966369, 0.5303300858899107, -0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE BIOR3_9_I_H[20] = { -0.000679744372783699, -0.002039233118351097, 0.005060319219611981, 0.020618912641105536, -0.014112787930175846, -0.09913478249423216, 0.012300136269419315, 0.32019196836077857, 0.0020500227115698858, -0.9421257006782068, 0.9421257006782068, -0.0020500227115698858, -0.32019196836077857, -0.012300136269419315, 0.09913478249423216, 0.014112787930175846, -0.020618912641105536, -0.005060319219611981, 0.002039233118351097, 0.000679744372783699, }; DTYPE BIOR4_4_L[10] = { 0.0, 0.03782845550726404, -0.023849465019556843, -0.11062440441843718, 0.37740285561283066, 0.8526986790088938, 0.37740285561283066, -0.11062440441843718, -0.023849465019556843, 0.03782845550726404, }; DTYPE BIOR4_4_I_L[10] = { 0.0, -0.06453888262869706, -0.04068941760916406, 0.41809227322161724, 0.7884856164055829, 0.41809227322161724, -0.04068941760916406, -0.06453888262869706, 0.0, 0.0, }; DTYPE BIOR4_4_H[10] = { 0.0, -0.06453888262869706, 0.04068941760916406, 0.41809227322161724, -0.7884856164055829, 0.41809227322161724, 0.04068941760916406, -0.06453888262869706, 0.0, 0.0, }; DTYPE BIOR4_4_I_H[10] = { 0.0, -0.03782845550726404, -0.023849465019556843, 0.11062440441843718, 0.37740285561283066, -0.8526986790088938, 0.37740285561283066, 0.11062440441843718, -0.023849465019556843, -0.03782845550726404, }; DTYPE BIOR5_5_L[12] = { 0.0, 0.0, 0.03968708834740544, 0.007948108637240322, -0.05446378846823691, 0.34560528195603346, 0.7366601814282105, 0.34560528195603346, -0.05446378846823691, 0.007948108637240322, 0.03968708834740544, 0.0 }; DTYPE BIOR5_5_H[12] = { -0.013456709459118716, -0.002694966880111507, 0.13670658466432914, -0.09350469740093886, -0.47680326579848425, 0.8995061097486484, -0.47680326579848425, -0.09350469740093886, 0.13670658466432914, -0.002694966880111507, -0.013456709459118716, 0.0 }; DTYPE BIOR5_5_I_L[12] = { 0.013456709459118716, -0.002694966880111507, -0.13670658466432914, -0.09350469740093886, 0.47680326579848425, 0.8995061097486484, 0.47680326579848425, -0.09350469740093886, -0.13670658466432914, -0.002694966880111507, 0.013456709459118716, 0.0 }; DTYPE BIOR5_5_I_H[12] = { 0.0, 0.0, 0.03968708834740544, -0.007948108637240322, -0.05446378846823691, -0.34560528195603346, 0.7366601814282105, -0.34560528195603346, -0.05446378846823691, -0.007948108637240322, 0.03968708834740544, 0.0 }; DTYPE BIOR6_8_L[18] = { 0.0, 0.0019088317364812906, -0.0019142861290887667, -0.016990639867602342, 0.01193456527972926, 0.04973290349094079, -0.07726317316720414, -0.09405920349573646, 0.4207962846098268, 0.8259229974584023, 0.4207962846098268, -0.09405920349573646, -0.07726317316720414, 0.04973290349094079, 0.01193456527972926, -0.016990639867602342, -0.0019142861290887667, 0.0019088317364812906 }; DTYPE BIOR6_8_H[18] = { 0.0, 0.0, 0.0, 0.014426282505624435, -0.014467504896790148, -0.07872200106262882, 0.04036797903033992, 0.41784910915027457, -0.7589077294536541, 0.41784910915027457, 0.04036797903033992, -0.07872200106262882, -0.014467504896790148, 0.014426282505624435, 0.0, 0.0, 0.0, 0.0 }; DTYPE BIOR6_8_I_L[18] = { 0.0, 0.0, 0.0, 0.014426282505624435, 0.014467504896790148, -0.07872200106262882, -0.04036797903033992, 0.41784910915027457, 0.7589077294536541, 0.41784910915027457, -0.04036797903033992, -0.07872200106262882, 0.014467504896790148, 0.014426282505624435, 0.0, 0.0, 0.0, 0.0 }; DTYPE BIOR6_8_I_H[18] = { 0.0, -0.0019088317364812906, -0.0019142861290887667, 0.016990639867602342, 0.01193456527972926, -0.04973290349094079, -0.07726317316720414, 0.09405920349573646, 0.4207962846098268, -0.8259229974584023, 0.4207962846098268, 0.09405920349573646, -0.07726317316720414, -0.04973290349094079, 0.01193456527972926, 0.016990639867602342, -0.0019142861290887667, -0.0019088317364812906, }; DTYPE RBIOR1_3_L[6] = { 0.0, 0.0, 0.7071067811865476, 0.7071067811865476, 0.0, 0.0, }; DTYPE RBIOR1_3_I_L[6] = { -0.08838834764831845, 0.08838834764831845, 0.7071067811865476, 0.7071067811865476, 0.08838834764831845, -0.08838834764831845, }; DTYPE RBIOR1_3_H[6] = { 0.08838834764831845, 0.08838834764831845, -0.7071067811865476, 0.7071067811865476, -0.08838834764831845, -0.08838834764831845, }; DTYPE RBIOR1_3_I_H[6] = { 0.0, 0.0, 0.7071067811865476, -0.7071067811865476, 0.0, 0.0, }; DTYPE RBIOR1_5_L[10] = { 0.0, 0.0, 0.0, 0.0, 0.7071067811865476, 0.7071067811865476, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR1_5_I_L[10] = { 0.01657281518405971, -0.01657281518405971, -0.12153397801643787, 0.12153397801643787, 0.7071067811865476, 0.7071067811865476, 0.12153397801643787, -0.12153397801643787, -0.01657281518405971, 0.01657281518405971, }; DTYPE RBIOR1_5_H[10] = { -0.01657281518405971, -0.01657281518405971, 0.12153397801643787, 0.12153397801643787, -0.7071067811865476, 0.7071067811865476, -0.12153397801643787, -0.12153397801643787, 0.01657281518405971, 0.01657281518405971, }; DTYPE RBIOR1_5_I_H[10] = { 0.0, 0.0, 0.0, 0.0, 0.7071067811865476, -0.7071067811865476, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_2_L[6] = { 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, }; DTYPE RBIOR2_2_I_L[6] = { -0.1767766952966369, 0.3535533905932738, 1.0606601717798214, 0.3535533905932738, -0.1767766952966369, 0.0, }; DTYPE RBIOR2_2_H[6] = { 0.1767766952966369, 0.3535533905932738, -1.0606601717798214, 0.3535533905932738, 0.1767766952966369, 0.0, }; DTYPE RBIOR2_2_I_H[6] = { 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, }; DTYPE RBIOR2_4_L[10] = { 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_4_I_L[10] = { 0.03314563036811942, -0.06629126073623884, -0.1767766952966369, 0.4198446513295126, 0.9943689110435825, 0.4198446513295126, -0.1767766952966369, -0.06629126073623884, 0.03314563036811942, 0.0, }; DTYPE RBIOR2_4_H[10] = { -0.03314563036811942, -0.06629126073623884, 0.1767766952966369, 0.4198446513295126, -0.9943689110435825, 0.4198446513295126, 0.1767766952966369, -0.06629126073623884, -0.03314563036811942, 0.0, }; DTYPE RBIOR2_4_I_H[10] = { 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_6_L[14] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_6_I_L[14] = { -0.006905339660024878, 0.013810679320049757, 0.046956309688169176, -0.10772329869638811, -0.16987135563661201, 0.4474660099696121, 0.966747552403483, 0.4474660099696121, -0.16987135563661201, -0.10772329869638811, 0.046956309688169176, 0.013810679320049757, -0.006905339660024878, 0.0, }; DTYPE RBIOR2_6_H[14] = { 0.006905339660024878, 0.013810679320049757, -0.046956309688169176, -0.10772329869638811, 0.16987135563661201, 0.4474660099696121, -0.966747552403483, 0.4474660099696121, 0.16987135563661201, -0.10772329869638811, -0.046956309688169176, 0.013810679320049757, 0.006905339660024878, 0.0, }; DTYPE RBIOR2_6_I_H[14] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_8_L[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, 0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR2_8_I_L[18] = { 0.0015105430506304422, -0.0030210861012608843, -0.012947511862546647, 0.02891610982635418, 0.052998481890690945, -0.13491307360773608, -0.16382918343409025, 0.4625714404759166, 0.9516421218971786, 0.4625714404759166, -0.16382918343409025, -0.13491307360773608, 0.052998481890690945, 0.02891610982635418, -0.012947511862546647, -0.0030210861012608843, 0.0015105430506304422, 0.0, }; DTYPE RBIOR2_8_H[18] = { -0.0015105430506304422, -0.0030210861012608843, 0.012947511862546647, 0.02891610982635418, -0.052998481890690945, -0.13491307360773608, 0.16382918343409025, 0.4625714404759166, -0.9516421218971786, 0.4625714404759166, 0.16382918343409025, -0.13491307360773608, -0.052998481890690945, 0.02891610982635418, 0.012947511862546647, -0.0030210861012608843, -0.0015105430506304422, 0.0, }; DTYPE RBIOR2_8_I_H[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932738, -0.7071067811865476, 0.3535533905932738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_1_L[4] = { 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, }; DTYPE RBIOR3_1_I_L[4] = { -0.3535533905932738, 1.0606601717798214, 1.0606601717798214, -0.3535533905932738, }; DTYPE RBIOR3_1_H[4] = { 0.3535533905932738, 1.0606601717798214, -1.0606601717798214, -0.3535533905932738, }; DTYPE RBIOR3_1_I_H[4] = { 0.1767766952966369, -0.5303300858899107, 0.5303300858899107, -0.1767766952966369, }; DTYPE RBIOR3_3_L[8] = { 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, }; DTYPE RBIOR3_3_I_L[8] = { 0.06629126073623884, -0.19887378220871652, -0.15467960838455727, 0.9943689110435825, 0.9943689110435825, -0.15467960838455727, -0.19887378220871652, 0.06629126073623884, }; DTYPE RBIOR3_3_H[8] = { -0.06629126073623884, -0.19887378220871652, 0.15467960838455727, 0.9943689110435825, -0.9943689110435825, -0.15467960838455727, 0.19887378220871652, 0.06629126073623884, }; DTYPE RBIOR3_3_I_H[8] = { 0.0, 0.0, 0.1767766952966369, -0.5303300858899107, 0.5303300858899107, -0.1767766952966369, 0.0, 0.0, }; DTYPE RBIOR3_5_L[12] = { 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_5_I_L[12] = { -0.013810679320049757, 0.04143203796014927, 0.052480581416189075, -0.26792717880896527, -0.07181553246425874, 0.966747552403483, 0.966747552403483, -0.07181553246425874, -0.26792717880896527, 0.052480581416189075, 0.04143203796014927, -0.013810679320049757, }; DTYPE RBIOR3_5_H[12] = { 0.013810679320049757, 0.04143203796014927, -0.052480581416189075, -0.26792717880896527, 0.07181553246425874, 0.966747552403483, -0.966747552403483, -0.07181553246425874, 0.26792717880896527, 0.052480581416189075, -0.04143203796014927, -0.013810679320049757, }; DTYPE RBIOR3_5_I_H[12] = { 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, -0.5303300858899107, 0.5303300858899107, -0.1767766952966369, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_7_L[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_7_I_L[16] = { 0.0030210861012608843, -0.009063258303782653, -0.01683176542131064, 0.074663985074019, 0.03133297870736289, -0.301159125922835, -0.026499240945345472, 0.9516421218971786, 0.9516421218971786, -0.026499240945345472, -0.301159125922835, 0.03133297870736289, 0.074663985074019, -0.01683176542131064, -0.009063258303782653, 0.0030210861012608843, }; DTYPE RBIOR3_7_H[16] = { -0.0030210861012608843, -0.009063258303782653, 0.01683176542131064, 0.074663985074019, -0.03133297870736289, -0.301159125922835, 0.026499240945345472, 0.9516421218971786, -0.9516421218971786, -0.026499240945345472, 0.301159125922835, 0.03133297870736289, -0.074663985074019, -0.01683176542131064, 0.009063258303782653, 0.0030210861012608843, }; DTYPE RBIOR3_7_I_H[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, -0.5303300858899107, 0.5303300858899107, -0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_9_L[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, 0.5303300858899107, 0.5303300858899107, 0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR3_9_I_L[20] = { -0.000679744372783699, 0.002039233118351097, 0.005060319219611981, -0.020618912641105536, -0.014112787930175846, 0.09913478249423216, 0.012300136269419315, -0.32019196836077857, 0.0020500227115698858, 0.9421257006782068, 0.9421257006782068, 0.0020500227115698858, -0.32019196836077857, 0.012300136269419315, 0.09913478249423216, -0.014112787930175846, -0.020618912641105536, 0.005060319219611981, 0.002039233118351097, -0.000679744372783699, }; DTYPE RBIOR3_9_H[20] = { 0.000679744372783699, 0.002039233118351097, -0.005060319219611981, -0.020618912641105536, 0.014112787930175846, 0.09913478249423216, -0.012300136269419315, -0.32019196836077857, -0.0020500227115698858, 0.9421257006782068, -0.9421257006782068, 0.0020500227115698858, 0.32019196836077857, 0.012300136269419315, -0.09913478249423216, -0.014112787930175846, 0.020618912641105536, 0.005060319219611981, -0.002039233118351097, -0.000679744372783699, }; DTYPE RBIOR3_9_I_H[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966369, -0.5303300858899107, 0.5303300858899107, -0.1767766952966369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; DTYPE RBIOR4_4_L[10] = { 0.0, 0.0, -0.06453888262869706, -0.04068941760916406, 0.41809227322161724, 0.7884856164055829, 0.41809227322161724, -0.04068941760916406, -0.06453888262869706, 0.0, }; DTYPE RBIOR4_4_I_L[10] = { 0.03782845550726404, -0.023849465019556843, -0.11062440441843718, 0.37740285561283066, 0.8526986790088938, 0.37740285561283066, -0.11062440441843718, -0.023849465019556843, 0.03782845550726404, 0.0, }; DTYPE RBIOR4_4_H[10] = { -0.03782845550726404, -0.023849465019556843, 0.11062440441843718, 0.37740285561283066, -0.8526986790088938, 0.37740285561283066, 0.11062440441843718, -0.023849465019556843, -0.03782845550726404, 0.0, }; DTYPE RBIOR4_4_I_H[10] = { 0.0, 0.0, -0.06453888262869706, 0.04068941760916406, 0.41809227322161724, -0.7884856164055829, 0.41809227322161724, 0.04068941760916406, -0.06453888262869706, 0.0, }; DTYPE RBIOR5_5_L[12] = { 0.0, 0.013456709459118716, -0.002694966880111507, -0.13670658466432914, -0.09350469740093886, 0.47680326579848425, 0.8995061097486484, 0.47680326579848425, -0.09350469740093886, -0.13670658466432914, -0.002694966880111507, 0.013456709459118716, }; DTYPE RBIOR5_5_I_L[12] = { 0.0, 0.03968708834740544, 0.007948108637240322, -0.05446378846823691, 0.34560528195603346, 0.7366601814282105, 0.34560528195603346, -0.05446378846823691, 0.007948108637240322, 0.03968708834740544, 0.0, 0.0, }; DTYPE RBIOR5_5_H[12] = { 0.0, 0.03968708834740544, -0.007948108637240322, -0.05446378846823691, -0.34560528195603346, 0.7366601814282105, -0.34560528195603346, -0.05446378846823691, -0.007948108637240322, 0.03968708834740544, 0.0, 0.0, }; DTYPE RBIOR5_5_I_H[12] = { 0.0, -0.013456709459118716, -0.002694966880111507, 0.13670658466432914, -0.09350469740093886, -0.47680326579848425, 0.8995061097486484, -0.47680326579848425, -0.09350469740093886, 0.13670658466432914, -0.002694966880111507, -0.013456709459118716, }; DTYPE RBIOR6_8_L[18] = { 0.0, 0.0, 0.0, 0.0, 0.014426282505624435, 0.014467504896790148, -0.07872200106262882, -0.04036797903033992, 0.41784910915027457, 0.7589077294536541, 0.41784910915027457, -0.04036797903033992, -0.07872200106262882, 0.014467504896790148, 0.014426282505624435, 0.0, 0.0, 0.0, }; DTYPE RBIOR6_8_I_L[18] = { 0.0019088317364812906, -0.0019142861290887667, -0.016990639867602342, 0.01193456527972926, 0.04973290349094079, -0.07726317316720414, -0.09405920349573646, 0.4207962846098268, 0.8259229974584023, 0.4207962846098268, -0.09405920349573646, -0.07726317316720414, 0.04973290349094079, 0.01193456527972926, -0.016990639867602342, -0.0019142861290887667, 0.0019088317364812906, 0.0, }; DTYPE RBIOR6_8_H[18] = { -0.0019088317364812906, -0.0019142861290887667, 0.016990639867602342, 0.01193456527972926, -0.04973290349094079, -0.07726317316720414, 0.09405920349573646, 0.4207962846098268, -0.8259229974584023, 0.4207962846098268, 0.09405920349573646, -0.07726317316720414, -0.04973290349094079, 0.01193456527972926, 0.016990639867602342, -0.0019142861290887667, -0.0019088317364812906, 0.0, }; DTYPE RBIOR6_8_I_H[18] = { 0.0, 0.0, 0.0, 0.0, 0.014426282505624435, -0.014467504896790148, -0.07872200106262882, 0.04036797903033992, 0.41784910915027457, -0.7589077294536541, 0.41784910915027457, 0.04036797903033992, -0.07872200106262882, -0.014467504896790148, 0.014426282505624435, 0.0, 0.0, 0.0, }; // The Haar transform has efficient dedicated kernel, since the boundary extension is not needed. // When performing SWT, however, the filters are extended, so the boundary extension is required. DTYPE HAAR_L[4] = { 0.7071067811865476, 0.7071067811865476 }; DTYPE HAAR_H[4] = { -0.7071067811865476, 0.7071067811865476 }; DTYPE HAAR_I_L[4] = { 0.7071067811865476, 0.7071067811865476 }; DTYPE HAAR_I_H[4] = { 0.7071067811865476, -0.7071067811865476 }; /// /// Structure containing the filters pointers /// wfilter all_filters[72] = { // aggregate initialization cannot be used here // { .wname = "db2", .hlen = 4, DB2_L, DB2_H, DB2_I_L, DB2_I_H }, { "db2", 4, DB2_L, DB2_H, DB2_I_L, DB2_I_H }, { "db3", 6, DB3_L, DB3_H, DB3_I_L, DB3_I_H }, { "db4", 8, DB4_L, DB4_H, DB4_I_L, DB4_I_H }, { "db5", 10, DB5_L, DB5_H, DB5_I_L, DB5_I_H }, { "db6", 12, DB6_L, DB6_H, DB6_I_L, DB6_I_H }, { "db7", 14, DB7_L, DB7_H, DB7_I_L, DB7_I_H }, { "db8", 16, DB8_L, DB8_H, DB8_I_L, DB8_I_H }, { "db9", 18, DB9_L, DB9_H, DB9_I_L, DB9_I_H }, { "db10", 20, DB10_L, DB10_H, DB10_I_L, DB10_I_H }, { "db11", 22, DB11_L, DB11_H, DB11_I_L, DB11_I_H }, { "db12", 24, DB12_L, DB12_H, DB12_I_L, DB12_I_H }, { "db13", 26, DB13_L, DB13_H, DB13_I_L, DB13_I_H }, { "db14", 28, DB14_L, DB14_H, DB14_I_L, DB14_I_H }, { "db15", 30, DB15_L, DB15_H, DB15_I_L, DB15_I_H }, { "db16", 32, DB16_L, DB16_H, DB16_I_L, DB16_I_H }, { "db17", 34, DB17_L, DB17_H, DB17_I_L, DB17_I_H }, { "db18", 36, DB18_L, DB18_H, DB18_I_L, DB18_I_H }, { "db19", 38, DB19_L, DB19_H, DB19_I_L, DB19_I_H }, { "db20", 40, DB20_L, DB20_H, DB20_I_L, DB20_I_H }, { "sym2", 4, SYM2_L, SYM2_H, SYM2_I_L, SYM2_I_H }, { "sym3", 6, SYM3_L, SYM3_H, SYM3_I_L, SYM3_I_H }, { "sym4", 8, SYM4_L, SYM4_H, SYM4_I_L, SYM4_I_H }, { "sym5", 10, SYM5_L, SYM5_H, SYM5_I_L, SYM5_I_H }, { "sym6", 12, SYM6_L, SYM6_H, SYM6_I_L, SYM6_I_H }, { "sym7", 14, SYM7_L, SYM7_H, SYM7_I_L, SYM7_I_H }, { "sym8", 16, SYM8_L, SYM8_H, SYM8_I_L, SYM8_I_H }, { "sym9", 18, SYM9_L, SYM9_H, SYM9_I_L, SYM9_I_H }, { "sym10", 20, SYM10_L, SYM10_H, SYM10_I_L, SYM10_I_H }, { "sym11", 22, SYM11_L, SYM11_H, SYM11_I_L, SYM11_I_H }, { "sym12", 24, SYM12_L, SYM12_H, SYM12_I_L, SYM12_I_H }, { "sym13", 26, SYM13_L, SYM13_H, SYM13_I_L, SYM13_I_H }, { "sym14", 28, SYM14_L, SYM14_H, SYM14_I_L, SYM14_I_H }, { "sym15", 30, SYM15_L, SYM15_H, SYM15_I_L, SYM15_I_H }, { "sym16", 32, SYM16_L, SYM16_H, SYM16_I_L, SYM16_I_H }, { "sym17", 34, SYM17_L, SYM17_H, SYM17_I_L, SYM17_I_H }, { "sym18", 36, SYM18_L, SYM18_H, SYM18_I_L, SYM18_I_H }, { "sym19", 38, SYM19_L, SYM19_H, SYM19_I_L, SYM19_I_H }, { "sym20", 40, SYM20_L, SYM20_H, SYM20_I_L, SYM20_I_H }, { "coif1", 6, COIF1_L, COIF1_H, COIF1_I_L, COIF1_I_H }, { "coif2", 12, COIF2_L, COIF2_H, COIF2_I_L, COIF2_I_H }, { "coif3", 18, COIF3_L, COIF3_H, COIF3_I_L, COIF3_I_H }, { "coif4", 24, COIF4_L, COIF4_H, COIF4_I_L, COIF4_I_H }, { "coif5", 30, COIF5_L, COIF5_H, COIF5_I_L, COIF5_I_H }, { "bior1.3", 6, BIOR1_3_L, BIOR1_3_H, BIOR1_3_I_L, BIOR1_3_I_H }, { "bior1.5", 10, BIOR1_5_L, BIOR1_5_H, BIOR1_5_I_L, BIOR1_5_I_H }, { "bior2.2", 6, BIOR2_2_L, BIOR2_2_H, BIOR2_2_I_L, BIOR2_2_I_H }, { "bior2.4", 10, BIOR2_4_L, BIOR2_4_H, BIOR2_4_I_L, BIOR2_4_I_H }, { "bior2.6", 14, BIOR2_6_L, BIOR2_6_H, BIOR2_6_I_L, BIOR2_6_I_H }, { "bior2.8", 18, BIOR2_8_L, BIOR2_8_H, BIOR2_8_I_L, BIOR2_8_I_H }, { "bior3.1", 4, BIOR3_1_L, BIOR3_1_H, BIOR3_1_I_L, BIOR3_1_I_H }, { "bior3.3", 8, BIOR3_3_L, BIOR3_3_H, BIOR3_3_I_L, BIOR3_3_I_H }, { "bior3.5", 12, BIOR3_5_L, BIOR3_5_H, BIOR3_5_I_L, BIOR3_5_I_H }, { "bior3.7", 16, BIOR3_7_L, BIOR3_7_H, BIOR3_7_I_L, BIOR3_7_I_H }, { "bior3.9", 20, BIOR3_9_L, BIOR3_9_H, BIOR3_9_I_L, BIOR3_9_I_H }, { "bior4.4", 10, BIOR4_4_L, BIOR4_4_H, BIOR4_4_I_L, BIOR4_4_I_H }, { "bior5.5", 12, BIOR5_5_L, BIOR5_5_H, BIOR5_5_I_L, BIOR5_5_I_H }, { "bior6.8", 18, BIOR6_8_L, BIOR6_8_H, BIOR6_8_I_L, BIOR6_8_I_H }, { "rbio1.3", 6, RBIOR1_3_L, RBIOR1_3_H, RBIOR1_3_I_L, RBIOR1_3_I_H }, { "rbio1.5", 10, RBIOR1_5_L, RBIOR1_5_H, RBIOR1_5_I_L, RBIOR1_5_I_H }, { "rbio2.2", 6, RBIOR2_2_L, RBIOR2_2_H, RBIOR2_2_I_L, RBIOR2_2_I_H }, { "rbio2.4", 10, RBIOR2_4_L, RBIOR2_4_H, RBIOR2_4_I_L, RBIOR2_4_I_H }, { "rbio2.6", 14, RBIOR2_6_L, RBIOR2_6_H, RBIOR2_6_I_L, RBIOR2_6_I_H }, { "rbio2.8", 18, RBIOR2_8_L, RBIOR2_8_H, RBIOR2_8_I_L, RBIOR2_8_I_H }, { "rbio3.1", 4, RBIOR3_1_L, RBIOR3_1_H, RBIOR3_1_I_L, RBIOR3_1_I_H }, { "rbio3.3", 8, RBIOR3_3_L, RBIOR3_3_H, RBIOR3_3_I_L, RBIOR3_3_I_H }, { "rbio3.5", 12, RBIOR3_5_L, RBIOR3_5_H, RBIOR3_5_I_L, RBIOR3_5_I_H }, { "rbio3.7", 16, RBIOR3_7_L, RBIOR3_7_H, RBIOR3_7_I_L, RBIOR3_7_I_H }, { "rbio3.9", 20, RBIOR3_9_L, RBIOR3_9_H, RBIOR3_9_I_L, RBIOR3_9_I_H }, { "rbio4.4", 10, RBIOR4_4_L, RBIOR4_4_H, RBIOR4_4_I_L, RBIOR4_4_I_H }, { "rbio5.5", 12, RBIOR5_5_L, RBIOR5_5_H, RBIOR5_5_I_L, RBIOR5_5_I_H }, { "rbio6.8", 18, RBIOR6_8_L, RBIOR6_8_H, RBIOR6_8_I_L, RBIOR6_8_I_H }, { "haar", 2, HAAR_L, HAAR_H, HAAR_I_L, HAAR_I_H }, }; ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/filters.h0000755000175000017500000002431200000000000016143 0ustar00pierrepierre/// /// Wavelets coefficients, extracted from http://wavelets.pybytes.com /// #ifndef FILTERS_H #define FILTERS_H #include // Mind that most GPUs are not primarily designed for double precision // (less "double precision units" in the hardware) // so the computations will be slower if this is enabled. // To build a library with double precision computations, // type "make libpdwtd.so" or manually compile with the flag "-DDOUBLEPRECISION" #ifndef DOUBLEPRECISION //~ typedef float DTYPE; #define DTYPE float #define cublas_asum cublasSasum #define cublas_nrm2 cublasSnrm2 #define cublas_scal cublasSscal #define cublas_axpy cublasSaxpy #else //~ typedef double DTYPE; #define DTYPE double #define cublas_asum cublasDasum #define cublas_nrm2 cublasDnrm2 #define cublas_scal cublasDscal #define cublas_axpy cublasDaxpy #endif // Should always be defined #define COMPILING_LIBRARY #ifdef COMPILING_LIBRARY #define LIBEXPORT extern "C" #else #define LIBEXPORT #endif // Uncomment to use separate compilation // mind that the "-dc" compilation flag must be used instead of "-c" // #define SEPARATE_COMPILATION LIBEXPORT DTYPE DB2_L[4]; LIBEXPORT DTYPE DB2_H[4]; LIBEXPORT DTYPE DB2_I_L[4]; LIBEXPORT DTYPE DB2_I_H[4]; LIBEXPORT DTYPE DB3_L[6]; LIBEXPORT DTYPE DB3_H[6]; LIBEXPORT DTYPE DB3_I_L[6]; LIBEXPORT DTYPE DB3_I_H[6]; LIBEXPORT DTYPE DB4_L[8]; LIBEXPORT DTYPE DB4_H[8]; LIBEXPORT DTYPE DB4_I_L[8]; LIBEXPORT DTYPE DB4_I_H[8]; LIBEXPORT DTYPE DB5_L[10]; LIBEXPORT DTYPE DB5_H[10]; LIBEXPORT DTYPE DB5_I_L[10]; LIBEXPORT DTYPE DB5_I_H[10]; LIBEXPORT DTYPE DB6_L[12]; LIBEXPORT DTYPE DB6_H[12]; LIBEXPORT DTYPE DB6_I_L[12]; LIBEXPORT DTYPE DB6_I_H[12]; LIBEXPORT DTYPE DB7_L[14]; LIBEXPORT DTYPE DB7_I_L[14]; LIBEXPORT DTYPE DB7_H[14]; LIBEXPORT DTYPE DB7_I_H[14]; LIBEXPORT DTYPE DB8_L[16]; LIBEXPORT DTYPE DB8_I_L[16]; LIBEXPORT DTYPE DB8_H[16]; LIBEXPORT DTYPE DB8_I_H[16]; LIBEXPORT DTYPE DB9_L[18]; LIBEXPORT DTYPE DB9_I_L[18]; LIBEXPORT DTYPE DB9_H[18]; LIBEXPORT DTYPE DB9_I_H[18]; LIBEXPORT DTYPE DB10_L[20]; LIBEXPORT DTYPE DB10_I_L[20]; LIBEXPORT DTYPE DB10_H[20]; LIBEXPORT DTYPE DB10_I_H[20]; LIBEXPORT DTYPE DB11_L[22]; LIBEXPORT DTYPE DB11_I_L[22]; LIBEXPORT DTYPE DB11_H[22]; LIBEXPORT DTYPE DB11_I_H[22]; LIBEXPORT DTYPE DB12_L[24]; LIBEXPORT DTYPE DB12_I_L[24]; LIBEXPORT DTYPE DB12_H[24]; LIBEXPORT DTYPE DB12_I_H[24]; LIBEXPORT DTYPE DB13_L[26]; LIBEXPORT DTYPE DB13_I_L[26]; LIBEXPORT DTYPE DB13_H[26]; LIBEXPORT DTYPE DB13_I_H[26]; LIBEXPORT DTYPE DB14_L[28]; LIBEXPORT DTYPE DB14_I_L[28]; LIBEXPORT DTYPE DB14_H[28]; LIBEXPORT DTYPE DB14_I_H[28]; LIBEXPORT DTYPE DB15_L[30]; LIBEXPORT DTYPE DB15_I_L[30]; LIBEXPORT DTYPE DB15_H[30]; LIBEXPORT DTYPE DB15_I_H[30]; LIBEXPORT DTYPE DB16_L[32]; LIBEXPORT DTYPE DB16_I_L[32]; LIBEXPORT DTYPE DB16_H[32]; LIBEXPORT DTYPE DB16_I_H[32]; LIBEXPORT DTYPE DB17_L[34]; LIBEXPORT DTYPE DB17_I_L[34]; LIBEXPORT DTYPE DB17_H[34]; LIBEXPORT DTYPE DB17_I_H[34]; LIBEXPORT DTYPE DB18_L[36]; LIBEXPORT DTYPE DB18_I_L[36]; LIBEXPORT DTYPE DB18_H[36]; LIBEXPORT DTYPE DB18_I_H[36]; LIBEXPORT DTYPE DB19_L[38]; LIBEXPORT DTYPE DB19_I_L[38]; LIBEXPORT DTYPE DB19_H[38]; LIBEXPORT DTYPE DB19_I_H[38]; LIBEXPORT DTYPE DB20_L[40]; LIBEXPORT DTYPE DB20_I_L[40]; LIBEXPORT DTYPE DB20_H[40]; LIBEXPORT DTYPE DB20_I_H[40]; LIBEXPORT DTYPE SYM2_L[4]; LIBEXPORT DTYPE SYM2_I_L[4]; LIBEXPORT DTYPE SYM2_H[4]; LIBEXPORT DTYPE SYM2_I_H[4]; LIBEXPORT DTYPE SYM3_L[6]; LIBEXPORT DTYPE SYM3_I_L[6]; LIBEXPORT DTYPE SYM3_H[6]; LIBEXPORT DTYPE SYM3_I_H[6]; LIBEXPORT DTYPE SYM4_L[8]; LIBEXPORT DTYPE SYM4_I_L[8]; LIBEXPORT DTYPE SYM4_H[8]; LIBEXPORT DTYPE SYM4_I_H[8]; LIBEXPORT DTYPE SYM5_L[10]; LIBEXPORT DTYPE SYM5_I_L[10]; LIBEXPORT DTYPE SYM5_H[10]; LIBEXPORT DTYPE SYM5_I_H[10]; LIBEXPORT DTYPE SYM6_L[12]; LIBEXPORT DTYPE SYM6_I_L[12]; LIBEXPORT DTYPE SYM6_H[12]; LIBEXPORT DTYPE SYM6_I_H[12]; LIBEXPORT DTYPE SYM7_L[14]; LIBEXPORT DTYPE SYM7_I_L[14]; LIBEXPORT DTYPE SYM7_H[14]; LIBEXPORT DTYPE SYM7_I_H[14]; LIBEXPORT DTYPE SYM8_L[16]; LIBEXPORT DTYPE SYM8_I_L[16]; LIBEXPORT DTYPE SYM8_H[16]; LIBEXPORT DTYPE SYM8_I_H[16]; LIBEXPORT DTYPE SYM9_L[18]; LIBEXPORT DTYPE SYM9_I_L[18]; LIBEXPORT DTYPE SYM9_H[18]; LIBEXPORT DTYPE SYM9_I_H[18]; LIBEXPORT DTYPE SYM10_L[20]; LIBEXPORT DTYPE SYM10_I_L[20]; LIBEXPORT DTYPE SYM10_H[20]; LIBEXPORT DTYPE SYM10_I_H[20]; LIBEXPORT DTYPE SYM11_L[22]; LIBEXPORT DTYPE SYM11_I_L[22]; LIBEXPORT DTYPE SYM11_H[22]; LIBEXPORT DTYPE SYM11_I_H[22]; LIBEXPORT DTYPE SYM12_L[24]; LIBEXPORT DTYPE SYM12_I_L[24]; LIBEXPORT DTYPE SYM12_H[24]; LIBEXPORT DTYPE SYM12_I_H[24]; LIBEXPORT DTYPE SYM13_L[26]; LIBEXPORT DTYPE SYM13_I_L[26]; LIBEXPORT DTYPE SYM13_H[26]; LIBEXPORT DTYPE SYM13_I_H[26]; LIBEXPORT DTYPE SYM14_L[28]; LIBEXPORT DTYPE SYM14_I_L[28]; LIBEXPORT DTYPE SYM14_H[28]; LIBEXPORT DTYPE SYM14_I_H[28]; LIBEXPORT DTYPE SYM15_L[30]; LIBEXPORT DTYPE SYM15_I_L[30]; LIBEXPORT DTYPE SYM15_H[30]; LIBEXPORT DTYPE SYM15_I_H[30]; LIBEXPORT DTYPE SYM16_L[32]; LIBEXPORT DTYPE SYM16_I_L[32]; LIBEXPORT DTYPE SYM16_H[32]; LIBEXPORT DTYPE SYM16_I_H[32]; LIBEXPORT DTYPE SYM17_L[34]; LIBEXPORT DTYPE SYM17_I_L[34]; LIBEXPORT DTYPE SYM17_H[34]; LIBEXPORT DTYPE SYM17_I_H[34]; LIBEXPORT DTYPE SYM18_L[36]; LIBEXPORT DTYPE SYM18_I_L[36]; LIBEXPORT DTYPE SYM18_H[36]; LIBEXPORT DTYPE SYM18_I_H[36]; LIBEXPORT DTYPE SYM19_L[38]; LIBEXPORT DTYPE SYM19_I_L[38]; LIBEXPORT DTYPE SYM19_H[38]; LIBEXPORT DTYPE SYM19_I_H[38]; LIBEXPORT DTYPE SYM20_L[40]; LIBEXPORT DTYPE SYM20_I_L[40]; LIBEXPORT DTYPE SYM20_H[40]; LIBEXPORT DTYPE SYM20_I_H[40]; LIBEXPORT DTYPE COIF1_L[6]; LIBEXPORT DTYPE COIF1_I_L[6]; LIBEXPORT DTYPE COIF1_H[6]; LIBEXPORT DTYPE COIF1_I_H[6]; LIBEXPORT DTYPE COIF2_L[12]; LIBEXPORT DTYPE COIF2_I_L[12]; LIBEXPORT DTYPE COIF2_H[12]; LIBEXPORT DTYPE COIF2_I_H[12]; LIBEXPORT DTYPE COIF3_L[18]; LIBEXPORT DTYPE COIF3_I_L[18]; LIBEXPORT DTYPE COIF3_H[18]; LIBEXPORT DTYPE COIF3_I_H[18]; LIBEXPORT DTYPE COIF4_L[24]; LIBEXPORT DTYPE COIF4_I_L[24]; LIBEXPORT DTYPE COIF4_H[24]; LIBEXPORT DTYPE COIF4_I_H[24]; LIBEXPORT DTYPE COIF5_L[30]; LIBEXPORT DTYPE COIF5_I_L[30]; LIBEXPORT DTYPE COIF5_H[30]; LIBEXPORT DTYPE COIF5_I_H[30]; LIBEXPORT DTYPE BIOR1_3_L[6]; LIBEXPORT DTYPE BIOR1_3_I_L[6]; LIBEXPORT DTYPE BIOR1_3_H[6]; LIBEXPORT DTYPE BIOR1_3_I_H[6]; LIBEXPORT DTYPE BIOR1_5_L[10]; LIBEXPORT DTYPE BIOR1_5_I_L[10]; LIBEXPORT DTYPE BIOR1_5_H[10]; LIBEXPORT DTYPE BIOR1_5_I_H[10]; LIBEXPORT DTYPE BIOR2_2_L[6]; LIBEXPORT DTYPE BIOR2_2_I_L[6]; LIBEXPORT DTYPE BIOR2_2_H[6]; LIBEXPORT DTYPE BIOR2_2_I_H[6]; LIBEXPORT DTYPE BIOR2_4_L[10]; LIBEXPORT DTYPE BIOR2_4_I_L[10]; LIBEXPORT DTYPE BIOR2_4_H[10]; LIBEXPORT DTYPE BIOR2_4_I_H[10]; LIBEXPORT DTYPE BIOR2_6_L[14]; LIBEXPORT DTYPE BIOR2_6_I_L[14]; LIBEXPORT DTYPE BIOR2_6_H[14]; LIBEXPORT DTYPE BIOR2_6_I_H[14]; LIBEXPORT DTYPE BIOR2_8_L[18]; LIBEXPORT DTYPE BIOR2_8_I_L[18]; LIBEXPORT DTYPE BIOR2_8_H[18]; LIBEXPORT DTYPE BIOR2_8_I_H[18]; LIBEXPORT DTYPE BIOR3_1_L[4]; LIBEXPORT DTYPE BIOR3_1_I_L[4]; LIBEXPORT DTYPE BIOR3_1_H[4]; LIBEXPORT DTYPE BIOR3_1_I_H[4]; LIBEXPORT DTYPE BIOR3_3_L[8]; LIBEXPORT DTYPE BIOR3_3_I_L[8]; LIBEXPORT DTYPE BIOR3_3_H[8]; LIBEXPORT DTYPE BIOR3_3_I_H[8]; LIBEXPORT DTYPE BIOR3_5_L[12]; LIBEXPORT DTYPE BIOR3_5_I_L[12]; LIBEXPORT DTYPE BIOR3_5_H[12]; LIBEXPORT DTYPE BIOR3_5_I_H[12]; LIBEXPORT DTYPE BIOR3_7_L[16]; LIBEXPORT DTYPE BIOR3_7_I_L[16]; LIBEXPORT DTYPE BIOR3_7_H[16]; LIBEXPORT DTYPE BIOR3_7_I_H[16]; LIBEXPORT DTYPE BIOR3_9_L[20]; LIBEXPORT DTYPE BIOR3_9_I_L[20]; LIBEXPORT DTYPE BIOR3_9_H[20]; LIBEXPORT DTYPE BIOR3_9_I_H[20]; LIBEXPORT DTYPE BIOR4_4_L[10]; LIBEXPORT DTYPE BIOR4_4_I_L[10]; LIBEXPORT DTYPE BIOR4_4_H[10]; LIBEXPORT DTYPE BIOR4_4_I_H[10]; LIBEXPORT DTYPE BIOR5_5_L[12]; LIBEXPORT DTYPE BIOR5_5_H[12]; LIBEXPORT DTYPE BIOR5_5_I_L[12]; LIBEXPORT DTYPE BIOR5_5_I_H[12]; LIBEXPORT DTYPE BIOR6_8_L[18]; LIBEXPORT DTYPE BIOR6_8_H[18]; LIBEXPORT DTYPE BIOR6_8_I_L[18]; LIBEXPORT DTYPE BIOR6_8_I_H[18]; LIBEXPORT DTYPE RBIOR1_3_L[6]; LIBEXPORT DTYPE RBIOR1_3_I_L[6]; LIBEXPORT DTYPE RBIOR1_3_H[6]; LIBEXPORT DTYPE RBIOR1_3_I_H[6]; LIBEXPORT DTYPE RBIOR1_5_L[10]; LIBEXPORT DTYPE RBIOR1_5_I_L[10]; LIBEXPORT DTYPE RBIOR1_5_H[10]; LIBEXPORT DTYPE RBIOR1_5_I_H[10]; LIBEXPORT DTYPE RBIOR2_2_L[6]; LIBEXPORT DTYPE RBIOR2_2_I_L[6]; LIBEXPORT DTYPE RBIOR2_2_H[6]; LIBEXPORT DTYPE RBIOR2_2_I_H[6]; LIBEXPORT DTYPE RBIOR2_4_L[10]; LIBEXPORT DTYPE RBIOR2_4_I_L[10]; LIBEXPORT DTYPE RBIOR2_4_H[10]; LIBEXPORT DTYPE RBIOR2_4_I_H[10]; LIBEXPORT DTYPE RBIOR2_6_L[14]; LIBEXPORT DTYPE RBIOR2_6_I_L[14]; LIBEXPORT DTYPE RBIOR2_6_H[14]; LIBEXPORT DTYPE RBIOR2_6_I_H[14]; LIBEXPORT DTYPE RBIOR2_8_L[18]; LIBEXPORT DTYPE RBIOR2_8_I_L[18]; LIBEXPORT DTYPE RBIOR2_8_H[18]; LIBEXPORT DTYPE RBIOR2_8_I_H[18]; LIBEXPORT DTYPE RBIOR3_1_L[4]; LIBEXPORT DTYPE RBIOR3_1_I_L[4]; LIBEXPORT DTYPE RBIOR3_1_H[4]; LIBEXPORT DTYPE RBIOR3_1_I_H[4]; LIBEXPORT DTYPE RBIOR3_3_L[8]; LIBEXPORT DTYPE RBIOR3_3_I_L[8]; LIBEXPORT DTYPE RBIOR3_3_H[8]; LIBEXPORT DTYPE RBIOR3_3_I_H[8]; LIBEXPORT DTYPE RBIOR3_5_L[12]; LIBEXPORT DTYPE RBIOR3_5_I_L[12]; LIBEXPORT DTYPE RBIOR3_5_H[12]; LIBEXPORT DTYPE RBIOR3_5_I_H[12]; LIBEXPORT DTYPE RBIOR3_7_L[16]; LIBEXPORT DTYPE RBIOR3_7_I_L[16]; LIBEXPORT DTYPE RBIOR3_7_H[16]; LIBEXPORT DTYPE RBIOR3_7_I_H[16]; LIBEXPORT DTYPE RBIOR3_9_L[20]; LIBEXPORT DTYPE RBIOR3_9_I_L[20]; LIBEXPORT DTYPE RBIOR3_9_H[20]; LIBEXPORT DTYPE RBIOR3_9_I_H[20]; LIBEXPORT DTYPE RBIOR4_4_L[10]; LIBEXPORT DTYPE RBIOR4_4_I_L[10]; LIBEXPORT DTYPE RBIOR4_4_H[10]; LIBEXPORT DTYPE RBIOR4_4_I_H[10]; LIBEXPORT DTYPE RBIOR5_5_L[12]; LIBEXPORT DTYPE RBIOR5_5_I_L[12]; LIBEXPORT DTYPE RBIOR5_5_H[12]; LIBEXPORT DTYPE RBIOR5_5_I_H[12]; LIBEXPORT DTYPE RBIOR6_8_L[18]; LIBEXPORT DTYPE RBIOR6_8_I_L[18]; LIBEXPORT DTYPE RBIOR6_8_H[18]; LIBEXPORT DTYPE RBIOR6_8_I_H[18]; LIBEXPORT DTYPE HAAR_L[4]; LIBEXPORT DTYPE HAAR_H[4]; LIBEXPORT DTYPE HAAR_I_L[4]; LIBEXPORT DTYPE HAAR_I_H[4]; /// /// Structure containing the filters pointers /// struct wfilter { char wname[16]; int hlen; DTYPE* f_l; // Forward lowpass DTYPE* f_h; // Forward highpass DTYPE* i_l; // Inverse lowpass DTYPE* i_h; // Inverse highpass }; LIBEXPORT wfilter all_filters[72]; #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/haar.cu0000644000175000017500000002106600000000000015566 0ustar00pierrepierre#include "haar.h" #include "utils.h" // The sqrt(2) factor is applied after two HAAR_*, so it becomes a 0.5 factor #define HAAR_AVG(a, b) ((a+b)) #define HAAR_DIF(a, b) ((a-b)) // must be run with grid size = (Nc/2, Nr/2) where Nr = numrows of input __global__ void kern_haar2d_fwd(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; int Nr_is_odd = (Nr & 1); int Nc_is_odd = (Nc & 1); int Nr2 = (Nr + Nr_is_odd)/2; int Nc2 = (Nc + Nc_is_odd)/2; if (gidy < Nr2 && gidx < Nc2) { // for odd N, image is virtually extended by repeating the last element int posx0 = 2*gidx; int posx1 = 2*gidx+1; if ((Nc_is_odd) && (posx1 == Nc)) posx1--; int posy0 = 2*gidy; int posy1 = 2*gidy+1; if ((Nr_is_odd) && (posy1 == Nr)) posy1--; DTYPE a = img[posy0*Nc + posx0]; DTYPE b = img[posy0*Nc + posx1]; DTYPE c = img[posy1*Nc + posx0]; DTYPE d = img[posy1*Nc + posx1]; c_a[gidy* Nc2 + gidx] = 0.5*HAAR_AVG(HAAR_AVG(a, c), HAAR_AVG(b, d)); // A c_v[gidy* Nc2 + gidx] = 0.5*HAAR_DIF(HAAR_AVG(a, c), HAAR_AVG(b, d)); // V c_h[gidy* Nc2 + gidx] = 0.5*HAAR_AVG(HAAR_DIF(a, c), HAAR_DIF(b, d)); // H c_d[gidy* Nc2 + gidx] = 0.5*HAAR_DIF(HAAR_DIF(a, c), HAAR_DIF(b, d)); // D } } // must be run with grid size = (2*Nr, 2*Nc) ; Nr = numrows of input __global__ void kern_haar2d_inv(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int Nr2, int Nc2) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr2 && gidx < Nc2) { DTYPE a = c_a[(gidy/2)*Nc + (gidx/2)]; DTYPE b = c_v[(gidy/2)*Nc + (gidx/2)]; DTYPE c = c_h[(gidy/2)*Nc + (gidx/2)]; DTYPE d = c_d[(gidy/2)*Nc + (gidx/2)]; DTYPE res = 0.0f; int gx1 = (gidx & 1), gy1 = (gidy & 1); if (gx1 == 0 && gy1 == 0) res = 0.5*HAAR_AVG(HAAR_AVG(a, c), HAAR_AVG(b, d)); if (gx1 == 1 && gy1 == 0) res = 0.5*HAAR_DIF(HAAR_AVG(a, c), HAAR_AVG(b, d)); if (gx1 == 0 && gy1 == 1) res = 0.5*HAAR_AVG(HAAR_DIF(a, c), HAAR_DIF(b, d)); if (gx1 == 1 && gy1 == 1) res = 0.5*HAAR_DIF(HAAR_DIF(a, c), HAAR_DIF(b, d)); img[gidy*Nc2 + gidx] = res; } } int haar_forward2d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels; int Nc2 = Nc, Nr2 = Nr; int Nc2_old = Nc2, Nr2_old = Nr2; w_div2(&Nc2); w_div2(&Nr2); int tpb = 16; // TODO : tune for max perfs. DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; // First level dim3 n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); kern_haar2d_fwd<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr, Nc); for (int i=1; i < levels; i++) { Nc2_old = Nc2; Nr2_old = Nr2; w_div2(&Nc2); w_div2(&Nr2); n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); kern_haar2d_fwd<<>>(d_tmp1, d_tmp2, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr2_old, Nc2_old); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp1, Nr2*Nc2*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } int haar_inverse2d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels; // Table of sizes. FIXME: consider adding this in the w_info structure int tNr[levels+1]; tNr[0] = Nr; int tNc[levels+1]; tNc[0] = Nc; for (int i = 1; i <= levels; i++) { tNr[i] = tNr[i-1]; tNc[i] = tNc[i-1]; w_div2(tNr + i); w_div2(tNc + i); } int tpb = 16; // TODO : tune for max perfs. DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; for (int i = levels-1; i >= 1; i--) { n_blocks = dim3(w_iDivUp(tNc[i], tpb), w_iDivUp(tNr[i], tpb), 1); kern_haar2d_inv<<>>(d_tmp2, d_tmp1, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], tNr[i+1], tNc[i+1], tNr[i], tNc[i]); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp1, tNr[1]*tNc[1]*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First level n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); kern_haar2d_inv<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], tNr[1], tNc[1], Nr, Nc); return 0; } /// ---------------------------------------------------------------------------- /// ------------------------ 1D HAAR TRANSFORM --------------------------------- /// ---------------------------------------------------------------------------- #define ONE_SQRT2 0.70710678118654746 // must be run with grid size = (Nc/2, Nr) where Nr = numrows of input __global__ void kern_haar1d_fwd(DTYPE* img, DTYPE* c_a, DTYPE* c_d, int Nr, int Nc) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; int Nc_is_odd = (Nc & 1); int Nc2 = (Nc + Nc_is_odd)/2; if (gidy < Nr && gidx < Nc2) { int gidx_next = 2*gidx+1; if ((Nc_is_odd) && (gidx_next == Nc)) gidx_next--; // for odd size: repeat last element DTYPE a = img[gidy*Nc + (gidx*2)]; DTYPE b = img[gidy*Nc + gidx_next]; c_a[gidy* Nc2 + gidx] = ONE_SQRT2 * HAAR_AVG(a, b); c_d[gidy* Nc2 + gidx] = ONE_SQRT2 * HAAR_DIF(a, b); } } // must be run with grid size = (Nr, 2*Nc) ; Nr = numrows of input __global__ void kern_haar1d_inv(DTYPE* img, DTYPE* c_a, DTYPE* c_d, int Nr, int Nc, int Nc2) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc2) { DTYPE a = c_a[gidy*Nc + (gidx/2)]; DTYPE b = c_d[gidy*Nc + (gidx/2)]; DTYPE res = 0.0f; if ((gidx & 1) == 0) res = ONE_SQRT2 * HAAR_AVG(a, b); else res = ONE_SQRT2 * HAAR_DIF(a, b); img[gidy*Nc2 + gidx] = res; } } int haar_forward1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels; int Nc2 = Nc; int Nc2_old = Nc2; w_div2(&Nc2); int tpb = 16; // TODO : tune for max perfs. DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; // First level dim3 n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); kern_haar1d_fwd<<>>(d_image, d_coeffs[0], d_coeffs[1], Nr, Nc); for (int i=1; i < levels; i++) { Nc2_old = Nc2; w_div2(&Nc2); n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr, tpb), 1); kern_haar1d_fwd<<>>(d_tmp1, d_tmp2, d_coeffs[i+1], Nr, Nc2_old); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp1, Nr*Nc2*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } // FIXME: for some reason, the precision of the inverse(forward) for HAAR 1D // is not as good as in 2D // (I have 1e-13 error for [0, 255] range in 2D, and 1e-5 in 1D) int haar_inverse1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels; // Table of sizes. FIXME: consider adding this in the w_info structure int tNc[levels+1]; tNc[0] = Nc; for (int i = 1; i <= levels; i++) { tNc[i] = tNc[i-1]; w_div2(tNc + i); } int tpb = 16; // TODO : tune for max perfs. DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; for (int i = levels-1; i >= 1; i--) { n_blocks = dim3(w_iDivUp(tNc[i], tpb), w_iDivUp(Nr, tpb), 1); kern_haar1d_inv<<>>(d_tmp2, d_tmp1, d_coeffs[i+1], Nr, tNc[i+1], tNc[i]); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels > 1) && ((levels & 1) == 0)) cudaMemcpy(d_coeffs[0], d_tmp1, Nr*tNc[1]*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First level n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); kern_haar1d_inv<<>>(d_image, d_coeffs[0], d_coeffs[1], Nr, tNc[1], Nc); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/haar.h0000644000175000017500000000142500000000000015403 0ustar00pierrepierre#ifndef HAAR_HDR #define HAAR_HDR #include "utils.h" __global__ void kern_haar2d_fwd(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc); __global__ void kern_haar2d_inv(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc); int haar_forward2d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int haar_inverse2d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); __global__ void kern_haar1d_fwd(DTYPE* img, DTYPE* c_a, DTYPE* c_d, int Nr, int Nc); __global__ void kern_haar1d_inv(DTYPE* img, DTYPE* c_a, DTYPE* c_d, int Nr, int Nc); int haar_forward1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int haar_inverse1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/io.h0000644000175000017500000000027600000000000015102 0ustar00pierrepierre#ifndef IO_H #define IO_H float* read_dat_file_float(const char* fname, int len); void write_dat_file_float(const char* fname, float* arr, int len); int prompt_text(char* input); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/nonseparable.cu0000644000175000017500000004250600000000000017326 0ustar00pierrepierre#include "nonseparable.h" #include "common.h" #ifdef SEPARATE_COMPILATION // Required for separate compilation (see Makefile) #ifndef CONSTMEM_FILTERS_NS #define CONSTMEM_FILTERS_NS __constant__ DTYPE c_kern_LL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_LH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_HL[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_HH[MAX_FILTER_WIDTH * MAX_FILTER_WIDTH]; #endif #endif // outer product of arrays "a", "b" of length "len" DTYPE* w_outer(DTYPE* a, DTYPE* b, int len) { DTYPE* res = (DTYPE*) calloc(len*len, sizeof(DTYPE)); for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { res[i*len+j] = a[i]*b[j]; } } return res; } /// Compute the four filters A, H, V, D from a family name. /// These filters are separable, i.e computed from 1D filters. /// wname: name of the filter ("haar", "db3", "sym4", ...) /// direction: 1 for forward transform, -1 for inverse transform /// Returns : the filter width "hlen" if success ; a negative value otherwise. int w_compute_filters(const char* wname, int direction, int do_swt) { if (direction == 0) { puts("ERROR: w_compute_filters(): please specify a direction for second argument : +1 for forward, -1 for inverse)"); return -1; } int hlen = 0; DTYPE* f1_l; // 1D lowpass DTYPE* f1_h; // 1D highpass DTYPE* f2_a, *f2_h, *f2_v, *f2_d; // 2D filters // Haar filters has specific kernels if (!do_swt) { if ((!strcasecmp(wname, "haar")) || (!strcasecmp(wname, "db1")) || (!strcasecmp(wname, "bior1.1")) || (!strcasecmp(wname, "rbior1.1"))) { return 2; } } // Browse available filters (see filters.h) int i; for (i = 0; i < 72; i++) { if (!strcasecmp(wname, all_filters[i].wname)) { hlen = all_filters[i].hlen; if (direction > 0) { f1_l = all_filters[i].f_l; f1_h = all_filters[i].f_h; } else { f1_l = all_filters[i].i_l; f1_h = all_filters[i].i_h; } break; } } if (hlen == 0) { printf("ERROR: w_compute_filters(): unknown filter %s\n", wname); return -2; } // Create the separable 2D filters f2_a = w_outer(f1_l, f1_l, hlen); f2_h = w_outer(f1_l, f1_h, hlen); // CHECKME f2_v = w_outer(f1_h, f1_l, hlen); f2_d = w_outer(f1_h, f1_h, hlen); // Copy the filters to device constant memory cudaMemcpyToSymbol(c_kern_LL, f2_a, hlen*hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(c_kern_LH, f2_h, hlen*hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); // CHECKME cudaMemcpyToSymbol(c_kern_HL, f2_v, hlen*hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(c_kern_HH, f2_d, hlen*hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); return hlen; } int w_set_filters_forward_nonseparable(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4, uint len) { if (cudaMemcpyToSymbol(c_kern_LL, filter1, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_LH, filter2, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_HL, filter3, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_HH, filter4, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess) { return -3; } return 0; } int w_set_filters_inverse_nonseparable(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4, uint len) { if (cudaMemcpyToSymbol(c_kern_LL, filter1, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_LH, filter2, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_HL, filter3, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_HH, filter4, len*len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess) { return -3; } return 0; } // must be run with grid size = (Nc/2, Nr/2) where Nr = numrows of input image __global__ void w_kern_forward(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; int Nr_is_odd = (Nr & 1); int Nr2 = (Nr + Nr_is_odd)/2; int Nc_is_odd = (Nc & 1); int Nc2 = (Nc + Nc_is_odd)/2; if (gidy < Nr2 && gidx < Nc2) { int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; DTYPE img_val; // Convolution with periodic boundaries extension. // The following can be sped-up by splitting into 3*3 loops, but it would be a nightmare for readability for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy*2 - c + jy; if (idx_y < 0) idx_y += (Nr + Nr_is_odd); // if N is odd, image is virtually extended // no "else if", since idx_y can be > N-1 after being incremented if (idx_y > Nr-1) { if ((idx_y == Nr) && (Nr_is_odd)) idx_y--; // if N is odd, repeat the right-most element else idx_y -= (Nr + Nr_is_odd); // if N is odd, image is virtually extended } for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx*2 - c + jx; if (idx_x < 0) idx_x += (Nc + Nc_is_odd); // if N is odd, image is virtually extended // no "else if", since idx_x can be > N-1 after being incremented if (idx_x > Nc-1) { if ((idx_x == Nc) && (Nc_is_odd)) idx_x--; // if N is odd, repeat the right-most element else idx_x -= (Nc + Nc_is_odd); // if N is odd, image is virtually extended } img_val = img[idx_y*Nc + idx_x]; res_a += img_val * c_kern_LL[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_h += img_val * c_kern_LH[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_v += img_val * c_kern_HL[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_d += img_val * c_kern_HH[(hlen-1-jy)*hlen + (hlen-1 - jx)]; } } c_a[gidy* Nc2 + gidx] = res_a; c_h[gidy* Nc2 + gidx] = res_h; c_v[gidy* Nc2 + gidx] = res_v; c_d[gidy* Nc2 + gidx] = res_d; } } // must be run with grid size = (2*Nr, 2*Nc) ; Nr = numrows of input __global__ void w_kern_inverse(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int Nr2, int Nc2, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr2 && gidx < Nc2) { int c, hL, hR; int hlen2 = hlen/2; // Convolutions with even/odd indices of the kernels if (hlen2 & 1) { // odd half-kernel size c = hlen2/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen2/2 - 0; hL = c; hR = c-1; // virtual id for shift // TODO : for the very first convolution (on the edges), this is not exactly accurate (?) gidx += 1; gidy += 1; } int jy1 = c - gidy/2; int jy2 = Nr - 1 - gidy/2 + c; int jx1 = c - gidx/2; int jx2 = Nc - 1 - gidx/2 + c; // There are 4 threads/coeff index. Each thread will do a convolution with the even/odd indices of the kernels along each dimension. int offset_x = 1-(gidx & 1); int offset_y = 1-(gidy & 1); DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy/2 - c + jy; if (jy < jy1) idx_y += Nr; if (jy > jy2) idx_y -= Nr; for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx/2 - c + jx; if (jx < jx1) idx_x += Nc; if (jx > jx2) idx_x -= Nc; res_a += c_a[idx_y*Nc + idx_x] * c_kern_LL[(hlen-1- (2*jy + offset_y))*hlen + (hlen-1 - (2*jx + offset_x))]; res_h += c_h[idx_y*Nc + idx_x] * c_kern_LH[(hlen-1- (2*jy + offset_y))*hlen + (hlen-1 - (2*jx + offset_x))]; res_v += c_v[idx_y*Nc + idx_x] * c_kern_HL[(hlen-1- (2*jy + offset_y))*hlen + (hlen-1 - (2*jx + offset_x))]; res_d += c_d[idx_y*Nc + idx_x] * c_kern_HH[(hlen-1- (2*jy + offset_y))*hlen + (hlen-1 - (2*jx + offset_x))]; } } if ((hlen2 & 1) == 1) img[gidy * Nc2 + gidx] = res_a + res_h + res_v + res_d; else img[(gidy-1) * Nc2 + (gidx-1)] = res_a + res_h + res_v + res_d; } } int w_forward(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; int tpb = 16; // TODO : tune for max perfs. int Nc2 = Nc, Nr2 = Nr; int Nc2_old = Nc2, Nr2_old = Nr2; w_div2(&Nr2); w_div2(&Nc2); DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; // First level dim3 n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); w_kern_forward<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr, Nc, hlen); for (int i=1; i < levels; i++) { Nr2_old = Nr2; Nc2_old = Nc2; w_div2(&Nr2); w_div2(&Nc2); n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); w_kern_forward<<>>(d_tmp1, d_tmp2, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr2_old, Nc2_old, hlen); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels > 1) && ((levels & 1) == 0)) cudaMemcpy(d_coeffs[0], d_tmp, Nr2*Nc2*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } int w_inverse(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; // Table of sizes. FIXME: consider adding this in the w_info structure int tNr[levels+1]; tNr[0] = Nr; int tNc[levels+1]; tNc[0] = Nc; for (int i = 1; i <= levels; i++) { tNr[i] = tNr[i-1]; tNc[i] = tNc[i-1]; w_div2(tNr + i); w_div2(tNc + i); } int tpb = 16; // TODO : tune for max perfs. DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks; for (int i = levels-1; i >= 1; i--) { n_blocks = dim3(w_iDivUp(tNc[i], tpb), w_iDivUp(tNr[i], tpb), 1); w_kern_inverse<<>>(d_tmp2, d_tmp1, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], tNr[i+1], tNc[i+1], tNr[i], tNc[i], hlen); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels > 1) && ((levels & 1) == 0)) cudaMemcpy(d_coeffs[0], d_tmp, tNr[1]*tNc[1]*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First level n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); w_kern_inverse<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], tNr[1], tNc[1], Nr, Nc, hlen); return 0; } /// ---------------------------------------------------------------------------- /// ------------------------- Undecimated DWT -------------------------------- /// ---------------------------------------------------------------------------- // must be run with grid size = (Nc, Nr) where Nr = numrows of input image __global__ void w_kern_forward_swt(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { int factor = 1 << (level - 1); int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } c *= factor; int jx1 = c - gidx; int jx2 = Nc - 1 - gidx + c; int jy1 = c - gidy; int jy2 = Nr - 1 - gidy + c; DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; DTYPE img_val; // Convolution with periodic boundaries extension. // The filters are 2-upsampled at each level : [h0, h1, h2, h3] --> [h0, 0, h1, 0, h2, 0, h3, 0] for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy - c + factor*jy; if (factor*jy < jy1) idx_y += Nr; if (factor*jy > jy2) idx_y -= Nr; for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx + jx*factor - c; if (factor*jx < jx1) idx_x += Nc; if (factor*jx > jx2) idx_x -= Nc; img_val = img[idx_y*Nc + idx_x]; res_a += img_val * c_kern_LL[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_h += img_val * c_kern_LH[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_v += img_val * c_kern_HL[(hlen-1-jy)*hlen + (hlen-1 - jx)]; res_d += img_val * c_kern_HH[(hlen-1-jy)*hlen + (hlen-1 - jx)]; } } c_a[gidy* Nc + gidx] = res_a; c_h[gidy* Nc + gidx] = res_h; c_v[gidy* Nc + gidx] = res_v; c_d[gidy* Nc + gidx] = res_d; } } // must be run with grid size = (2*Nr, 2*Nc) ; Nr = numrows of input __global__ void w_kern_inverse_swt(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { int factor = 1 << (level - 1); int c, hL, hR; if (hlen & 1) { // odd half-kernel size c = hlen/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen/2 - 0; hL = c; hR = c-1; } c *= factor; int jy1 = c - gidy; int jy2 = Nr - 1 - gidy + c; int jx1 = c - gidx; int jx2 = Nc - 1 - gidx + c; DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy - c + jy*factor; if (factor*jy < jy1) idx_y += Nr; if (factor*jy > jy2) idx_y -= Nr; for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx - c + jx*factor; if (factor*jx < jx1) idx_x += Nc; if (factor*jx > jx2) idx_x -= Nc; res_a += c_a[idx_y*Nc + idx_x] * c_kern_LL[(hlen-1-jy)*hlen + (hlen-1 - jx)]/4; res_h += c_h[idx_y*Nc + idx_x] * c_kern_LH[(hlen-1-jy)*hlen + (hlen-1 - jx)]/4; res_v += c_v[idx_y*Nc + idx_x] * c_kern_HL[(hlen-1-jy)*hlen + (hlen-1 - jx)]/4; res_d += c_d[idx_y*Nc + idx_x] * c_kern_HH[(hlen-1-jy)*hlen + (hlen-1 - jx)]/4; } } img[gidy * Nc + gidx] = res_a + res_h + res_v + res_d; } } int w_forward_swt(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; // First level int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); w_kern_forward_swt<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr, Nc, hlen, 1); for (int i=1; i < levels; i++) { w_kern_forward_swt<<>>(d_tmp1, d_tmp2, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr, Nc, hlen, i+1); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp, Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } int w_inverse_swt(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; int tpb = 16; // TODO : tune for max perfs. dim3 n_threads_per_block = dim3(tpb, tpb, 1); dim3 n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); for (int i = levels-1; i >= 1; i--) { w_kern_inverse_swt<<>>(d_tmp2, d_tmp1, d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr, Nc, hlen, i+1); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp, Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First scale n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); w_kern_inverse_swt<<>>(d_image, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr, Nc, hlen, 1); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/nonseparable.h0000644000175000017500000000235500000000000017144 0ustar00pierrepierre#ifndef NONSEPARABLE_H #define NONSEPARABLE_H #include "utils.h" DTYPE* w_outer(DTYPE* a, DTYPE* b, int len); int w_compute_filters(const char* wname, int direction, int do_swt); int w_set_filters_forward_nonseparable(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4, uint len); int w_set_filters_inverse_nonseparable(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4, uint len); __global__ void w_kern_forward(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen); __global__ void w_kern_inverse(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int Nr2, int Nc2, int hlen); int w_forward(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_inverse(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); __global__ void w_kern_forward_swt(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level); __global__ void w_kern_inverse_swt(DTYPE* img, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level); int w_forward_swt(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_inverse_swt(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/separable.cu0000644000175000017500000006615500000000000016621 0ustar00pierrepierre#include "separable.h" #include "common.h" #ifdef SEPARATE_COMPILATION // Required for separate compilation (see Makefile) #ifndef CONSTMEM_FILTERS_S #define CONSTMEM_FILTERS_S __constant__ DTYPE c_kern_L[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_H[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_IL[MAX_FILTER_WIDTH]; __constant__ DTYPE c_kern_IH[MAX_FILTER_WIDTH]; #endif #endif /// Compute the low-pass and high-pass filters for separable convolutions. /// wname: name of the filter ("haar", "db3", "sym4", ...) /// Returns : the filter width "hlen" if success ; a negative value otherwise. int w_compute_filters_separable(const char* wname, int do_swt) { int hlen = 0; DTYPE* f1_l, *f1_h, *f1_il, *f1_ih; // Haar filters has specific kernels if (!do_swt) { if ((!strcasecmp(wname, "haar")) || (!strcasecmp(wname, "db1")) || (!strcasecmp(wname, "bior1.1")) || (!strcasecmp(wname, "rbior1.1"))) { return 2; } } // Browse available filters (see filters.h) int i; for (i = 0; i < 72; i++) { if (!strcasecmp(wname, all_filters[i].wname)) { hlen = all_filters[i].hlen; f1_l = all_filters[i].f_l; f1_h = all_filters[i].f_h; f1_il = all_filters[i].i_l; f1_ih = all_filters[i].i_h; break; } } if (hlen == 0) { printf("ERROR: w_compute_filters(): unknown filter %s\n", wname); return -2; } // Copy the filters to device constant memory cudaMemcpyToSymbol(c_kern_L, f1_l, hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(c_kern_H, f1_h, hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(c_kern_IL, f1_il, hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(c_kern_IH, f1_ih, hlen*sizeof(DTYPE), 0, cudaMemcpyHostToDevice); return hlen; } int w_set_filters_forward(DTYPE* filter1, DTYPE* filter2, uint len) { if (cudaMemcpyToSymbol(c_kern_L, filter1, len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_H, filter2, len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess) { return -3; } return 0; } int w_set_filters_inverse(DTYPE* filter1, DTYPE* filter2, uint len) { if (cudaMemcpyToSymbol(c_kern_IL, filter1, len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess || cudaMemcpyToSymbol(c_kern_IH, filter2, len*sizeof(DTYPE), 0, cudaMemcpyHostToDevice) != cudaSuccess) { return -3; } return 0; } /// ---------------------------------------------------------------------------- /// ---------------------------- Forward DWT ---------------------------------- /// ---------------------------------------------------------------------------- // must be run with grid size = (Nc/2, Nr) where Nr = numrows of input image // Pass 1 : Input image ==> horizontal convolution with L, H + horizontal subsampling ==> (tmp_a1, tmp_a2) __global__ void w_kern_forward_pass1(DTYPE* img, DTYPE* tmp_a1, DTYPE* tmp_a2, int Nr, int Nc, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; int Nc_is_odd = (Nc & 1); int Nc2 = (Nc + Nc_is_odd)/2; if (gidy < Nr && gidx < Nc2) { // horiz subsampling : Input (Nr, Nc) => Output (Nr, Nc/2) int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } DTYPE res_tmp_a1 = 0, res_tmp_a2 = 0; DTYPE img_val; // Convolution with periodic boundaries extension. for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx*2 - c + jx; if (idx_x < 0) idx_x += (Nc + Nc_is_odd); // if N is odd, image is virtually extended // no "else if", since idx_x can be > N-1 after being incremented if (idx_x > Nc-1) { if ((idx_x == Nc) && (Nc_is_odd)) idx_x--; // if N is odd, repeat the right-most element else idx_x -= (Nc + Nc_is_odd); // if N is odd, image is virtually extended } img_val = img[gidy*Nc + idx_x]; res_tmp_a1 += img_val * c_kern_L[hlen-1 - jx]; res_tmp_a2 += img_val * c_kern_H[hlen-1 - jx]; } tmp_a1[gidy* Nc2 + gidx] = res_tmp_a1; tmp_a2[gidy* Nc2 + gidx] = res_tmp_a2; } } // must be run with grid size = (Nc/2, Nr/2) where Nr = numrows of input image. Here Nc is actually halved wrt to Nc_image since there was a horiz subs. // Pass 2 : (tmp_a1, tmp_a2) ==> Vertic convolution on tmp_a1 and tmp_a2 with L, H + vertical subsampling ==> (a, h, v, d) __global__ void w_kern_forward_pass2(DTYPE* tmp_a1, DTYPE* tmp_a2, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; int Nr_is_odd = (Nr & 1); int Nr2 = (Nr + Nr_is_odd)/2; if (gidy < Nr2 && gidx < Nc) { // vertic subsampling : Input (Nr, Nc/2) => Output (Nr/2, Nc/2) int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; // Convolution with periodic boundaries extension. for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy*2 - c + jy; if (idx_y < 0) idx_y += (Nr + Nr_is_odd); // if N is odd, image is virtually extended // no "else if", since idx_y can be > N-1 after being incremented if (idx_y > Nr-1) { if ((idx_y == Nr) && (Nr_is_odd)) idx_y--; // if N is odd, repeat the right-most element else idx_y -= (Nr + Nr_is_odd); // if N is odd, image is virtually extended } res_a += tmp_a1[idx_y*Nc + gidx] * c_kern_L[hlen-1 - jy]; res_h += tmp_a1[idx_y*Nc + gidx] * c_kern_H[hlen-1 - jy]; res_v += tmp_a2[idx_y*Nc + gidx] * c_kern_L[hlen-1 - jy]; res_d += tmp_a2[idx_y*Nc + gidx] * c_kern_H[hlen-1 - jy]; } c_a[gidy* Nc + gidx] = res_a; c_h[gidy* Nc + gidx] = res_h; c_v[gidy* Nc + gidx] = res_v; c_d[gidy* Nc + gidx] = res_d; } } int w_forward_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; int Nc2 = Nc, Nr2 = Nr; int Nc2_old = Nc2, Nr2_old = Nr; w_div2(&Nc2); w_div2(&Nr2); // d_tmp can have up to 2*Nr*Nc elemets (two input images) [Nr*Nc would be enough here]. // Here d_tmp1 (resp. d_tmp2) is used for the horizontal (resp. vertical) downsampling. // Given a dimension size N, the subsampled dimension size is N/2 if N is even, (N+1)/2 otherwise. DTYPE* d_tmp1 = d_tmp; DTYPE* d_tmp2 = d_tmp + Nr*Nc2; // First level int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks_1 = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_blocks_2 = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); w_kern_forward_pass1<<>>(d_image, d_tmp1, d_tmp2, Nr2_old, Nc2_old, hlen); w_kern_forward_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr2_old, Nc2, hlen); for (int i=1; i < levels; i++) { Nc2_old = Nc2; Nr2_old = Nr2; w_div2(&Nc2); w_div2(&Nr2); n_blocks_1 = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2_old, tpb), 1); n_blocks_2 = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr2, tpb), 1); w_kern_forward_pass1<<>>(d_coeffs[0], d_tmp1, d_tmp2, Nr2_old, Nc2_old, hlen); w_kern_forward_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr2_old, Nc2, hlen); } return 0; } // (batched) 1D transform. It boils down to the 2D separable transform without the second pass. int w_forward_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1 = d_coeffs[0]; DTYPE* d_tmp2 = d_tmp; // First level int tpb = 16; // TODO : tune for max perfs. int Nc2 = Nc; int Nc2_old = Nc2; w_div2(&Nc2); // TODO: which block strategy for the "y" dimension ? dim3 n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); w_kern_forward_pass1<<>>(d_image, d_coeffs[0], d_coeffs[1], Nr, Nc, hlen); for (int i=1; i < levels; i++) { Nc2_old = Nc2; w_div2(&Nc2); n_blocks = dim3(w_iDivUp(Nc2, tpb), w_iDivUp(Nr, tpb), 1); w_kern_forward_pass1<<>>(d_tmp1, d_tmp2, d_coeffs[i+1], Nr, Nc2_old, hlen); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels > 1) && ((levels & 1) == 0)) cudaMemcpy(d_coeffs[0], d_tmp, Nr*Nc2*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } /// ---------------------------------------------------------------------------- /// ---------------------------- Inverse DWT ----------------------------------- /// ---------------------------------------------------------------------------- // must be run with grid size = (Nc, 2*Nr) ; Nr = numrows of input coefficients // pass 1 : (a, h, v, d) ==> Vertical convol with IL, IH + vertical oversampling==> (tmp1, tmp2) __global__ void w_kern_inverse_pass1(DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* tmp1, DTYPE* tmp2, int Nr, int Nc, int Nr2, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr2 && gidx < Nc) { // vertic oversampling : Input (Nr, Nc) => Output (Nr*2, Nc) int c, hL, hR; int hlen2 = hlen/2; // Convolutions with even/odd indices of the kernels if (hlen2 & 1) { // odd half-kernel size c = hlen2/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen2/2 - 0; hL = c; hR = c-1; // virtual id for shift // TODO : more elegant gidy += 1; } int jy1 = c - gidy/2; int jy2 = Nr - 1 - gidy/2 + c; int offset_y = 1-(gidy & 1); DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy/2 - c + jy; if (jy < jy1) idx_y += Nr; if (jy > jy2) idx_y -= Nr; res_a += c_a[idx_y*Nc + gidx] * c_kern_IL[hlen-1 - (2*jy + offset_y)]; res_h += c_h[idx_y*Nc + gidx] * c_kern_IH[hlen-1 - (2*jy + offset_y)]; res_v += c_v[idx_y*Nc + gidx] * c_kern_IL[hlen-1 - (2*jy + offset_y)]; res_d += c_d[idx_y*Nc + gidx] * c_kern_IH[hlen-1 - (2*jy + offset_y)]; } if ((hlen2 & 1) == 1) { tmp1[gidy * Nc + gidx] = res_a + res_h; tmp2[gidy * Nc + gidx] = res_v + res_d; } else { tmp1[(gidy-1) * Nc + gidx] = res_a + res_h; tmp2[(gidy-1) * Nc + gidx] = res_v + res_d; } } } // must be run with grid size = (2*Nr, 2*Nc) ; Nc = numcols of input coeffs. Here the param Nr is actually doubled wrt Nr_coeffs because of the vertical oversampling. // pass 2 : (tmp1, tmp2) ==> Horiz convol with IL, IH + horiz oversampling ==> I __global__ void w_kern_inverse_pass2(DTYPE* tmp1, DTYPE* tmp2, DTYPE* img, int Nr, int Nc, int Nc2, int hlen) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc2) { // horiz oversampling : Input (Nr*2, Nc) => Output (Nr*2, Nc*2) int c, hL, hR; int hlen2 = hlen/2; // Convolutions with even/odd indices of the kernels if (hlen2 & 1) { // odd half-kernel size c = hlen2/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen2/2 - 0; hL = c; hR = c-1; // virtual id for shift // TODO : for the very first convolution (on the edges), this is not exactly accurate (?) gidx += 1; } int jx1 = c - gidx/2; int jx2 = Nc - 1 - gidx/2 + c; int offset_x = 1-(gidx & 1); DTYPE res_1 = 0, res_2 = 0; for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx/2 - c + jx; if (jx < jx1) idx_x += Nc; if (jx > jx2) idx_x -= Nc; res_1 += tmp1[gidy*Nc + idx_x] * c_kern_IL[hlen-1 - (2*jx + offset_x)]; res_2 += tmp2[gidy*Nc + idx_x] * c_kern_IH[hlen-1 - (2*jx + offset_x)]; } if ((hlen2 & 1) == 1) img[gidy * Nc2 + gidx] = res_1 + res_2; else img[gidy * Nc2 + (gidx-1)] = res_1 + res_2; } } int w_inverse_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; // Table of sizes. FIXME: consider adding this in the w_info structure int tNr[levels+1]; tNr[0] = Nr; int tNc[levels+1]; tNc[0] = Nc; for (int i = 1; i <= levels; i++) { tNr[i] = tNr[i-1]; tNc[i] = tNc[i-1]; w_div2(tNr + i); w_div2(tNc + i); } DTYPE* d_tmp1 = d_tmp; DTYPE* d_tmp2 = d_tmp + Nr*tNc[1]; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks_1, n_blocks_2; dim3 n_threads_per_block = dim3(tpb, tpb, 1); // TODO: variables for better readability instead of tNr[i], tNc[i] for (int i = levels-1; i >= 1; i--) { n_blocks_1 = dim3(w_iDivUp(tNc[i+1], tpb), w_iDivUp(tNr[i], tpb), 1); n_blocks_2 = dim3(w_iDivUp(tNc[i], tpb), w_iDivUp(tNr[i], tpb), 1); w_kern_inverse_pass1<<>>(d_coeffs[0], d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], d_tmp1, d_tmp2, tNr[i+1], tNc[i+1], tNr[i], hlen); w_kern_inverse_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], tNr[i], tNc[i+1], tNc[i], hlen); } // First scale n_blocks_1 = dim3(w_iDivUp(tNc[1], tpb), w_iDivUp(tNr[0], tpb), 1); n_blocks_2 = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); w_kern_inverse_pass1<<>>(d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], d_tmp1, d_tmp2, tNr[1], tNc[1], tNr[0], hlen); w_kern_inverse_pass2<<>>(d_tmp1, d_tmp2, d_image, tNr[0], tNc[1], tNc[0], hlen); return 0; } // (batched) 1D inverse transform. Boils down to 2D separable transform without the first pass. // TODO: consider deleting these memcpy. Simply do inverse_pass2: coeffs[i] => coeffs[i+1]. coeffs are overwritten anyway. int w_inverse_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; // Table of sizes. FIXME: consider adding this in the w_info structure int tNc[levels+1]; tNc[0] = Nc; for (int i = 1; i <= levels; i++) { tNc[i] = tNc[i-1]; w_div2(tNc + i); } DTYPE* d_tmp1, *d_tmp2; d_tmp1 = d_coeffs[0]; d_tmp2 = d_tmp; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks; dim3 n_threads_per_block = dim3(tpb, tpb, 1); for (int i = levels-1; i >= 1; i--) { n_blocks = dim3(w_iDivUp(tNc[i], tpb), w_iDivUp(Nr, tpb), 1); w_kern_inverse_pass2<<>>(d_tmp1, d_coeffs[i+1], d_tmp2, Nr, tNc[i+1], tNc[i], hlen); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels > 1) && ((levels & 1) == 0)) cudaMemcpy(d_coeffs[0], d_tmp1, Nr*tNc[1]*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First scale n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); w_kern_inverse_pass2<<>>(d_coeffs[0], d_coeffs[1], d_image, Nr, tNc[1], Nc, hlen); return 0; } /// ---------------------------------------------------------------------------- /// --------------------- Forward Undecimated DWT ------------------------------ /// ---------------------------------------------------------------------------- // must be run with grid size = (Nc, Nr) where Nr = numrows of input image // Pass 1 : Input image ==> horizontal convolution with L, H ==> (tmp_a1, tmp_a2) __global__ void w_kern_forward_swt_pass1(DTYPE* img, DTYPE* tmp_a1, DTYPE* tmp_a2, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { int factor = 1 << (level - 1); int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } c *= factor; int jx1 = c - gidx; int jx2 = Nc - 1 - gidx + c; DTYPE res_tmp_a1 = 0, res_tmp_a2 = 0; DTYPE img_val; // Convolution with periodic boundaries extension. // The filters are 2-upsampled at each level : [h0, h1, h2, h3] --> [h0, 0, h1, 0, h2, 0, h3, 0] for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx + jx*factor - c; if (factor*jx < jx1) idx_x += Nc; if (factor*jx > jx2) idx_x -= Nc; img_val = img[(gidy)*Nc + idx_x]; res_tmp_a1 += img_val * c_kern_L[hlen-1 - jx]; res_tmp_a2 += img_val * c_kern_H[hlen-1 - jx]; } tmp_a1[gidy* Nc + gidx] = res_tmp_a1; tmp_a2[gidy* Nc + gidx] = res_tmp_a2; } } // must be run with grid size = (Nc, Nr) where Nr = numrows of input image // Pass 2 : (tmp_a1, tmp_a2) ==> Vertic convolution on tmp_a1 and tmp_a2 with L, H ==> (a, h, v, d) __global__ void w_kern_forward_swt_pass2(DTYPE* tmp_a1, DTYPE* tmp_a2, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { int factor = 1 << (level - 1); int c, hL, hR; if (hlen & 1) { // odd kernel size c = hlen/2; hL = c; hR = c; } else { // even kernel size : center is shifted to the left c = hlen/2 - 1; hL = c; hR = c+1; } c *= factor; int jy1 = c - gidy; int jy2 = Nr - 1 - gidy + c; DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; // Convolution with periodic boundaries extension. // The filters are 2-upsampled at each level : [h0, h1, h2, h3] --> [h0, 0, h1, 0, h2, 0, h3, 0] for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy + factor*jy - c; if (factor*jy < jy1) idx_y += Nr; if (factor*jy > jy2) idx_y -= Nr; res_a += tmp_a1[idx_y*Nc + gidx] * c_kern_L[hlen-1 - jy]; res_h += tmp_a1[idx_y*Nc + gidx] * c_kern_H[hlen-1 - jy]; res_v += tmp_a2[idx_y*Nc + gidx] * c_kern_L[hlen-1 - jy]; res_d += tmp_a2[idx_y*Nc + gidx] * c_kern_H[hlen-1 - jy]; } c_a[gidy* Nc + gidx] = res_a; c_h[gidy* Nc + gidx] = res_h; c_v[gidy* Nc + gidx] = res_v; c_d[gidy* Nc + gidx] = res_d; } } int w_forward_swt_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1 = d_tmp; DTYPE* d_tmp2 = d_tmp + Nr*Nc; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks_1 = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_blocks_2 = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); // First level w_kern_forward_swt_pass1<<>>(d_image, d_tmp1, d_tmp2, Nr, Nc, hlen, 1); w_kern_forward_swt_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], Nr, Nc, hlen, 1); // Other levels for (int i=1; i < levels; i++) { w_kern_forward_swt_pass1<<>>(d_coeffs[0], d_tmp1, d_tmp2, Nr, Nc, hlen, i+1); w_kern_forward_swt_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], Nr, Nc, hlen, i+1); } return 0; } // (batched) 1D forward SWT. Boils down to 2D non-separable transform without the second pass. int w_forward_swt_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1 = d_coeffs[0]; DTYPE* d_tmp2 = d_tmp; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); // First level w_kern_forward_swt_pass1<<>>(d_image, d_coeffs[0], d_coeffs[1], Nr, Nc, hlen, 1); // Other levels for (int i=1; i < levels; i++) { w_kern_forward_swt_pass1<<>>(d_tmp1, d_tmp2, d_coeffs[i+1], Nr, Nc, hlen, i+1); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp, Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); return 0; } /// ---------------------------------------------------------------------------- /// --------------------- Inverse Undecimated DWT ------------------------------ /// ---------------------------------------------------------------------------- // must be run with grid size = (Nc, Nr) ; Nr = numrows of input coefficients // pass 1 : (a, h, v, d) ==> Vertical convol with IL, IH ==> (tmp1, tmp2) __global__ void w_kern_inverse_swt_pass1(DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* tmp1, DTYPE* tmp2, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { // vertic oversampling : Input (Nr, Nc) => Output (Nr*2, Nc) int c, hL, hR; int factor = 1 << (level - 1); if (hlen & 1) { // odd half-kernel size c = hlen/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen/2 - 0; hL = c; hR = c-1; } c *= factor; int jy1 = c - gidy; int jy2 = Nr - 1 - gidy + c; int offset_y = 1-(gidy & 1); offset_y = 0; DTYPE res_a = 0, res_h = 0, res_v = 0, res_d = 0; for (int jy = 0; jy <= hR+hL; jy++) { int idx_y = gidy - c + factor*jy; if (factor*jy < jy1) idx_y += Nr; if (factor*jy > jy2) idx_y -= Nr; res_a += c_a[idx_y*Nc + gidx] * c_kern_IL[hlen-1 - (jy + offset_y)]/2; res_h += c_h[idx_y*Nc + gidx] * c_kern_IH[hlen-1 - (jy + offset_y)]/2; res_v += c_v[idx_y*Nc + gidx] * c_kern_IL[hlen-1 - (jy + offset_y)]/2; res_d += c_d[idx_y*Nc + gidx] * c_kern_IH[hlen-1 - (jy + offset_y)]/2; } tmp1[gidy * Nc + gidx] = res_a + res_h; tmp2[gidy * Nc + gidx] = res_v + res_d; } } // must be run with grid size = (Nr, Nc) ; Nc = numcols of input coeffs. // pass 2 : (tmp1, tmp2) ==> Horiz convol with IL, IH ==> I __global__ void w_kern_inverse_swt_pass2(DTYPE* tmp1, DTYPE* tmp2, DTYPE* img, int Nr, int Nc, int hlen, int level) { int gidx = threadIdx.x + blockIdx.x*blockDim.x; int gidy = threadIdx.y + blockIdx.y*blockDim.y; if (gidy < Nr && gidx < Nc) { // horiz oversampling : Input (Nr*2, Nc) => Output (Nr*2, Nc*2) int c, hL, hR; int factor = 1 << (level - 1); if (hlen & 1) { // odd half-kernel size c = hlen/2; hL = c; hR = c; } else { // even half-kernel size : center is shifted to the RIGHT for reconstruction. c = hlen/2 - 0; hL = c; hR = c-1; } c *= factor; int jx1 = c - gidx; int jx2 = Nc - 1 - gidx + c; int offset_x = 1-(gidx & 1); offset_x = 0; DTYPE res_1 = 0, res_2 = 0; for (int jx = 0; jx <= hR+hL; jx++) { int idx_x = gidx - c + factor*jx; if (factor*jx < jx1) idx_x += Nc; if (factor*jx > jx2) idx_x -= Nc; res_1 += tmp1[gidy*Nc + idx_x] * c_kern_IL[hlen-1 - (jx + offset_x)]/2; res_2 += tmp2[gidy*Nc + idx_x] * c_kern_IH[hlen-1 - (jx + offset_x)]/2; } img[gidy * Nc + gidx] = res_1 + res_2; } } int w_inverse_swt_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1 = d_tmp; DTYPE* d_tmp2 = d_tmp + Nr*Nc; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks_1 = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_blocks_2 = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); for (int i = levels-1; i >= 1; i--) { w_kern_inverse_swt_pass1<<>>(d_coeffs[0], d_coeffs[3*i+1], d_coeffs[3*i+2], d_coeffs[3*i+3], d_tmp1, d_tmp2, Nr, Nc, hlen, i+1); w_kern_inverse_swt_pass2<<>>(d_tmp1, d_tmp2, d_coeffs[0], Nr, Nc, hlen, i+1); } // First scale w_kern_inverse_swt_pass1<<>>(d_coeffs[0], d_coeffs[1], d_coeffs[2], d_coeffs[3], d_tmp1, d_tmp2, Nr, Nc, hlen, 1); w_kern_inverse_swt_pass2<<>>(d_tmp1, d_tmp2, d_image, Nr, Nc, hlen, 1); return 0; } // (batched) 1D inverse SWT. Boils down to 2D non-separable transform without the first pass. int w_inverse_swt_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos) { int Nr = winfos.Nr, Nc = winfos.Nc, levels = winfos.nlevels, hlen = winfos.hlen; DTYPE* d_tmp1 = d_coeffs[0]; DTYPE* d_tmp2 = d_tmp; int tpb = 16; // TODO : tune for max perfs. dim3 n_blocks = dim3(w_iDivUp(Nc, tpb), w_iDivUp(Nr, tpb), 1); dim3 n_threads_per_block = dim3(tpb, tpb, 1); for (int i = levels-1; i >= 1; i--) { w_kern_inverse_swt_pass2<<>>(d_tmp1, d_coeffs[i+1], d_tmp2, Nr, Nc, hlen, i+1); w_swap_ptr(&d_tmp1, &d_tmp2); } if ((levels & 1) == 0) cudaMemcpy(d_coeffs[0], d_tmp, Nr*Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); // First scale w_kern_inverse_swt_pass2<<>>(d_coeffs[0], d_coeffs[1], d_image, Nr, Nc, hlen, 1); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/separable.h0000644000175000017500000000402000000000000016420 0ustar00pierrepierre#ifndef SEPARABLE_H #define SEPARABLE_H #include "utils.h" int w_compute_filters_separable(const char* wname, int do_swt); int w_set_filters_forward(DTYPE* filter1, DTYPE* filter2, uint len); int w_set_filters_inverse(DTYPE* filter1, DTYPE* filter2, uint len); __global__ void w_kern_forward_pass1(DTYPE* img, DTYPE* tmp_a1, DTYPE* tmp_a2, int Nr, int Nc, int hlen); __global__ void w_kern_forward_pass2(DTYPE* tmp_a1, DTYPE* tmp_a2, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen); int w_forward_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_forward_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); __global__ void w_kern_inverse_pass1(DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* tmp1, DTYPE* tmp2, int Nr, int Nc, int Nr2, int hlen); __global__ void w_kern_inverse_pass2(DTYPE* tmp1, DTYPE* tmp2, DTYPE* img, int Nr, int Nc, int Nc2, int hlen); int w_inverse_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_inverse_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); __global__ void w_kern_forward_swt_pass1(DTYPE* img, DTYPE* tmp_a1, DTYPE* tmp_a2, int Nr, int Nc, int hlen, int level); __global__ void w_kern_forward_swt_pass2(DTYPE* tmp_a1, DTYPE* tmp_a2, DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, int Nr, int Nc, int hlen, int level); int w_forward_swt_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_forward_swt_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); __global__ void w_kern_inverse_swt_pass1(DTYPE* c_a, DTYPE* c_h, DTYPE* c_v, DTYPE* c_d, DTYPE* tmp1, DTYPE* tmp2, int Nr, int Nc, int hlen, int level); __global__ void w_kern_inverse_swt_pass2(DTYPE* tmp1, DTYPE* tmp2, DTYPE* img, int Nr, int Nc, int hlen, int level); int w_inverse_swt_separable(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); int w_inverse_swt_separable_1d(DTYPE* d_image, DTYPE** d_coeffs, DTYPE* d_tmp, w_info winfos); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/utils.cu0000644000175000017500000000074700000000000016016 0ustar00pierrepierre#include "utils.h" int w_iDivUp(int a, int b) { return (a % b != 0) ? (a / b + 1) : (a / b); } int w_ipow2(int a) { return 1 << a; } int w_ilog2(int i) { int l = 0; while (i >>= 1) { ++l; } return l; } /// When the size is odd, allocate one extra element before subsampling void w_div2(int* N) { if ((*N) & 1) *N = ((*N)+1)/2; else *N = (*N)/2; } void w_swap_ptr(DTYPE** a, DTYPE** b) { DTYPE* tmp = *a; *a = *b; *b = tmp; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/utils.h0000644000175000017500000000123300000000000015625 0ustar00pierrepierre#ifndef UTILS_H #define UTILS_H #include #include #include "filters.h" struct w_info { // Number of dimensions. For now only 2D and (batched) 1D are supported int ndims; // Number of rows and columns of the image (for 1D : Nr = 1) int Nr; int Nc; // Wavelet transform related informations int nlevels; // Number of decomposition levels int do_swt; // Do Stationary (Undecimated) Wavelet Transform int hlen; // "Filter" length }; int w_iDivUp(int a, int b); int w_ipow2(int a); int w_ilog2(int i); void w_div2(int* N); void w_swap_ptr(DTYPE** a, DTYPE** b); #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/wt.cu0000755000175000017500000005444200000000000015314 0ustar00pierrepierre#include #include #include #include #include //~ #include "utils.h" #include "common.h" #include "wt.h" #include "separable.h" #include "nonseparable.h" #include "haar.h" # define CUDACHECK \ { cudaThreadSynchronize(); \ cudaError_t last = cudaGetLastError();\ if(last!=cudaSuccess) {\ printf("ERRORX: %s %s %i \n", cudaGetErrorString( last), __FILE__, __LINE__ ); \ exit(1);\ }\ } // FIXME: temp. workaround #define MAX_FILTER_WIDTH 40 /// **************************************************************************** /// ******************** Wavelets class **************************************** /// **************************************************************************** /// Constructor : copy assignment // do not use ! /* Wavelets& Wavelets::operator=(const Wavelets &rhs) { if (this != &rhs) { // protect against invalid self-assignment // allocate new memory and copy the elements size_t sz = rhs.Nr * rhs.Nc * sizeof(DTYPE); DTYPE* new_image, *new_tmp; DTYPE** new_coeffs; cudaMalloc(&new_image, sz); cudaMemcpy(new_image, rhs.d_image, sz, cudaMemcpyDeviceToDevice); new_coeffs = w_create_coeffs_buffer(rhs.Nr, rhs.Nc, rhs.nlevels, rhs.do_swt); if (ndim == 2) w_copy_coeffs_buffer(new_coeffs, rhs.d_coeffs, rhs.Nr, rhs.Nc, rhs.nlevels, rhs.do_swt); else w_copy_coeffs_buffer_1d(new_coeffs, rhs.d_coeffs, rhs.Nr, rhs.Nc, rhs.nlevels, rhs.do_swt); cudaMalloc(&new_tmp, sz); cudaMemcpy(new_tmp, rhs.d_tmp, 2*sz, cudaMemcpyDeviceToDevice); // Two temp. images // deallocate old memory cudaFree(d_image); w_free_coeffs_buffer(d_coeffs, nlevels); cudaFree(d_tmp); // assign the new memory to the object d_image = new_image; d_coeffs = new_coeffs; d_tmp = new_tmp; Nr = rhs.Nr; Nc = rhs.Nc; strncpy(wname, rhs.wname, 128); nlevels = rhs.nlevels; do_cycle_spinning = rhs.do_cycle_spinning; current_shift_r = rhs.current_shift_r; current_shift_c = rhs.current_shift_c; do_swt = rhs.do_swt; do_separable = rhs.do_separable; } return *this; } */ /// Constructor : default Wavelets::Wavelets(void) : d_image(NULL), d_coeffs(NULL), do_cycle_spinning(0), d_tmp(NULL), current_shift_r(0), current_shift_c(0), do_separable(1) { } /// Constructor : Wavelets from image Wavelets::Wavelets( DTYPE* img, int Nr, int Nc, const char* wname, int levels, int memisonhost, int do_separable, int do_cycle_spinning, int do_swt, int ndim) : d_image(NULL), d_coeffs(NULL), do_cycle_spinning(do_cycle_spinning), d_tmp(NULL), current_shift_r(0), current_shift_c(0), do_separable(do_separable), state(W_INIT) { winfos.Nr = Nr; winfos.Nc = Nc; winfos.nlevels = levels; winfos.do_swt = do_swt; winfos.ndims = ndim; if (levels < 1) { puts("Warning: cannot initialize wavelet coefficients with nlevels < 1. Forcing nlevels = 1"); winfos.nlevels = 1; } // Image DTYPE* d_arr_in; cudaMalloc(&d_arr_in, Nr*Nc*sizeof(DTYPE)); if (!img) cudaMemset(d_arr_in, 0, Nr*Nc*sizeof(DTYPE)); else { cudaMemcpyKind transfer; if (memisonhost) transfer = cudaMemcpyHostToDevice; else transfer = cudaMemcpyDeviceToDevice; cudaMemcpy(d_arr_in, img, Nr*Nc*sizeof(DTYPE), transfer); } d_image = d_arr_in; DTYPE* d_tmp_new; cudaMalloc(&d_tmp_new, 2*Nr*Nc*sizeof(DTYPE)); // Two temp. images d_tmp = d_tmp_new; // Dimensions if (Nr == 1) { // 1D data ndim = 1; winfos.ndims = 1; } if (ndim == 1 && do_separable == 0) { puts("Warning: 1D DWT was requestred, which is incompatible with non-separable transform."); puts("Ignoring the do_separable option."); do_separable = 1; } // Filters strncpy(this->wname, wname, 128); int hlen = 0; if (do_separable) hlen = w_compute_filters_separable(wname, do_swt); else hlen = w_compute_filters(wname, 1, do_swt); if (hlen == 0) { printf("ERROR: unknown wavelet name %s\n", wname); //~ exit(1); state = W_CREATION_ERROR; } winfos.hlen = hlen; // Compute max achievable level according to image dimensions and filter size int N; if (ndim == 2) N = min(Nr, Nc); else N = Nc; int wmaxlev = w_ilog2(N/(hlen-1)); // TODO: remove this limitation if (levels > wmaxlev) { printf("Warning: required level (%d) is greater than the maximum possible level for %s (%d) on a %dx%d image.\n", winfos.nlevels, wname, wmaxlev, winfos.Nc, winfos.Nr); printf("Forcing nlevels = %d\n", wmaxlev); winfos.nlevels = wmaxlev; } // Allocate coeffs DTYPE** d_coeffs_new; if (ndim == 1) d_coeffs_new = w_create_coeffs_buffer_1d(winfos); else if (ndim == 2) d_coeffs_new = w_create_coeffs_buffer(winfos); else { printf("ERROR: ndim=%d is not implemented\n", ndim); //~ exit(1); //~ throw std::runtime_error("Error on ndim"); state = W_CREATION_ERROR; } d_coeffs = d_coeffs_new; if (do_cycle_spinning && do_swt) puts("Warning: makes little sense to use Cycle spinning with stationary Wavelet transform"); // TODO if (do_cycle_spinning && ndim == 1) { puts("ERROR: cycle spinning is not implemented for 1D. Use SWT instead."); //~ exit(1); state = W_CREATION_ERROR; } } /// Constructor: copy Wavelets::Wavelets(const Wavelets &W) : do_cycle_spinning(W.do_cycle_spinning), current_shift_c(W.current_shift_c), current_shift_r(W.current_shift_r), do_separable(W.do_separable), state(W.state) { winfos.Nr = W.winfos.Nr; winfos.Nc = W.winfos.Nc; winfos.nlevels = W.winfos.nlevels; winfos.ndims = W.winfos.ndims; winfos.hlen = W.winfos.hlen; winfos.do_swt = W.winfos.do_swt; strncpy(wname, W.wname, 128); cudaMalloc(&d_image, winfos.Nr*winfos.Nc*sizeof(DTYPE)); cudaMemcpy(d_image, W.d_image, winfos.Nr*winfos.Nc*sizeof(DTYPE), cudaMemcpyDeviceToDevice); cudaMalloc(&d_tmp, 2*winfos.Nr*winfos.Nc*sizeof(DTYPE)); if (winfos.ndims == 1) { d_coeffs = w_create_coeffs_buffer_1d(winfos); w_copy_coeffs_buffer_1d(d_coeffs, W.d_coeffs, winfos); } else if (winfos.ndims == 2) { d_coeffs = w_create_coeffs_buffer(winfos); w_copy_coeffs_buffer(d_coeffs, W.d_coeffs, winfos); } else { puts("ERROR: 3D wavelets not implemented yet"); state = W_CREATION_ERROR; } } /// Destructor Wavelets::~Wavelets(void) { if (d_image) cudaFree(d_image); if (d_coeffs) { if (winfos.ndims == 2) w_free_coeffs_buffer(d_coeffs, winfos.nlevels); else w_free_coeffs_buffer_1d(d_coeffs, winfos.nlevels); } if (d_tmp) cudaFree(d_tmp); } /// Method : forward void Wavelets::forward(void) { if (state == W_CREATION_ERROR) { puts("Warning: forward transform not computed, as there was an error when creating the wavelets"); return; } // TODO: handle W_FORWARD_ERROR with return codes of transforms if (do_cycle_spinning) { current_shift_r = rand() % winfos.Nr; current_shift_c = rand() % winfos.Nc; circshift(current_shift_r, current_shift_c, 1); } if (winfos.ndims == 1) { if ((winfos.hlen == 2) && (!winfos.do_swt)) haar_forward1d(d_image, d_coeffs, d_tmp, winfos); else { if (!winfos.do_swt) w_forward_separable_1d(d_image, d_coeffs, d_tmp, winfos); else w_forward_swt_separable_1d(d_image, d_coeffs, d_tmp, winfos); } } else if (winfos.ndims == 2) { if ((winfos.hlen == 2) && (!winfos.do_swt)) haar_forward2d(d_image, d_coeffs, d_tmp, winfos); else { if (do_separable) { if (!winfos.do_swt) w_forward_separable(d_image, d_coeffs, d_tmp, winfos); else w_forward_swt_separable(d_image, d_coeffs, d_tmp, winfos); } else { if (!winfos.do_swt) w_forward(d_image, d_coeffs, d_tmp, winfos); else w_forward_swt(d_image, d_coeffs, d_tmp, winfos); } } } // else: not implemented yet state = W_FORWARD; } /// Method : inverse void Wavelets::inverse(void) { if (state == W_INVERSE) { // TODO: what to do in this case ? Force re-compute, or abort ? puts("Warning: W.inverse() has already been run. Inverse is available in W.get_image()"); return; } if (state == W_FORWARD_ERROR || state == W_THRESHOLD_ERROR) { puts("Warning: inverse transform not computed, as there was an error in a previous stage"); return; } // TODO: handle W_INVERSE_ERROR with return codes of inverse transforms if (winfos.ndims == 1) { if ((winfos.hlen == 2) && (!winfos.do_swt)) haar_inverse1d(d_image, d_coeffs, d_tmp, winfos); else { if (!winfos.do_swt) w_inverse_separable_1d(d_image, d_coeffs, d_tmp, winfos); else w_inverse_swt_separable_1d(d_image, d_coeffs, d_tmp, winfos); } } else if (winfos.ndims == 2) { if ((winfos.hlen == 2) && (!winfos.do_swt)) haar_inverse2d(d_image, d_coeffs, d_tmp, winfos); else { if (do_separable) { if (!winfos.do_swt) w_inverse_separable(d_image, d_coeffs, d_tmp, winfos); else w_inverse_swt_separable(d_image, d_coeffs, d_tmp, winfos); } else { w_compute_filters(wname, -1, winfos.do_swt); // TODO : dedicated inverse coeffs to avoid this computation ? if (!winfos.do_swt) w_inverse(d_image, d_coeffs, d_tmp, winfos); else w_inverse_swt(d_image, d_coeffs, d_tmp, winfos); } } } // else: not implemented yet if (do_cycle_spinning) circshift(-current_shift_r, -current_shift_c, 1); state = W_INVERSE; } /// Method : soft thresholding (L1 proximal) void Wavelets::soft_threshold(DTYPE beta, int do_thresh_appcoeffs, int normalize) { if (state == W_INVERSE) { puts("Warning: Wavelets(): cannot threshold coefficients, as they were modified by W.inverse()"); return; } w_call_soft_thresh(d_coeffs, beta, winfos, do_thresh_appcoeffs, normalize); // TODO: handle W_THRESHOLD_ERROR from a return code } /// Method : hard thresholding void Wavelets::hard_threshold(DTYPE beta, int do_thresh_appcoeffs, int normalize) { if (state == W_INVERSE) { puts("Warning: Wavelets(): cannot threshold coefficients, as they were modified by W.inverse()"); return; } w_call_hard_thresh(d_coeffs, beta, winfos, do_thresh_appcoeffs, normalize); // TODO: handle W_THRESHOLD_ERROR from a return code } /// Method : soft thresholding (L1 proximal) void Wavelets::group_soft_threshold(DTYPE beta, int do_thresh_appcoeffs, int normalize) { if (state == W_INVERSE) { puts("Warning: Wavelets(): cannot threshold coefficients, as they were modified by W.inverse()"); return; } w_call_group_soft_thresh(d_coeffs, beta, winfos, do_thresh_appcoeffs, normalize); // TODO: handle W_THRESHOLD_ERROR from a return code } /// Method : shrink (L2 proximal) void Wavelets::shrink(DTYPE beta, int do_thresh_appcoeffs) { if (state == W_INVERSE) { puts("Warning: Wavelets(): cannot threshold coefficients, as they were modified by W.inverse()"); return; } w_shrink(d_coeffs, beta, winfos, do_thresh_appcoeffs); // TODO: handle W_THRESHOLD_ERROR from a return code } /// Method : projection onto the L-infinity ball (infinity norm proximal, i.e dual L1 norm proximal) void Wavelets::proj_linf(DTYPE beta, int do_thresh_appcoeffs) { if (state == W_INVERSE) { puts("Warning: Wavelets(): cannot threshold coefficients, as they were modified by W.inverse()"); return; } w_call_proj_linf(d_coeffs, beta, winfos, do_thresh_appcoeffs); // TODO: handle W_THRESHOLD_ERROR from a return code } /// Method : circular shift // If inplace = 1, the result is in d_image ; otherwise result is in d_tmp. void Wavelets::circshift(int sr, int sc, int inplace) { w_call_circshift(d_image, d_tmp, winfos, sr, sc, inplace); } /// Method : squared L2 norm DTYPE Wavelets::norm2sq(void) { DTYPE res = 0.0f; int Nr2 = winfos.Nr; int Nc2 = winfos.Nc; DTYPE tmp = 0; for (int i = 0; i < winfos.nlevels; i++) { if (!winfos.do_swt) { if (winfos.ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } if (winfos.ndims == 2) { // 2D tmp = cublas_nrm2(Nr2*Nc2, d_coeffs[3*i+1], 1); res += tmp*tmp; tmp =cublas_nrm2(Nr2*Nc2, d_coeffs[3*i+2], 1); res += tmp*tmp; tmp = cublas_nrm2(Nr2*Nc2, d_coeffs[3*i+3], 1); res += tmp*tmp; } else { // 1D res += cublas_asum(Nr2*Nc2, d_coeffs[i+1], 1); } } tmp = cublas_nrm2(Nr2*Nc2, d_coeffs[0], 1); res += tmp*tmp; return res; } /// Method : L1 norm DTYPE Wavelets::norm1(void) { DTYPE res = 0.0f; int Nr2 = winfos.Nr; int Nc2 = winfos.Nc; for (int i = 0; i < winfos.nlevels; i++) { if (!winfos.do_swt) { if (winfos.ndims > 1) w_div2(&Nr2); w_div2(&Nc2); } if (winfos.ndims == 2) { // 2D res += cublas_asum(Nr2*Nc2, d_coeffs[3*i+1], 1); res += cublas_asum(Nr2*Nc2, d_coeffs[3*i+2], 1); res += cublas_asum(Nr2*Nc2, d_coeffs[3*i+3], 1); } else { // 1D res += cublas_asum(Nr2*Nc2, d_coeffs[i+1], 1); } } res += cublas_asum(Nr2*Nc2, d_coeffs[0], 1); return res; } /// Method : get the image from device int Wavelets::get_image(DTYPE* res) { // TODO: more defensive cudaMemcpy(res, d_image, winfos.Nr*winfos.Nc*sizeof(DTYPE), cudaMemcpyDeviceToHost); return winfos.Nr*winfos.Nc; } /// Method : set the class image void Wavelets::set_image(DTYPE* img, int mem_is_on_device) { // There are no memory check ! cudaMemcpyKind copykind; if (mem_is_on_device) copykind = cudaMemcpyDeviceToDevice; else copykind = cudaMemcpyHostToDevice; cudaMemcpy(d_image, img, winfos.Nr*winfos.Nc*sizeof(DTYPE), copykind); state = W_INIT; } /// Method : set a coefficient void Wavelets::set_coeff(DTYPE* coeff, int num, int mem_is_on_device) { // There are no memory check ! cudaMemcpyKind copykind; if (mem_is_on_device) copykind = cudaMemcpyDeviceToDevice; else copykind = cudaMemcpyHostToDevice; int Nr2 = winfos.Nr, Nc2 = winfos.Nc; if (winfos.ndims == 2) { // In 2D, num stands for the following: // A H1 V1 D1 H2 V2 D2 // 0 1 2 3 4 5 6 // for num>0, 1+(num-1)/3 tells the scale number int scale; if (num == 0) scale = winfos.nlevels; else scale = ((num-1)/3) +1; if (!winfos.do_swt) for (int i = 0; i < scale; i++) { w_div2(&Nr2); w_div2(&Nc2); } } else if (winfos.ndims == 1) { // In 1D, num stands for the following: // A D1 D2 D3 // 0 1 2 3 int scale; if (num == 0) scale = winfos.nlevels; else scale = num; if (!winfos.do_swt) for (int i = 0; i < scale; i++) { w_div2(&Nc2); } } cudaMemcpy(d_coeffs[num], coeff, Nr2*Nc2*sizeof(DTYPE), copykind); //~ state = W_FORWARD; // ? } /// Method : get a coefficient vector from device int Wavelets::get_coeff(DTYPE* coeff, int num) { if (state == W_INVERSE) { puts("Warning: get_coeff(): inverse() has been performed, the coefficients has been modified and do not make sense anymore."); return 0; } int Nr2 = winfos.Nr, Nc2 = winfos.Nc; if (winfos.ndims == 2) { // In 2D, num stands for the following: // A H1 V1 D1 H2 V2 D2 // 0 1 2 3 4 5 6 // for num>0, 1+(num-1)/3 tells the scale number int scale; if (num == 0) scale = winfos.nlevels; else scale = ((num-1)/3) +1; if (!winfos.do_swt) for (int i = 0; i < scale; i++) { w_div2(&Nr2); w_div2(&Nc2); } } else if (winfos.ndims == 1) { // In 1D, num stands for the following: // A D1 D2 D3 // 0 1 2 3 int scale; if (num == 0) scale = winfos.nlevels; else scale = num; if (!winfos.do_swt) for (int i = 0; i < scale; i++) { w_div2(&Nc2); } } //~ printf("Retrieving %d (%d x %d)\n", num, Nr2, Nc2); cudaMemcpy(coeff, d_coeffs[num], Nr2*Nc2*sizeof(DTYPE), cudaMemcpyDeviceToHost); //TODO: handle DeviceToDevice ? return Nr2*Nc2; } /// Method : give some informations on the wavelet void Wavelets::print_informations() { const char* state[2] = {"no", "yes"}; puts("------------- Wavelet transform infos ------------"); printf("Data dimensions : "); if (winfos.ndims == 2) printf("(%d, %d)\n", winfos.Nr, winfos.Nc); else { // 1D if (winfos.Nr == 1) printf("%d\n", winfos.Nc); else printf("(%d, %d) [batched 1D transform]\n", winfos.Nr, winfos.Nc); } printf("Wavelet name : %s\n", wname); printf("Number of levels : %d\n", winfos.nlevels); printf("Stationary WT : %s\n", state[winfos.do_swt]); printf("Cycle spinning : %s\n", state[do_cycle_spinning]); printf("Separable transform : %s\n", state[do_separable]); size_t mem_used = 0; if (!winfos.do_swt) { // DWT : size(output) = size(input), since sizes are halved at each level. // d_image (1), d_coeffs (1), d_tmp (2) mem_used = 5*winfos.Nr*winfos.Nc*sizeof(DTYPE); } else { // SWT : size(output) = size(input)*4*levels // d_image (1), d_coeffs (3*levels+1), d_tmp (2) if (winfos.ndims == 2) mem_used = (3*winfos.nlevels+4)*winfos.Nr*winfos.Nc*sizeof(DTYPE); else mem_used = (winfos.nlevels+4)*winfos.Nr*winfos.Nc*sizeof(DTYPE); } printf("Estimated memory footprint : %.2f MB\n", mem_used/1e6); int device; cudaGetDevice(&device); cudaDeviceProp properties; cudaGetDeviceProperties(&properties, device); char* device_name = strdup(properties.name); printf("Running on device : %s\n", device_name); free(device_name); puts("--------------------------------------------------"); } /// Provide a custom filter bank to the current Wavelet instance. /// If do_separable = 1, the filters are expected to be L, H. /// Otherwise, the filters are expected to be A, H, V, D (square size) // We cannot directly use the __constant__ symbols (unless with separate compilation), // hence a further indirection in (non)separable.cu where these symbols are defined int Wavelets::set_filters_forward(char* filtername, uint len, DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4) { int res = 0; if (len > MAX_FILTER_WIDTH) { printf("ERROR: Wavelets.set_filters_forward(): filter length (%d) exceeds the maximum size (%d)\n", len, MAX_FILTER_WIDTH); return -1; } if (do_separable) { res = w_set_filters_forward(filter1, filter2, len); } else { if (filter3 == NULL || filter4 == NULL) { puts("ERROR: Wavelets.set_filters_forward(): expected argument 4 and 5 for non-separable filtering"); return -2; } res = w_set_filters_forward_nonseparable(filter1, filter2, filter3, filter4, len); } winfos.hlen = len; strncpy(wname, filtername, 128); return res; } /// Here the filters are assumed to be of the same size of those provided to set_filters_forward() // We cannot directly use the __constant__ symbols (unless with separate compilation), // hence a further indirection in (non)separable.cu where these symbols are defined int Wavelets::set_filters_inverse(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3, DTYPE* filter4) { uint len = winfos.hlen; int res = 0; if (do_separable) { // ignoring args 4 and 5 res = w_set_filters_inverse(filter1, filter2, len); } else { if (filter3 == NULL || filter4 == NULL) { puts("ERROR: Wavelets.set_filters_inverse(): expected argument 4 and 5 for non-separable filtering"); return -2; } // The same symbols are used for the inverse filters res = w_set_filters_inverse_nonseparable(filter1, filter2, filter3, filter4, len); } return res; } /// ---------------------------------------------------------------------------- /// --------- Operators... for now I am not considering overloading ----------- /// ---------------------------------------------------------------------------- /** * \brief In-place addition of wavelets coefficients * * For a given instance "Wav" of the class Wavelets, it performs * Wav += W. Only the wavelets coefficients are added, the image attribute * is not replaced * * * \param W : Wavelets class instance * \return 0 if no error * */ int Wavelets::add_wavelet(Wavelets W, DTYPE alpha) { // Various checks if ((winfos.nlevels != W.winfos.nlevels) || (strcasecmp(wname, W.wname))) { puts("ERROR: add_wavelet(): right operand is not the same transform (wname, level)"); return -1; } if (state == W_INVERSE || W.state == W_INVERSE) { puts("WARNING: add_wavelet(): this operation makes no sense when wavelet has just been inverted"); return 1; } if (winfos.Nr != W.winfos.Nr || winfos.Nc != W.winfos.Nc || winfos.ndims != W.winfos.ndims) { puts("ERROR: add_wavelet(): operands do not have the same geometry"); return -2; } if ((winfos.do_swt) ^ (W.winfos.do_swt)) { puts("ERROR: add_wavelet(): operands should both use SWT or DWT"); return -3; } if ( (do_cycle_spinning * W.do_cycle_spinning) && ( (current_shift_r != W.current_shift_r) || (current_shift_c != W.current_shift_c) ) ) { puts("ERROR: add_wavelet(): operands do not have the same current shift"); return -4; } if (winfos.ndims == 1) w_add_coeffs_1d(d_coeffs, W.d_coeffs, winfos, alpha); else w_add_coeffs(d_coeffs, W.d_coeffs, winfos, alpha); return 0; } /// Return the memory pointer (unsigned int64) of the device image __intptr_t Wavelets::image_int_ptr(void) { return (__intptr_t) d_image; } /// Return the memory pointer (unsigned int64) of the device coefficient. __intptr_t Wavelets::coeff_int_ptr(int num) { return (__intptr_t) d_coeffs[num]; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/pdwt/src/wt.h0000644000175000017500000000640300000000000015123 0ustar00pierrepierre#ifndef WT_H #define WT_H #include "utils.h" // Possible states of the Wavelet class. // It prevents, for example, W.inverse() from being run twice (since W.d_coeffs[0] is modified) typedef enum w_state { W_INIT, // The class has just been initialized (coeffs not computed) W_FORWARD, // W.forward() has just been performed (coeffs computed) W_INVERSE, // W.inverse() has just been performed (d_image modified, coeffs modified !) W_THRESHOLD, // The coefficients have been modified W_CREATION_ERROR, // Error when creating the Wavelets instance W_FORWARD_ERROR, // Error when computing the forward transform W_INVERSE_ERROR, // Error when computing the inverse transform W_THRESHOLD_ERROR // Error when thresholding the coefficients } w_state; class Wavelets { public: // Members // -------- DTYPE* d_image; // Image (input or result of reconstruction), on device DTYPE** d_coeffs; // Wavelet coefficients, on device DTYPE* d_tmp; // Temporary device array (to avoid multiple malloc/free) int current_shift_r; int current_shift_c; char wname[128]; // Wavelet name int do_separable; // 1 if performing separable WT int do_cycle_spinning; // Do image shifting for approximate TI denoising w_info winfos; w_state state; // Operations // ----------- // Default constructor Wavelets(); // Constructor : Wavelets from image Wavelets(DTYPE* img, int Nr, int Nc, const char* wname, int levels, int memisonhost=1, int do_separable=1, int do_cycle_spinning=0, int do_swt=0, int ndim=2); // Constructor: copy Wavelets(const Wavelets &W);// Pass by non-const reference ONLY if the function will modify the parameter and it is the intent to change the caller's copy of the data // Constructor : Wavelets from coeffs //~ Wavelets(DTYPE** d_thecoeffs, int Nr, int Nc, const char* wname, int levels, int do_cycle_spinning); // Destructor ~Wavelets(); // Assignment (copy assignment constructor) // do not use ! // Wavelets& operator=(const Wavelets &rhs); // Methods // ------- void forward(); void soft_threshold(DTYPE beta, int do_thresh_appcoeffs = 0, int normalize = 0); void hard_threshold(DTYPE beta, int do_thresh_appcoeffs = 0, int normalize = 0); void group_soft_threshold(DTYPE beta, int do_thresh_appcoeffs = 0, int normalize = 0); void shrink(DTYPE beta, int do_thresh_appcoeffs = 1); void proj_linf(DTYPE beta, int do_thresh_appcoeffs = 1); void circshift(int sr, int sc, int inplace = 1); void inverse(); DTYPE norm2sq(); DTYPE norm1(); int get_image(DTYPE* img); void print_informations(); int get_coeff(DTYPE* coeff, int num); void set_image(DTYPE* img, int mem_is_on_device = 0); void set_coeff(DTYPE* coeff, int num, int mem_is_on_device = 0); int set_filters_forward(char* filtername, uint len, DTYPE* filter1, DTYPE* filter2, DTYPE* filter3 = NULL, DTYPE* filter4 = NULL); int set_filters_inverse(DTYPE* filter1, DTYPE* filter2, DTYPE* filter3 = NULL, DTYPE* filter4 = NULL); int add_wavelet(Wavelets W, DTYPE alpha=1.0f); __intptr_t image_int_ptr(void); __intptr_t coeff_int_ptr(int num); }; #endif ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/pycudwt.egg-info/0000755000175000017500000000000000000000000015741 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/PKG-INFO0000644000175000017500000000050700000000000017040 0ustar00pierrepierreMetadata-Version: 2.1 Name: pycudwt Version: 1.0.2 Summary: UNKNOWN Home-page: UNKNOWN Author: Pierre Paleo Author-email: pierre.paleo@esrf.fr Maintainer: Pierre Paleo Maintainer-email: pierre.paleo@esrf.fr License: UNKNOWN Platform: UNKNOWN License-File: LICENSE Python Wrapper for Cuda Discrete Wavelet Transform ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/SOURCES.txt0000644000175000017500000000116300000000000017626 0ustar00pierrepierreLICENSE MANIFEST.in README.md pyproject.toml setup.py pdwt/src/common.cu pdwt/src/common.h pdwt/src/filters.cpp pdwt/src/filters.h pdwt/src/haar.cu pdwt/src/haar.h pdwt/src/io.h pdwt/src/nonseparable.cu pdwt/src/nonseparable.h pdwt/src/separable.cu pdwt/src/separable.h pdwt/src/utils.cu pdwt/src/utils.h pdwt/src/wt.cu pdwt/src/wt.h pycudwt.egg-info/PKG-INFO pycudwt.egg-info/SOURCES.txt pycudwt.egg-info/dependency_links.txt pycudwt.egg-info/not-zip-safe pycudwt.egg-info/requires.txt pycudwt.egg-info/top_level.txt src/pypwt.pyx test/test_all.py test/test_single.py test/test_sizes.py test/test_wavelets.py test/testutils.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/dependency_links.txt0000644000175000017500000000000100000000000022007 0ustar00pierrepierre ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/not-zip-safe0000644000175000017500000000000100000000000020167 0ustar00pierrepierre ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/requires.txt0000644000175000017500000000000600000000000020335 0ustar00pierrepierrenumpy ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061560.0 pycudwt-1.0.2/pycudwt.egg-info/top_level.txt0000644000175000017500000000001000000000000020462 0ustar00pierrepierrepycudwt ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061329.0 pycudwt-1.0.2/pyproject.toml0000644000175000017500000000017700000000000015471 0ustar00pierrepierre[build-system] requires = [ "wheel", "setuptools", "numpy", "cython" ] build-backend = "setuptools.build_meta" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/setup.cfg0000644000175000017500000000004600000000000014371 0ustar00pierrepierre[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061378.0 pycudwt-1.0.2/setup.py0000755000175000017500000002107700000000000014274 0ustar00pierrepierre#!/usr/bin/env python # ------------------------------------------------------------------------------ # --------------------------- setup.py ----------------------------------------- # Copyright (c) 2014, Robert T. McGibbon and the Authors # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ------------------------------------------------------------------------------ import os from os.path import join as pjoin from setuptools import setup from distutils.extension import Extension from Cython.Distutils import build_ext import subprocess import numpy def find_in_path(name, path): "Find a file in a search path" # adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/ for dir in path.split(os.pathsep): binpath = pjoin(dir, name) if os.path.exists(binpath): return os.path.abspath(binpath) return None def locate_cuda(): """Locate the CUDA environment on the system Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64' and values giving the absolute path to each directory. Starts by looking for the CUDAHOME env variable. If not found, everything is based on finding 'nvcc' in the PATH. """ # first check if the CUDAHOME env variable is in use if "CUDAHOME" in os.environ: home = os.environ["CUDAHOME"] nvcc = pjoin(home, "bin", "nvcc") else: # otherwise, search the PATH for NVCC nvcc = find_in_path("nvcc", os.environ["PATH"]) if nvcc is None: raise EnvironmentError( "The nvcc binary could not be " "located in your $PATH. Either add it to your path, or set $CUDAHOME" ) home = os.path.dirname(os.path.dirname(nvcc)) cudaconfig = { "home": home, "nvcc": nvcc, "include": pjoin(home, "include"), # ~ 'lib64': "/usr/lib/x86_64-linux-gnu/" } # ~ cudaconfig = {'home':home, 'nvcc':nvcc, # ~ 'include': pjoin(home, 'include'), # ~ 'lib64': pjoin(home, 'lib64')} for k, v in cudaconfig.items(): # iteritems(): if not os.path.exists(v): raise EnvironmentError("The CUDA %s path could not be located in %s" % (k, v)) return cudaconfig CUDA = locate_cuda() # Obtain the numpy include directory. This logic works across numpy versions. try: numpy_include = numpy.get_include() except AttributeError: numpy_include = numpy.get_numpy_include() nvcc_compile_args = ["--ptxas-options=-v", "-c", "--compiler-options", "'-fPIC'"] compute_cap = os.environ.get("PYCUDWT_CC", None) if compute_cap is not None: nvcc_compile_args.append("-arch=compute_%s" % compute_cap) nvcc_compile_args.append("-code=sm_%s" % compute_cap) ext = Extension( "pycudwt", sources=[ "pdwt/src/wt.cu", "pdwt/src/common.cu", "pdwt/src/utils.cu", "pdwt/src/separable.cu", "pdwt/src/nonseparable.cu", "pdwt/src/haar.cu", "pdwt/src/filters.cpp", "src/pypwt.pyx", ], # ~ library_dirs=[CUDA['lib64']], libraries=["cudart", "cublas"], language="c++", # ~ runtime_library_dirs=[CUDA['lib64']], # this syntax is specific to this build system # we're only going to use certain compiler args with nvcc and not with gcc # the implementation of this trick is in customize_compiler() below extra_compile_args={ "gcc": [], "nvcc": nvcc_compile_args, }, include_dirs=[numpy_include, CUDA["include"], "src"], ) def customize_compiler_for_nvcc(self): """inject deep into distutils to customize how the dispatch to gcc/nvcc works. If you subclass UnixCCompiler, it's not trivial to get your subclass injected in, and still have the right customizations (i.e. distutils.sysconfig.customize_compiler) run on it. So instead of going the OO route, I have this. Note, it's kindof like a wierd functional subclassing going on.""" # tell the compiler it can processes .cu self.src_extensions.append(".cu") # save references to the default compiler_so and _comple methods default_compiler_so = self.compiler_so super = self._compile # now redefine the _compile method. This gets executed for each # object but distutils doesn't have the ability to change compilers # based on source extension: we add it. def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts): if os.path.splitext(src)[1] == ".cu": ######## # use the cuda for .cu files self.set_executable("compiler_so", CUDA["nvcc"]) # ~ self.set_executable('linker_so', CUDA['nvcc']) # use only a subset of the extra_postargs, which are 1-1 translated # from the extra_compile_args in the Extension class postargs = extra_postargs["nvcc"] else: postargs = extra_postargs["gcc"] # ~ self.set_executable('linker_so', CUDA['nvcc']) # TEST super(obj, src, ext, cc_args, postargs, pp_opts) # reset the default compiler_so, which we might have changed for cuda self.compiler_so = default_compiler_so # inject our redefined _compile method into the class self._compile = _compile def customize_linker_for_nvcc(self): """ Same as customize_compiler_for_nvcc, but for linker """ # tell the compiler it can processes .cu self.src_extensions.append(".cu") # save references to the default compiler_so and _comple methods default_linker_so = self.linker_so super = self.link # now redefine the link method. def _link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): self.set_executable("linker_so", CUDA["nvcc"]) # use only a subset of the extra_postargs, which are 1-1 translated # from the extra_compile_args in the Extension class postargs = extra_postargs["nvcc"] super( target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ) # reset the default likner_so, which we might have changed for cuda self.linker_so = default_linker_so # inject our redefined _compile method into the class self.link = _link # run the customize_compiler class custom_build_ext(build_ext): def build_extensions(self): customize_compiler_for_nvcc(self.compiler) build_ext.build_extensions(self) setup( name="pycudwt", author="Pierre Paleo", version="1.0.2", author_email="pierre.paleo@esrf.fr", maintainer="Pierre Paleo", maintainer_email="pierre.paleo@esrf.fr", install_requires=["numpy"], long_description=""" Python Wrapper for Cuda Discrete Wavelet Transform """, ext_modules=[ext], # inject our custom trigger cmdclass={"build_ext": custom_build_ext}, # since the package has c code, the egg cannot be zipped zip_safe=False, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/src/0000755000175000017500000000000000000000000013337 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1686061409.0 pycudwt-1.0.2/src/pypwt.pyx0000644000175000017500000004217300000000000015273 0ustar00pierrepierreimport numpy as np cimport numpy as np assert sizeof(int) == sizeof(np.int32_t) from copy import deepcopy from libc.stdint cimport intptr_t cdef extern from "../pdwt/src/wt.h": ctypedef struct w_info: int ndims int Nr int Nc int nlevels int do_swt int hlen ctypedef enum w_state: W_INIT, # The class has just been initialized (coeffs not computed) W_FORWARD, # W.forward() has just been performed (coeffs computed) W_INVERSE, # W.inverse() has just been performed (d_image modified, coeffs modified !) W_THRESHOLD, # The coefficients have been modified W_CREATION_ERROR, # Error when creating the Wavelets instance W_FORWARD_ERROR, # Error when computing the forward transform W_INVERSE_ERROR, # Error when computing the inverse transform W_THRESHOLD_ERROR # Error when thresholding the coefficients cdef cppclass C_Wavelets "Wavelets": # C++ attributes should be declared here if we want to access them # ----------------------------------------------------------------- int do_cycle_spinning int do_separable w_info winfos w_state state # Methods # ------- C_Wavelets() # Wavelets(float* img, int Nr, int Nc, const char* wname, int levels, int memisonhost=1, int do_separable = 1, int do_cycle_spinning = 0, int do_swt = 0, int ndim = 2); C_Wavelets(float*, int, int, const char*, int, int, int, int, int, int) C_Wavelets(C_Wavelets) # copy constructor void forward() void soft_threshold(float, int, int) void hard_threshold(float, int, int) void shrink(float, int) void circshift(int, int, int) void inverse() float norm2sq() float norm1() int get_image(float*) void print_informations() int get_coeff(float*, int) void set_image(float*, int) void set_coeff(float*, int, int) int add_wavelet(C_Wavelets, float) intptr_t image_int_ptr() intptr_t coeff_int_ptr(int) cdef class Wavelets: """ Initializes the Wavelet transform from an image and given parameters. img: 2D numpy.ndarray, float32 Input image wname: string Name of the wavelet levels: int Number of decomposition levels do_separable: int if not 0, perform a separable transform do_cycle_spinning: int if not 0, perform a random shift on the image (useful for iterative algorithms) do_swt: int if not 0, perform a Stationary (non-decimated) wavelet transform """ # Attributes in cdef classes behave differently from attributes in regular classes: # - All attributes must be pre-declared at compile-time # - Attributes are by default only accessible from Cython (typed access) # - Properties can be declared to expose dynamic attributes to Python-space # The attributes may be Python objects (either generic or of a particular extension type), # or they may be of any C data type. So you can use extension types to wrap arbitrary # C data structures and provide a Python-like interface to them. # By default, extension type attributes are only accessible by direct access, # not Python access, which means that they are not accessible from Python code. # To make them accessible from Python code, you need to declare them as public or readonly. cdef C_Wavelets* w # pointer to the C Wavelet object cdef readonly int Nr cdef readonly int Nc cdef readonly list sizes cdef readonly char* _wname cdef readonly str wname cdef readonly int levels cdef readonly int do_cycle_spinning cdef int hlen cdef readonly int do_swt cdef readonly int do_separable cdef readonly int ndim cdef list _coeffs cdef tuple shape cdef readonly int batched1d def __cinit__(self, np.ndarray img, str wname, int levels, int do_separable = 1, int do_cycle_spinning = 0, int do_swt = 0, int ndim = 2, Wavelets copy = None ): """ cdef C_Wavelets _w# cdef statement is only allowed here if copy: # Wavelets instanciated from another class _w = (copy.w)[0] self.w = new C_Wavelets(_w) # Call the C++ copy constructor # Now, copy the other attributes self.wname = copy.wname self._wname = copy._wname self.levels = copy.levels self.hlen = copy.hlen self.do_separable = copy.do_separable self.do_cycle_spinning = copy.do_cycle_spinning self.do_swt = copy.do_swt self.ndim = copy.ndim self.Nr, self.Nc = copy.Nr, copy.Nc self.shape = copy.shape self.batched1d = copy.batched1d self._coeffs = deepcopy(copy._coeffs) return """ img = self._checkarray(img) ndim = min(ndim, 2) # tmp fix # We can have ndim != img.ndim, which means batched 1D transform self.batched1d = 0 if img.ndim == 2: self.Nr = img.shape[0] self.Nc = img.shape[1] if (img.ndim != ndim): self.batched1d = 1 elif img.ndim == 1: # For 1D, make Nr = 1 and Nc = img.shape[0] for a contiguous C array self.Nr = 1 self.Nc = img.shape[0] else: raise NotImplementedError("Wavelets(): Only 1D and 2D transforms are supported for now") # for ND # FIXME: the "ndim" mechanism is not clear, as self.ndim ends up with "2" for batched transform shp = [] for i in range(img.ndim): shp.append(img.shape[i]) self.shape = tuple(shp) self.wname = wname py_wname = wname.encode("ASCII") # python variable keeps the reference cdef char* c_wname = py_wname self._wname = c_wname self.levels = levels self.do_separable = do_separable self.do_cycle_spinning = do_cycle_spinning self.do_swt = do_swt self.ndim = img.ndim # Build the C++ Wavelet object self.w = new C_Wavelets( np.PyArray_DATA(img), self.Nr, self.Nc, self._wname, self.levels, 1, self.do_separable, self.do_cycle_spinning, self.do_swt, ndim) # Retrieve the possibly updated attributes after the C++ initialization self.levels = self.w.winfos.nlevels self.hlen = self.w.winfos.hlen self.do_separable = self.w.do_separable # Image size at each level self.sizes = self._compute_sizes() # Initialize the python coefficients # for 2D : [A, [H1, V1, D1], [H2, V2, D2], ... ] # for 1D : [A, D1, ... Dn] # ------------------------------------------------ self._coeffs = [] # App coeff self._coeffs.append(np.zeros(self.sizes[-1], dtype=np.float32)) # Det coeffs for i in range(self.levels): # 1D if (self.ndim < 2) or (self.batched1d): self._coeffs.append(np.zeros((self.sizes[i]), dtype=np.float32)) # 2D else: ahvd = [] for j in range(3): ahvd.append(np.zeros(self.sizes[i], dtype=np.float32)) self._coeffs.append(ahvd) def info(self): """ Print some information on the current ``Wavelets`` instance. """ self.w.print_informations() def __repr__(self): self.info() return "" def __str__(self): self.info() return "" @staticmethod def _checkarray(arr, shp=None): res = arr if arr.dtype != np.float32 or not(arr.flags["C_CONTIGUOUS"]): res = np.ascontiguousarray(arr, dtype=np.float32) if shp is not None: if arr.ndim != len(shp): raise ValueError("Invalid number of dimensions (expected %d, got %d)" % (len(shp), arr.ndim)) for i in range(arr.ndim): if arr.shape[i] != shp[i]: raise ValueError("The image does not have the correct shape (expected %s, got %s)" % (str(shp), str(arr.shape))) return res @staticmethod def div2(n): """ Returns (N + (N%2))/2. This is used for the computation of the image size at each scale. """ return (n + (n & 1))//2 def _compute_sizes(self): Nr = self.Nr Nc = self.Nc if self.do_swt: # no subsampling return [(Nr, Nc)]*self.levels res = [] for i in range(self.levels): Nc = self.div2(Nc) if not(self.batched1d): Nr = self.div2(Nr) res.append((Nr, Nc)) return res def coeff_only(self, int num): """ Get only the coeff "num" from the C++ class instance. You should use it if you know that you will access only one coeff, since this is faster than coeff[level][k] num : int Number of the coefficient. The indexing is as follows : 2D : [0: A, 1: H1, 2: V1, 3: D1, 4: H2, ...] 1D : [0: A, 1: D1, 2: D2, ...] """ if num == 0: coeff_ref = self._coeffs[0] else: if (self.ndim == 2) and not(self.batched1d): curr_level = (num-1)//3 +1 curr_coeff = (num-1)%3 coeff_ref = self._coeffs[curr_level][curr_coeff] else: # (batched) 1D coeff_ref = self._coeffs[num] c_dstbuf = np.PyArray_DATA(coeff_ref) numc = self.w.get_coeff(c_dstbuf, num) if numc != coeff_ref.size: raise RuntimeError("Wavelets.coeff_only(): something went wrong when retrieving coefficients numbef %d, expected %d coeffs, got %d" % (num, coeff_ref.size, numc)) return coeff_ref @property def coeffs(self): """ Get all the coefficients from the C++ class instance Returns the following list : [A, [H1, V1, D1], [H2, V2, D2], ...] Note: using coeffs[0] is slower than coeff_only(0), since calling coeff() copies all the coefficients from the device """ self.coeff_only(0) if self.ndim == 2 and not(self.batched1d): i_end = 3*self.levels else: # 1D i_end = self.levels for cnt in range(1, i_end + 1): self.coeff_only(cnt) return self._coeffs @property def image(self): res = np.zeros((self.Nr, self.Nc), dtype=np.float32) c_dstbuf = np.PyArray_DATA(res) numc = self.w.get_image(c_dstbuf) if numc != res.size: raise RuntimeError("Wavelets.image(): something went wrong when retrieving image, expected %d coeffs, got %d" % (res.size, numc)) return res #~ @image.setter # Not working in cython (?) def set_image(self, img): """ Modifies the image of the wavelet class. img: numpy.ndarray Provided image. The dimensions have to be consistent with the current ``Wavelets`` instance. **Note**: it does not update the coefficients. You have to perform ``Wavelets.forward()`` to update the coefficients. """ img = self._checkarray(img, (self.Nr, self.Nc)) self.w.set_image( np.PyArray_DATA(img), 0) def forward(self, img = None): """ Performs the foward wavelet transform with the current configuration. img: numpy.ndarray Optionnal. If an image is provided, the transform is performed on this image. Otherwise, the transform is performed on ``Wavelets.image`` """ if img is not None: img = self._checkarray(img, self.shape) self.w.set_image( np.PyArray_DATA(img), 0) self.w.forward() def inverse(self): """ Invert the wavelet transform with the current configuration. It Transforms back the coefficients ``Wavelets.coeffs`` to an image. **Note**: The inverse function modifies the coefficients. This means that performing ``Wavelets.inverse()`` twice leads to an inconsistent result. The underlying library prevents any further usage of ``Wavelets.coeffs`` (including ``Wavelets.inverse()``) once ``Wavelets.inverse()`` has been performed once. This mechanism is reset as soon as ``Wavelets.forward()`` is performed. """ self.w.inverse() def soft_threshold(self, float beta, int do_threshold_appcoeffs = 0, int normalize = 0): """ Soft threshold the wavelets coefficients. The soft thresholding is defined by .. math:: \\text{ST}(x, t) = (|x| - t)_+ \\cdot \\text{sign}(x) This is the proximal operator of beta * L1 norm. beta: float threshold factor do_threshold_appcoeffs : int, optional (default is 0) if not 0, the approximation coefficients will also be thresholded normalize: int, optional (default is 0) If set, the threshold is divided by sqrt(2) at each scale """ cdef float c_beta = beta cdef int c_dt = do_threshold_appcoeffs cdef int c_n = normalize self.w.soft_threshold(c_beta, c_dt, c_n) def hard_threshold(self, float beta, int do_threshold_appcoeffs = 0, int normalize = 0): """ Hard threshold the wavelets coefficients. The hard thresholding is defined by .. math:: \\text{HT}(x, t) = x \\cdot 1_{|x| > t} beta: float threshold factor do_threshold_appcoeffs : int if not 0, the approximation coefficients will also be thresholded """ cdef float c_beta = beta cdef int c_dt = do_threshold_appcoeffs cdef int c_n = normalize self.w.hard_threshold(c_beta, c_dt, c_n) def shrink(self, float beta, int do_threshold_appcoeffs = 1): """ Shrink the wavelets coefficients. The shrink is defined by .. math:: \\text{shrink}(x, t) = \\frac{x}{1+t} This is the proximal operator of beta * L2 norm. beta: float shrink factor do_threshold_appcoeffs : int if not 0, the approximation coefficients will also be shrunk. """ cdef float c_beta = beta cdef int c_dt = do_threshold_appcoeffs self.w.shrink(c_beta, c_dt) def norm1(self): """ Returns the L1 norm of the Wavelets coefficients : .. math:: \\left\\| w \\right\\|_1 = \\sum_i |w_i| """ return self.w.norm1() def norm2sq(self): """ Returns the squared L2 norm of the Wavelets coefficients : .. math:: \\left\\| w \\right\\|_2^2 = \\sum_i |w_i|^2 """ return self.w.norm2sq() def add_wavelet(self, Wavelets W, alpha=1.0): """ Adds wavelets coefficients to the current wavelets coefficients. W: Wavelets instance alpha: coefficient multiplying the coefficients of W (optional, default is 1) """ cdef float c_alpha = alpha self.w.add_wavelet((W.w)[0], c_alpha) def set_coeff(self, coeff, num, check=False): """ Sets the Wavelet coefficient "num". See coeff_only() documentation for more information on how "num" is linked to the coefficients. coeff: numpy.ndarray 2D array containing the coefficient num: int number of the coefficient check: bool if True, the size of the provided coefficient is checked against the target. This implies an extra device->host memory transfer. """ coeff = self._checkarray(coeff) # TODO: more elegant way for checking correct shape if check: dcoeff = self.coeff_only(num) if dcoeff.shape[0] != coeff.shape[0] or dcoeff.shape[1] != coeff.shape[1]: raise ValueError("set_coefInvalid coefficient shape : expected %s, got %s" % (str(dcoeff.shape), str(coeff.shape))) self.w.set_coeff( np.PyArray_DATA(coeff), num, 0) def image_int_ptr(self): """ Return the address (unsigned int64) of the device image. """ return self.w.image_int_ptr() def coeff_int_ptr(self, num): """ Return the address (unsigned int64) of a device coefficient. num: int Number of the coefficient """ return self.w.coeff_int_ptr(num) def __dealloc__(self): """ Destructor """ self.cleanup() def cleanup(self): # should not be called manually if self.w is not NULL: del self.w self.w = NULL @classmethod def version(cls): """ Return the current version of the pypwt library This mechanism is not so elegant and will be replaced in the future """ return "1.0.2" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1686061560.2791889 pycudwt-1.0.2/test/0000755000175000017500000000000000000000000013527 5ustar00pierrepierre././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/test/test_all.py0000644000175000017500000000334400000000000015714 0ustar00pierrepierre#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2015 Pierre Paleo # License: BSD # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of ESRF nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import unittest from test_wavelets import test_all def run(): mysuite = test_all() runner = unittest.TextTestRunner() if not runner.run(mysuite).wasSuccessful(): exit(1) if __name__ == '__main__': run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/test/test_single.py0000644000175000017500000000433600000000000016427 0ustar00pierrepierre#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2015 Pierre Paleo # License: BSD # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of ESRF nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import unittest from testutils import scipy_img from test_wavelets import test_wavelet def run(): # You can customize the input data/levels in the following lines data = scipy_img levels = 5#8 # You can customize what test is performed by modifying the value of "what" #what = "dwt2" #what = "idwt2" #what = "swt2" #what = "iswt2" #what = "dwt" #what = "dwt_batched" #what = "idwt" #what = "idwt_batched" #what = "swt" what = "swt_batched" #what = "iswt" #what = "iswt_batched" mysuite = test_wavelet(what, data, levels) runner = unittest.TextTestRunner() if not runner.run(mysuite).wasSuccessful(): exit(1) if __name__ == '__main__': run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/test/test_sizes.py0000644000175000017500000000502400000000000016276 0ustar00pierrepierre#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2015 Pierre Paleo # License: BSD # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of ESRF nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import numpy as np import unittest from testutils import scipy_img, create_data_to_good_size from test_wavelets import test_wavelet def run(): # You can customize the following # ----------------------------------- data = scipy_img data_sizes = [ (128, 128), (256, 256), (512, 512), (1024, 1024), (2048, 2048), #(4096, 4096), ] levels = 999 # will be cliped to max possible level wname = "db20" what = "dwt" # ----------------------------------- testSuite = unittest.TestSuite() for size in data_sizes: data_curr = create_data_to_good_size(data, size) # Make sure to use contiguous array for benchmarking if not(data_curr.flags["C_CONTIGUOUS"]): data_curr = np.ascontiguousarray(data_curr) testSuite.addTest(test_wavelet(what, data_curr, levels=levels, wname=wname)) runner = unittest.TextTestRunner() if not runner.run(testSuite).wasSuccessful(): exit(1) if __name__ == '__main__': run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/test/test_wavelets.py0000644000175000017500000005745500000000000017012 0ustar00pierrepierre#!/usr/bin/env python # -*- coding: utf-8 -*- # TODO: # - "pywt" vs "PyWavelets" # - [OK] Legacy: support pywt # - Take PyWavelets new swt order into account import sys import unittest import logging import numpy as np from time import time from copy import deepcopy from testutils import available_filters, scipy_img try: import pywt except ImportError: print("ERROR : could not find the python module pywt") sys.exit(1) try: from pypwt import Wavelets except ImportError: print("ERROR: could not load pypwt. Make sure it is installed (python setup.py install --user)") sys.exit(1) # Version <= 0.5 of PyWavelets uses the word "periodization" # for the dwt extension mode, instead of "per" for nigma/pywt version. # These are not compatibible for now. try: pywt_ver_full = pywt.version.full_version v = pywt_ver_full.split(".") pywt_ver = float(v[0]) + 10**-(len(v[1]))*float(v[1]) per_kw = "periodization" except AttributeError: # nigma/pywt per_kw = "per" pywt_ver = -1.0 pywt_ver_full = "?" # Uncomment for odd-size data # scipy_img = scipy_img[:511, :509] # Logging logging.basicConfig(filename='results.log', filemode='w', format='%(asctime)s %(levelname)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S', level=logging.DEBUG) # ----- def elapsed_ms(t0): return (time()-t0)*1e3 def _calc_errors(arr1, arr2, string=None): if string is None: string = "" maxerr = np.max(np.abs(arr1 - arr2)) msg = str("%s max error: %e" % (string, maxerr)) logging.info(msg) return maxerr # http://eli.thegreenplace.net/2011/08/02/python-unit-testing-parametrized-test-cases/ class ParametrizedTestCase(unittest.TestCase): """ TestCase classes that want to be parametrized should inherit from this class. """ def __init__(self, methodName='runTest', param=None): super(ParametrizedTestCase, self).__init__(methodName) self.param = param @staticmethod def parametrize(testcase_klass, param=None): """ Create a suite containing all tests taken from the given subclass, passing them the parameter 'param'. """ testloader = unittest.TestLoader() testnames = testloader.getTestCaseNames(testcase_klass) suite = unittest.TestSuite() for name in testnames: suite.addTest(testcase_klass(name, param=param)) return suite class TestWavelet(ParametrizedTestCase): def setUp(self): """ Set up the TestWavelet class with default parameters. """ # Maximum acceptable error wrt pywt for float32 precision. # As the transform are not scaled, the error increases with # the number of levels. Thus, self.tol is multiplied with 2**levels self.tol = 3e-4 self.data = scipy_img self.do_pywt = False # use pywt when testing reconstruction (for benchmarking) # Default arguments when testing only one wavelet self.wname = "haar" self.levels = 8 # Bind names to methods self.tests = { "dwt2": self.dwt2, "idwt2": self.idwt2, "swt2": self.swt2, "iswt2": self.iswt2, "dwt": self.dwt, "idwt": self.idwt, "swt": self.swt, "iswt": self.iswt, } self.W = None v_str = str("Using pypwt version %s and pywavelets version %s" % (Wavelets.version(), str(pywt_ver_full))) logging.info(v_str) def tearDown(self): # # This one is very important when running many tests. # For some reason, it looks like the reference to the Wavelets object # is not always updated, causing some errors. # This should be investigated further... # if self.W is not None: del self.W def test_wavelet(self): """ Method which is actually executed when the test in launched. An additional parameter can be passed: param=..., where: param[0]: wavelet name param[1]: number of levels param[2]: input data param[3]: what to do ("dwt2", "idwt2", "swt2", "iswt2", "dwt", "idwt", "swt", "iswt" param[4]: separable mode for pypwt (default is True) param[5]: test-dependent extra parameters """ if self.param is None: self.what = "dwt2" self.separable = 1 self.extra_args = None else: self.wname = self.param["wname"] self.levels = self.param["levels"] self.data = self.param["data"] self.what = self.param["what"] self.separable = self.param["separable"] self.extra_args = None if "extra" in self.param.keys(): self.extra_args = self.param["extra"] if "tol" in self.extra_args.keys(): self.tol = self.extra_args["tol"] if "do_pywt" in self.extra_args.keys() and bool(self.extra_args["do_pywt"]): self.do_pywt = True # batched WT is not available in nigma/pywt if pywt_ver < 0 and self.what in ["dwt", "idwt", "swt", "iswt"] and self.data.ndim > 1: self.skipTest("Skipping %s as batch is not supported in this version of pywt" % self.what) #FIXME: coefficients in PyWavelets are re-computed, which can lead to significant errors for coif5 if ("i" not in self.what) and (pywt_ver > 0 and pywt_ver <= 0.5) and (self.wname == "coif5"): self.skipTest("Skipping coif5 test for PyWavelets %s" %pywt_ver_full) #FIXME: big error for rbio3.1 if "i" in self.what and self.wname == "rbio3.1": self.skipTest("Skipping rbio3.1 inversion") # FIXME: big error for bior3.1 if "i" not in self.what and "swt" in self.what and self.wname == "bior3.1": self.skipTest("Skipping bior3.1 SWT") # Force an appropriate value for levels self.levels = min(self.levels, int(np.log2(min(self.data.shape)//pywt.Wavelet(self.wname).dec_len))) # Build the pywt Wavelet instance if "swt" in self.what: do_swt = 1 else: do_swt = 0 if "2" in self.what: ndim = 2 else: ndim = 1 self.W = Wavelets(self.data, self.wname, self.levels, do_separable=self.separable, do_swt=do_swt, ndim=ndim) # pywt/PyWavelets do not support odd-size SWT if "swt" in self.what: nope = 0 if (self.data.shape[0] & 1): nope = 1 if (self.W.ndim > 1): if (self.data.shape[1] & 1): nope = 1 if nope: if "i" in self.what: # Inversion test can be performed without pywt if self.extra_args is None: self.extra_args = {} self.extra_args["do_pywt"] = False else: # Forward transform must be run with pywt for comparisons self.skipTest("Skipping %s with data shape %s, as pywt does not support odd-sized SWT" % (self.what, str(self.data.shape))) # Run the test if self.what not in self.tests: raise ValueError("Unknown test %s" % self.what) isbatched = "batched" if self.W.batched1d else "" logging.info("Testing %s %s%s with %s, %d levels" % (isbatched, self.what, self.data.shape, self.wname, self.levels)) self.tests[self.what]() def dwt2(self): """ Test pypwt against pywt for DWT2 (wavedec2). """ W = self.W levels = self.levels wname = self.wname # Forward DWT2 with pypwt logging.info("computing Wavelets from pypwt") t0 = time() W.forward() logging.info("Wavelets.forward took %.3f ms" % elapsed_ms(t0)) # Forward DWT2 with pywt logging.info("computing wavedec2 from pywt") Wpy = pywt.wavedec2(self.data, self.wname, mode=per_kw, level=self.levels) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Compare results # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**levels W_coeffs = W.coeffs if (levels != W.levels): err_msg = str("compare_coeffs(): pypwt instance has %d levels while pywt instance has %d levels" % (W.levels, levels)) logging.error(err_msg) raise ValueError(err_msg) A = Wpy[0] maxerr = _calc_errors(A, W_coeffs[0], "[app]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the approximation coefficients (%d levels) (errmax = %e)" % (wname, levels, maxerr)) for i in range(levels): # wavedec2 format # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**(i+1) D1, D2, D3 = Wpy[levels-i][0], Wpy[levels-i][1], Wpy[levels-i][2] logging.info("%s Level %d %s" % ("-"*5, i+1, "-"*5)) maxerr = _calc_errors(D1, W_coeffs[i+1][0], "[det.H]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 1 at level %d (errmax = %e)" % (wname, i+1, maxerr)) maxerr = _calc_errors(D2, W_coeffs[i+1][1], "[det.V]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 2 at level %d (errmax = %e)" % (wname, i+1, maxerr)) maxerr = _calc_errors(D3, W_coeffs[i+1][2], "[det.D]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 3 at level %d (errmax = %e)" % (wname, i+1, maxerr)) def idwt2(self): """ Test pypwt for DWT reconstruction (waverec2). """ W = self.W levels = self.levels # inverse DWT with pypwt W.forward() logging.info("computing Wavelets.inverse from pypwt") t0 = time() W.inverse() logging.info("Wavelets.inverse took %.3f ms" % elapsed_ms(t0)) if self.do_pywt: # inverse DWT with pywt Wpy = pywt.wavedec2(self.data, self.wname, mode=per_kw, level=levels) logging.info("computing waverec2 from pywt") _ = pywt.waverec2(Wpy, self.wname, mode=per_kw) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Check reconstruction W_image = W.image maxerr = _calc_errors(self.data, W_image, "[rec]") self.assertTrue(maxerr < self.tol, msg="[%s] something wrong with the reconstruction (errmax = %e)" % (self.wname, maxerr)) def swt2(self): """ Test pypwt against pywt for SWT2. """ W = self.W levels = self.levels wname = self.wname # Forward SWT2 with pypwt logging.info("computing Wavelets from pypwt") t0 = time() W.forward() logging.info("Wavelets.forward took %.3f ms" % elapsed_ms(t0)) # Forward SWT2 with pywt logging.info("computing wavedec2 from pywt") Wpy = pywt.swt2(self.data, self.wname, level=levels) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Compare results # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**levels W_coeffs = W.coeffs if (levels != W.levels): err_msg = str("compare_coeffs(): pypwt instance has %d levels while pywt instance has %d levels" % (W.levels, levels)) logging.error(err_msg) raise ValueError(err_msg) # For now pypwt only returns the last appcoeff A = Wpy[levels-1][0] maxerr = _calc_errors(A, W_coeffs[0], "[app]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the approximation coefficients (%d levels) (errmax = %e)" % (wname, levels, maxerr)) for i in range(levels): # wavedec2 format. TODO: pywavelets > 0.5 will use another order tol = self.tol * 2**(i+1) A, D1, D2, D3 = Wpy[i][0], Wpy[i][1][0], Wpy[i][1][1], Wpy[i][1][2] logging.info("%s Level %d %s" % ("-"*5, i+1, "-"*5)) maxerr = _calc_errors(D1, W_coeffs[i+1][0], "[det.H]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 1 at level %d (errmax = %e)" % (wname, i+1, maxerr)) maxerr = _calc_errors(D2, W_coeffs[i+1][1], "[det.V]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 2 at level %d (errmax = %e)" % (wname, i+1, maxerr)) maxerr = _calc_errors(D3, W_coeffs[i+1][2], "[det.D]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients 3 at level %d (errmax = %e)" % (wname, i+1, maxerr)) def iswt2(self): """ Test pypwt for DWT2 reconstruction (iswt2). """ W = self.W # inverse DWT with pypwt W.forward() logging.info("computing Wavelets.inverse from pypwt") t0 = time() W.inverse() logging.info("Wavelets.inverse took %.3f ms" % elapsed_ms(t0)) if self.do_pywt: # inverse DWT with pywt Wpy = pywt.swt2(self.data, self.wname, level=self.levels) logging.info("computing iswt2 from pywt") _ = pywt.iswt2(Wpy, self.wname) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Check reconstruction W_image = W.image maxerr = _calc_errors(self.data, W_image, "[rec]") self.assertTrue(maxerr < self.tol, msg="[%s] something wrong with the reconstruction (errmax = %e)" % (self.wname, maxerr)) def dwt(self): """ Test pypwt against pywt for DWT (wavedec). """ W = self.W levels = self.levels wname = self.wname # Forward DWT with pypwt logging.info("computing Wavelets from pypwt") t0 = time() W.forward() logging.info("Wavelets.forward took %.3f ms" % elapsed_ms(t0)) # Forward DWT2 with pywt logging.info("computing wavedec from pywt") Wpy = pywt.wavedec(self.data, self.wname, mode=per_kw, level=levels) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Compare results # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**levels W_coeffs = W.coeffs if (levels != W.levels): err_msg = str("compare_coeffs(): pypwt instance has %d levels while pywt instance has %d levels" % (W.levels, levels)) logging.error(err_msg) raise ValueError(err_msg) A = Wpy[0] maxerr = _calc_errors(A, W_coeffs[0], "[app]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the approximation coefficients (%d levels) (errmax = %e)" % (wname, levels, maxerr)) for i in range(levels): # wavedec2 format # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**(i+1) D1 = Wpy[levels-i] logging.info("%s Level %d %s" % ("-"*5, i+1, "-"*5)) maxerr = _calc_errors(D1, W_coeffs[i+1], "[det]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients at level %d (errmax = %e)" % (wname, i+1, maxerr)) def idwt(self): """ Test pypwt for DWT reconstruction (waverec). """ W = self.W # inverse DWT with pypwt W.forward() logging.info("computing Wavelets.inverse from pypwt") t0 = time() W.inverse() logging.info("Wavelets.inverse took %.3f ms" % elapsed_ms(t0)) if self.do_pywt: # inverse DWT with pywt Wpy = pywt.wavedec(self.data, self.wname, mode=per_kw, level=self.levels) logging.info("computing waverec from pywt") _ = pywt.waverec(Wpy, self.wname, mode=per_kw) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Check reconstruction W_image = W.image maxerr = _calc_errors(self.data, W_image, "[rec]") self.assertTrue(maxerr < self.tol, msg="[%s] something wrong with the reconstruction (errmax = %e)" % (self.wname, maxerr)) def swt(self): """ Test pypwt against pywt for SWT. """ W = self.W levels = self.levels wname = self.wname # Forward DWT with pypwt logging.info("computing Wavelets from pypwt") t0 = time() W.forward() logging.info("Wavelets.forward took %.3f ms" % elapsed_ms(t0)) # Forward DWT2 with pywt logging.info("computing swt from pywt") Wpy = pywt.swt(self.data, self.wname, level=levels) logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Compare results # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**levels W_coeffs = W.coeffs if (levels != W.levels): err_msg = str("compare_coeffs(): pypwt instance has %d levels while pywt instance has %d levels" % (W.levels, levels)) logging.error(err_msg) raise ValueError(err_msg) A = Wpy[0][0] W_a = W_coeffs[0] if W.batched1d else W_coeffs[0].ravel() maxerr = _calc_errors(A, W_a, "[app]") # self.assertTrue(maxerr < tol, msg="[%s] something wrong with the approximation coefficients (%d levels) (errmax = %e)" % (wname, levels, maxerr)) for i in range(levels): # wavedec2 format # FIXME: Error increases when levels increase, since output is scaled. tol = self.tol * 2**(i+1) D1 = Wpy[levels-i-1][1] # TODO: take the new PyWavelet swt order into account logging.info("%s Level %d %s" % ("-"*5, i+1, "-"*5)) W_D1 = W_coeffs[i+1] if W.batched1d else W_coeffs[i+1].ravel() maxerr = _calc_errors(D1, W_D1, "[det]") self.assertTrue(maxerr < tol, msg="[%s] something wrong with the detail coefficients at level %d (errmax = %e)" % (wname, i+1, maxerr)) def iswt(self): """ Test pypwt for ISWT reconstruction. """ W = self.W # inverse DWT with pypwt W.forward() logging.info("computing Wavelets.inverse from pypwt") t0 = time() W.inverse() logging.info("Wavelets.inverse took %.3f ms" % elapsed_ms(t0)) # PyWavelets <= 0.5 does not have an "axis" property for iswt #~ if self.do_pywt: #~ # inverse DWT with pywt #~ Wpy = pywt.swt(self.data, self.wname, level=self.levels) #~ logging.info("computing waverec from pywt") #~ _ = pywt.iswt(Wpy, self.wname) #~ logging.info("pywt took %.3f ms" % elapsed_ms(t0)) # Check reconstruction W_image = W.image maxerr = _calc_errors(self.data, W_image, "[rec]") self.assertTrue(maxerr < self.tol, msg="[%s] something wrong with the reconstruction (errmax = %e)" % (self.wname, maxerr)) # End of class # ---------------- def test_wavelet(what, data=None, levels=None, wname=None): """ Entry point for running a test. It returns a unittest.TestSuite() instance. Parameters ----------- what: str Name of the test data: numpy.ndarray, optional Input data levels: int, optional Number of decomposition levels wname: str, optional Name of the wavelet to test. If no argument is provided, all wavelets will be tested. Example --------- runner = unittest.TextTestRunner() mysuite = test_wavelet("dwt2", my_img, 8) runner.run(mysuite) """ if data is None: data = scipy_img if levels is None: levels = 999 # Max level will be automatically computed testSuite = unittest.TestSuite() if what == "dwt2": par = { "levels": levels, "data": data, "what": "dwt2", "separable": 1, "extra": { "tol": 4e-4, # bior3.1.... } } if what == "idwt2": par = { "levels": levels, "data": data, "what": "idwt2", "separable": 1, "extra": { "tol": 7e-4, "do_pywt": True # False # set to True for benchmarking - can be slow ! } } if what == "swt2": par = { "levels": levels, "data": data, "what": "swt2", "separable": 1, "extra": { "tol": 3e-4, } } if what == "iswt2": par = { "levels": levels, "data": data, "what": "iswt2", "separable": 1, "extra": { "tol": 4e-4, "do_pywt": True # False # set to True for benchmarking - can be slow ! } } if what == "dwt": par = { "levels": levels, "data": data[50, :], "what": "dwt", "separable": 1, "extra": { "tol": 1e-4, } } if what == "dwt_batched": par = { "levels": levels, "data": data, "what": "dwt", "separable": 1, "extra": { "tol": 1e-4, } } if what == "idwt": par = { "levels": levels, "data": data[50, :], "what": "idwt", "separable": 1, "extra": { "tol": 2e-4, "do_pywt": False # set to True for benchmarking } } if what == "idwt_batched": par = { "levels": levels, "data": data, "what": "idwt", "separable": 1, "extra": { "tol": 5e-4, # bior* wavelets... "do_pywt": False # set to True for benchmarking } } if what == "swt": par = { "levels": levels, "data": data[50, :], "what": "swt", "separable": 1, "extra": { "tol": 4e-5, } } if what == "swt_batched": par = { "levels": levels, "data": data, "what": "swt", "separable": 1, "extra": { "tol": 1.1e-4, # db17 } } if what == "iswt": par = { "levels": levels, "data": data[50, :], "what": "iswt", "separable": 1, "extra": { "tol": 1e-4, "do_pywt": False # set to True for benchmarking } } if what == "iswt_batched": par = { "levels": levels, "data": data, "what": "iswt", "separable": 1, "extra": { "tol": 3e-4, # bior* wavelets... "do_pywt": False # set to True for benchmarking - can be slow ! } } if wname is None: wnames = available_filters else: wnames = [wname] # TODO: iterable user-provided "wname" for wname in wnames: par_curr = deepcopy(par) # otherwise the same dict is used for all tests par_curr["wname"] = wname testcase = ParametrizedTestCase.parametrize(TestWavelet, param=par_curr) testSuite.addTest(testcase) return testSuite def test_all(): suite = unittest.TestSuite() suite.addTest(test_wavelet("dwt2")) suite.addTest(test_wavelet("idwt2")) suite.addTest(test_wavelet("swt2")) suite.addTest(test_wavelet("iswt2")) suite.addTest(test_wavelet("dwt")) suite.addTest(test_wavelet("dwt_batched")) suite.addTest(test_wavelet("idwt")) suite.addTest(test_wavelet("idwt_batched")) suite.addTest(test_wavelet("swt")) suite.addTest(test_wavelet("swt_batched")) suite.addTest(test_wavelet("iswt")) suite.addTest(test_wavelet("iswt_batched")) return suite if __name__ == '__main__': mysuite = test_all() runner = unittest.TextTestRunner() runner.run(mysuite) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1647337531.0 pycudwt-1.0.2/test/testutils.py0000644000175000017500000000711600000000000016146 0ustar00pierrepierre#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np from pywt import wavedec, wavedec2, waverec, waverec2, swt, swt2 try: from pywt import iswt, iswt2 except ImportError: # nigma/pywt iswt = None iswt2 = None try: from scipy.misc import ascent scipy_img = ascent() except ImportError: from scipy.misc import lena scipy_img = lena() def iDivUp(a, b): return (a + (b - 1))//b def create_data_to_good_size(data, size): """ From a numpy array, create a second numpy array with a given size. The result contains the tiled data, which is then cropped to the wanted size. """ # For 1D if min(size) == 1: sz = max(size) clip = iDivUp(sz, data.shape[0]) res = np.tile(data[0], clip)[:sz] return res[:, np.newaxis].T clip_r = iDivUp(size[0], data.shape[0]) clip_c = iDivUp(size[1], data.shape[1]) res = np.tile(data, (clip_r, clip_c)) return res[:size[0], :size[1]] what_to_params = { "dwt2": { "name": "2D Forward DWT", "do_swt": 0, "ndim": 2, "pywt_function": wavedec2, }, "idwt2": { "name": "2D Inverse DWT", "do_swt": 0, "ndim": 2, "pywt_function": waverec2, }, "dwt": { "name": "1D Forward DWT", "do_swt": 0, "ndim": 1, "pywt_function": wavedec, }, "idwt": { "name": "1D Inverse DWT", "do_swt": 0, "ndim": 1, "pywt_function": waverec, }, "batched dwt": { "name": "Batched 1D Forward DWT", "do_swt": 0, "ndim": 1, "pywt_function": wavedec, }, "batched idwt": { "name": "Batched 1D Inverse DWT", "do_swt": 0, "ndim": 1, "pywt_function": waverec, }, "swt2": { "name": "2D Forward SWT", "do_swt": 1, "ndim": 2, "pywt_function": swt2, }, "iswt2": { "name": "2D Inverse SWT", "do_swt": 1, "ndim": 2, "pywt_function": iswt2, }, "swt": { "name": "1D Forward SWT", "do_swt": 0, "ndim": 2, "pywt_function": swt, }, "iswt": { "name": "1D Inverse SWT", "do_swt": 1, "ndim": 1, "pywt_function": iswt, }, "batched swt": { "name": "Batched 1D Forward SWT", "do_swt": 1, "ndim": 1, "pywt_function": swt, }, "batched iswt": { "name": "Batched 1D Inverse SWT", "do_swt": 1, "ndim": 1, "pywt_function": iswt, }, } # See ppdwt/filters.h available_filters = [ "haar", "db2", "db3", "db4", "db5", "db6", "db7", "db8", "db9", "db10", "db11", "db12", "db13", "db14", "db15", "db16", "db17", "db18", "db19", "db20", "sym2", "sym3", "sym4", "sym5", "sym6", "sym7", "sym8", "sym9", "sym10", "sym11", "sym12", "sym13", "sym14", "sym15", "sym16", "sym17", "sym18", "sym19", "sym20", "coif1", "coif2", "coif3", "coif4", "coif5", # pywt 0.5 has a problem with this one "bior1.3", "bior1.5", "bior2.2", "bior2.4", "bior2.6", "bior2.8", "bior3.1", "bior3.3", "bior3.5", "bior3.7", "bior3.9", "bior4.4", "bior5.5", "bior6.8", "rbio1.3", "rbio1.5", "rbio2.2", "rbio2.4", "rbio2.6", "rbio2.8", "rbio3.1", "rbio3.3", "rbio3.5", "rbio3.7", "rbio3.9", "rbio4.4", "rbio5.5", "rbio6.8"] # ------