(*
%use "/homes/cbj/public_html/FISh-1.1/Samples/Matrix/fft.fsh";;
*)
(* fft.fsh - modified version of Leroy's fft.ml *)
let pi = 3.14159265358979323846
;;
let tpi = 2.0 *. pi
;;
let fft px py np =
new i = 2
and m = 1
in
while (!i < np) do
i := !i + !i;
m := !m + 1
done ;
new n = !i
in
if (not (n = np)) then (* checks that np is power of 2 *)
let f = (fun t -> 0.0)
in
update f px;
update f py
else skip ;
new n2 = n+n
in
for (1 <= k < !m) do
n2 := !n2 div 2;
new n4 = !n2 div 4
in
new e = tpi /. (int2float(!n2))
in
for (1 <= j < n4 + 1) do
new a = e *. (int2float(j - 1))
and a3 = 3.0 *. a
and cc1 = cos(a)
and ss1 = sin(a)
and cc3 = cos(a3)
and ss3 = sin(a3)
and is = j
and id = 2 * !n2
in
while (!is < n) do
new i0r = !is
in
while (!i0r < n) do
new i0 = !i0r
and i1 = i0 + n4
and i2 = i1 + n4
and i3 = i2 + n4
and r1 = px[i0] -. px[i2]
in
px[i0] := px[i0] +. px[i2];
new r2 = px[i1] -. px[i3]
in
px[i1] := px[i1] +. px[i3];
new s1 = py[i0] -. py[i2]
in
py[i0] := py[i0] +. py[i2];
new s2 = py[i1] -. py[i3]
in
py[i1] := py[i1] +. py[i3];
new s3 = r1 -. s2
and r1 = r1 +. s2
and s2 = r2 -. s1
and r2 = r2 +. s1
in
px[i2] := r1 *. cc1 -. s2 *. ss1;
py[i2] := (0.0 -. s2 *. cc1) -. r1 *. ss1;
px[i3] := s3 *. cc3 +. r2*.ss3;
py[i3] := r2 *. cc3 -. s3*.ss3;
i0r := i0 + !id
end (* new s3,r1,s2,r2 *)
end (* new s2 *)
end (* new s1 *)
end (* new r2 *)
end (* new i0,i1,i2,i3,r1 *)
done ; (* while !i0r *)
is := 2 * !id - !n2 + j;
id := 4 * !id
end (* new i0r *)
done (* while is *)
end (* new a, a3, cc1, ss1,cc3,ss3,is,id *)
done
end (* new e *)
end (* new n4 *)
done
end ; (* new n2 *)
(************************************)
(* Last stage, length=2 butterfly *)
(************************************)
new is = 1
and id = 4
in
while (!is < n) do
new i0r = !is
in
while (!i0r <= n) do
new i0 = !i0r
and i1 = i0 + 1
and r1 = px[i0]
in
px[i0] := r1 +. px[i1];
px[i1] := r1 -. px[i1];
new r1 = py[i0]
in
py[i0] := r1 +. py[i1];
py[i1] := r1 -. py[i1];
i0r := i0 + !id
end (* new r1 *)
end (* new i0,i1,r1 *)
done ;
is := 2 * !id - 1;
id := 4 * !id
end (* new i0r *)
done
end ; (* new is, id *)
(*************************)
(* Bit reverse counter *)
(*************************)
new j = 1
in
for (1 <= i < n) do
if (i < !j) then
new xt = px[!j]
in
px[!j] := px[i];
px[i] := xt;
new xt = py[!j]
in
py[!j] := py[i];
py[i] := xt
end (* new xt *)
end (* new xt *)
else skip ;
new k = n div 2
in
while (!k < !j) do
j := !j - !k;
k := !k div 2
done ;
j := !j + !k
end (* new k *)
done
end (* new j *)
end (* new n *)
end (* new i,m *)
;;
(*
let runtest (np:size) =
new enp = int2float(np)
and npm = np div 2 - 1
and #pxr = { np + 2 : float_shape }
and #pxi = #pxr
in
update (fun t -> 0.0) pxr;
update (fun t -> 0.0) pxi;
new t = pi /. enp
in
pxr[1] := (enp -. 1.0) *. 0.5;
pxi[1] := 0.0;
new n2 = np div 2 in
pxr[n2+1] := -.0.5;
pxi[n2+1] := 0.0
end ; (* new n2 *)
for (1 <= i < npm + 1) do
new j = np - i
in
pxr[i+1] := -.0.5;
pxr[j+1] := -.0.5;
new z = t *. int2float(i)
and y = -.0.5 *. (cos(z)/.sin(z))
in
pxi[i+1] := y;
pxi[j+1] := 0.0 -. y
end (* new x,y *)
end (* new j *)
done ;
fft pxr pxi np ;
new zr = 0.0
and zi = 0.0
and kr = 0
and ki = 0
in
for (0 <= i < np) do
new a = fabs(pxr[i+1] -. int2float(i))
in
if (!zr <. a)
then
zr := a;
kr := i
else
skip
end ; (* new a *)
new a = fabs(pxi[i+1])
in
if (!zi <. a)
then
zi := a;
ki := i
else
skip
end (* new a *)
done
end (* new zr,zi,kr,ki *)
end (* new t *)
end (* new enp,npm,pxr,pxi *)
;;
let fftest =
(runtest 16;
runtest 32;
runtest 64;
runtest 128;
runtest 256;
runtest 512;
runtest 1024;
runtest 2048;
runtest 4096;
runtest 8192;
runtest 16384;
runtest 32768;
runtest 65536)
;;
%run -c -q fftest
;;
*)