NFFT Logo 3.2.3
mri.c
1 /*
2  * Copyright (c) 2002, 2012 Jens Keiner, Stefan Kunis, Daniel Potts
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 /* $Id: mri.c 3965 2013-04-22 12:12:31Z tovo $ */
20 
21 #include "config.h"
22 
23 #include <string.h>
24 #include <math.h>
25 #ifdef HAVE_COMPLEX_H
26 #include <complex.h>
27 #endif
28 #include "nfft3util.h"
29 #include "nfft3.h"
30 #include "infft.h"
31 
37 typedef struct window_funct_plan_ {
38  int d;
39  int m;
40  int n[1];
41  double sigma[1];
42  double *b;
43  double *spline_coeffs;
46 
50 static void window_funct_init(window_funct_plan* ths, int m, int n, double sigma) {
51  ths->d=1;
52  ths->m=m;
53  ths->n[0]=n;
54  ths->sigma[0]=sigma;
55  WINDOW_HELP_INIT
56 }
57 
58 /*
59  * mri_inh_2d1d
60  */
61 
62 void mri_inh_2d1d_trafo(mri_inh_2d1d_plan *that) {
63  int l,j;
64  double _Complex *f = (double _Complex*) nfft_malloc(that->M_total*sizeof(double _Complex));
65  double _Complex *f_hat = (double _Complex*) nfft_malloc(that->N_total*sizeof(double _Complex));
66 
68  window_funct_init(ths,that->plan.m,that->N3,that->sigma3);
69 
70  /* the pointers that->f and that->f_hat have been modified by the solver */
71  that->plan.f = that->f;
72  that->plan.f_hat = that->f_hat;
73 
74 
75  memset(f,0,that->M_total*sizeof(double _Complex));
76  for(j=0;j<that->N_total;j++)
77  {
78  f_hat[j]=that->f_hat[j];
79  }
80 
81  for(l=-ths->n[0]/2;l<=ths->n[0]/2;l++) {
82  for(j=0;j<that->N_total;j++)
83  that->f_hat[j]*=cexp(-2*PI*_Complex_I*that->w[j]*((double)l))/PHI_HUT(ths->n[0]*that->w[j],0);
84  nfft_trafo(&that->plan);
85  for(j=0;j<that->M_total;j++){
86  /* PHI has compact support */
87  if(fabs(that->t[j]-((double)l)/((double)ths->n[0]))<that->plan.m/((double)ths->n[0]))
88  {
89  double phi_val = PHI(that->t[j]-((double)l)/((double)ths->n[0]),0);
90  f[j]+=that->f[j]*phi_val;
91 // the line below causes internal compiler error for gcc 4.7.1
92 // f[j]+=that->f[j]*PHI(that->t[j]-((double)l)/((double)ths->n[0]),0);
93  }
94  }
95  for(j=0;j<that->N_total;j++)
96  that->f_hat[j]=f_hat[j];
97  }
98 
99  nfft_free(that->plan.f);
100  that->f=f;
101  that->plan.f = that->f;
102 
103  nfft_free(f_hat);
104 
105  WINDOW_HELP_FINALIZE
106  nfft_free(ths);
107 }
108 
109 void mri_inh_2d1d_adjoint(mri_inh_2d1d_plan *that) {
110  int l,j;
111  double _Complex *f = (double _Complex*) nfft_malloc(that->M_total*sizeof(double _Complex));
112  double _Complex *f_hat = (double _Complex*) nfft_malloc(that->N_total*sizeof(double _Complex));
113 
115  window_funct_init(ths,that->plan.m,that->N3,that->sigma3);
116 
117  memset(f_hat,0,that->N_total*sizeof(double _Complex));
118 
119  /* the pointers that->f and that->f_hat have been modified by the solver */
120  that->plan.f = that->f;
121  that->plan.f_hat = that->f_hat;
122 
123  for(j=0;j<that->M_total;j++)
124  {
125  f[j]=that->f[j];
126  }
127 
128 
129 
130  for(l=-ths->n[0]/2;l<=ths->n[0]/2;l++) {
131 
132  for(j=0;j<that->M_total;j++) {
133  /* PHI has compact support */
134  if(fabs(that->t[j]-((double)l)/((double)ths->n[0]))<that->plan.m/((double)ths->n[0]))
135  that->f[j]*=PHI(that->t[j]-((double)l)/((double)ths->n[0]),0);
136  else
137  that->f[j]=0.0;
138  }
139  nfft_adjoint(&that->plan);
140  for(j=0;j<that->N_total;j++)
141  f_hat[j]+=that->f_hat[j]*cexp(2*PI*_Complex_I*that->w[j]*((double)l));
142  for(j=0;j<that->M_total;j++)
143  that->f[j]=f[j];
144  }
145 
146  for(j=0;j<that->N_total;j++)
147  {
148  f_hat[j] /= PHI_HUT(ths->n[0]*that->w[j],0);
149  }
150 
151  nfft_free(that->plan.f_hat);
152  that->f_hat=f_hat;
153  that->plan.f_hat = that->f_hat;
154 
155  nfft_free(f);
156 
157  WINDOW_HELP_FINALIZE
158  nfft_free(ths);
159 }
160 
161 void mri_inh_2d1d_init_guru(mri_inh_2d1d_plan *ths, int *N, int M, int *n,
162  int m, double sigma, unsigned nfft_flags, unsigned fftw_flags) {
163 
164  nfft_init_guru(&ths->plan,2,N,M,n,m,nfft_flags,fftw_flags);
165  ths->N3=N[2];
166  ths->sigma3=sigma;
167  ths->N_total = ths->plan.N_total;
168  ths->M_total = ths->plan.M_total;
169  ths->f = ths->plan.f;
170  ths->f_hat = ths->plan.f_hat;
171 
172  ths->t = (double*) nfft_malloc(ths->M_total*sizeof(double));
173  ths->w = (double*) nfft_malloc(ths->N_total*sizeof(double));
174 
175  ths->mv_trafo = (void (*) (void* ))mri_inh_2d1d_trafo;
176  ths->mv_adjoint = (void (*) (void* ))mri_inh_2d1d_adjoint;
177 }
178 
179 void mri_inh_2d1d_finalize(mri_inh_2d1d_plan *ths) {
180  nfft_free(ths->t);
181  nfft_free(ths->w);
182 
183  /* the pointers ths->f and ths->f_hat have been modified by the solver */
184  ths->plan.f = ths->f;
185  ths->plan.f_hat = ths->f_hat;
186 
187  nfft_finalize(&ths->plan);
188 }
189 
190 /*
191  * mri_inh_3d
192  */
193 
194 void mri_inh_3d_trafo(mri_inh_3d_plan *that) {
195  int l,j;
197  window_funct_init(ths,that->plan.m,that->N3,that->sigma3);
198 
199  /* the pointers that->f has been modified by the solver */
200  that->plan.f =that->f ;
201 
202 
203 
204  for(j=0;j<that->N_total;j++) {
205  for(l=-ths->n[0]/2;l<ths->n[0]/2;l++)
206  {
207  /* PHI has compact support */
208  if(fabs(that->w[j]-((double)l)/((double)ths->n[0]))<ths->m/((double)ths->n[0]))
209  that->plan.f_hat[j*ths->n[0]+(l+ths->n[0]/2)]= that->f_hat[j]*PHI(that->w[j]-((double)l)/((double)ths->n[0]),0);
210  else
211  that->plan.f_hat[j*ths->n[0]+(l+ths->n[0]/2)]=0.0;
212  }
213  }
214 
215  nfft_trafo(&that->plan);
216 
217  for(j=0;j<that->M_total;j++)
218  {
219  that->f[j] /= PHI_HUT(ths->n[0]*that->plan.x[3*j+2],0);
220  }
221 
222  WINDOW_HELP_FINALIZE
223  nfft_free(ths);
224 }
225 
226 void mri_inh_3d_adjoint(mri_inh_3d_plan *that) {
227  int l,j;
229  window_funct_init(ths,that->plan.m,that->N3,that->sigma3);
230 
231  /* the pointers that->f has been modified by the solver */
232  that->plan.f =that->f ;
233 
234  for(j=0;j<that->M_total;j++)
235  {
236  that->f[j] /= PHI_HUT(ths->n[0]*that->plan.x[3*j+2],0);
237  }
238 
239  nfft_adjoint(&that->plan);
240 
241  for(j=0;j<that->N_total;j++) {
242  that->f_hat[j]=0.0;
243  for(l=-ths->n[0]/2;l<ths->n[0]/2;l++)
244  {
245  /* PHI has compact support */
246  if(fabs(that->w[j]-((double)l)/((double)ths->n[0]))<ths->m/((double)ths->n[0]))
247  that->f_hat[j]+= that->plan.f_hat[j*ths->n[0]+(l+ths->n[0]/2)]*PHI(that->w[j]-((double)l)/((double)ths->n[0]),0);
248  }
249  }
250 
251 
252  WINDOW_HELP_FINALIZE
253  nfft_free(ths);
254 }
255 
256 void mri_inh_3d_init_guru(mri_inh_3d_plan *ths, int *N, int M, int *n,
257  int m, double sigma, unsigned nfft_flags, unsigned fftw_flags) {
258  ths->N3=N[2];
259  ths->sigma3=sigma;
260  nfft_init_guru(&ths->plan,3,N,M,n,m,nfft_flags,fftw_flags);
261  ths->N_total = N[0]*N[1];
262  ths->M_total = ths->plan.M_total;
263  ths->f = ths->plan.f;
264  ths->f_hat = (double _Complex*) nfft_malloc(ths->N_total*sizeof(double _Complex));
265  ths->w = (double*) nfft_malloc(ths->N_total*sizeof(double));
266 
267  ths->mv_trafo = (void (*) (void* ))mri_inh_3d_trafo;
268  ths->mv_adjoint = (void (*) (void* ))mri_inh_3d_adjoint;
269 }
270 
271 void mri_inh_3d_finalize(mri_inh_3d_plan *ths) {
272  nfft_free(ths->w);
273  nfft_free(ths->f_hat);
274  nfft_finalize(&ths->plan);
275 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1