n乗根の計算

 投稿者:しばっち  投稿日:2012年 7月 7日(土)21時37分18秒
  OPTION ARITHMETIC NATIVE !'二進モード
PUBLIC NUMERIC BIAS, KETA, SIGN, EPS
LET  EPS = 16 !'打ち切りによる収束誤差分(末尾 EPS*4桁分)
LET  NN=2^15-EPS !' (※ NN=2^18-EPSで100万桁オーバー)
LET  BIAS = 2 !'10000^(BIAS+1)まで
LET  KETA =-BIAS+NN+EPS !'10000^(-KETA) (KETA*4桁)
LET  SIGN = -BIAS - 1 !'多倍長数の符号
DIM Y(-BIAS-1 TO KETA),X(-BIAS-1 TO KETA)
INPUT  PROMPT "K^(1/N) K=":K
DO
   INPUT  PROMPT "K^(1/N) N=":N
   LET N=INT(ABS(N))
LOOP UNTIL N>=2
CALL LLET(Y,STR$(K))
CALL LLET(X,USING$("#.################",K^(-(N-1)/N))) !'ニュートン法の初期値
PRINT (KETA-EPS)*4;"桁の計算開始 ";TIME$
LET T=TIME
CALL LROOT(Y,N,X)
PRINT "計算終了 ";TIME$;TIME-T;"秒"
PRINT "ファイルへ書き出し中"
CALL DISPLAY(Y,"OUT.txt") !'ファイルへ書き出し
END

EXTERNAL  SUB LROOT(T(),N,X()) !'ニュートン法
OPTION ARITHMETIC NATIVE
DIM TT(-BIAS-1 TO KETA),XX(-BIAS-1 TO KETA),Y(-BIAS-1 TO KETA)
CALL LCOPY(TT,T)
FOR I=1 TO N-2
   CALL LMUL2(TT,T)
NEXT I
DO
   CALL LCOPY(Y,X)
   CALL LCOPY(XX,X)
   CALL SMUL(XX,N+1)
   FOR I=1 TO N
      CALL LMUL2(X,Y)
   NEXT I
   CALL LMUL2(X,TT)
   CALL LSUB2(XX,X)
   CALL SDIV(XX,N)
   CALL LCOPY(X,XX)
LOOP UNTIL EQUAL(Y,X)<>0
CALL LMUL2(T,X)
END SUB

EXTERNAL  SUB DISPLAY(X(),N$)
OPTION ARITHMETIC NATIVE
IF N$="" THEN
   OPEN #1: TEXTWINDOW1
ELSE
   OPEN #1:NAME N$
END IF
ERASE #1
FOR K=-BIAS TO 0
   IF X(K)<>0 THEN EXIT FOR
NEXT K
IF X(SIGN) = -1 THEN PRINT #1:"- ";
IF K>=0 THEN
   LET K=0
   PRINT #1:STR$(X(0));"."
ELSE
   PRINT #1:STR$(X(K));
   FOR I=K+1 TO 0
      LET A$=A$ & RIGHT$("000" & STR$(X(I)),4)
      IF LEN(A$)=100 THEN
         PRINT #1:A$
         LET A$=""
      END IF
   NEXT I
   IF LEN(A$)>0 THEN
      PRINT #1:A$;"."
      LET A$=""
   END IF
END IF
LET S=0
FOR I=1 TO KETA-EPS
   LET A$=A$ & RIGHT$("000" & STR$(X(I)),4)
   IF LEN(A$)=100 THEN
      LET S=S+100
      FOR J=1 TO 10
         PRINT #1:LEFT$(A$,10);" ";
         IF J=5 THEN PRINT #1:"   ";
         LET A$=RIGHT$(A$,LEN(A$)-10)
      NEXT J
      PRINT #1:":";S
      LET A$=""
      IF MOD(S,1000)=0 THEN PRINT #1
   END IF
NEXT I
IF LEN(A$)>0 THEN
   LET S=S+LEN(A$)
   LET A$=A$ & REPEAT$(" ",10)
   FOR J=1 TO 9
      PRINT #1:RTRIM$(LEFT$(A$,10));" ";
      IF J=5 THEN PRINT #1:"   ";
      LET A$=RIGHT$(A$,LEN(A$)-10)
      IF RTRIM$(A$)="" THEN EXIT FOR
   NEXT J
   !'  PRINT #1:":";S
END IF
CLOSE #1
END SUB

EXTERNAL  FUNCTION EQUAL(A(), B())
OPTION ARITHMETIC NATIVE
FOR I=-BIAS-1 TO KETA-EPS
   IF A(I)<>B(I) THEN
      FOR J=0 TO 3
         IF INT(A(I)/10^(3-J))<>INT(B(I)/10^(3-J)) THEN EXIT FOR
      NEXT  J
      PRINT (I-1)*4+J;"桁まで計算終了 ";TIME$
      LET  EQUAL = 0
      EXIT FUNCTION
   END IF
NEXT I
PRINT (I-1)*4;"桁まで計算終了 ";TIME$
LET EQUAL=-1
END FUNCTION

EXTERNAL  FUNCTION GREAT(A(), B())
OPTION ARITHMETIC NATIVE
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
IF SIGNA = -1 AND SIGNB = 1 THEN
   LET  GREAT = 0
   EXIT FUNCTION
END IF
IF SIGNA = 1 AND SIGNB = -1 THEN
   LET  GREAT = -1
   EXIT FUNCTION
END IF
FOR I = -BIAS TO KETA
   IF SIGNA = -1 AND SIGNB = -1 THEN
      IF A(I) < B(I) THEN
         LET  GREAT = -1
         EXIT FUNCTION
      END IF
      IF A(I) > B(I) THEN
         LET  GREAT = 0
         EXIT FUNCTION
      END IF
   ELSE
      IF A(I) > B(I) THEN
         LET  GREAT = -1
         EXIT FUNCTION
      END IF
      IF A(I) < B(I) THEN
         LET  GREAT = 0
         EXIT FUNCTION
      END IF
   END IF
NEXT I
LET  GREAT = 0
END FUNCTION

EXTERNAL  SUB LCLR(A())
OPTION ARITHMETIC NATIVE
MAT A=ZER
LET  A(SIGN) = 1
END SUB

EXTERNAL  SUB LCOPY(A(), B())
OPTION ARITHMETIC NATIVE
MAT A=B
END SUB

EXTERNAL  SUB LLET(A(), X$)
OPTION ARITHMETIC NATIVE
CALL LCLR(A)
LET  X$ = LTRIM$(RTRIM$(X$))
FOR I = 1 TO LEN(X$)
   IF POS("0123456789.-", MID$(X$, I, 1)) = 0 THEN
      PRINT "ERROR in LLET"
      STOP
   END IF
NEXT I
IF LEFT$(X$, 1) = "-" THEN
   LET  A(SIGN) = -1
   LET X$ = RIGHT$(X$, LEN(X$)-1)
ELSE
   LET  A(SIGN) = 1
END IF
LET  K1 = POS(X$, ".")
LET  X$ = "000" & X$
IF K1 = 0 THEN LET  X$ = X$ & "."
LET  KK = POS(X$, ".")
IF KK - 4 > BIAS * 4 + 4 THEN
   PRINT "OVER FLOW in LLET"
   STOP
END IF
FOR J = 0 TO INT((KK - 1) / 4) - 1
   LET  A(-J) = VAL(MID$(X$, KK - 4 * J - 4, 4))
NEXT J
LET  X$ = X$ & "000"
FOR J = 1 TO(LEN(X$) - KK) / 4
   LET  A(J) = VAL(MID$(X$, KK + 4 * J - 3, 4))
NEXT J
END SUB

EXTERNAL  SUB SDIV(A(), XA)
OPTION ARITHMETIC NATIVE
LET  SIGNA = A(SIGN)
LET  SG = SGN(XA)
LET  XA = ABS(XA)
FOR I = -BIAS TO KETA - 1
   LET  R = A(I) - INT(A(I) / XA) * XA
   LET  A(I) = INT(A(I) / XA)
   LET  A(I + 1) = A(I + 1) + R * 10000
NEXT I
LET  A(KETA) = INT(A(KETA) / XA)
LET A(SIGN)=SIGNA * SG
END SUB

EXTERNAL  SUB SMUL(A(), XA)
OPTION ARITHMETIC NATIVE
LET  SIGNA = A(SIGN)
LET  SG = SGN(XA)
LET  XA = ABS(XA)
MAT A = XA * A
FOR I = KETA TO -BIAS + 1 STEP -1
   IF A(I) >= 10000 THEN
      LET  R = INT(A(I) / 10000)
      LET  A(I) = MOD(A(I),10000)
      LET  A(I - 1) = A(I - 1) + R
   END IF
NEXT I
IF A(-BIAS) >= 10000 THEN
   PRINT "OVER FLOW in SMUL"
   STOP
END IF
LET A(SIGN)=SIGNA * SG
END SUB

EXTERNAL  SUB LADD2(A(), B())
OPTION ARITHMETIC NATIVE
DIM C(-BIAS - 1 TO KETA)
CALL LADD(A,B,C)
CALL LCOPY(A,C)
END SUB

EXTERNAL  SUB LSUB2(A(), B())
OPTION ARITHMETIC NATIVE
DIM C(-BIAS - 1 TO KETA)
CALL LSUB(A,B,C)
CALL LCOPY(A,C)
END SUB

EXTERNAL  SUB LADD(A(), B(), C())
OPTION ARITHMETIC NATIVE
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
IF SIGNA = 1 AND SIGNB = -1 THEN
   LET  B(SIGN) = 1
   CALL LSUB(A, B, C)
   LET  B(SIGN) = -1
   EXIT SUB
ELSEIF SIGNA = -1 AND SIGNB = 1 THEN
   LET  A(SIGN) = 1
   CALL LSUB(B, A, C)
   LET  A(SIGN) = -1
   EXIT SUB
END IF
MAT C=A+B
FOR I = KETA TO -BIAS + 1 STEP -1
   IF C(I) >= 10000 THEN
      LET  C(I) = C(I) - 10000
      LET  C(I - 1) = C(I - 1) + 1
   END IF
NEXT I
IF C(-BIAS) >= 10000 THEN
   PRINT "OVER FLOW in LADD"
   STOP
END IF
IF SIGNA = -1 AND SIGNB = -1 THEN LET  C(SIGN) = -1 ELSE LET  C(SIGN) = 1
END SUB

EXTERNAL  SUB LSUB(A(), B(), C())
OPTION ARITHMETIC NATIVE
LET  SIGNA = A(SIGN)
LET  SIGNB = B(SIGN)
LET  A(SIGN) = 1
LET  B(SIGN) = 1
IF SIGNA * SIGNB = -1 THEN
   CALL LADD(A, B, C)
   LET  C(SIGN) = SIGNA
   LET  A(SIGN) = SIGNA
   LET  B(SIGN) = SIGNB
   EXIT SUB
END IF
LET  GR = GREAT(A, B)
IF SIGNA = 1 AND SIGNB = 1 THEN
   IF GR<>0 THEN
      MAT C=A-B
      LET  C(SIGN) = 1
   ELSE
      MAT C=B-A
      LET  C(SIGN) = -1
   END IF
ELSE
   IF GR<>0 THEN
      MAT C=B-A
      LET  C(SIGN) = 1
   ELSE
      MAT C=A-B
      LET  C(SIGN) = -1
   END IF
END IF
FOR I = KETA TO -BIAS + 1 STEP -1
   IF C(I) < 0 THEN
      LET  C(I) = C(I) + 10000
      LET  C(I - 1) = C(I - 1) - 1
   END IF
NEXT I
LET  A(SIGN) = SIGNA
LET  B(SIGN) = SIGNB
END SUB

EXTERNAL  SUB LMUL(A(),B(),C())
OPTION ARITHMETIC NATIVE
LET N=(KETA+BIAS)*2
IF INT(LOG2(N))<>LOG2(N) THEN
   PRINT "ERROR in LMUL"
   STOP
END IF
OPTION BASE 0
DIM AA(2*N),BB(2*N),CC(2*N),IP(2+2^(INT(LOG(N+0.5)/LOG(2))/2)),W(N/2-1)
FOR I = 0 TO N/2-1
   LET  AA(2*I) = A(-BIAS+I)
   LET  BB(2*I) = B(-BIAS+I)
NEXT I
CALL CDFT(2*N, 1, AA, IP, W)
CALL CDFT(2*N, 1, BB, IP, W)
FOR I = 0 TO N-1
   LET  CC(2*I) = AA(2*I) * BB(2*I) - AA(2*I+1) * BB(2*I+1)
   LET  CC(2*I+1) = AA(2*I) * BB(2*I+1) + BB(2*I) * AA(2*I+1)
NEXT I
CALL CDFT(2*N, -1,CC, IP, W)
FOR I=0 TO N/2-1
   IF -2*BIAS+I>=-BIAS AND -2*BIAS+I<=KETA THEN
      LET C(-2*BIAS+I)=INT(CC(2*I)/N+.5)
   END IF
NEXT I
FOR I=KETA TO -BIAS STEP -1
   IF C(I) >=10000 THEN
      LET  R = INT(C(I) / 10000)
      LET  C(I) = C(I) - R * 10000
      LET  C(I - 1) = C(I - 1) + R
   ELSE
      DO WHILE C(I)<0
         LET C(I)=C(I)+10000
         LET C(I-1)=C(I-1)-1
      LOOP
   END IF
NEXT I
LET C(SIGN)=A(SIGN)*B(SIGN)
END SUB

EXTERNAL  SUB LMUL2(A(),B())
OPTION ARITHMETIC NATIVE
DIM C(-BIAS - 1 TO KETA)
CALL LMUL(A,B,C)
CALL LCOPY(A,C)
END SUB

! これより以下のFFTルーチンは下記サイトより入手したものを移植した
!
! -------- Complex DFT (Discrete Fourier Transform) --------
!     [definition]
!         <case1>
!             X(k) = sum_j=0^n-1 x(j)*exp(2*pi*i*j*k/n), 0<=k<n
!         <case2>
!             X(k) = sum_j=0^n-1 x(j)*exp(-2*pi*i*j*k/n), 0<=k<n
!         (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
!     [usage]
!         <case1>
!             ip(0) = 0  ! first time only
!             call cdft(2*n, 1, a, ip, w)
!         <case2>
!             ip(0) = 0  ! first time only
!             call cdft(2*n, -1, a, ip, w)
!     [parameters]
!         2*n          :data length (integer)
!                       n >= 1, n = power of 2
!         a(0:2*n-1)   :input/output data (real*8)
!                       input data
!                           a(2*j) = Re(x(j)),
!                           a(2*j+1) = Im(x(j)), 0<=j<n
!                       output data
!                           a(2*k) = Re(X(k)),
!                           a(2*k+1) = Im(X(k)), 0<=k<n
!         ip(0:*)      :work area for bit reversal (integer)
!                       length of ip >= 2+sqrt(n)
!                       strictly,
!                       length of ip >=
!                           2+2**(int(log(n+0.5)/log(2.0))/2).
!                       ip(0),ip(1) are pointers of the cos/sin table.
!         w(0:n/2-1)   :cos/sin table (real*8)
!                       w(),ip() are initialized if ip(0) = 0.
!     [remark]
!         Inverse of
!             call cdft(2*n, -1, a, ip, w)
!         is
!             call cdft(2*n, 1, a, ip, w)
!             do j = 0, 2 * n - 1
!                 a(j) = a(j) / n
!             end do

EXTERNAL  SUB CDFT(N, ISGN, A(), IP(), W())
OPTION ARITHMETIC NATIVE
IF N > 4 * IP(0) THEN
   CALL MAKEWT(N / 4, IP, W)
END IF
IF N > 4 THEN
   IF ISGN >= 0 THEN
      CALL BITRV2(N, IP, A)
      CALL CFTFSUB(N, A, W)
   ELSE
      CALL BITRV2CONJ(N, IP, A)
      CALL CFTBSUB(N, A, W)
   END IF
ELSEIF N = 4 THEN
   CALL CFTFSUB(N, A, W)
END IF
END SUB

EXTERNAL  SUB MAKEWT(NW, IP(), W())
OPTION ARITHMETIC NATIVE
LET  IP(0) = NW
LET  IP(1) = 1
IF NW > 2 THEN
   LET  NWH = NW / 2
   LET  DELTA = ATN(1.0) / NWH
   LET  W(0) = 1
   LET  W(1) = 0
   LET  W(NWH) = COS(DELTA * NWH)
   LET  W(NWH + 1) = W(NWH)
   IF NWH > 2 THEN
      FOR J = 2 TO NWH - 2 STEP 2
         LET  X = COS(DELTA * J)
         LET  Y = SIN(DELTA * J)
         LET  W(J) = X
         LET  W(J + 1) = Y
         LET  W(NW - J) = Y
         LET  W(NW - J + 1) = X
      NEXT J
      CALL BITRV2(NW, IP, W)
   END IF
END IF
END SUB

EXTERNAL  SUB CFTFSUB(N, A(), W())
OPTION ARITHMETIC NATIVE
LET  L = 2
IF N > 8 THEN
   CALL CFT1ST(N, A, W)
   LET  L = 8
   DO WHILE 4 * L < N
      CALL CFTMDL(N, L, A, W)
      LET  L = 4 * L
   LOOP
END IF
IF 4 * L = N THEN
   FOR J = 0 TO L - 2 STEP 2
      LET  J1 = J + L
      LET  J2 = J1 + L
      LET  J3 = J2 + L
      LET  X0R = A(J) + A(J1)
      LET  X0I = A(J + 1) + A(J1 + 1)
      LET  X1R = A(J) - A(J1)
      LET  X1I = A(J + 1) - A(J1 + 1)
      LET  X2R = A(J2) + A(J3)
      LET  X2I = A(J2 + 1) + A(J3 + 1)
      LET  X3R = A(J2) - A(J3)
      LET  X3I = A(J2 + 1) - A(J3 + 1)
      LET  A(J) = X0R + X2R
      LET  A(J + 1) = X0I + X2I
      LET  A(J2) = X0R - X2R
      LET  A(J2 + 1) = X0I - X2I
      LET  A(J1) = X1R - X3I
      LET  A(J1 + 1) = X1I + X3R
      LET  A(J3) = X1R + X3I
      LET  A(J3 + 1) = X1I - X3R
   NEXT J
ELSE
   FOR J = 0 TO L - 2 STEP 2
      LET  J1 = J + L
      LET  X0R = A(J) - A(J1)
      LET  X0I = A(J + 1) - A(J1 + 1)
      LET  A(J) = A(J) + A(J1)
      LET  A(J + 1) = A(J + 1) + A(J1 + 1)
      LET  A(J1) = X0R
      LET  A(J1 + 1) = X0I
   NEXT J
END IF
END SUB
 

Re: n乗根の計算

 投稿者:しばっち  投稿日:2012年 7月 7日(土)21時38分6秒
  > No.1918[元記事へ]

続き

EXTERNAL  SUB BITRV2(N, IP(), A())
OPTION ARITHMETIC NATIVE
LET  IP(0) = 0
LET  L = N
LET  M = 1
DO WHILE 8 * M < L
   LET  L = L / 2
   FOR J = 0 TO M - 1
      LET  IP(M + J) = IP(J) + L
   NEXT J
   LET  M = M * 2
LOOP
LET  M2 = 2 * M
IF 8 * M = L THEN
   FOR K = 0 TO M - 1
      FOR J = 0 TO K - 1
         LET  J1 = 2 * J + IP(K)
         LET  K1 = 2 * K + IP(J)
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + 2 * M2
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 - M2
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + 2 * M2
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
      NEXT J
      LET  J1 = 2 * K + M2 + IP(K)
      LET  K1 = J1 + M2
      LET  XR = A(J1)
      LET  XI = A(J1 + 1)
      LET  YR = A(K1)
      LET  YI = A(K1 + 1)
      LET  A(J1) = YR
      LET  A(J1 + 1) = YI
      LET  A(K1) = XR
      LET  A(K1 + 1) = XI
   NEXT K
ELSE
   FOR K = 1 TO M - 1
      FOR J = 0 TO K - 1
         LET  J1 = 2 * J + IP(K)
         LET  K1 = 2 * K + IP(J)
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + M2
         LET  XR = A(J1)
         LET  XI = A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
      NEXT J
   NEXT K
END IF
END SUB

EXTERNAL  SUB BITRV2CONJ(N, IP(), A())
OPTION ARITHMETIC NATIVE
LET  IP(0) = 0
LET  L = N
LET  M = 1
DO WHILE 8 * M < L
   LET  L = L / 2
   FOR J = 0 TO M - 1
      LET  IP(M + J) = IP(J) + L
   NEXT J
   LET  M = M * 2
LOOP
LET  M2 = 2 * M
IF 8 * M = L THEN
   FOR K = 0 TO M - 1
      FOR J = 0 TO K - 1
         LET  J1 = 2 * J + IP(K)
         LET  K1 = 2 * K + IP(J)
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + 2 * M2
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 - M2
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + 2 * M2
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
      NEXT J
      LET  K1 = 2 * K + IP(K)
      LET  A(K1 + 1) = -A(K1 + 1)
      LET  J1 = K1 + M2
      LET  K1 = J1 + M2
      LET  XR = A(J1)
      LET  XI = -A(J1 + 1)
      LET  YR = A(K1)
      LET  YI = -A(K1 + 1)
      LET  A(J1) = YR
      LET  A(J1 + 1) = YI
      LET  A(K1) = XR
      LET  A(K1 + 1) = XI
      LET  K1 = K1 + M2
      LET  A(K1 + 1) = -A(K1 + 1)
   NEXT K
ELSE
   LET  A(1) = -A(1)
   LET  A(M2 + 1) = -A(M2 + 1)
   FOR K = 1 TO M - 1
      FOR J = 0 TO K - 1
         LET  J1 = 2 * J + IP(K)
         LET  K1 = 2 * K + IP(J)
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
         LET  J1 = J1 + M2
         LET  K1 = K1 + M2
         LET  XR = A(J1)
         LET  XI = -A(J1 + 1)
         LET  YR = A(K1)
         LET  YI = -A(K1 + 1)
         LET  A(J1) = YR
         LET  A(J1 + 1) = YI
         LET  A(K1) = XR
         LET  A(K1 + 1) = XI
      NEXT J
      LET  K1 = 2 * K + IP(K)
      LET  A(K1 + 1) = -A(K1 + 1)
      LET  A(K1 + M2 + 1) = -A(K1 + M2 + 1)
   NEXT K
END IF
END SUB

EXTERNAL  SUB CFTBSUB(N, A(), W())
OPTION ARITHMETIC NATIVE
LET  L = 2
IF N > 8 THEN
   CALL CFT1ST(N, A, W)
   LET  L = 8
   DO WHILE 4 * L < N
      CALL CFTMDL(N, L, A, W)
      LET  L = 4 * L
   LOOP
END IF
IF 4 * L = N THEN
   FOR J = 0 TO L - 2 STEP 2
      LET  J1 = J + L
      LET  J2 = J1 + L
      LET  J3 = J2 + L
      LET  X0R = A(J) + A(J1)
      LET  X0I = -A(J + 1) - A(J1 + 1)
      LET  X1R = A(J) - A(J1)
      LET  X1I = -A(J + 1) + A(J1 + 1)
      LET  X2R = A(J2) + A(J3)
      LET  X2I = A(J2 + 1) + A(J3 + 1)
      LET  X3R = A(J2) - A(J3)
      LET  X3I = A(J2 + 1) - A(J3 + 1)
      LET  A(J) = X0R + X2R
      LET  A(J + 1) = X0I - X2I
      LET  A(J2) = X0R - X2R
      LET  A(J2 + 1) = X0I + X2I
      LET  A(J1) = X1R - X3I
      LET  A(J1 + 1) = X1I - X3R
      LET  A(J3) = X1R + X3I
      LET  A(J3 + 1) = X1I + X3R
   NEXT J
ELSE
   FOR J = 0 TO L - 2 STEP 2
      LET  J1 = J + L
      LET  X0R = A(J) - A(J1)
      LET  X0I = -A(J + 1) + A(J1 + 1)
      LET  A(J) = A(J) + A(J1)
      LET  A(J + 1) = -A(J + 1) - A(J1 + 1)
      LET  A(J1) = X0R
      LET  A(J1 + 1) = X0I
   NEXT J
END IF
END SUB

EXTERNAL  SUB CFT1ST(N, A(), W())
OPTION ARITHMETIC NATIVE
LET  X0R = A(0) + A(2)
LET  X0I = A(1) + A(3)
LET  X1R = A(0) - A(2)
LET  X1I = A(1) - A(3)
LET  X2R = A(4) + A(6)
LET  X2I = A(5) + A(7)
LET  X3R = A(4) - A(6)
LET  X3I = A(5) - A(7)
LET  A(0) = X0R + X2R
LET  A(1) = X0I + X2I
LET  A(4) = X0R - X2R
LET  A(5) = X0I - X2I
LET  A(2) = X1R - X3I
LET  A(3) = X1I + X3R
LET  A(6) = X1R + X3I
LET  A(7) = X1I - X3R
LET  WK1R = W(2)
LET  X0R = A(8) + A(10)
LET  X0I = A(9) + A(11)
LET  X1R = A(8) - A(10)
LET  X1I = A(9) - A(11)
LET  X2R = A(12) + A(14)
LET  X2I = A(13) + A(15)
LET  X3R = A(12) - A(14)
LET  X3I = A(13) - A(15)
LET  A(8) = X0R + X2R
LET  A(9) = X0I + X2I
LET  A(12) = X2I - X0I
LET  A(13) = X0R - X2R
LET  X0R = X1R - X3I
LET  X0I = X1I + X3R
LET  A(10) = WK1R * (X0R - X0I)
LET  A(11) = WK1R * (X0R + X0I)
LET  X0R = X3I + X1R
LET  X0I = X3R - X1I
LET  A(14) = WK1R * (X0I - X0R)
LET  A(15) = WK1R * (X0I + X0R)
LET  K1 = 0
FOR J = 16 TO N - 16 STEP 16
   LET  K1 = K1 + 2
   LET  K2 = 2 * K1
   LET  WK2R = W(K1)
   LET  WK2I = W(K1 + 1)
   LET  WK1R = W(K2)
   LET  WK1I = W(K2 + 1)
   LET  WK3R = WK1R - 2 * WK2I * WK1I
   LET  WK3I = 2 * WK2I * WK1R - WK1I
   LET  X0R = A(J) + A(J + 2)
   LET  X0I = A(J + 1) + A(J + 3)
   LET  X1R = A(J) - A(J + 2)
   LET  X1I = A(J + 1) - A(J + 3)
   LET  X2R = A(J + 4) + A(J + 6)
   LET  X2I = A(J + 5) + A(J + 7)
   LET  X3R = A(J + 4) - A(J + 6)
   LET  X3I = A(J + 5) - A(J + 7)
   LET  A(J) = X0R + X2R
   LET  A(J + 1) = X0I + X2I
   LET  X0R = X0R - X2R
   LET  X0I = X0I - X2I
   LET  A(J + 4) = WK2R * X0R - WK2I * X0I
   LET  A(J + 5) = WK2R * X0I + WK2I * X0R
   LET  X0R = X1R - X3I
   LET  X0I = X1I + X3R
   LET  A(J + 2) = WK1R * X0R - WK1I * X0I
   LET  A(J + 3) = WK1R * X0I + WK1I * X0R
   LET  X0R = X1R + X3I
   LET  X0I = X1I - X3R
   LET  A(J + 6) = WK3R * X0R - WK3I * X0I
   LET  A(J + 7) = WK3R * X0I + WK3I * X0R
   LET  WK1R = W(K2 + 2)
   LET  WK1I = W(K2 + 3)
   LET  WK3R = WK1R - 2 * WK2R * WK1I
   LET  WK3I = 2 * WK2R * WK1R - WK1I
   LET  X0R = A(J + 8) + A(J + 10)
   LET  X0I = A(J + 9) + A(J + 11)
   LET  X1R = A(J + 8) - A(J + 10)
   LET  X1I = A(J + 9) - A(J + 11)
   LET  X2R = A(J + 12) + A(J + 14)
   LET  X2I = A(J + 13) + A(J + 15)
   LET  X3R = A(J + 12) - A(J + 14)
   LET  X3I = A(J + 13) - A(J + 15)
   LET  A(J + 8) = X0R + X2R
   LET  A(J + 9) = X0I + X2I
   LET  X0R = X0R - X2R
   LET  X0I = X0I - X2I
   LET  A(J + 12) = -WK2I * X0R - WK2R * X0I
   LET  A(J + 13) = -WK2I * X0I + WK2R * X0R
   LET  X0R = X1R - X3I
   LET  X0I = X1I + X3R
   LET  A(J + 10) = WK1R * X0R - WK1I * X0I
   LET  A(J + 11) = WK1R * X0I + WK1I * X0R
   LET  X0R = X1R + X3I
   LET  X0I = X1I - X3R
   LET  A(J + 14) = WK3R * X0R - WK3I * X0I
   LET  A(J + 15) = WK3R * X0I + WK3I * X0R
NEXT J
END SUB

EXTERNAL  SUB CFTMDL(N, L, A(), W())
OPTION ARITHMETIC NATIVE
LET  M = 4 * L
FOR J = 0 TO L - 2 STEP 2
   LET  J1 = J + L
   LET  J2 = J1 + L
   LET  J3 = J2 + L
   LET  X0R = A(J) + A(J1)
   LET  X0I = A(J + 1) + A(J1 + 1)
   LET  X1R = A(J) - A(J1)
   LET  X1I = A(J + 1) - A(J1 + 1)
   LET  X2R = A(J2) + A(J3)
   LET  X2I = A(J2 + 1) + A(J3 + 1)
   LET  X3R = A(J2) - A(J3)
   LET  X3I = A(J2 + 1) - A(J3 + 1)
   LET  A(J) = X0R + X2R
   LET  A(J + 1) = X0I + X2I
   LET  A(J2) = X0R - X2R
   LET  A(J2 + 1) = X0I - X2I
   LET  A(J1) = X1R - X3I
   LET  A(J1 + 1) = X1I + X3R
   LET  A(J3) = X1R + X3I
   LET  A(J3 + 1) = X1I - X3R
NEXT J
LET  WK1R = W(2)
FOR J = M TO L + M - 2 STEP 2
   LET  J1 = J + L
   LET  J2 = J1 + L
   LET  J3 = J2 + L
   LET  X0R = A(J) + A(J1)
   LET  X0I = A(J + 1) + A(J1 + 1)
   LET  X1R = A(J) - A(J1)
   LET  X1I = A(J + 1) - A(J1 + 1)
   LET  X2R = A(J2) + A(J3)
   LET  X2I = A(J2 + 1) + A(J3 + 1)
   LET  X3R = A(J2) - A(J3)
   LET  X3I = A(J2 + 1) - A(J3 + 1)
   LET  A(J) = X0R + X2R
   LET  A(J + 1) = X0I + X2I
   LET  A(J2) = X2I - X0I
   LET  A(J2 + 1) = X0R - X2R
   LET  X0R = X1R - X3I
   LET  X0I = X1I + X3R
   LET  A(J1) = WK1R * (X0R - X0I)
   LET  A(J1 + 1) = WK1R * (X0R + X0I)
   LET  X0R = X3I + X1R
   LET  X0I = X3R - X1I
   LET  A(J3) = WK1R * (X0I - X0R)
   LET  A(J3 + 1) = WK1R * (X0I + X0R)
NEXT J
LET  K1 = 0
LET  M2 = 2 * M
FOR K = M2 TO N - M2 STEP M2
   LET  K1 = K1 + 2
   LET  K2 = 2 * K1
   LET  WK2R = W(K1)
   LET  WK2I = W(K1 + 1)
   LET  WK1R = W(K2)
   LET  WK1I = W(K2 + 1)
   LET  WK3R = WK1R - 2 * WK2I * WK1I
   LET  WK3I = 2 * WK2I * WK1R - WK1I
   FOR J = K TO L + K - 2 STEP 2
      LET  J1 = J + L
      LET  J2 = J1 + L
      LET  J3 = J2 + L
      LET  X0R = A(J) + A(J1)
      LET  X0I = A(J + 1) + A(J1 + 1)
      LET  X1R = A(J) - A(J1)
      LET  X1I = A(J + 1) - A(J1 + 1)
      LET  X2R = A(J2) + A(J3)
      LET  X2I = A(J2 + 1) + A(J3 + 1)
      LET  X3R = A(J2) - A(J3)
      LET  X3I = A(J2 + 1) - A(J3 + 1)
      LET  A(J) = X0R + X2R
      LET  A(J + 1) = X0I + X2I
      LET  X0R = X0R - X2R
      LET  X0I = X0I - X2I
      LET  A(J2) = WK2R * X0R - WK2I * X0I
      LET  A(J2 + 1) = WK2R * X0I + WK2I * X0R
      LET  X0R = X1R - X3I
      LET  X0I = X1I + X3R
      LET  A(J1) = WK1R * X0R - WK1I * X0I
      LET  A(J1 + 1) = WK1R * X0I + WK1I * X0R
      LET  X0R = X1R + X3I
      LET  X0I = X1I - X3R
      LET  A(J3) = WK3R * X0R - WK3I * X0I
      LET  A(J3 + 1) = WK3R * X0I + WK3I * X0R
   NEXT J
   LET  WK1R = W(K2 + 2)
   LET  WK1I = W(K2 + 3)
   LET  WK3R = WK1R - 2 * WK2R * WK1I
   LET  WK3I = 2 * WK2R * WK1R - WK1I
   FOR J = K + M TO L + (K + M) - 2 STEP 2
      LET  J1 = J + L
      LET  J2 = J1 + L
      LET  J3 = J2 + L
      LET  X0R = A(J) + A(J1)
      LET  X0I = A(J + 1) + A(J1 + 1)
      LET  X1R = A(J) - A(J1)
      LET  X1I = A(J + 1) - A(J1 + 1)
      LET  X2R = A(J2) + A(J3)
      LET  X2I = A(J2 + 1) + A(J3 + 1)
      LET  X3R = A(J2) - A(J3)
      LET  X3I = A(J2 + 1) - A(J3 + 1)
      LET  A(J) = X0R + X2R
      LET  A(J + 1) = X0I + X2I
      LET  X0R = X0R - X2R
      LET  X0I = X0I - X2I
      LET  A(J2) = -WK2I * X0R - WK2R * X0I
      LET  A(J2 + 1) = -WK2I * X0I + WK2R * X0R
      LET  X0R = X1R - X3I
      LET  X0I = X1I + X3R
      LET  A(J1) = WK1R * X0R - WK1I * X0I
      LET  A(J1 + 1) = WK1R * X0I + WK1I * X0R
      LET  X0R = X1R + X3I
      LET  X0I = X1I - X3R
      LET  A(J3) = WK3R * X0R - WK3I * X0I
      LET  A(J3 + 1) = WK3R * X0I + WK3I * X0R
   NEXT J
NEXT K
END SUB
 

戻る