/* * ( AT A + lambda I) x = b */ static void maps_apply_pinverse(const void* _data, float lambda, complex float* dst, const complex float* src) { struct maps_data* data = (struct maps_data*)_data; maps_init_normal(data); md_zsadd(DIMS, data->img_dims, data->norm, data->norm, lambda); md_zdiv(DIMS, data->img_dims, dst, src, data->norm); md_zsadd(DIMS, data->img_dims, data->norm, data->norm, -lambda); }
/** * 1/2 || Ax - b ||^2 + rho/2 || x - y ||^2 * * x = (ATA + lI)^-1 b * * X = 1 / (pat^2 + l) B * */ static void ufft_apply_pinverse(const linop_data_t* _data, float rho, complex float* dst, const complex float* src) { const struct ufft_data* data = CONTAINER_OF(_data, const struct ufft_data, base); md_zsadd(DIMS, data->pat_dims, data->pat, data->pat, rho); linop_forward(data->fft_op, DIMS, data->ksp_dims, dst, DIMS, data->ksp_dims, src); md_zdiv2(DIMS, data->ksp_dims, data->ksp_strs, dst, data->ksp_strs, dst, data->pat_strs, data->pat); linop_adjoint(data->fft_op, DIMS, data->ksp_dims, dst, DIMS, data->ksp_dims, dst); md_zsadd(DIMS, data->pat_dims, data->pat, data->pat, -rho); }
/** * Compute Strang's circulant preconditioner * * Strang's reconditioner is simply the cropped psf in the image domain * */ static complex float* compute_precond(unsigned int N, const long* pre_dims, const long* pre_strs, const long* psf_dims, const long* psf_strs, const complex float* psf, const complex float* linphase) { int ND = N + 1; unsigned long flags = FFT_FLAGS; complex float* pre = md_alloc(ND, pre_dims, CFL_SIZE); complex float* psft = md_alloc(ND, psf_dims, CFL_SIZE); // Transform psf to image domain ifftuc(ND, psf_dims, flags, psft, psf); // Compensate for linear phase to get cropped psf md_clear(ND, pre_dims, pre, CFL_SIZE); md_zfmacc2(ND, psf_dims, pre_strs, pre, psf_strs, psft, psf_strs, linphase); md_free(psft); // Transform to Fourier domain fftuc(N, pre_dims, flags, pre, pre); md_zabs(N, pre_dims, pre, pre); md_zsadd(N, pre_dims, pre, pre, 1e-3); return pre; }
static void noir_calc_weights(const long dims[3], complex float* dst) { unsigned int flags = 0; for (int i = 0; i < 3; i++) if (1 != dims[i]) flags = MD_SET(flags, i); klaplace(3, dims, flags, dst); md_zsmul(3, dims, dst, dst, 220.); md_zsadd(3, dims, dst, dst, 1.); md_zspow(3, dims, dst, dst, -16.); // 1 + 222. \Laplace^16 }