コード例 #1
0
ファイル: someops.c プロジェクト: welcheb/bart
/**
 * Create an Identity linear operator: I x
 * @param N number of dimensions
 * @param dims dimensions of input (domain)
 */
struct linop_s* linop_identity_create(unsigned int N, const long dims[N])
{
	PTR_ALLOC(struct identity_data_s, data);
	SET_TYPEID(identity_data_s, data);

	data->domain = iovec_create(N, dims, CFL_SIZE);

	return linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), identity_apply, identity_apply, identity_apply, NULL, identity_free);
}
コード例 #2
0
ファイル: someops.c プロジェクト: welcheb/bart
/**
 * Operator interface for a true matrix:
 * out = mat * in
 * in:	[x x x x 1 x x K x x]
 * mat:	[x x x x T x x K x x]
 * out:	[x x x x T x x 1 x x]
 * where the x's are arbitrary dimensions and T and K may be transposed
 *
 * use this interface if K == 1 or T == 1
 *
 * @param N number of dimensions
 * @param out_dims output dimensions after applying the matrix (codomain)
 * @param in_dims input dimensions to apply the matrix (domain)
 * @param T_dim dimension corresponding to the rows of A
 * @param K_dim dimension corresponding to the columns of A
 * @param matrix matrix data
 */
struct linop_s* linop_matrix_altcreate(unsigned int N, const long out_dims[N], const long in_dims[N], const unsigned int T_dim, const unsigned int K_dim, const complex float* matrix)
{
	long matrix_dims[N];
	md_singleton_dims(N, matrix_dims);

	matrix_dims[K_dim] = in_dims[K_dim];
	matrix_dims[T_dim] = out_dims[T_dim];

	unsigned int T = out_dims[T_dim];
	unsigned int K = in_dims[K_dim];

	PTR_ALLOC(long[N], max_dims);

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

		if ((in_dims[i] > 1) && (out_dims[i] == 1)) {

			(*max_dims)[i] = in_dims[i];
		}
		else if ((in_dims[i] == 1) && (out_dims[i] > 1)) {

			(*max_dims)[i] = out_dims[i];
		}
		else {

			assert(in_dims[i] == out_dims[i]);

			(*max_dims)[i] = in_dims[i];
		}
	}

	complex float* mat = md_alloc_sameplace(N, matrix_dims, CFL_SIZE, matrix);
	complex float* matc = md_alloc_sameplace(N, matrix_dims, CFL_SIZE, matrix);

	md_copy(N, matrix_dims, mat, matrix, CFL_SIZE);
	md_zconj(N, matrix_dims, matc, mat);

	complex float* gram = NULL;
	const struct iovec_s* gram_iovec = compute_gram_matrix(N, T_dim, T, K_dim, K, &gram, matrix_dims, matrix);

	PTR_ALLOC(struct operator_matrix_s, data);
	SET_TYPEID(operator_matrix_s, data);

	data->mat_iovec = iovec_create(N, matrix_dims, CFL_SIZE);
	data->mat_gram_iovec = gram_iovec;

	data->max_dims = *max_dims;

	data->mat = mat;
	data->mat_conj = matc;
	data->mat_gram = gram;

	data->K_dim = K_dim;
	data->T_dim = T_dim;
	data->K = K;
	data->T = T;

	data->domain_iovec = iovec_create(N, in_dims, CFL_SIZE);
	data->codomain_iovec = iovec_create(N, out_dims, CFL_SIZE);

	return linop_create(N, out_dims, N, in_dims, CAST_UP(PTR_PASS(data)), linop_matrix_apply, linop_matrix_apply_adjoint, linop_matrix_apply_normal, NULL, linop_matrix_del);
}
コード例 #3
0
ファイル: someops.c プロジェクト: welcheb/bart
/**
 * Compute the Gram matrix, A^H A.
 * Stores the result in @param gram, which is allocated by the function
 * Returns: iovec_s corresponding to the gram matrix dimensions
 *
 * @param N number of dimensions
 * @param T_dim dimension corresponding to the rows of A
 * @param T number of rows of A (codomain)
 * @param K_dim dimension corresponding to the columns of A
 * @param K number of columns of A (domain)
 * @param gram store the result (allocated by this function)
 * @param matrix_dims dimensions of A
 * @param matrix matrix data
 */
