Esempio n. 1
0
/*
 * Adjoint of finite difference operator along specified dimensions.
 * Equivalent to finite difference in reverse order
 * 
 * @param snip if false: keeps the original value for the last entry;
 * if true: implements the adjoint of the difference matrix with all zero first row
 *
 * optr = [-diff(iptr); iptr(end)] = flip(fdiff_apply(flip(iptr)))
 */
static void fdiff_apply_adjoint(const linop_data_t* _data, complex float* optr, const complex float* iptr)
{
	const auto data = CAST_DOWN(fdiff_s, _data);

	md_copy2(data->D, data->dims, data->str, optr, data->str, iptr, CFL_SIZE);

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

		unsigned int single_flag = data->flags & MD_BIT(i);

		if (single_flag) {

			complex float* tmp = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr);
			complex float* tmp2 = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr);
			md_flip2(data->D, data->dims, single_flag, data->str, tmp2, data->str, optr, CFL_SIZE);
			md_zfinitediff_core2(data->D, data->dims, single_flag, false, tmp, data->str, tmp2, data->str, tmp2);
			md_flip2(data->D, data->dims, single_flag, data->str, optr, data->str, tmp2, CFL_SIZE);

			md_free(tmp2);
			md_free(tmp);

			if (data->snip) {

				long zdims[data->D];
				md_select_dims(data->D, ~0, zdims, data->dims);

				zdims[i] = 1;
				md_zsub2(data->D, zdims, data->str, optr, data->str, optr, data->str, iptr);
			}
		}
	}
}
Esempio n. 2
0
static void homodyne(struct wdata wdata, unsigned int flags, unsigned int N, const long dims[N],
		const long strs[N], complex float* data, const complex float* idata)
{
	long cdims[N];
	md_copy_dims(N, cdims, dims);
	// cdims[0] = cdims[1] = cdims[2] = 24;
	cdims[wdata.pfdim] = (wdata.frac - 0.5) * dims[wdata.pfdim];

	complex float* center = md_alloc(N, cdims, CFL_SIZE);
	complex float* phase = md_alloc(N, dims, CFL_SIZE);

	md_resize_center(N, cdims, center, dims, idata, CFL_SIZE);
	md_resize_center(N, dims, phase, cdims, center, CFL_SIZE);
	md_free(center);

	ifftuc(N, dims, flags, phase, phase);
	md_zphsr(N, dims, phase, phase);

	md_zmul2(N, dims, strs, data, strs, idata, wdata.wstrs, wdata.weights);

	ifftuc(N, dims, flags, data, data);

	md_zmulc(N, dims, data, data, phase);
	md_zreal(N, dims, data, data);

	md_free(phase);
}
Esempio n. 3
0
void calc_geo_phantom(const long dims[DIMS], complex float* out, bool kspace, int phtype)
{
	complex float* round = md_alloc(DIMS, dims, CFL_SIZE);
	complex float* angular = md_alloc(DIMS, dims, CFL_SIZE);

	switch (phtype) {

	case 1:
		sample(DIMS, dims, round, ARRAY_SIZE(phantom_geo1), phantom_geo1, kspace, true);
		sample(DIMS, dims, angular, ARRAY_SIZE(phantom_geo2), phantom_geo2, kspace, false);
		md_zadd(DIMS, dims, out, round, angular);
		break;

	case 2:
		sample(DIMS, dims, round, ARRAY_SIZE(phantom_geo4), phantom_geo4, kspace, true);
		sample(DIMS, dims, angular, ARRAY_SIZE(phantom_geo3), phantom_geo3, kspace, false);
		md_zadd(DIMS, dims, out, round, angular);
		break;

	default:
		assert(0);
	}

	md_free(round);
	md_free(angular);
}
static void nufft_free_data(const void* _data)
{
	struct nufft_data* data = (struct nufft_data*)_data;

	free(data->ksp_dims);
	free(data->cim_dims);
	free(data->cml_dims);
	free(data->img_dims);
	free(data->trj_dims);
	free(data->lph_dims);
	free(data->psf_dims);
	free(data->wgh_dims);

	free(data->ksp_strs);
	free(data->cim_strs);
	free(data->cml_strs);
	free(data->img_strs);
	free(data->trj_strs);
	free(data->lph_strs);
	free(data->psf_strs);
	free(data->wgh_strs);

	md_free(data->grid);
	md_free((void*)data->linphase);
	md_free((void*)data->psf);
	md_free((void*)data->fftmod);
	md_free((void*)data->weights);

	linop_free(data->fft_op);

	free(data);
}
Esempio n. 5
0
static void unisoftthresh_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src)
{
	const auto data = CAST_DOWN(thresh_s, _data);

	if (0. == mu) {

		md_copy(data->D, data->dim, dst, src, CFL_SIZE);

	} else {

		const long* transform_dims = linop_codomain(data->unitary_op)->dims;
		const long* transform_strs = linop_codomain(data->unitary_op)->strs;

		complex float* tmp = md_alloc_sameplace(data->D, transform_dims, CFL_SIZE, dst);

		linop_forward(data->unitary_op, data->D, transform_dims, tmp, data->D, data->dim, src);

		complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, dst);
		md_zsoftthresh_core2(data->D, transform_dims, data->lambda * mu, data->flags, tmp_norm, transform_strs, tmp, transform_strs, tmp);
		md_free(tmp_norm);

		linop_adjoint(data->unitary_op, data->D, data->dim, dst, data->D, transform_dims, tmp);

		md_free(tmp);
	}
}
Esempio n. 6
0
float nuclearnorm(long M, long N, const complex float* d) { // FIXME: destroys input

	long minMN = MIN(M,N);
	long dimsU[3]	=	{M, minMN, 1};
	long dimsVT[3]	=	{minMN, N, 1};
	long dimsS[3]	=	{minMN, 1, 1};


	complex float* U = md_alloc_sameplace(3, dimsU, CFL_SIZE, d);
	complex float* VT = md_alloc_sameplace(3, dimsVT, CFL_SIZE, d );
	float* S = md_alloc_sameplace(3, dimsS, FL_SIZE, d);


	// SVD
	lapack_svd_econ(M, N, (complex float (*) []) U, (complex float (*) []) VT, S, (complex float (*) [N])d);

	float nnorm = 0.;
	for (int i = 0; i < minMN; i++)
		nnorm += S[i];

	md_free(U);
	md_free(VT);
	md_free(S);


	return nnorm;
}
Esempio n. 7
0
static bool test_md_zmatmul(void)
{
	int A = 10;
	int B = 20;
	int C = 30;

	long odims[3] = { C, 1, A };
	long idims1[3] = { 1, B, A };
	long idims2[3] = { C, B, 1 };

	complex float* dst1 = md_alloc(3, odims, CFL_SIZE);
	complex float* dst2 = md_alloc(3, odims, CFL_SIZE);
	complex float* src1 = md_alloc(3, idims1, CFL_SIZE);
	complex float* src2 = md_alloc(3, idims2, CFL_SIZE);

	md_gaussian_rand(3, odims, dst1);
	md_gaussian_rand(3, odims, dst2);
	md_gaussian_rand(3, idims1, src1);
	md_gaussian_rand(3, idims2, src2);

	md_zmatmul(3, odims, dst1, idims1, src1, idims2, src2);

	matrix_mult(A, B, C, &MD_CAST_ARRAY2(complex float, 3, odims, dst2, 0, 2),
			&MD_CAST_ARRAY2(const complex float, 3, idims1, src1, 1, 2),
			&MD_CAST_ARRAY2(const complex float, 3, idims2, src2, 0, 1));

	double err = md_znrmse(3, odims, dst2, dst1);

	md_free(src1);
	md_free(src2);
	md_free(dst1);
	md_free(dst2);

	return (err < UT_TOL);
}
Esempio n. 8
0
File: prox.c Progetto: mjacob75/bart
static void prox_lineq_del(const operator_data_t* _data)
{
	struct prox_lineq_data* pdata = CAST_DOWN(prox_lineq_data, _data);

	md_free(pdata->adj);
	md_free(pdata->tmp);
	free(pdata);
}
Esempio n. 9
0
int
g_parse_opts(char *input, _p_opt_cb _proc, void *arg, int dl_o, int dl_v)
{
  mda m_dl_o =
    { 0 };
  md_init(&m_dl_o, 32);

  int ret = 0;

  int c = split_string(input, dl_o, &m_dl_o);

  if (c == 0)
    {
      ret = 1;
      goto end_1;
    }

  p_md_obj ptr_o = m_dl_o.objects;

  while (ptr_o)
    {
      char *opt = (char*) ptr_o->ptr;

      mda m_dl_v =
        { 0 };
      md_init(&m_dl_v, 8);

      if (split_string(opt, dl_v, &m_dl_v) == 0)
        {
          md_free(&m_dl_v);
          ret = 2;
          goto end_1;
        }

      if (m_dl_v.offset < 1)
        {
          ret = 3;
          goto end_1;
        }

      if (0 != _proc(&m_dl_v, arg))
        {
          ret = 4;
          goto end_1;
        }

      md_free(&m_dl_v);

      ptr_o = ptr_o->next;
    }

  end_1: ;

  md_free(&m_dl_o);

  return ret;
}
Esempio n. 10
0
/*
 * Cumulative sum along dimensions specified by flags (with strides)
 *
 * optr = cumsum(iptr)
 */
void md_zcumsum2(unsigned int D, const long dims[D], unsigned int flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr)
{
	complex float* tmp = md_alloc_sameplace(D, dims, CFL_SIZE, optr);
	complex float* tmp2 = md_alloc_sameplace(D, dims, CFL_SIZE, optr);

	md_zcumsum_core2(D, dims, flags, tmp, tmp2, ostrs, optr, istrs, iptr);

	md_free(tmp);
	md_free(tmp2);
}
Esempio n. 11
0
static void prox_dfwavelet_del(const operator_data_t* _data)
{
	struct prox_dfwavelet_data* data = CONTAINER_OF(_data, struct prox_dfwavelet_data, base);

        md_free(data->vx);
        md_free(data->vy);
        md_free(data->vz);
        dfwavelet_free(data->plan);

	free(data);
}
Esempio n. 12
0
void fwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[2 * N], complex float* out, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen])
{
	long odims[2 * N];
	wavelet_dims(N, flags, odims, dims, flen);

	assert(md_calc_size(2 * N, odims) >= md_calc_size(N, dims));

	// FIXME one of these is unnecessary if we use the output

	complex float* tmpA = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out);
	complex float* tmpB = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out);

	long tidims[2 * N];
	md_copy_dims(N, tidims, dims);
	md_singleton_dims(N, tidims + N);
	
	long tistrs[2 * N];
	md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE);

	long todims[2 * N];
	md_copy_dims(2 * N, todims, tidims);

	long tostrs[2 * N];

	// maybe we should push the randshift into lower levels

	//md_copy2(N, dims, tistrs, tmpA, istr, in, CFL_SIZE);
	md_circ_shift2(N, dims, shifts, tistrs, tmpA, istr, in, CFL_SIZE);

	for (unsigned int i = 0; i < N; i++) {

		if (MD_IS_SET(flags, i)) {

			todims[0 + i] = odims[0 + i];
			todims[N + i] = odims[N + i];

			md_calc_strides(2 * N, tostrs, todims, CFL_SIZE);
		
			fwt1(2 * N, i, tidims, tostrs, tmpB, (void*)tmpB + tostrs[N + i], tistrs, tmpA, flen, filter);

			md_copy_dims(2 * N, tidims, todims);
			md_copy_dims(2 * N, tistrs, tostrs);

			complex float* swap = tmpA;
			tmpA = tmpB;
			tmpB = swap;
		}
	}

	md_copy2(2 * N, todims, ostr, out, tostrs, tmpA, CFL_SIZE);

	md_free(tmpA);
	md_free(tmpB);
}
Esempio n. 13
0
File: wavelet.c Progetto: hcmh/bart
void fwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* low, complex float* hgh, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen])
{
	debug_printf(DP_DEBUG4, "fwt1: %d/%d\n", d, N);
	debug_print_dims(DP_DEBUG4, N, dims);

	assert(dims[d] >= 2);

	long odims[N];
	md_copy_dims(N, odims, dims);
	odims[d] = bandsize(dims[d], flen);

	debug_print_dims(DP_DEBUG4, N, odims);

	long o = d + 1;
	long u = N - o;

	// 0 1 2 3 4 5 6|7
	// --d-- * --u--|N
	// ---o---

	assert(d == md_calc_blockdim(d, dims + 0, istr + 0, CFL_SIZE));
	assert(u == md_calc_blockdim(u, dims + o, istr + o, CFL_SIZE * md_calc_size(o, dims)));

	assert(d == md_calc_blockdim(d, odims + 0, ostr + 0, CFL_SIZE));
	assert(u == md_calc_blockdim(u, odims + o, ostr + o, CFL_SIZE * md_calc_size(o, odims)));

	// merge dims

	long wdims[3] = { md_calc_size(d, dims), dims[d], md_calc_size(u, dims + o) };
	long wistr[3] = { CFL_SIZE, istr[d], CFL_SIZE * md_calc_size(o, dims) };
	long wostr[3] = { CFL_SIZE, ostr[d], CFL_SIZE * md_calc_size(o, odims) };

#ifdef  USE_CUDA
	if (cuda_ondevice(in)) {

		assert(cuda_ondevice(low));
		assert(cuda_ondevice(hgh));

		float* flow = md_gpu_move(1, MD_DIMS(flen), filter[0][0], FL_SIZE);
		float* fhgh = md_gpu_move(1, MD_DIMS(flen), filter[0][1], FL_SIZE);

		wl3_cuda_down3(wdims, wostr, low, wistr, in, flen, flow);
		wl3_cuda_down3(wdims, wostr, hgh, wistr, in, flen, fhgh);

		md_free(flow);
		md_free(fhgh);
		return;
	}
#endif

	// no clear needed
	wavelet_down3(wdims, wostr, low, wistr, in, flen, filter[0][0]);
	wavelet_down3(wdims, wostr, hgh, wistr, in, flen, filter[0][1]);
}
Esempio n. 14
0
void iwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const long istr[2 * N], const complex float* in, const long flen, const float filter[2][2][flen])
{
	long idims[2 * N];
	wavelet_dims(N, flags, idims, dims, flen);

	assert(md_calc_size(2 * N, idims) >= md_calc_size(N, dims));

	complex float* tmpA = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out);
	complex float* tmpB = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out);

	long tidims[2 * N];
	md_copy_dims(2 * N, tidims, idims);
	
	long tistrs[2 * N];
	md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE);

	long todims[2 * N];
	md_copy_dims(2 * N, todims, tidims);

	long tostrs[2 * N];

	long ishifts[N];
	for (unsigned int i = 0; i < N; i++)
		ishifts[i] = -shifts[i];

	md_copy2(2 * N, tidims, tistrs, tmpA, istr, in, CFL_SIZE);

	for (int i = N - 1; i >= 0; i--) {	// run backwards to maintain contigous blocks

		if (MD_IS_SET(flags, i)) {

			todims[0 + i] = dims[0 + i];
			todims[N + i] = 1;

			md_calc_strides(2 * N, tostrs, todims, CFL_SIZE);
		
			iwt1(2 * N, i, todims, tostrs, tmpB, tistrs, tmpA, (void*)tmpA + tistrs[N + i], flen, filter);

			md_copy_dims(2 * N, tidims, todims);
			md_copy_dims(2 * N, tistrs, tostrs);

			complex float* swap = tmpA;
			tmpA = tmpB;
			tmpB = swap;
		}
	}

	//md_copy2(N, dims, ostr, out, tostrs, tmpA, CFL_SIZE);
	md_circ_shift2(N, dims, ishifts, ostr, out, tostrs, tmpA, CFL_SIZE);

	md_free(tmpA);
	md_free(tmpB);
}
Esempio n. 15
0
// [AC-Adaptive]
static void radial_self_delays(unsigned int N, float shifts[N], const float phi[N], const long dims[DIMS], const complex float* in)
{
	unsigned int d = 2;
	unsigned int flags = (1 << d);

	assert(N == dims[d]);

	long dims1[DIMS];
	md_select_dims(DIMS, ~flags, dims1, dims);

	complex float* tmp1 = md_alloc(DIMS, dims1, CFL_SIZE);
	complex float* tmp2 = md_alloc(DIMS, dims1, CFL_SIZE);

	long pos[DIMS] = { 0 };

	for (unsigned int i = 0; i < dims[d]; i++) {

		pos[d] = i;
		md_copy_block(DIMS, pos, dims1, tmp1, dims, in, CFL_SIZE);

		// find opposing spoke

		float mdelta = 0.;
		int mindex = 0;

		for (unsigned int j = 0; j < dims[d]; j++) {

			float delta = cabsf(cexpf(1.i * phi[j]) - cexpf(1.i * phi[i]));

			if (mdelta <= delta) {

				mdelta = delta;
				mindex = j;
			}
		}

		pos[d] = mindex;
		md_copy_block(DIMS, pos, dims1, tmp2, dims, in, CFL_SIZE);


		unsigned int d2 = 1;
		float rshifts[DIMS];
		md_flip(DIMS, dims1, MD_BIT(d2), tmp2, tmp2, CFL_SIZE); // could be done by iFFT in est_subpixel_shift
		est_subpixel_shift(DIMS, rshifts, dims1, MD_BIT(d2), tmp2, tmp1);

		float mshift = rshifts[d2] / 2.; // mdelta

		shifts[i] = mshift;
	}

	md_free(tmp1);
	md_free(tmp2);
}
Esempio n. 16
0
File: wavelet.c Progetto: hcmh/bart
void iwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* out, const long istr[N], const complex float* low, const complex float* hgh, const long flen, const float filter[2][2][flen])
{
	debug_printf(DP_DEBUG4, "ifwt1: %d/%d\n", d, N);
	debug_print_dims(DP_DEBUG4, N, dims);

	assert(dims[d] >= 2);

	long idims[N];
	md_copy_dims(N, idims, dims);
	idims[d] = bandsize(dims[d], flen);

	debug_print_dims(DP_DEBUG4, N, idims);

	long o = d + 1;
	long u = N - o;

	// 0 1 2 3 4 5 6|7
	// --d-- * --u--|N
	// ---o---

	assert(d == md_calc_blockdim(d, dims + 0, ostr + 0, CFL_SIZE));
	assert(u == md_calc_blockdim(u, dims + o, ostr + o, CFL_SIZE * md_calc_size(o, dims)));
	assert(d == md_calc_blockdim(d, idims + 0, istr + 0, CFL_SIZE));
	assert(u == md_calc_blockdim(u, idims + o, istr + o, CFL_SIZE * md_calc_size(o, idims)));

	long wdims[3] = { md_calc_size(d, dims), dims[d], md_calc_size(u, dims + o) };
	long wistr[3] = { CFL_SIZE, istr[d], CFL_SIZE * md_calc_size(o, idims) };
	long wostr[3] = { CFL_SIZE, ostr[d], CFL_SIZE * md_calc_size(o, dims) };

	md_clear(3, wdims, out, CFL_SIZE);	// we cannot clear because we merge outputs

#ifdef  USE_CUDA
	if (cuda_ondevice(out)) {

		assert(cuda_ondevice(low));
		assert(cuda_ondevice(hgh));

		float* flow = md_gpu_move(1, MD_DIMS(flen), filter[1][0], FL_SIZE);
		float* fhgh = md_gpu_move(1, MD_DIMS(flen), filter[1][1], FL_SIZE);

		wl3_cuda_up3(wdims, wostr, out, wistr, low, flen, flow);
		wl3_cuda_up3(wdims, wostr, out, wistr, hgh, flen, fhgh);

		md_free(flow);
		md_free(fhgh);
		return;
	}
#endif

	wavelet_up3(wdims, wostr, out, wistr, low, flen, filter[1][0]);
	wavelet_up3(wdims, wostr, out, wistr, hgh, flen, filter[1][1]);
}
Esempio n. 17
0
void noir_recon(const struct noir_conf_s* conf, const long dims[DIMS], complex float* outbuf, complex float* sensout, const complex float* psf, const complex float* mask, const complex float* kspace)
{
	long imgs_dims[DIMS];
	long coil_dims[DIMS];
	long data_dims[DIMS];
	long img1_dims[DIMS];

	md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|CSHIFT_FLAG, imgs_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, coil_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG, data_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS, img1_dims, dims);

	long skip = md_calc_size(DIMS, imgs_dims);
	long size = skip + md_calc_size(DIMS, coil_dims);
	long data_size = md_calc_size(DIMS, data_dims);

	long d1[1] = { size };
	complex float* img = md_alloc_sameplace(1, d1, CFL_SIZE, kspace);
	complex float* imgH = md_alloc_sameplace(1, d1, CFL_SIZE, kspace);


	md_clear(DIMS, imgs_dims, img, CFL_SIZE);

	md_zfill(DIMS, img1_dims, outbuf, 1.);	// initial only first image
	md_copy(DIMS, img1_dims, img, outbuf, CFL_SIZE);

	md_clear(DIMS, coil_dims, img + skip, CFL_SIZE);

	md_clear(DIMS, imgs_dims, imgH, CFL_SIZE);
	md_clear(DIMS, coil_dims, imgH + skip, CFL_SIZE);

	struct noir_data* ndata = noir_init(dims, mask, psf, conf->rvc, conf->usegpu);
	struct data data = { ndata };

	struct iter3_irgnm_conf irgnm_conf = { .iter = conf->iter, .alpha = conf->alpha, .redu = conf->redu };
	iter3_irgnm(&irgnm_conf.base, frw, der, adj, &data, size * 2, (float*)img, data_size * 2, (const float*)kspace);


	md_copy(DIMS, imgs_dims, outbuf, img, CFL_SIZE);

	if (NULL != sensout) {

		assert(!conf->usegpu);
		noir_forw_coils(ndata, sensout, img + skip);
	}

	noir_free(ndata);

	md_free(img);
	md_free(imgH);
}
Esempio n. 18
0
/*
 * Cumulative sum - inverse of finite difference operator 
 *
 * optr = cumsum(iptr);
 */
