module Numeric.Transform.Fourier.CT (fft_ct1, fft_ct2) where
import Data.List (transpose)
import Data.Array
import Data.Complex
fft_ct1 :: (Ix a, Integral a, RealFloat b) => Array a (Complex b)
-> a
-> a
-> (Array a (Complex b) -> Array a (Complex b))
-> Array a (Complex b)
fft_ct1 a l m fft = array (0,n1) $ zip ks (elems x')
where x = listArray ((0,0),(l1,m1)) [ a!i | i <- xs ]
f = listArray ((0,0),(l1,m1)) (flatten_rows $ map fft $ rows x)
g = listArray ((0,0),(l1,m1)) [ f!(i,j) * w!(i*j) | i <- [0..(l1)], j <- [0..(m1)] ]
x' = listArray ((0,0),(l1,m1)) (flatten_cols $ map fft $ cols g)
wn = cis (2 * pi / fromIntegral n)
w = listArray (0,n1) $ iterate (* wn) 1
(xs,ks) = ct_index_map1 l m
n = l * m
fft_ct2 :: (Ix a, Integral a, RealFloat b) => Array a (Complex b)
-> a
-> a
-> (Array a (Complex b) -> Array a (Complex b))
-> Array a (Complex b)
fft_ct2 a l m fft = array (0,n1) $ zip ks (elems x')
where x = listArray ((0,0),(l1,m1)) [ a!i | i <- xs ]
f = listArray ((0,0),(l1,m1)) (flatten_cols $ map fft $ cols x)
g = listArray ((0,0),(l1,m1)) [ f!(i,j) * w!(i*j) | i <- [0..(l1)], j <- [0..(m1)] ]
x' = listArray ((0,0),(l1,m1)) (flatten_rows $ map fft $ rows g)
wn = cis (2 * pi / fromIntegral n)
w = listArray (0,n1) $ iterate (* wn) 1
(xs,ks) = ct_index_map2 l m
n = l * m
ct_index_map1 :: (Integral a) => a -> a -> ([a],[a])
ct_index_map1 l m = (n,k)
where n = [ n1 + l * n2 | n1 <- [0..(l1)], n2 <- [0..(m1)] ]
k = [ m * k1 + k2 | k1 <- [0..(l1)], k2 <- [0..(m1)] ]
ct_index_map2 :: (Integral a) => a -> a -> ([a],[a])
ct_index_map2 l m = (n,k)
where n = [ m * n1 + n2 | n1 <- [0..(l1)], n2 <- [0..(m1)] ]
k = [ k1 + l * k2 | k1 <- [0..(l1)], k2 <- [0..(m1)] ]
rows :: (Ix a, Integral a, RealFloat b) => Array (a,a) (Complex b) -> [Array a (Complex b)]
rows x = [ listArray (0,m) [ x!(i,j) | j <- [0..m] ] | i <- [0..l] ]
where ((_,_),(l,m)) = bounds x
cols :: (Ix a, Integral a, RealFloat b) => Array (a,a) (Complex b) -> [Array a (Complex b)]
cols x = [ listArray (0,l) [ x!(i,j) | i <- [0..l] ] | j <- [0..m] ]
where ((_,_),(l,m)) = bounds x
flatten_rows :: (Ix a, Integral a, RealFloat b) => [Array a (Complex b)] -> [(Complex b)]
flatten_rows a = foldr (++) [] $ map elems a
flatten_cols :: (Ix a, Integral a, RealFloat b) => [Array a (Complex b)] -> [(Complex b)]
flatten_cols a = foldr (++) [] $ transpose $ map elems a