/* * Invert a toeplitz matrix. Input is the first column of the matrix and also * is the output. * IMP - size must be a power of two. */ void serial_matrix_inversion(size_t size, const fftw_complex *input, fftw_complex *result) { if(size < 1) return; //base case result[0] = 1 / input[0]; if(size < 2) return; result[1] = - result[0] * input[1] * result[0]; unsigned int current_size = 2; while(current_size < size) { fftw_complex *reversed_input = alloc_reverse_from_vec(current_size * 2 - 1, input); fftw_complex *temporary = alloc_complex(current_size); //first convolution toeplitz_mult(current_size, reversed_input, result, temporary); fftw_complex *reversed_inverted_pad = alloc_complex(current_size * 2 - 1); zero_memory(current_size * 2 - 1, reversed_inverted_pad); memcpy(reversed_inverted_pad + (current_size-1), result, current_size * sizeof(fftw_complex)); reverse_vec(current_size * 2 - 1, reversed_inverted_pad); //second convolution reverse_vec(current_size, temporary); toeplitz_mult(current_size, reversed_inverted_pad, temporary, reversed_input); //complement sign for(int i=0; i < current_size; i++) reversed_input[i] = - reversed_input[i]; reverse_vec(current_size, reversed_input); //finally copy in result vec memcpy(result + current_size, reversed_input, current_size * sizeof(fftw_complex)); fftw_free(temporary); fftw_free(reversed_input); fftw_free(reversed_inverted_pad); current_size *= 2; } }
static void nufft_apply_normal(const void* _data, complex float* dst, const complex float* src) { const struct nufft_data* data = _data; if (data->conf.toeplitz) { toeplitz_mult(data, dst, src); } else { complex float* tmp_ksp = md_alloc(data->N + 3, data->ksp_dims, CFL_SIZE); nufft_apply((const void*)data, tmp_ksp, src); nufft_apply_adjoint((const void*)data, dst, tmp_ksp); md_free(tmp_ksp); } }