static void cumsum_apply(const linop_data_t* _data, float lambda, complex float* optr, const complex float* iptr)
{
	const auto data = CAST_DOWN(fdiff_s, _data);

	assert(0. == lambda);

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

	md_zcumsum_core2(data->D, data->dims, data->flags, tmp, tmp2, data->str, optr, data->str, iptr);

	md_free(tmp2);
	md_free(tmp);
}
Esempio n. 19
0
static complex float* compute_psf2(unsigned int N, const long psf_dims[N + 3], const long trj_dims[N + 3], const complex float* traj, const complex float* weights)
{
	unsigned int ND = N + 3;

	long img_dims[ND];
	long img_strs[ND];

	md_select_dims(ND, ~MD_BIT(N + 0), img_dims, psf_dims);
	md_calc_strides(ND, img_strs, img_dims, CFL_SIZE);

	// PSF 2x size

	long img2_dims[ND];
	long img2_strs[ND];

	md_copy_dims(ND, img2_dims, img_dims);

	for (int i = 0; i < 3; i++)
		img2_dims[i] = (1 == img_dims[i]) ? 1 : (2 * img_dims[i]);

	md_calc_strides(ND, img2_strs, img2_dims, CFL_SIZE);

	complex float* traj2 = md_alloc(ND, trj_dims, CFL_SIZE);
	md_zsmul(ND, trj_dims, traj2, traj, 2.);

	complex float* psft = compute_psf(ND, img2_dims, trj_dims, traj2, weights);
	md_free(traj2);

	fftuc(ND, img2_dims, FFT_FLAGS, psft, psft);

	// reformat

	long sub2_strs[ND];
	md_copy_strides(ND, sub2_strs, img2_strs);

	for(int i = 0; i < 3; i++)
		sub2_strs[i] *= 2;;

	complex float* psf = md_alloc(ND, psf_dims, CFL_SIZE);

	long factors[N];

	for (unsigned int i = 0; i < N; i++)
		factors[i] = ((img_dims[i] > 1) && (i < 3)) ? 2 : 1;

	md_decompose(N + 0, factors, psf_dims, psf, img2_dims, psft, CFL_SIZE);

	md_free(psft);
	return psf;
}
Esempio n. 20
0
static double bench_generic_add(long dims[DIMS], unsigned int flags, bool forloop)
{
	long dimsX[DIMS];
	long dimsY[DIMS];

	long dimsC[DIMS];

	md_select_dims(DIMS, flags, dimsX, dims);
	md_select_dims(DIMS, ~flags, dimsC, dims);
	md_select_dims(DIMS, ~0u, dimsY, dims);

	long strsX[DIMS];
	long strsY[DIMS];

	md_calc_strides(DIMS, strsX, dimsX, CFL_SIZE);
	md_calc_strides(DIMS, strsY, dimsY, CFL_SIZE);

	complex float* x = md_alloc(DIMS, dimsX, CFL_SIZE);
	complex float* y = md_alloc(DIMS, dimsY, CFL_SIZE);

	md_gaussian_rand(DIMS, dimsX, x);
	md_gaussian_rand(DIMS, dimsY, y);

	long L = md_calc_size(DIMS, dimsC);
	long T = md_calc_size(DIMS, dimsX);

	double tic = timestamp();

	if (forloop) {

		for (long i = 0; i < L; i++) {

			for (long j = 0; j < T; j++)
				y[i + j * L] += x[j];
		}

	} else {

		md_zaxpy2(DIMS, dims, strsY, y, 1., strsX, x);
	}

	double toc = timestamp();


	md_free(x);
	md_free(y);

	return toc - tic;
}
Esempio n. 21
0
File: tv.c Progetto: andruw17/bart
void tv_adjoint(unsigned int D, const long dims[D], unsigned int flags, complex float* out, const complex float* in)
{
	unsigned int N = bitcount(flags);

	assert(N == dims[D - 1]);	// we use the highest dim to store our different partial derivatives

	unsigned int flags2 = flags;

	complex float* tmp = md_alloc_sameplace(D - 1, dims, CFL_SIZE, out);

	md_clear(D - 1, dims, out, CFL_SIZE);
	md_clear(D - 1, dims, tmp, CFL_SIZE);

	for (unsigned int i = 0; i < N; i++) {

		unsigned int lsb = ffs(flags2) - 1;
		flags2 = MD_CLEAR(flags2, lsb);

		md_zfdiff_backwards(D - 1, dims, lsb, tmp, in + i * md_calc_size(D - 1, dims));
	
		md_zadd(D - 1, dims, out, out, tmp);
	}

	md_free(tmp);

	assert(0 == flags2);
}
Esempio n. 22
0
/**
 * 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;
}
Esempio n. 23
0
void calone(const struct ecalib_conf* conf, const long cov_dims[4], complex float* imgcov, unsigned int SN, float svals[SN], const long calreg_dims[DIMS], const complex float* data)
{
	assert(1 == md_calc_size(DIMS - 5, calreg_dims + 5));

#if 1
	long nskerns_dims[5];
	complex float* nskerns;
	compute_kernels(conf, nskerns_dims, &nskerns, SN, svals, calreg_dims, data);
#else
	long channels = calreg_dims[3];

	long kx = conf->kdims[0];
	long ky = conf->kdims[1];
	long kz = conf->kdims[2];

	long nskerns_dims[5] = { kx, ky, kz, channels, 0 };
	long N = md_calc_size(4, nskerns_dims);

	assert(N > 0);
	nskerns_dims[4] = N;

	complex float* nskerns = md_alloc(5, nskerns_dims, CFL_SIZE);

	long nr_kernels = channels;
	nskerns_dims[4] = channels;
	spirit_kernel(nskerns_dims, nskerns, calreg_dims, data);
#endif

	compute_imgcov(cov_dims, imgcov, nskerns_dims, nskerns);

	md_free(nskerns);
}
Esempio n. 24
0
File: prox.c Progetto: mjacob75/bart
/**
 * 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_iter((struct linop_s*)pdata->op, rho, z, b);
		}

		md_free(b);
	}
}
Esempio n. 25
0
// Forward: from image to kspace
static void nufft_apply(const void* _data, complex float* dst, const complex float* src)
{
	struct nufft_data* data = (struct nufft_data*)_data;

	assert(!data->conf.toeplitz); // if toeplitz linphase has no roll, so would need to be added

	unsigned int ND = data->N + 3;

	md_zmul2(ND, data->cml_dims, data->cml_strs, data->grid, data->cim_strs, src, data->lph_strs, data->linphase);
	linop_forward(data->fft_op, ND, data->cml_dims, data->grid, ND, data->cml_dims, data->grid);
	md_zmul2(ND, data->cml_dims, data->cml_strs, data->grid, data->cml_strs, data->grid, data->img_strs, data->fftmod);

	md_clear(ND, data->ksp_dims, dst, CFL_SIZE);

	complex float* gridX = md_alloc(data->N, data->cm2_dims, CFL_SIZE);

	long factors[data->N];

	for (unsigned int i = 0; i < data->N; i++)
		factors[i] = ((data->img_dims[i] > 1) && (i < 3)) ? 2 : 1;

	md_recompose(data->N, factors, data->cm2_dims, gridX, data->cml_dims, data->grid, CFL_SIZE);

	grid2H(2., data->width, data->beta, ND, data->trj_dims, data->traj, data->ksp_dims, dst, data->cm2_dims, gridX);

	md_free(gridX);

	if (NULL != data->weights)
		md_zmul2(data->N, data->ksp_dims, data->ksp_strs, dst, data->ksp_strs, dst, data->wgh_strs, data->weights);
}
Esempio n. 26
0
complex float* compute_psf(unsigned int N, const long img2_dims[N], const long trj_dims[N], const complex float* traj, const complex float* weights)
{      
	long ksp_dims1[N];
	md_select_dims(N, ~MD_BIT(0), ksp_dims1, trj_dims);

	struct linop_s* op2 = nufft_create(N, ksp_dims1, img2_dims, trj_dims, traj, NULL,
					nufft_conf_defaults, false);

	complex float* ones = md_alloc(N, ksp_dims1, CFL_SIZE);
	md_zfill(N, ksp_dims1, ones, 1.);

	if (NULL != weights) {

		md_zmul(N, ksp_dims1, ones, ones, weights);
		md_zmulc(N, ksp_dims1, ones, ones, weights);
	}

	complex float* psft = md_alloc(N, img2_dims, CFL_SIZE);

	linop_adjoint_unchecked(op2, psft, ones);

	md_free(ones);
	linop_free(op2);

	return psft;
}
Esempio n. 27
0
SSL_ROM_TEXT_SECTION
int md_free_ctx( md_context_t *ctx )
{
    md_free( ctx );

    return( 0 );
}
Esempio n. 28
0
static void mmap_free(mmap_t* m)
{
  if(!m) return;
  munmap(m->data,m->sz);
  fclose(m->f);
  md_free(m);
}
Esempio n. 29
0
static double bench_wavelet_thresh(int version, long scale)
{
	long dims[DIMS] = { 1, 256 * scale, 256 * scale, 1, 16, 1, 1, 1 };
	long minsize[DIMS] = { [0 ... DIMS - 1] = 1 };
	minsize[0] = MIN(dims[0], 16);
	minsize[1] = MIN(dims[1], 16);
	minsize[2] = MIN(dims[2], 16);

	const struct operator_p_s* p;

	switch (version) {
	case 2:
		p = prox_wavethresh_create(DIMS, dims, 7, minsize, 1.1, true, false);
		break;
	case 3:
		p = prox_wavelet3_thresh_create(DIMS, dims, 6, minsize, 1.1, true);
		break;
	default:
		assert(0);
	}

	complex float* x = md_alloc(DIMS, dims, CFL_SIZE);
	md_gaussian_rand(DIMS, dims, x);

	double tic = timestamp();

	operator_p_apply(p, 0.98, DIMS, dims, x, DIMS, dims, x);

	double toc = timestamp();

	md_free(x);
	operator_p_free(p);

	return toc - tic;
}
Esempio n. 30
0
File: someops.c Progetto: hcmh/bart
static void linop_matrix_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src)
{
	struct operator_matrix_s* data = CAST_DOWN(operator_matrix_s, _data);

	if (NULL == data->mat_gram) {

		complex float* tmp = md_alloc_sameplace(data->N, data->out_dims, CFL_SIZE, src);

		linop_matrix_apply(_data, tmp, src);
		linop_matrix_apply_adjoint(_data, dst, tmp);

		md_free(tmp);

	} else {

		const complex float* mat_gram = data->mat_gram;
#ifdef USE_CUDA
		if (cuda_ondevice(src)) {

			if (NULL == data->mat_gram_gpu)
				data->mat_gram_gpu = md_gpu_move(2 * data->N, data->grm_dims, data->mat_gram, CFL_SIZE);

			mat_gram = data->mat_gram_gpu;
		}
#endif
		md_ztenmul(2 * data->N, data->gout_dims, dst, data->gin_dims, src, data->grm_dims, mat_gram);
	}
}