예제 #1
0
파일: linop.c 프로젝트: andrewcurtis/bart
/**
 * Free the linear operator and associated data,
 * Note: only frees the data if its reference count is zero
 *
 * @param op linear operator
 */
void linop_free(const struct linop_s* op)
{
	operator_free(op->forward);
	operator_free(op->adjoint);
	operator_free(op->normal);
	operator_p_free(op->norm_inv);
	free((void*)op);
}
예제 #2
0
파일: lsqr.c 프로젝트: andruw17/bart
/**
 * Perform iterative, multi-regularized least-squares reconstruction
 */
void lsqr2(	unsigned int N, const struct lsqr_conf* conf,
		italgo_fun2_t italgo, void* iconf,
		const struct linop_s* model_op,
		unsigned int num_funs,
		const struct operator_p_s** prox_funs,
		const struct linop_s** prox_linops,
		const long x_dims[N], _Complex float* x, 
		const long y_dims[N], const _Complex float* y,
		const complex float* x_truth,
		void* obj_eval_data,
		float (*obj_eval)(const void*, const float*))
{
	// -----------------------------------------------------------
	// normal equation right hand side

	complex float* x_adj = md_alloc_sameplace(N, x_dims, CFL_SIZE, y);
	linop_adjoint(model_op, N, x_dims, x_adj, N, y_dims, y);


	// -----------------------------------------------------------
	// initialize data: struct to hold all data and operators

	struct lsqr_data data;

	data.l2_lambda = conf->lambda;
	data.model_op = model_op;
	data.G_ops = prox_linops;
	data.prox_ops = prox_funs;
	data.size = 2 * md_calc_size(N, x_dims);


	// -----------------------------------------------------------
	// run recon

	const struct operator_s* normaleq_op = operator_create(N, x_dims, N, x_dims, (void*)&data, normaleq_l2_apply, NULL);


	italgo(iconf, normaleq_op, num_funs, prox_funs, prox_linops, NULL, 
			data.size, (float*)x, (const float*)x_adj,
			(const float*)x_truth, obj_eval_data, obj_eval);


	// -----------------------------------------------------------
	// clean up
	
	md_free(x_adj);
	operator_free(normaleq_op);
}
예제 #3
0
파일: linop.c 프로젝트: andrewcurtis/bart
/**
 * Create chain of linear operators.
 * C = B A 
 * C^H = A^H B^H
 * C^H C = A^H B^H B A
 */
struct linop_s* linop_chain(const struct linop_s* a, const struct linop_s* b)
{
	struct linop_s* c = xmalloc(sizeof(struct linop_s));

	c->forward = operator_chain(a->forward, b->forward);
	c->adjoint = operator_chain(b->adjoint, a->adjoint);

	if (NULL == b->normal) {

		c->normal = operator_chain(c->forward, c->adjoint);

	} else {

		const struct operator_s* top = operator_chain(b->normal, a->adjoint);
		c->normal = operator_chain(a->forward, top);
		operator_free(top);
	}

	c->norm_inv = NULL;

	return c;
}
예제 #4
0
파일: fft.c 프로젝트: Markusjsommer/bart
void fft_free(const struct operator_s* o)
{
	operator_free(o);
}
예제 #5
0
파일: nufft.c 프로젝트: mjacob75/bart
int main_nufft(int argc, char* argv[])
{
	bool adjoint = false;
	bool inverse = false;
	bool use_gpu = false;
	bool precond = false;
	bool dft = false;

	struct nufft_conf_s conf = nufft_conf_defaults;
	struct iter_conjgrad_conf cgconf = iter_conjgrad_defaults;

	long coilim_vec[3] = { 0 };

	float lambda = 0.;

	const struct opt_s opts[] = {

		OPT_SET('a', &adjoint, "adjoint"),
		OPT_SET('i', &inverse, "inverse"),
		OPT_VEC3('d', &coilim_vec, "x:y:z", "dimensions"),
		OPT_VEC3('D', &coilim_vec, "", "()"),
		OPT_SET('t', &conf.toeplitz, "Toeplitz embedding for inverse NUFFT"),
		OPT_SET('c', &precond, "Preconditioning for inverse NUFFT"),
		OPT_FLOAT('l', &lambda, "lambda", "l2 regularization"),
		OPT_UINT('m', &cgconf.maxiter, "", "()"),
		OPT_SET('s', &dft, "DFT"),
	};

	cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts);

	long coilim_dims[DIMS] = { 0 };
	md_copy_dims(3, coilim_dims, coilim_vec);

	// Read trajectory
	long traj_dims[DIMS];
	complex float* traj = load_cfl(argv[1], DIMS, traj_dims);

	assert(3 == traj_dims[0]);


	num_init();

	if (inverse || adjoint) {

		long ksp_dims[DIMS];
		const complex float* ksp = load_cfl(argv[2], DIMS, ksp_dims);

		assert(1 == ksp_dims[0]);
		assert(md_check_compat(DIMS, ~(PHS1_FLAG|PHS2_FLAG), ksp_dims, traj_dims));

		md_copy_dims(DIMS - 3, coilim_dims + 3, ksp_dims + 3);

		if (0 == md_calc_size(DIMS, coilim_dims)) {

			estimate_im_dims(DIMS, coilim_dims, traj_dims, traj);
			debug_printf(DP_INFO, "Est. image size: %ld %ld %ld\n", coilim_dims[0], coilim_dims[1], coilim_dims[2]);
		}

		complex float* img = create_cfl(argv[3], DIMS, coilim_dims);

		md_clear(DIMS, coilim_dims, img, CFL_SIZE);

		const struct linop_s* nufft_op;

		if (!dft)
			nufft_op = nufft_create(DIMS, ksp_dims, coilim_dims, traj_dims, traj, NULL, conf, use_gpu);
		else
			nufft_op = nudft_create(DIMS, FFT_FLAGS, ksp_dims, coilim_dims, traj_dims, traj);


		if (inverse) {

			const struct operator_s* precond_op = NULL;

			if (conf.toeplitz && precond)
				precond_op = nufft_precond_create(nufft_op);

			lsqr(DIMS, &(struct lsqr_conf){ lambda }, iter_conjgrad, CAST_UP(&cgconf),
			     nufft_op, NULL, coilim_dims, img, ksp_dims, ksp, precond_op);

			if (conf.toeplitz && precond)
				operator_free(precond_op);

		} else {