#include #include // Global Value extern double BASE ; extern int NORID ; extern FILE *FT1 ; // Function definition double MTCFM(double *A, double *B, double *C, int N, double *WK) ; void CFMT4(double *A, int N, int ID, double *WK) ; void CFMT(double *A, int N, int ID, double *WK) ; void CFMTTB(int N2, int ID, double *TBL) ; void CFMTSB(double *A, int M, int L, double *TB, double *WK) ; void FADD(double *A, double *B, double *C, int N, int ID) ; void FCADD(int IA, double *B, double *C, int N, int ID) ; void FCMT(double *A, int IB, double *C, int N) ; void FCDIV(double *A, int IB, double *C, int N) ; void NORM(double *A, int N) ; void FNORM(double *A, int N) ; void COPY(double *A, double *C, int N) ; void SETV(int IV, double *C, int N) ; int LOG2F(int N) ; double SIGN(double a, double b) ; double fmax(double A1, double A2) ; double fmax3(double A1, double A2, double A3) ; int MIN(int N1, int N2) ; //==================================================================C double FMTCFM(double *A, double *B, double *C, int N, double *WK) //------------------------------------------------------------------C // Floating Multiplication (C=A*B) by N-Length Complex FMT C // A(0:N) R*8, In, First Input for A C // B(0:N) R*8, In, Second Input for B C // C(0:2*N) R*8, Out, Ouput for C=A*B C // N I*4, In, Number of Input(A,B) Elements C // ERR R*8, Out, Maximum Rounding Error to Convert Int. C // WK(2,N,3) R*8, Work, Work for FMT C //------------------------------------------------------------------C // Written by Y. Ushiro ( Waseda Uni. and Hitachi ) 2003.01.12 C //==================================================================C { double ERR ; // Exponent Part C[0] = A[0] + B[0] ; // Fixed Multiplication ERR = MTCFM(&A[1], &B[1], &C[1], N, WK) ; // fprintf(FT1,"C=A*B; %f %f %f %f \n",C[0],C[1],C[2],C[3]); // Floating Normalize FNORM(C, 2*N) ; return (ERR) ; } //==================================================================C double MTCFM(double *A, double *B, double *C, int N, double *WK) //------------------------------------------------------------------C // Fixed Multiplication (C=A*B) by N-Length Complex FMT C // A(N) R*8, In, First Input for A C // B(N) R*8, In, Second Input for B C // C(2*N) R*8, Out, Ouput for C=A*B C // N I*4, In, Number of Input(A,B) Elements C // ERR R*8, Out, Maximum Rounding Error to Convert Int. C // WK(2,N,3) R*8, Work, Work for FMT C //------------------------------------------------------------------C // Written by Y. Ushiro ( Waseda Uni. and Hitachi ) 2003.01.12 C //==================================================================C { int k ; double ERR, WR, WI, CR, CI, D5 ; // C=A*B using N-Length Complex FMT // Move from A,B to WK(1,k), C(2k-1) and Set 0 to WK(2,k), C(2k) for ( k=0; k= 0) { // C=SQRT(IA)=IA*(1/SQRT(IA)), C=FW=IA*C FCMT(C, IA, FW, N) ; COPY(FW, C, N+1) ; } return (ERR) ; } //==================================================================C double FSQRT(double *A, double *C, int N,int ID, double *FW,double *WK) //------------------------------------------------------------------C // Floating SQRT (C=SQRT(A)) by Complex FMT and Mult. C // C = 1/SQRT(A) <-- X = X + X*(1-IA*X*X)/2 : Iteration C // A(0:N) R*8, In, Input Data A C // C(0:N) R*8, Out, Ouput for C=SQRT(A) or 1/SQRT(A) C // N I*4, In, Number of Output Elements C // ID I*4, In, ID= 1 ; C=SQRT(A) C // -1 ; C=1/SQRT(A) C // ERR R*8, Out, Maximum Rounding Error to Int. C // FW(0:2*N,2) R*8, Work, Work for SQRT C // WK(2,N,3) R*8, Work, Work for FMT C //------------------------------------------------------------------C // Written by Y. Ushiro ( Waseda Uni. and Hitachi ) 2003.01.12 C //==================================================================C { int k, NL, NLP, NN, NFP, IA0 ; double OEXP, BS1, X, XI, ERR, ERR1, ERR2, ERR3 ; // Set Initial Value IA0 = A[0] ; OEXP = IA0%2 ; if(fabs(OEXP) == 1.0) { C[0] = (-A[0] + 1.0)/2.0 ; BS1 = BASE ; } else { C[0] = -A[0]/2.0 + 1.0 ; BS1 = sqrt(BASE) ; } X = BS1/sqrt(A[1]+A[2]/BASE) ; XI = (int)(X) ; C[1] = XI ; C[2] = (int)((X - XI)*BASE) ; SETV(0, &C[3], N-2) ; // Iteration Loop NLP = LOG2F(N) ; NFP = 2*N + 1 ; NL = 2 ; ERR = 0.0 ; for (k=1; k<=NLP+1; k++) // FW(1) = C*C, FW(2) = A*FW(1), FW(1) = 1 - FW(2) { NN = MIN(N, 2*NL) ; ERR1 = FMTCFM(C, C, FW, NL, WK) ; ERR2 = FMTCFM(FW, A, &FW[NFP], NL, WK) ; ERR = fmax3(ERR, ERR1, ERR2) ; FCADD(1, &FW[NFP], FW, 2*NL, -1) ; // FW(2) = C*FW(1), FW(1) = FW(2)/2, C = C + FW(1) ERR3 = FMTCFM(C, FW, &FW[NFP], NL, WK) ; FCDIV(&FW[NFP], 2, FW, NN) ; ERR = fmax(ERR, ERR3) ; FADD(C, FW, C, NN, 1) ; if(NL < N) { NL = 2*NL ; } } if(ID >= 0) { // C=SQRT(A)=A*(1/SQRT(A)), C=FW=A*C ERR1 = FMTCFM(C, A, FW, N, WK) ; ERR = fmax(ERR, ERR1) ; COPY(FW, C, N+1) ; } return (ERR) ; } //==================================================================C void CFMT4(double *A, int N, int ID, double *WK) //------------------------------------------------------------------C // A = Complex FMT for Real Convolution C // A(N) C*16, I/O, Input and Output Data for FMT C // N I*4, In, Number of FMT Elements, N=2**NB C // ID I*4, In, ID=0 : Normal FMT C // ID=1 : Reverse FMT with 1/N C // WK(N,2) C*16, Work, Work for FMT C //------------------------------------------------------------------C // Written by Y. Ushiro ( Waseda Uni. and Hitachi ) 2003.01.12 C //==================================================================C { int k ; double PIN, ARG, AR, AI, OR, OI ; // Set Constant PIN = 2.0*atan(1.0)/N ; // Test ID if(ID != 1) { // Normal FMT : A=FMT(A*OMG(k)) // A(k)=CEXP(Pi*(k)*i/(2N)) for (k=0; k