const struct iovec_s* compute_gram_matrix(unsigned int N, unsigned int T_dim, unsigned int T, unsigned int K_dim, unsigned int K, complex float** gram, const long matrix_dims[N], const complex float* matrix)
{
	// FIXME this can certainly be simplfied...
	// Just be careful to consider the case where the data passed to the operator is a subset of a bigger array
	

	// B_dims = [T K 1]  or  [K T 1]
	// C_dims = [T 1 K]  or  [1 T K]
	// A_dims = [1 K K]  or  [K 1 K]
	// after: gram_dims = [1 K1 K2] --> [K2 K1 1]  or  [K1 1 K2] --> [K1 K2 1]

	long A_dims[N + 1];
	long B_dims[N + 1];
	long C_dims[N + 1];
	long fake_gram_dims[N + 1];

	long A_str[N + 1];
	long B_str[N + 1];
	long C_str[N + 1];
	long max_dims[N + 1];

	md_singleton_dims(N + 1, A_dims);
	md_singleton_dims(N + 1, B_dims);
	md_singleton_dims(N + 1, C_dims);
	md_singleton_dims(N + 1, fake_gram_dims);
	md_singleton_dims(N + 1, max_dims);

	A_dims[K_dim] = K;
	A_dims[N] = K;

	B_dims[T_dim] = T;
	B_dims[K_dim] = K;

	C_dims[T_dim] = T;
	C_dims[N] = K;

	max_dims[T_dim] = T;
	max_dims[K_dim] = K;
	max_dims[N] = K;

	fake_gram_dims[T_dim] = K;
	fake_gram_dims[K_dim] = K;

	md_calc_strides(N + 1, A_str, A_dims, CFL_SIZE);
	md_calc_strides(N + 1, B_str, B_dims, CFL_SIZE);
	md_calc_strides(N + 1, C_str, C_dims, CFL_SIZE);

	complex float* tmpA = md_alloc_sameplace(N + 1 , A_dims, CFL_SIZE, matrix);
	complex float* tmpB = md_alloc_sameplace(N + 1, B_dims, CFL_SIZE, matrix);
	complex float* tmpC = md_alloc_sameplace(N + 1, C_dims, CFL_SIZE, matrix);

	md_copy(N, matrix_dims, tmpB, matrix, CFL_SIZE);
	//md_copy(N, matrix_dims, tmpC, matrix, CFL_SIZE);

	md_transpose(N + 1, K_dim, N, C_dims, tmpC, B_dims, tmpB, CFL_SIZE);
	md_clear(N + 1, A_dims, tmpA, CFL_SIZE);
	md_zfmacc2(N + 1, max_dims, A_str, tmpA, B_str, tmpB, C_str, tmpC);

	*gram = md_alloc_sameplace(N, fake_gram_dims, CFL_SIZE, matrix);
	md_transpose(N + 1, T_dim, N, fake_gram_dims, *gram, A_dims, tmpA, CFL_SIZE); 


	const struct iovec_s* s =  iovec_create(N, fake_gram_dims, CFL_SIZE);

	md_free(tmpA);
	md_free(tmpB);
	md_free(tmpC);

	return s;
}
コード例 #4
0
ファイル: someops.c プロジェクト: morpheus-med/bart
/**
 * Create an Identity linear operator: I x
 * @param N number of dimensions
 * @param dims dimensions of input (domain)
 */
struct linop_s* linop_identity_create(unsigned int N, const long dims[N])
{
	const struct iovec_s* domain = iovec_create(N, dims, CFL_SIZE);

	return linop_create(N, dims, N, dims, (void*)domain, identity_apply, identity_apply, identity_apply, NULL, identity_free);
}