void fwt(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], complex float* out, const long istr[N], const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]) { if (0 == flags) { if (out != in) md_copy2(N, dims, istr, out, istr, in, CFL_SIZE); return; } unsigned long coeffs = wavelet_coeffs(N, flags, dims, minsize, flen); long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); long ostr[2 * N]; md_calc_strides(2 * N, ostr, wdims, CFL_SIZE); long offset = coeffs - md_calc_size(2 * N, wdims); debug_printf(DP_DEBUG4, "%d %ld %ld\n", flags, coeffs, offset); long shifts0[N]; for (unsigned int i = 0; i < N; i++) shifts0[i] = 0; fwtN(N, flags, shifts, dims, ostr, out + offset, istr, in, flen, filter); fwt(N, wavelet_filter_flags(N, flags, wdims, minsize), shifts0, wdims, out, ostr, out + offset, minsize, flen, filter); }
long wavelet_num_levels(unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen) { if (0 == flags) return 1; long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); return 1 + wavelet_num_levels(N, wavelet_filter_flags(N, flags, wdims, min), wdims, min, flen); }
void fwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[2 * N], complex float* out, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen]) { long odims[2 * N]; wavelet_dims(N, flags, odims, dims, flen); assert(md_calc_size(2 * N, odims) >= md_calc_size(N, dims)); // FIXME one of these is unnecessary if we use the output complex float* tmpA = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out); complex float* tmpB = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out); long tidims[2 * N]; md_copy_dims(N, tidims, dims); md_singleton_dims(N, tidims + N); long tistrs[2 * N]; md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE); long todims[2 * N]; md_copy_dims(2 * N, todims, tidims); long tostrs[2 * N]; // maybe we should push the randshift into lower levels //md_copy2(N, dims, tistrs, tmpA, istr, in, CFL_SIZE); md_circ_shift2(N, dims, shifts, tistrs, tmpA, istr, in, CFL_SIZE); for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { todims[0 + i] = odims[0 + i]; todims[N + i] = odims[N + i]; md_calc_strides(2 * N, tostrs, todims, CFL_SIZE); fwt1(2 * N, i, tidims, tostrs, tmpB, (void*)tmpB + tostrs[N + i], tistrs, tmpA, flen, filter); md_copy_dims(2 * N, tidims, todims); md_copy_dims(2 * N, tistrs, tostrs); complex float* swap = tmpA; tmpA = tmpB; tmpB = swap; } } md_copy2(2 * N, todims, ostr, out, tostrs, tmpA, CFL_SIZE); md_free(tmpA); md_free(tmpB); }
void iwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const long istr[2 * N], const complex float* in, const long flen, const float filter[2][2][flen]) { long idims[2 * N]; wavelet_dims(N, flags, idims, dims, flen); assert(md_calc_size(2 * N, idims) >= md_calc_size(N, dims)); complex float* tmpA = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out); complex float* tmpB = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out); long tidims[2 * N]; md_copy_dims(2 * N, tidims, idims); long tistrs[2 * N]; md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE); long todims[2 * N]; md_copy_dims(2 * N, todims, tidims); long tostrs[2 * N]; long ishifts[N]; for (unsigned int i = 0; i < N; i++) ishifts[i] = -shifts[i]; md_copy2(2 * N, tidims, tistrs, tmpA, istr, in, CFL_SIZE); for (int i = N - 1; i >= 0; i--) { // run backwards to maintain contigous blocks if (MD_IS_SET(flags, i)) { todims[0 + i] = dims[0 + i]; todims[N + i] = 1; md_calc_strides(2 * N, tostrs, todims, CFL_SIZE); iwt1(2 * N, i, todims, tostrs, tmpB, tistrs, tmpA, (void*)tmpA + tistrs[N + i], flen, filter); md_copy_dims(2 * N, tidims, todims); md_copy_dims(2 * N, tistrs, tostrs); complex float* swap = tmpA; tmpA = tmpB; tmpB = swap; } } //md_copy2(N, dims, ostr, out, tostrs, tmpA, CFL_SIZE); md_circ_shift2(N, dims, ishifts, ostr, out, tostrs, tmpA, CFL_SIZE); md_free(tmpA); md_free(tmpB); }
static long wavelet_coeffs_r(unsigned int levels, unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen) { long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); long coeffs = md_calc_size(N, wdims); long bands = md_calc_size(N, wdims + N); assert((0 == flags) == (0 == levels)); if (0 == flags) return bands * coeffs; return coeffs * (bands - 1) + wavelet_coeffs_r(levels - 1, N, wavelet_filter_flags(N, flags, wdims, min), wdims, min, flen); }
void iwt(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]) { if (0 == flags) { if (out != in) md_copy2(N, dims, ostr, out, ostr, in, CFL_SIZE); return; } unsigned long coeffs = wavelet_coeffs(N, flags, dims, minsize, flen); long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); long istr[2 * N]; md_calc_strides(2 * N, istr, wdims, CFL_SIZE); long offset = coeffs - md_calc_size(2 * N, wdims); debug_printf(DP_DEBUG4, "%d %ld %ld\n", flags, coeffs, offset); complex float* tmp = md_alloc_sameplace(2 * N, wdims, CFL_SIZE, out); md_copy(2 * N, wdims, tmp, in + offset, CFL_SIZE); long shifts0[N]; for (unsigned int i = 0; i < N; i++) shifts0[i] = 0; // fix me we need temp storage iwt(N, wavelet_filter_flags(N, flags, wdims, minsize), shifts0, wdims, istr, tmp, in, minsize, flen, filter); iwtN(N, flags, shifts, dims, ostr, out, istr, tmp, flen, filter); md_free(tmp); }
void iwt2(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], const long ostr[N], complex float* out, const long idims[N], const long istr[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]) { assert(wavelet_check_dims(N, flags, odims, minsize)); if (0 == flags) { // note: recursion does *not* end here assert(md_check_compat(N, 0u, odims, idims)); md_copy2(N, idims, ostr, out, istr, in, CFL_SIZE); return; } // check input dimensions long idims2[N]; wavelet_coeffs2(N, flags, idims2, odims, minsize, flen); assert(md_check_compat(N, 0u, idims2, idims)); long wdims2[2 * N]; wavelet_dims(N, flags, wdims2, odims, flen); // only consider transform dims... long dims1[N]; md_select_dims(N, flags, dims1, odims); long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims1, flen); long level_coeffs = md_calc_size(2 * N, wdims); // ... which get embedded in dimension b unsigned int b = ffs(flags) - 1; long istr2[2 * N]; md_calc_strides(2 * N, istr2, wdims, istr[b]); // merge with original strides for (unsigned int i = 0; i < N; i++) if (!MD_IS_SET(flags, i)) istr2[i] = istr[i]; assert(idims[b] >= level_coeffs); long offset = (idims[b] - level_coeffs) * (istr[b] / CFL_SIZE); long bands = md_calc_size(N, wdims + N); long coeffs = md_calc_size(N, wdims + 0); // subtract coefficients in high band idims2[b] -= (bands - 1) * coeffs; assert(idims2[b] > 0); debug_printf(DP_DEBUG4, "ifwt2: flags:%d lcoeffs:%ld coeffs:%ld (space:%ld) bands:%ld str:%ld off:%ld\n", flags, level_coeffs, coeffs, idims2[b], bands, istr[b], offset / ostr[b]); // fix me we need temp storage complex float* tmp = md_alloc_sameplace(2 * N, wdims2, CFL_SIZE, out); long tstr[2 * N]; md_calc_strides(2 * N, tstr, wdims2, CFL_SIZE); md_copy2(2 * N, wdims2, tstr, tmp, istr2, in + offset, CFL_SIZE); long shifts0[N]; for (unsigned int i = 0; i < N; i++) shifts0[i] = 0; unsigned int flags2 = wavelet_filter_flags(N, flags, wdims, minsize); assert((0 == offset) == (0u == flags2)); if (0u != flags2) { long idims3[N]; wavelet_coeffs2(N, flags2, idims3, wdims2, minsize, flen); long istr3[N]; embed(N, flags, istr3, idims3, istr); iwt2(N, flags2, shifts0, wdims2, tstr, tmp, idims3, istr3, in, minsize, flen, filter); } iwtN(N, flags, shifts, odims, ostr, out, tstr, tmp, flen, filter); md_free(tmp); }