home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 02 / fourier.mod < prev    next >
Encoding:
Modula Implementation  |  1987-12-10  |  5.4 KB  |  235 lines

  1. IMPLEMENTATION MODULE Fourier ;
  2. (* 
  3.    (C) Michael Kowalik & PASCAL INTERNATIONAL
  4.  
  5.    x   - vector of points projected on abscissa
  6.    y   - vector of points projected on ordinate
  7.    a,b - vectors of Fourier's coefficients
  8.    a[i]*cos(2*pi*x[i]/T)
  9.    b[i]*sin(2*pi*x[i]/T)
  10. *)
  11.    
  12. FROM Conversions IMPORT ConvertAddrDec;
  13. FROM MathLib0    IMPORT sin, cos ;
  14. FROM SYSTEM      IMPORT ADDRESS, CODE, REGISTER, SETREG;
  15.  
  16. CONST
  17.   MAXSIZE=512;       (* max number of vector elements *)
  18.   S=MAXSIZE-1;
  19.   pi=3.141592654;
  20.  
  21. PROCEDURE Interpolation( VAR x, y, a, b : ARRAY OF REAL);
  22.  
  23. VAR
  24.   i, k, l, n, q : CARDINAL ;
  25. BEGIN
  26.   n := HIGH(y) + 1 ;
  27.   q := n DIV 2 ;
  28.   FOR i := 1 TO n DO
  29.     x[i-1] := FLOAT(i-1)/FLOAT(n)*2.0*pi
  30.   END ;
  31.   a[0] := 0.0 ;
  32.   FOR k := 0 TO n-1 DO
  33.     a[0] := y[k] + a[0]
  34.   END ;
  35.   a[0] := 1.0/FLOAT(n)*a[0] ;
  36.   FOR l := 1 TO q-1 DO
  37.     a[l] := 0.0 ;
  38.     b[l] := 0.0 ;
  39.     FOR k := 0 TO n-1 DO
  40.       a[l] := y[k]*cos(FLOAT(l)*x[k]) + a[l] ;
  41.       b[l] := y[k]*sin(FLOAT(l)*x[k]) + b[l]
  42.     END ;
  43.     a[l] := 2.0/FLOAT(n)*a[l] ;
  44.     b[l] := 2.0/FLOAT(n)*b[l]
  45.   END ;
  46.   a[q] := 0.0 ;
  47.   FOR k := 0 TO n-1 DO
  48.     a[q] := y[k]*cos(FLOAT(q)*x[k]) + a[q]
  49.   END ;
  50.   a[q] := 1.0/FLOAT(n)*a[q]
  51. END Interpolation ;
  52.  
  53.  
  54. PROCEDURE RungeFaltung(VAR x, y, a, b : ARRAY OF REAL);
  55. CONST S=MAXSIZE; 
  56.       q=S DIV 2; 
  57.       p=q DIV 2;
  58. VAR
  59.      s                   : ARRAY [0..q] OF REAL;
  60.      d                   : ARRAY [1..q-1] OF REAL;
  61.      ss                  : ARRAY [0..p] OF REAL;
  62.      sd                  : ARRAY [1..p] OF REAL;
  63.      ds                  : ARRAY [0..p-1] OF REAL;
  64.      dd                  : ARRAY [1..p-1] OF REAL;
  65.      N, P, Q, n, i, k, l : CARDINAL;
  66.  
  67. BEGIN
  68.   N:=HIGH(y)+1;
  69.   Q:=N DIV 2;
  70.   P:=Q DIV 2;
  71.   FOR   i := 1 TO N DO
  72.     x[i-1] := FLOAT(i-1)/FLOAT(N)*2.0*pi
  73.   END;
  74.   (* first convolution *)
  75.   s[0]    := y[0];
  76.   s[Q]    := y[Q];
  77.   FOR i   := 1 TO Q-1 DO
  78.     s[i]  := y[i] + y[N-i];
  79.     d[i]  := y[i] - y[N-i]
  80.   END;
  81.   (* second convolution *)
  82.   ss[P]   := s[P];
  83.   sd[P]   := d[P];
  84.   FOR i   := 0 TO P-1 DO
  85.     ss[i] := s[i] + s[Q-i];
  86.     ds[i] := s[i] - s[Q-i]
  87.   END;
  88.   FOR i   := 1 TO P-1 DO
  89.     sd[i] := d[i] + d[Q-i];
  90.     dd[i] := d[i] - d[Q-i]
  91.   END;
  92.   (* first and last cosinus coefficients *)
  93.   a[0]    := 0.0;
  94.   FOR   k := 0 TO P DO
  95.     a[0]  := a[0] + ss[k]
  96.   END;
  97.   a[0]    := a[0]/FLOAT(N); a[Q]    := 0.0;
  98.   FOR k   := 0 TO P DO
  99.     IF ODD(k) THEN 
  100.       a[Q] := a[Q] - ss[k] 
  101.     ELSE 
  102.       a[Q] := a[Q] + ss[k] 
  103.     END
  104.   END;
  105.   a[Q]    := a[Q]/FLOAT(N);
  106.   (* coefficients with odd  index *)
  107.   FOR l   := 1 TO Q-1 BY 2 DO
  108.     a[l]  := 0.0;
  109.     FOR k := 0 TO P-1 DO
  110.       a[l]:= a[l] + ds[k]*cos(FLOAT(l)*x[k])
  111.     END;
  112.     b[l]  := 0.0;
  113.     FOR k := 1 TO P DO
  114.       b[l]:= b[l] + sd[k]*sin(FLOAT(l)*x[k])
  115.     END;
  116.     a[l]  := 2.0*a[l]/FLOAT(N); 
  117.     b[l]  := 2.0*b[l]/FLOAT(N)
  118.   END;
  119.   (* coefficients with even index *)
  120.   FOR l   := 2 TO Q-2 BY 2 DO
  121.     a[l]  := 0.0;
  122.     FOR k := 0 TO P DO
  123.       a[l]:= a[l] + ss[k]*cos(FLOAT(l)*x[k])
  124.     END;
  125.     b[l]  := 0.0;
  126.     FOR k := 1 TO P-1 DO
  127.       b[l]:= b[l] + dd[k]*sin(FLOAT(l)*x[k])
  128.     END;
  129.     a[l]  := 2.0*a[l]/FLOAT(N); 
  130.     b[l]  := 2.0*b[l]/FLOAT(N)
  131.   END
  132. END RungeFaltung;
  133.  
  134.  
  135. PROCEDURE DFT(VAR x, y, a, b : ARRAY OF REAL);
  136. VAR
  137.   alpha, c, s, suma, sumb, h, he : REAL;
  138.   N, k, n                        : CARDINAL;
  139.   Ar, Ai                         : ARRAY [0..S] OF REAL;
  140. BEGIN
  141.   N := HIGH(y);
  142.   h := FLOAT(N+1);
  143.   FOR k   := 0 TO N DO
  144.     he    := FLOAT(k);
  145.     suma  := 0.0; sumb  := 0.0;
  146.     FOR n := 0 TO N DO
  147.       alpha := 2.0*pi*he*FLOAT(n)/h;
  148.       suma  := suma + y[n]*cos(alpha);
  149.       sumb  := sumb + y[n]*sin(alpha);
  150.     END;
  151.     Ar[k] := 2.0*suma/h;
  152.     Ai[k] := 2.0*sumb/h
  153.   END;
  154.   a[0] := Ar[0];
  155.   b[0] := Ai[0];
  156.   FOR k  := 1 TO N DIV 2 DO
  157.     a[k] := Ar[k]+Ar[N+1-k];
  158.     IF k<((N+1) DIV 2) THEN 
  159.       b[k] := Ai[k]-Ai[N+1-k] 
  160.     END
  161.   END
  162. END DFT;
  163.  
  164.  
  165. PROCEDURE FFT(VAR Re, Im, a, b : ARRAY OF REAL);
  166. VAR
  167.   alpha, tr, ti, wr, wi, h        : REAL;
  168.   L, N, i, j, m, mr, mn, l, istep : CARDINAL;
  169.   Ar, Ai                          : ARRAY [0..S] OF REAL;
  170.  
  171.  
  172. PROCEDURE BitRevShuffle(i, length : CARDINAL) : CARDINAL;
  173. VAR
  174.   m : CARDINAL;
  175. BEGIN
  176.   CODE(04287H);                    (* clr.l d7          *)
  177.   SETREG(6, i);
  178.   FOR m:=1 TO length DO
  179.     CODE(0E24EH);                  (* lsr.w  #1,d6      *)
  180.     CODE(0E357H);                  (* roxl.w #1,d7      *)
  181.   END;
  182.   RETURN CARDINAL(REGISTER(7))
  183. END BitRevShuffle;
  184.  
  185.  
  186. BEGIN
  187.   N := HIGH(Re);
  188.   h := FLOAT(N+1);
  189.   L := 0;
  190.   m := N;
  191.  
  192.   WHILE m>0 DO (* estimate number of bits *)
  193.     m := m DIV 2; 
  194.     INC(L) 
  195.   END; 
  196.  
  197.   FOR m := 0 TO N DO
  198.     Ar[BitRevShuffle(m, L)] := Re[m];
  199.     Ai[BitRevShuffle(m, L)] := Im[m]
  200.   END;
  201.  
  202.   l := 1;
  203.   WHILE l<N DO
  204.     istep := 2*l;
  205.     FOR m := 1 TO l DO
  206.       alpha := pi*FLOAT(m-1)/FLOAT(l);
  207.       wr  := cos(alpha);
  208.       wi  := sin(alpha);
  209.       i   := m - 1;
  210.       REPEAT
  211.         j := i+l;
  212.         tr:= wr*Ar[j]-wi*Ai[j];
  213.         ti:= wr*Ai[j]+wi*Ar[j];
  214.         Ar[j] := Ar[i]-tr;
  215.         Ai[j] := Ai[i]-ti;
  216.         Ar[i] := Ar[i]+tr;
  217.         Ai[i] := Ai[i]+ti;
  218.         i:= i + istep
  219.       UNTIL i>=N
  220.     END;
  221.     l := istep
  222.   END;
  223.   a[0] := Ar[0]/h;
  224.   b[0] := Ai[0]/h;
  225.  
  226.   FOR m := 1 TO N DIV 2 DO
  227.     a[m] := (Ar[m]+Ar[N+1-m])/h;
  228.     IF m<((N+1) DIV 2) THEN 
  229.       b[m] := (Ai[m]-Ai[N+1-m])/h 
  230.     END
  231.   END
  232. END FFT
  233.  
  234. END Fourier.
  235.