00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <fftw3.h>
00005 #include "fftw_convolve.h"
00006
00007
00008
00009
00010 fftw_convolve_op *dfftw_convolve_1d_prepare(int reva, int na, int nb,
00011 double *a, double *padb,
00012 fftw_complex *padc)
00013 {
00014 int i,N=na+nb-1;
00015 fftw_convolve_op *op;
00016 fftw_plan p;
00017
00018
00019 op = (fftw_convolve_op *) malloc(sizeof(fftw_convolve_op));
00020 op->na = na;
00021 op->nb = nb;
00022 op->N = N;
00023 op->ma = 1;
00024 op->mb = 1;
00025 op->M = 1;
00026 op->scale = 1.0/op->N;
00027 op->pada = fftw_malloc(sizeof(double) * 2*(N/2+1));
00028 if (padb==NULL)
00029 {
00030 op->padb = fftw_malloc(sizeof(double) * 2*(N/2+1));
00031 op->freeb = 1;
00032 }
00033 else
00034 {
00035 op->padb = padb;
00036 op->freeb = 0;
00037 }
00038 if (padc==NULL)
00039 {
00040 op->cc = fftw_malloc(sizeof(fftw_complex) * (N/2+1));
00041 op->freec = 1;
00042 }
00043 else
00044 {
00045 op->cc = padc;
00046 op->freec = 0;
00047 }
00048 #pragma omp critical
00049 {
00050 p = fftw_plan_dft_r2c_1d(N, op->pada, (fftw_complex *)(op->pada),
00051 FFTW_MEASURE);
00052 op->q = fftw_plan_dft_r2c_1d(N, op->padb, (fftw_complex *)(op->padb),
00053 FFTW_MEASURE);
00054 op->s = fftw_plan_dft_c2r_1d(N, op->cc, (double *)(op->cc),
00055 FFTW_MEASURE);
00056 }
00057
00058
00059 if (!reva)
00060 memcpy(op->pada, a, na*sizeof(double));
00061 else
00062 for (i=0; i<na; i++)
00063 op->pada[i] = a[na-1-i];
00064 memset(&(op->pada[na]), 0, (2*(N/2+1)-na)*sizeof(double));
00065
00066
00067 fftw_execute(p);
00068
00069
00070 fftw_destroy_plan(p);
00071
00072
00073 return op;
00074 }
00075
00076
00077 void dfftw_convolve_1d_execute(fftw_convolve_op *op, int revb,
00078 double *b, double *c)
00079 {
00080 int i;
00081 int N,nb;
00082 double scale,*pada, *padb, *rc;
00083 fftw_complex *cc, *ca, *cb;
00084 fftw_plan q,s;
00085
00086 nb = op->nb;
00087 N = op->N;
00088 scale = op->scale;
00089 pada = op->pada;
00090 padb = op->padb;
00091 cc = op->cc;
00092 q = op->q;
00093 s = op->s;
00094
00095
00096 ca = (fftw_complex *) pada;
00097 cb = (fftw_complex *) padb;
00098 if (!revb)
00099 memcpy(padb, b, nb*sizeof(double));
00100 else
00101 for (i=0; i<nb; i++)
00102 padb[i] = b[nb-1-i];
00103 memset(&padb[nb], 0, (2*(N/2+1)-nb)*sizeof(double));
00104
00105 rc = (double *) cc;
00106
00107
00108 fftw_execute(q);
00109
00110
00111 for (i=0; i<N/2+1; i++)
00112 {
00113 double ra, ia, rb,ib;
00114 ra = ca[i][0];
00115 ia = ca[i][1];
00116 rb = cb[i][0];
00117 ib = cb[i][1];
00118
00119 cc[i][0] = ra*rb - ia*ib;
00120 cc[i][1] = ra*ib + ia*rb;
00121 }
00122
00123 fftw_execute(s);
00124
00125
00126 for (i=0; i<N; i++)
00127 c[i] = scale*rc[i];
00128 }
00129
00130 void dfftw_convolve_1d_free(fftw_convolve_op *op)
00131 {
00132 if (op==NULL)
00133 return;
00134
00135
00136 if (op->q)
00137 {
00138 fftw_destroy_plan(op->q);
00139 op->q = NULL;
00140 }
00141 if (op->s)
00142 {
00143 fftw_destroy_plan(op->s);
00144 op->s = NULL;
00145 }
00146
00147 if (op->pada) {
00148 fftw_free(op->pada);
00149 op->pada = NULL;
00150 }
00151 if (op->freeb && op->padb)
00152 {
00153 fftw_free(op->padb);
00154 op->padb = NULL;
00155 }
00156 if (op->freec && op->cc)
00157 {
00158 fftw_free(op->cc);
00159 op->cc = NULL;
00160 }
00161 free(op);
00162 }
00163
00164
00165
00166
00167 void dfftw_convolve_1d(int reva, int na, double *a, int revb, int nb,
00168 double *b, double *c)
00169 {
00170 int i;
00171 int N = na+nb-1;
00172 double scale=1.0/N, *pada, *padb, *rc;
00173 fftw_complex *cc, *ca, *cb;
00174 fftw_plan p,q,s;
00175
00176
00177 pada = fftw_malloc(sizeof(double) * 2*(N/2+1));
00178 padb = fftw_malloc(sizeof(double) * 2*(N/2+1));
00179 cc = fftw_malloc(sizeof(fftw_complex) * (N/2+1));
00180 #pragma omp critical
00181 {
00182 p = fftw_plan_dft_r2c_1d(N, pada, (fftw_complex *)pada, FFTW_MEASURE);
00183 q = fftw_plan_dft_r2c_1d(N, padb, (fftw_complex *)padb, FFTW_MEASURE);
00184 s = fftw_plan_dft_c2r_1d(N, cc, (double *)cc, FFTW_MEASURE);
00185 }
00186
00187 ca = (fftw_complex *) pada;
00188 if (!reva)
00189 memcpy(pada, a, na*sizeof(double));
00190 else
00191 for (i=0; i<na; i++)
00192 pada[i] = a[na-1-i];
00193 memset(&pada[na], 0, (2*(N/2+1)-na)*sizeof(double));
00194
00195 cb = (fftw_complex *) padb;
00196 if (!revb)
00197 memcpy(padb, b, nb*sizeof(double));
00198 else
00199 for (i=0; i<nb; i++)
00200 padb[i] = b[nb-1-i];
00201 memset(&padb[nb], 0, (2*(N/2+1)-nb)*sizeof(double));
00202
00203 rc = (double *) cc;
00204
00205
00206 fftw_execute(p);
00207 fftw_execute(q);
00208
00209
00210 for (i=0; i<N/2+1; i++)
00211 {
00212 double ra, ia, rb,ib;
00213 ra = ca[i][0];
00214 ia = ca[i][1];
00215 rb = cb[i][0];
00216 ib = cb[i][1];
00217
00218 cc[i][0] = ra*rb - ia*ib;
00219 cc[i][1] = ra*ib + ia*rb;
00220 }
00221
00222 fftw_execute(s);
00223
00224
00225 for (i=0; i<N; i++)
00226 c[i] = scale*rc[i];
00227
00228
00229
00230 fftw_destroy_plan(p);
00231 fftw_destroy_plan(q);
00232 fftw_destroy_plan(s);
00233
00234 fftw_free(pada);
00235 fftw_free(padb);
00236 fftw_free(cc);
00237 }
00238
00239
00240
00241 fftw_convolve_op *dfftw_convolve_2d_prepare(int ma, int na,
00242 int mb, int nb, double *a,
00243 double *padb, fftw_complex *padc)
00244 {
00245 fftw_convolve_op *op;
00246 double scale;
00247 int i,j;
00248 int N = na+nb-1, M = ma+mb-1;
00249 fftw_plan p;
00250
00251
00252 op = (fftw_convolve_op *) malloc(sizeof(fftw_convolve_op));
00253 op->na = na;
00254 op->nb = nb;
00255 op->N = N;
00256 op->ma = ma;
00257 op->mb = mb;
00258 op->M = M;
00259 op->pada = fftw_malloc(sizeof(double) * N*2*(M/2+1));
00260 if (padb==NULL)
00261 {
00262 op->padb = fftw_malloc(sizeof(double) * N*2*(M/2+1));
00263 op->freeb = 1;
00264 }
00265 else
00266 {
00267 op->padb = padb;
00268 op->freeb = 0;
00269 }
00270 if (padc==NULL)
00271 {
00272 op->cc = fftw_malloc(sizeof(fftw_complex) * N*(M/2+1));
00273 op->freec = 1;
00274 }
00275 else
00276 {
00277 op->cc = padc;
00278 op->freec = 0;
00279 }
00280 #pragma omp critical
00281 {
00282 p = fftw_plan_dft_r2c_2d(N, M, op->pada, (fftw_complex *)(op->pada),
00283 FFTW_MEASURE);
00284 op->q = fftw_plan_dft_r2c_2d(N, M, op->padb, (fftw_complex *)(op->padb),
00285 FFTW_MEASURE);
00286 op->s = fftw_plan_dft_c2r_2d(N, M, op->cc, (double *)(op->cc),
00287 FFTW_MEASURE);
00288 }
00289
00290
00291 scale = 1.0/(M*N);
00292 for (i=0; i<na; i++)
00293 {
00294 for (j=0; j<ma; j++)
00295 op->pada[i*2*(M/2+1)+j] = scale*a[i*ma+j];
00296 memset(&(op->pada[i*2*(M/2+1)+ma]),0,sizeof(double)*(2*(M/2+1)-ma));
00297 }
00298 for (i=na; i<N; i++)
00299 memset(&(op->pada[i*2*(M/2+1)]),0,sizeof(double)*2*(M/2+1));
00300
00301 op->scale = 1.0;
00302
00303
00304 fftw_execute(p);
00305
00306
00307
00308 fftw_destroy_plan(p);
00309
00310 return op;
00311 }
00312
00313
00314 void dfftw_convolve_2d_execute(fftw_convolve_op *op, int shape, int reva,
00315 int revb, double *b, double alpha,
00316 double beta, double *c)
00317 {
00318 int i,j, ii,jj;
00319 int N, M;
00320 int na,nb,ma,mb;
00321 double *pada, *padb, *rc;
00322 fftw_complex *cc, *ca, *cb;
00323 fftw_plan q,s;
00324
00325 na = op->na;
00326 nb = op->nb;
00327 N = op->N;
00328 ma = op->ma;
00329 mb = op->mb;
00330 M = op->M;
00331 pada = op->pada;
00332 padb = op->padb;
00333 cc = op->cc;
00334 q = op->q;
00335 s = op->s;
00336
00337
00338 for (i=0; i<nb; i++)
00339 {
00340 if ((!reva && revb) || (reva && !revb))
00341 for (j=0; j<mb; j++)
00342 padb[i*2*(M/2+1)+j] = b[(nb-1-i)*mb+(mb-1-j)];
00343 else
00344 memcpy(&padb[i*2*(M/2+1)], &b[i*mb], mb*sizeof(double));
00345 memset(&padb[i*2*(M/2+1)+mb],0,sizeof(double)*(2*(M/2+1)-mb));
00346 }
00347 for (i=nb; i<N; i++)
00348 memset(&padb[i*2*(M/2+1)],0,sizeof(double)*2*(M/2+1));
00349
00350
00351 fftw_execute(q);
00352
00353
00354 ca = (fftw_complex *) pada;
00355 cb = (fftw_complex *) padb;
00356 for (j=0; j<N; j++)
00357 for (i=0; i<(M/2+1); i++)
00358 {
00359 double ra, ia, rb,ib;
00360 ra = ca[j*(M/2+1)+i][0];
00361 ia = ca[j*(M/2+1)+i][1];
00362 rb = cb[j*(M/2+1)+i][0];
00363 ib = cb[j*(M/2+1)+i][1];
00364
00365 cc[j*(M/2+1)+i][0] = ra*rb - ia*ib;
00366 cc[j*(M/2+1)+i][1] = ra*ib + ia*rb;
00367 }
00368
00369
00370 fftw_execute(s);
00371
00372
00373 rc = (double *) cc;
00374
00375 switch(shape)
00376 {
00377 case FFTW_CONV_SHAPE_FULL:
00378 if (!reva)
00379 {
00380 if (beta==0.0 && alpha==1.0)
00381 for (j=0; j<N; j++)
00382 for (i=0; i<M; i++)
00383 c[j*M+i] = rc[2*j*(M/2+1)+i];
00384 else if (beta==1.0 && alpha==1.0)
00385 for (j=0; j<N; j++)
00386 for (i=0; i<M; i++)
00387 c[j*M+i] += rc[2*j*(M/2+1)+i];
00388 else
00389 for (j=0; j<N; j++)
00390 for (i=0; i<M; i++)
00391 c[j*M+i] = alpha*rc[2*j*(M/2+1)+i] + beta*c[j*M+i];
00392 }
00393 else
00394 {
00395 if (beta==0.0 && alpha==1.0)
00396 for (j=0; j<N; j++)
00397 for (i=0; i<M; i++)
00398 c[j*M+i] = rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00399 else if (beta==1.0 && alpha==1.0)
00400 for (j=0; j<N; j++)
00401 for (i=0; i<M; i++)
00402 c[j*M+i] += rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00403 else
00404 for (j=0; j<N; j++)
00405 for (i=0; i<M; i++)
00406 c[j*M+i] = alpha*rc[2*(N-j-1)*(M/2+1)+(M-i-1)] + beta*c[j*M+i];
00407 }
00408 break;
00409 case FFTW_CONV_SHAPE_AS_A:
00410 if (!reva)
00411 {
00412 if (beta==0.0 && alpha==1.0)
00413 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00414 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00415 c[jj*ma+ii] = rc[2*j*(M/2+1)+i];
00416 else if (beta==1.0 && alpha==1.0)
00417 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00418 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00419 c[jj*ma+ii] += rc[2*j*(M/2+1)+i];
00420 else
00421 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00422 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00423 c[jj*ma+ii] = alpha*rc[2*j*(M/2+1)+i] + beta*c[jj*ma+ii];
00424 }
00425 else
00426 {
00427 if (beta==0.0 && alpha==1.0)
00428 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00429 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00430 c[jj*ma+ii] = rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00431 else if (beta==1.0 && alpha==1.0)
00432 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00433 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00434 c[jj*ma+ii] += rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00435 else
00436 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00437 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00438 c[jj*ma+ii] = alpha*rc[2*(N-j-1)*(M/2+1)+(M-i-1)] + beta*c[jj*ma+ii];
00439 }
00440 break;
00441 case FFTW_CONV_SHAPE_AS_B:
00442 if (!reva)
00443 {
00444 if (beta==0.0 && alpha==1.0)
00445 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00446 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00447 c[jj*mb+ii] = rc[2*j*(M/2+1)+i];
00448 else if (beta==1.0 && alpha==1.0)
00449 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00450 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00451 c[jj*mb+ii] += rc[2*j*(M/2+1)+i];
00452 else
00453 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00454 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00455 c[jj*mb+ii] = alpha*rc[2*j*(M/2+1)+i] + beta*c[jj*mb+ii];
00456 }
00457 else
00458 {
00459 if (beta==0.0 && alpha==1.0)
00460 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00461 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00462 c[jj*mb+ii] = rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00463 else if (beta==1.0 && alpha==1.0)
00464 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00465 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00466 c[jj*mb+ii] += rc[2*(N-j-1)*(M/2+1)+(M-i-1)];
00467 else
00468 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00469 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00470 c[jj*mb+ii] = alpha*rc[2*(N-j-1)*(M/2+1)+(M-i-1)] + beta*c[jj*mb+ii];
00471 }
00472 break;
00473 default:
00474 fprintf(stderr,"%s:%d: ERROR: Unknown shape parameter %d.\n",
00475 __FILE__,__LINE__,shape);
00476 abort();
00477 break;
00478 }
00479 }
00480
00481
00482 void dfftw_convolve_2d_free(fftw_convolve_op *op)
00483 {
00484 dfftw_convolve_1d_free(op);
00485 }
00486
00487 void dfftw_convolve_2d(int shape,
00488 int reva, int ma, int na, double *a,
00489 int revb, int mb, int nb, double *b,
00490 double alpha, double beta, double *c)
00491 {
00492 int i,j, ii, jj;
00493 int N = na+nb-1, M = ma+mb-1;
00494 double scale=alpha/(N*M), *pada, *padb, *rc;
00495 fftw_complex *cc, *ca, *cb;
00496 fftw_plan p,q,s;
00497
00498
00499
00500 pada = fftw_malloc(sizeof(double) * N*2*(M/2+1));
00501 padb = fftw_malloc(sizeof(double) * N*2*(M/2+1));
00502 cc = fftw_malloc(sizeof(fftw_complex) * N*(M/2+1));
00503 #pragma omp critical
00504 {
00505 p = fftw_plan_dft_r2c_2d(N, M, pada, (fftw_complex *)pada, FFTW_MEASURE);
00506 q = fftw_plan_dft_r2c_2d(N, M, padb, (fftw_complex *)padb, FFTW_MEASURE);
00507 s = fftw_plan_dft_c2r_2d(N, M, cc, (double *)cc, FFTW_MEASURE);
00508 }
00509
00510 for (i=0; i<na; i++)
00511 {
00512 if (!reva)
00513 memcpy(&pada[i*2*(M/2+1)], &a[i*ma], ma*sizeof(double));
00514 else
00515 for (j=0; j<ma; j++)
00516 pada[i*2*(M/2+1)+j] = a[(na-1-i)*ma+(ma-1-j)];
00517 memset(&pada[i*2*(M/2+1)+ma],0,sizeof(double)*(2*(M/2+1)-ma));
00518 }
00519 for (i=na; i<N; i++)
00520 memset(&pada[i*2*(M/2+1)],0,sizeof(double)*2*(M/2+1));
00521
00522 for (i=0; i<nb; i++)
00523 {
00524 if (!revb)
00525 memcpy(&padb[i*2*(M/2+1)], &b[i*mb], mb*sizeof(double));
00526 else
00527 for (j=0; j<mb; j++)
00528 padb[i*2*(M/2+1)+j] = b[(nb-1-i)*mb+(mb-1-j)];
00529 memset(&padb[i*2*(M/2+1)+mb],0,sizeof(double)*(2*(M/2+1)-mb));
00530 }
00531 for (i=nb; i<N; i++)
00532 memset(&padb[i*2*(M/2+1)],0,sizeof(double)*2*(M/2+1));
00533
00534
00535
00536 fftw_execute(p);
00537 fftw_execute(q);
00538
00539
00540 ca = (fftw_complex *) pada;
00541 cb = (fftw_complex *) padb;
00542 for (j=0; j<N; j++)
00543 for (i=0; i<(M/2+1); i++)
00544 {
00545 double ra, ia, rb,ib;
00546 ra = ca[j*(M/2+1)+i][0];
00547 ia = ca[j*(M/2+1)+i][1];
00548 rb = cb[j*(M/2+1)+i][0];
00549 ib = cb[j*(M/2+1)+i][1];
00550
00551 cc[j*(M/2+1)+i][0] = ra*rb - ia*ib;
00552 cc[j*(M/2+1)+i][1] = ra*ib + ia*rb;
00553 }
00554
00555
00556 fftw_execute(s);
00557
00558
00559 rc = (double *) cc;
00560 switch(shape)
00561 {
00562 case FFTW_CONV_SHAPE_FULL:
00563 for (j=0; j<N; j++)
00564 for (i=0; i<M; i++)
00565 c[j*M+i] = scale*rc[2*j*(M/2+1)+i];
00566 break;
00567 case FFTW_CONV_SHAPE_AS_A:
00568 for (jj=0, j=nb/2; j<na+nb/2; j++, jj++)
00569 for (ii=0, i=mb/2; i<ma+mb/2; i++, ii++)
00570 c[jj*ma+ii] = scale*rc[2*j*(M/2+1)+i];
00571 break;
00572 case FFTW_CONV_SHAPE_AS_B:
00573 for (jj=0, j=na/2; j<na/2+nb; j++, jj++)
00574 for (ii=0, i=ma/2; i<ma/2+mb; i++, ii++)
00575 c[jj*mb+ii] = scale*rc[2*j*(M/2+1)+i];
00576 break;
00577 default:
00578 fprintf(stderr,"%s:%d: ERROR: Unknown shape parameter %d.\n",
00579 __FILE__,__LINE__,shape);
00580 abort();
00581 break;
00582 }
00583
00584
00585 {
00586 fftw_destroy_plan(p);
00587 fftw_destroy_plan(q);
00588 fftw_destroy_plan(s);
00589 }
00590 fftw_free(pada);
00591 fftw_free(padb);
00592 fftw_free(cc);
00593 }
00594
00595
00596
00597 void dfftw_corr_1d_(int *na, double *a, int *nb, double *b, double *c)
00598 {
00599 dfftw_corr_1d(*na, a, *nb, b, c);
00600 }
00601
00602 void dfftw_conv_1d_(int *na, double *a, int *nb, double *b, double *c)
00603 {
00604 dfftw_conv_1d(*na, a, *nb, b, c);
00605 }
00606
00607 void dfftw_convolve_1d_prepare_(fftw_convolve_op **op, int *reva,
00608 int *na, int *nb, double *a,
00609 double **padb, fftw_complex **padc)
00610 {
00611 *op = dfftw_convolve_1d_prepare(*reva, *na, *nb, a, *padb, *padc);
00612 }
00613
00614 void dfftw_convolve_1d_execute_(fftw_convolve_op **op, int *revb,
00615 double *b, double *c)
00616 {
00617 dfftw_convolve_1d_execute(*op, *revb, b, c);
00618 }
00619
00620 void dfftw_convolve_1d_free_(fftw_convolve_op **op)
00621 {
00622 dfftw_convolve_1d_free(*op);
00623 }
00624
00625 void dfftw_convolve_1d_(int *reva, int *na, double *a, int *revb, int *nb,
00626 double *b, double *c)
00627 {
00628 dfftw_convolve_1d(*reva, *na, a, *revb, *nb, b, c);
00629 }
00630
00631
00632 void dfftw_corr_2d_(int *shape, int *ma, int *na, double *a, int *mb, int *nb,
00633 double *b, double *c)
00634 {
00635 dfftw_corr_2d(*shape, *ma, *na, a, *mb, *nb, b, c);
00636 }
00637
00638 void dfftw_conv_2d_(int *shape, int *ma, int *na, double *a, int *mb, int *nb,
00639 double *b, double *c)
00640 {
00641 dfftw_conv_2d(*shape, *ma, *na, a, *mb, *nb, b, c);
00642 }
00643
00644 void dfftw_convolve_2d_prepare_(fftw_convolve_op **op, int *ma,
00645 int *na, int *mb, int *nb, double *a,
00646 double **padb, fftw_complex **padc)
00647 {
00648 *op = dfftw_convolve_2d_prepare(*ma, *na, *mb, *nb, a, *padb, *padc);
00649 }
00650
00651 void dfftw_convolve_2d_execute_(fftw_convolve_op **op, int *shape,
00652 int *reva, int *revb,
00653 double *b, double *alpha, double *beta,
00654 double *c)
00655 {
00656 dfftw_convolve_2d_execute(*op, *shape, *reva, *revb, b, *alpha, *beta, c);
00657 }
00658
00659 void dfftw_convolve_2d_free_(fftw_convolve_op **op)
00660 {
00661 dfftw_convolve_2d_free(*op);
00662 }
00663
00664 void dfftw_convolve_2d_(int *shape,
00665 int *reva, int *ma, int *na, double *a,
00666 int *revb, int *mb, int *nb, double *b,
00667 double *alpha, double *beta, double *c)
00668 {
00669 dfftw_convolve_2d(*shape, *reva, *ma, *na, a,
00670 *revb, *mb, *nb, b, *alpha, *beta, c);
00671 }