Beispiel #1
0
/**
 * Proximal function for f(z) = 0.5 || y - A z ||_2^2.
 * Solution is (A^H A + (1/mu) I)z = A^H y + (1/mu)(x_plus_u)
 *
 * @param prox_data should be of type prox_normaleq_data
 * @param mu proximal penalty
 * @param z output
 * @param x_plus_u input
 */
static void prox_normaleq_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u)
{
	struct prox_normaleq_data* pdata = CAST_DOWN(prox_normaleq_data, prox_data);

	if (0 == mu) {

		md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE);

	} else {

		float rho = 1. / mu;
		float* b = md_alloc_sameplace(1, MD_DIMS(pdata->size), FL_SIZE, x_plus_u);
		md_copy(1, MD_DIMS(pdata->size), b, pdata->adj, FL_SIZE);
		md_axpy(1, MD_DIMS(pdata->size), b, rho, x_plus_u);

		if (NULL == pdata->op->norm_inv) {

			struct iter_conjgrad_conf* cg_conf = pdata->cgconf;
			cg_conf->l2lambda = rho;

			iter_conjgrad(CAST_UP(cg_conf), pdata->op->normal, NULL, pdata->size, z, (float*)b, NULL);

		} else {

			linop_norm_inv_unchecked(pdata->op, rho, (complex float*)z, (const complex float*)b);
		}

		md_free(b);
	}
}
Beispiel #2
0
/**
 * Wrapper for calling pseudo-inverse operation using italgos.
 */
extern void linop_norm_inv_iter(void* _o, float lambda, float* _dst, const float* _src)
{
	struct linop_s* o = _o;
	complex float* dst = (complex float*)_dst;
	const complex float* src = (complex float*)_src;

	linop_norm_inv_unchecked(o, lambda, dst, src);
}
Beispiel #3
0
void fd_proj_noninc(const struct linop_s* o, complex float* optr, const complex float* iptr)
{
	struct fdiff_s* data = (struct fdiff_s*)linop_get_data(o);	// FIXME: CAST?
	
	dump_cfl("impre", data->D, data->dims, iptr);

	complex float* tmp2 = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr);
	linop_forward_unchecked(o, tmp2, iptr);

	long tmpdim = data->dims[0];
	long dims2[data->D];
	md_select_dims(data->D, ~0u, dims2, data->dims);
	dims2[0] *= 2; 
	dump_cfl("dxpre", data->D, data->dims, tmp2);

	md_smin(data->D, dims2, (float*)optr, (float*)tmp2, 0.);

	// add back initial value
	dims2[0] = tmpdim;

	for (unsigned int i = 0; i < data->D; i++) {

		if (MD_IS_SET(data->flags, i)) {

			dims2[i] = 1;
			md_copy2(data->D, dims2, data->str, optr, data->str, tmp2, CFL_SIZE);
			break;
		}
	}

	dump_cfl("dxpost", data->D, data->dims, optr);
	linop_norm_inv_unchecked(o, 0., optr, optr);
	
	dump_cfl("impost", data->D, data->dims, optr);

	md_free(tmp2);
}