/** * Thresholding operator for l0-norm: f(x) = || x ||_0 <= k, as used in NIHT algorithm. * y = HT(x, k) (hard thresholding, ie keeping the k largest elements). * * @param D number of dimensions * @param dim dimensions of x * @param k threshold parameter (non-zero elements to keep) * @param flags bitmask for joint thresholding */ const struct operator_p_s* prox_niht_thresh_create(unsigned int D, const long dim[D], const unsigned int k, const unsigned long flags) { PTR_ALLOC(struct thresh_s, data); SET_TYPEID(thresh_s, data); data->lambda = 0.; data->k = k; data->D = D; data->flags = flags; data->unitary_op = NULL; PTR_ALLOC(long[D], ndim); md_copy_dims(D, *ndim, dim); data->dim = *PTR_PASS(ndim); // norm dimensions are the flagged input dimensions PTR_ALLOC(long[D], norm_dim); md_select_dims(D, ~flags, *norm_dim, data->dim); data->norm_dim = *PTR_PASS(norm_dim); PTR_ALLOC(long[D], nstr); md_calc_strides(D, *nstr, data->dim, CFL_SIZE); data->str = *PTR_PASS(nstr); return operator_p_create(D, dim, D, dim, CAST_UP(PTR_PASS(data)), hardthresh_apply, thresh_del); }
const struct operator_p_s* prox_dfwavelet_create(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { struct prox_dfwavelet_data* data = prepare_prox_dfwavelet_data(im_dims, min_size, res, flow_dim, lambda, use_gpu); return operator_p_create(DIMS, im_dims, DIMS, im_dims, &data->base, prox_dfwavelet_thresh, prox_dfwavelet_del); }
/** * Proximal operator for l1-norm with unitary transform: f(x) = lambda || T x ||_1 * * @param D number of dimensions * @param dim dimensions of x * @param lambda threshold parameter * @param unitary_op unitary linear operator * @param flags bitmask for joint soft-thresholding */ extern const struct operator_p_s* prox_unithresh_create(unsigned int D, const struct linop_s* unitary_op, const float lambda, const unsigned long flags) { PTR_ALLOC(struct thresh_s, data); SET_TYPEID(thresh_s, data); data->lambda = lambda; data->D = D; data->flags = flags; data->unitary_op = unitary_op; const long* dims = linop_domain(unitary_op)->dims; PTR_ALLOC(long[D], ndim); md_copy_dims(D, *ndim, dims); data->dim = *PTR_PASS(ndim); PTR_ALLOC(long[D], nstr); md_calc_strides(D, *nstr, data->dim, CFL_SIZE); data->str = *PTR_PASS(nstr); // norm dimensions are the flagged transform dimensions // FIXME should use linop_codomain(unitary_op)->N PTR_ALLOC(long[D], norm_dim); md_select_dims(D, ~flags, *norm_dim, linop_codomain(unitary_op)->dims); data->norm_dim = *PTR_PASS(norm_dim); return operator_p_create(D, dims, D, dims, CAST_UP(PTR_PASS(data)), unisoftthresh_apply, thresh_del); }
/* * Proximal function for real-value constraint */ const struct operator_p_s* prox_rvc_create(unsigned int N, const long dims[N]) { PTR_ALLOC(struct prox_rvc_data, pdata); SET_TYPEID(prox_rvc_data, pdata); pdata->size = md_calc_size(N, dims); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_rvc_apply, prox_rvc_del); }
const struct operator_p_s* prox_l2norm_create(unsigned int N, const long dims[N], float lambda) { PTR_ALLOC(struct prox_l2norm_data, pdata); SET_TYPEID(prox_l2norm_data, pdata); pdata->lambda = lambda; pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_l2norm_apply, prox_l2norm_del); }
static const struct operator_p_s* prox_ineq_create(unsigned int N, const long dims[N], const complex float* b, bool positive) { PTR_ALLOC(struct prox_ineq_data, pdata); SET_TYPEID(prox_ineq_data, pdata); pdata->size = md_calc_size(N, dims) * 2; pdata->b = (const float*)b; pdata->positive = positive; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_ineq_apply, prox_ineq_del); }
const struct operator_p_s* prox_l2ball_create(unsigned int N, const long dims[N], float eps, const complex float* center) { PTR_ALLOC(struct prox_l2ball_data, pdata); SET_TYPEID(prox_l2ball_data, pdata); pdata->center = (const float*)center; pdata->eps = eps; pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_l2ball_apply, prox_l2ball_del); }
const struct operator_p_s* prox_leastsquares_create(unsigned int N, const long dims[N], float lambda, const complex float* y) { PTR_ALLOC(struct prox_leastsquares_data, pdata); SET_TYPEID(prox_leastsquares_data, pdata); pdata->y = (const float*)y; pdata->lambda = lambda; pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_leastsquares_apply, prox_leastsquares_del); }
const struct operator_p_s* prox_thresh_create(unsigned int N, const long dims[N], float lambda, void (*thresh)(void* _data, float lambda, float* _dst, const float* _src), void* data) { PTR_ALLOC(struct prox_thresh_data, pdata); pdata->thresh = thresh; pdata->lambda = lambda; pdata->data = data; return operator_p_create(N, dims, dims, PTR_PASS(pdata), prox_thresh_apply, prox_thresh_del); }
/** * Proximal operator for l1-norm with Wavelet transform: f(x) = lambda || W x ||_1 * * @param numdims number of dimensions * @param imSize dimensions of x * @param wave_flags bitmask for Wavelet transform * @param minSize minimium size of coarse Wavelet scale * @param lambda threshold parameter * @param randshift apply random shift before Wavelet transforming * @param use_gpu true if using gpu */ const struct operator_p_s* prox_wavethresh_create(int numdims, const long imSize[numdims], unsigned int wave_flags, const long minSize[numdims], float lambda, bool randshift, bool use_gpu) { PTR_ALLOC(struct wave_prox_s, data); SET_TYPEID(wave_prox_s, data); data->plan = prepare_wavelet_plan(numdims, imSize, wave_flags, minSize, use_gpu); data->plan->randshift = randshift; data->plan->lambda = lambda; return operator_p_create(numdims, imSize, numdims, imSize, CAST_UP(PTR_PASS(data)), wavelet_thresh, wavelet_prox_del); }
const struct operator_p_s* prox_lineq_create(const struct linop_s* op, const complex float* y) { PTR_ALLOC(struct prox_lineq_data, pdata); unsigned int N = linop_domain(op)->N; const long* dims = linop_domain(op)->dims; pdata->op = op; pdata->adj = md_alloc_sameplace(N, dims, CFL_SIZE, y); linop_adjoint(op, N, dims, pdata->adj, N, linop_codomain(op)->dims, y); pdata->tmp = md_alloc_sameplace(N, dims, CFL_SIZE, y); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_lineq_apply, prox_lineq_del); }
const struct operator_p_s* prox_normaleq_create(const struct linop_s* op, const complex float* y) { PTR_ALLOC(struct prox_normaleq_data, pdata); SET_TYPEID(prox_normaleq_data, pdata); PTR_ALLOC(struct iter_conjgrad_conf, cgconf); *cgconf = iter_conjgrad_defaults; cgconf->maxiter = 10; cgconf->l2lambda = 0; pdata->cgconf = PTR_PASS(cgconf); pdata->op = op; pdata->size = 2 * md_calc_size(linop_domain(op)->N, linop_domain(op)->dims); pdata->adj = md_alloc_sameplace(1, &(pdata->size), FL_SIZE, y); linop_adjoint_iter((struct linop_s*)op, pdata->adj, (const float*)y); return operator_p_create(linop_domain(op)->N, linop_domain(op)->dims, linop_domain(op)->N, linop_domain(op)->dims, CAST_UP(PTR_PASS(pdata)), prox_normaleq_apply, prox_normaleq_del); }
/** * Proximal operator for l1-norm with Wavelet transform: f(x) = lambda || W x ||_1 * * @param N number of dimensions * @param dims dimensions of x * @param flags bitmask for Wavelet transform * @param minsize minimium size of coarse Wavelet scale * @param lambda threshold parameter * @param randshift random shifting */ const struct operator_p_s* prox_wavelet3_thresh_create(unsigned int N, const long dims[N], unsigned int flags, const long minsize[N], float lambda, bool randshift) { PTR_ALLOC(struct wavelet3_thresh_s, data); SET_TYPEID(wavelet3_thresh_s, data); data->N = N; long (*ndims)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, (*ndims), dims); data->dims = *ndims; long (*nminsize)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, (*nminsize), minsize); data->minsize = *nminsize; data->flags = flags; data->lambda = lambda; data->randshift = randshift; data->rand_state = 1; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), wavelet3_thresh_apply, wavelet3_thresh_del); }
/** * Intialize lrthresh operator * * @param dims_decom - decomposition dimensions * @param randshift - randshift boolean * @param mflags - selects which dimensions gets reshaped as the first dimension in matrix * @param blkdims - contains block dimensions for all levels * */ const struct operator_p_s* lrthresh_create(const long dims_lev[DIMS], bool randshift, unsigned long mflags, const long blkdims[MAX_LEV][DIMS], float lambda, bool noise, int remove_mean) { struct lrthresh_data_s* data = lrthresh_create_data(dims_lev, randshift, mflags, blkdims, lambda, noise, remove_mean); return operator_p_create(DIMS, dims_lev, DIMS, dims_lev, CAST_UP(data), lrthresh_apply, lrthresh_free_data); }