📄 interp3_table_mex.c
字号:
/** interp3_table_mex.c* Mex file for 2D periodic interpolation using tabulated interpolator.* Copyright 03-30-2004 Yingying Zhang and Jeff Fessler, University of Michigan*/#include "mex.h"#include "math.h"#include "def,table.h"#if 0#define ifloor(x) ( (int) (x) ) /* wrong for negatives */#define iround(x) ifloor( (x) + 0.5 ) /* wrong for negatives! */#define iround(x) round(x)#endif#define iround(x) ( (int) ((x) >= 0 ? ((x) + 0.5) : ((x) - 0.5)) )#define ifloor(x) floor(x)static void interp3_table_complex(const double *r_ck, /* [K1,K2,K3] in */const double *i_ck,const int K1,const int K2,const int K3,const double *r_h1, /* [J1*L1+1,1] in */const double *i_h1,const double *r_h2, /* [J2*L2+1,1] in */const double *i_h2,const double *r_h3, /* [J3*L3+1,1] in */const double *i_h3,const int J1,const int J2,const int J3,const int L1,const int L2,const int L3,const double *p_tm, /* [M,3] in */const int M,double *r_fm, /* [M,1] out */double *i_fm){ int mm; const int J_shift1 = (J1 % 2) ? (J1+1)/2 : J1/2; /* nufft_offset */ const int J_shift2 = (J2 % 2) ? (J2+1)/2 : J2/2; /* from 0 in C */ const int J_shift3 = (J3 % 2) ? (J3+1)/2 : J3/2; /* trick: shift table pointer to center */ { const int ncenter1 = ifloor(J1 * L1/2); r_h1 += ncenter1; i_h1 += ncenter1; } { const int ncenter2 = ifloor(J2 * L2/2); r_h2 += ncenter2; i_h2 += ncenter2; } { const int ncenter3 = ifloor(J3 * L3/2); r_h3 += ncenter3; i_h3 += ncenter3; } /* interp */ for (mm=0; mm<M; mm++) { const double t3 = p_tm[2*M]; const double t2 = p_tm[M]; const double t1 = *p_tm++; /* put t_m in range [0,K) */ const double tm1 = t1 - K1 * ifloor(t1 / K1); const double tm2 = t2 - K2 * ifloor(t2 / K2); const double tm3 = t3 - K3 * ifloor(t3 / K3); const int koff1 = 1 + ((J1%2==1) ? ( iround(tm1) - J_shift1 ) : ( ifloor(tm1) - J_shift1 )); const int koff2 = 1 + ((J2%2==1) ? ( iround(tm2) - J_shift2 ) : ( ifloor(tm2) - J_shift2 )); int k3 = 1 + ((J3%2==1) ? ( iround(tm3) - J_shift3 ) : ( ifloor(tm3) - J_shift3 )); register double sum3r = 0.; register double sum3i = 0.; int jj1, j2, j3; for (j3=0; j3<J3; j3++, k3++) { const int n3 = /* ncenter3 + */ iround((tm3 - k3) * L3); register double coef3r = r_h3[n3]; register double coef3i = i_h3[n3]; const int k3mod = (k3 + K3) % K3; register double sum2r = 0.; register double sum2i = 0.; int k2 = koff2; for (j2=0; j2<J2; j2++, k2++) { const int n2 = /* ncenter2 + */ iround((tm2 - k2) * L2); register double coef2r = r_h2[n2]; register double coef2i = i_h2[n2]; const int k2mod = (k2 + K2) % K2; const int k23mod = (k3mod*K2 + k2mod)*K1; register double sum1r = 0.; register double sum1i = 0.; int k1 = koff1; for (jj1=0; jj1<J1; jj1++, k1++) { const int n1 = /* ncenter1 + */ iround((tm1 - k1) * L1); register double coef1r = r_h1[n1]; register double coef1i = i_h1[n1]; const int k1mod = (k1 + K1) % K1; /* const int kk = k3mod*K1*K2 + k2mod*K1 + k1mod; */ const int kk = k23mod + k1mod; /* sum1 += coef1 * ck */ sum1r += coef1r * r_ck[kk] - coef1i * i_ck[kk]; sum1i += coef1r * i_ck[kk] + coef1i * r_ck[kk]; } /* j1 */ /* sum2 += coef2 * sum1 */ sum2r += coef2r * sum1r - coef2i * sum1i; sum2i += coef2r * sum1i + coef2i * sum1r; } /* j2 */ /* sum3 += coef3 * sum2 */ sum3r += coef3r * sum2r - coef3i * sum2i; sum3i += coef3r * sum2i + coef3i * sum2r; } /* j3 */ *r_fm++ = sum3r; *i_fm++ = sum3i; }}static void interp3_table_real(const double *r_ck, /* [K1,K2,K3] in */const double *i_ck,const int K1,const int K2,const int K3,const double *r_h1, /* [J1*L1+1,1] in */const double *r_h2, /* [J2*L2+1,1] in */const double *r_h3, /* [J3*L3+1,1] in */const int J1,const int J2,const int J3,const int L1,const int L2,const int L3,const double *p_tm, /* [M,3] in */const int M,double *r_fm, /* [M,1] out */double *i_fm){ int mm; const int J_shift1 = (J1 % 2) ? (J1+1)/2 : J1/2; /* nufft_offset */ const int J_shift2 = (J2 % 2) ? (J2+1)/2 : J2/2; /* from 0 in C */ const int J_shift3 = (J3 % 2) ? (J3+1)/2 : J3/2; /* trick: shift table pointer to center */ { const int ncenter1 = ifloor(J1 * L1/2); r_h1 += ncenter1; } { const int ncenter2 = ifloor(J2 * L2/2); r_h2 += ncenter2; } { const int ncenter3 = ifloor(J3 * L3/2); r_h3 += ncenter3; } /* interp */ for (mm=0; mm<M; mm++) { const double t3 = p_tm[2*M]; const double t2 = p_tm[M]; const double t1 = *p_tm++; /* put t_m in range [0,K) */ const double tm1 = t1 - K1 * ifloor(t1 / K1); const double tm2 = t2 - K2 * ifloor(t2 / K2); const double tm3 = t3 - K3 * ifloor(t3 / K3); const int koff1 = 1 + ((J1%2==1) ? ( iround(tm1) - J_shift1 ) : ( ifloor(tm1) - J_shift1 )); const int koff2 = 1 + ((J2%2==1) ? ( iround(tm2) - J_shift2 ) : ( ifloor(tm2) - J_shift2 )); int k3 = 1 + ((J3%2==1) ? ( iround(tm3) - J_shift3 ) : ( ifloor(tm3) - J_shift3 )); register double sum3r = 0.; register double sum3i = 0.; int jj1, j2, j3; for (j3=0; j3<J3; j3++, k3++) { const int n3 = /* ncenter3 + */ iround((tm3 - k3) * L3); register double coef3r = r_h3[n3]; const int k3mod = (k3 + K3) % K3; register double sum2r = 0.; register double sum2i = 0.; int k2 = koff2; for (j2=0; j2<J2; j2++, k2++) { const int n2 = /* ncenter2 + */ iround((tm2 - k2) * L2); register double coef2r = r_h2[n2]; const int k2mod = (k2 + K2) % K2; const int k23mod = (k3mod*K2 + k2mod)*K1; register double sum1r = 0.; register double sum1i = 0.; int k1 = koff1; for (jj1=0; jj1<J1; jj1++, k1++) { const int n1 = /* ncenter1 + */ iround((tm1 - k1) * L1); register double coef1r = r_h1[n1]; const int k1mod = (k1 + K1) % K1; /* const int kk = k3mod*K1*K2 + k2mod*K1 + k1mod; */ const int kk = k23mod + k1mod; /* sum1 += coef1 * ck */ sum1r += coef1r * r_ck[kk]; sum1i += coef1r * i_ck[kk]; } /* j1 */ /* sum2 += coef2 * sum1 */ sum2r += coef2r * sum1r; sum2i += coef2r * sum1i; } /* j2 */ /* sum3 += coef3 * sum2 */ sum3r += coef3r * sum2r; sum3i += coef3r * sum2i; } /* j3 */ *r_fm++ = sum3r; *i_fm++ = sum3i; }}int interp3_table_mex(mxArray *plhs[],const mxArray *mx_ck, /* [K1,K2,K3] DFT coefficients */const mxArray *mx_h1,const mxArray *mx_h2,const mxArray *mx_h3,const mxArray *mx_J,const mxArray *mx_L,const mxArray *mx_tm){ int nn; const int ndim = mxGetNumberOfDimensions(mx_ck); const int K1 = (ndim > 0) ? (mxGetDimensions(mx_ck))[0] : 1; const int K2 = (ndim > 1) ? (mxGetDimensions(mx_ck))[1] : 1; const int K3 = (ndim > 2) ? (mxGetDimensions(mx_ck))[2] : 1; const int N = (ndim > 3) ? (mxGetDimensions(mx_ck))[3] : 1; const int M = mxGetM(mx_tm); /* # of time samples */ const int *Jd = (int *) mxGetData(mx_J); const int *Ld = (int *) mxGetData(mx_L); const double *p_tm = mxGetPr(mx_tm); const double *r_h1 = mxGetPr(mx_h1); const double *r_h2 = mxGetPr(mx_h2); const double *r_h3 = mxGetPr(mx_h3); const double *r_ck = mxGetPr(mx_ck); const double *i_ck = mxGetPi(mx_ck); double *r_fm, *i_fm; if (N != 1) fprintf(stderr, "Caution: multiple realizations?"); Call(mxIsComplexDouble, (mx_ck)) Call(mxIsRealDouble, (mx_tm)) /* J,L must be [1,3] */ if (!mxIsInt32n(mx_J, 3)) Fail("J must be [1,3]") if (!mxIsInt32n(mx_L, 3)) Fail("L must be [1,3]") /* check size & type of tables */ if ((int) mxGetM(mx_h1) != Jd[0]*Ld[0]+1 || mxGetN(mx_h1) != 1) { fprintf(stderr, "J=%d L=%d tablelength=%d\n", Jd[0], Ld[0], (int) mxGetM(mx_h1)); Fail("h1 size problem") } if ((int) mxGetM(mx_h2) != Jd[1]*Ld[1]+1 || mxGetN(mx_h2) != 1) { fprintf(stderr, "J=%d L=%d tablelength=%d\n", Jd[1], Ld[1], (int) mxGetM(mx_h2)); Fail("h2 size problem") } if ((int) mxGetM(mx_h3) != Jd[2]*Ld[2]+1 || mxGetN(mx_h3) != 1) { fprintf(stderr, "J=%d L=%d tablelength=%d\n", Jd[2], Ld[2], (int) mxGetM(mx_h3)); Fail("h3 size problem") } if (mxGetN(mx_tm) != 3) Fail("tm must have 3 columns") /* create a new array and set the output pointer to it */ if (N != 1) Fail("N=1 done only") else plhs[0] = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); r_fm = mxGetPr(plhs[0]); i_fm = mxGetPi(plhs[0]); if (mxIsComplexDouble(mx_h1) && mxIsComplexDouble(mx_h2) && mxIsComplexDouble(mx_h3)) { const double *i_h1 = mxGetPi(mx_h1); const double *i_h2 = mxGetPi(mx_h2); const double *i_h3 = mxGetPi(mx_h3); for (nn=0; nn < N; ++nn) { interp3_table_complex(r_ck, i_ck, K1, K2, K3, r_h1, i_h1, r_h2, i_h2, r_h3, i_h3, Jd[0], Jd[1], Jd[2], Ld[0], Ld[1], Ld[2], p_tm, M, r_fm, i_fm); r_ck += K1*K2*K3; i_ck += K1*K2*K3; r_fm += M; i_fm += M; } } else if (mxIsRealDouble(mx_h1) && mxIsRealDouble(mx_h2) && mxIsRealDouble(mx_h3)) { for (nn=0; nn < N; ++nn) { interp3_table_real(r_ck, i_ck, K1, K2, K3, r_h1, r_h2, r_h3, Jd[0], Jd[1], Jd[2], Ld[0], Ld[1], Ld[2], p_tm, M, r_fm, i_fm); r_ck += K1*K2*K3; i_ck += K1*K2*K3; r_fm += M; i_fm += M; } } else Fail("h must be real or complex double (preferably real)") return 1;}/* The gateway routine. */void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]){ /* check for the proper number of arguments */ if (nrhs != 7) mexFail("7 inputs required: (ck, h1, h2, h3, J, L, tm)") if (nlhs > 1) mexFail("Less than one output arguments.") if (!interp3_table_mex(plhs, prhs[0], prhs[1], prhs[2], prhs[3], prhs[4], prhs[5], prhs[6])) mexFail("interp3_table_mex failed") return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -