Mercurial > hg > sv-dependency-builds
diff src/fftw-3.3.8/genfft/trig.ml @ 82:d0c2a83c1364
Add FFTW 3.3.8 source, and a Linux build
author | Chris Cannam |
---|---|
date | Tue, 19 Nov 2019 14:52:55 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fftw-3.3.8/genfft/trig.ml Tue Nov 19 14:52:55 2019 +0000 @@ -0,0 +1,152 @@ +(* + * Copyright (c) 1997-1999 Massachusetts Institute of Technology + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + *) + +(* trigonometric transforms *) +open Util + +(* DFT of real input *) +let rdft sign n input = + Fft.dft sign n (Complex.real @@ input) + +(* DFT of hermitian input *) +let hdft sign n input = + Fft.dft sign n (Complex.hermitian n input) + +(* DFT real transform of vectors of two real numbers, + multiplication by (NaN I), and summation *) +let dft_via_rdft sign n input = + let f = rdft sign n input + in fun i -> + Complex.plus + [Complex.real (f i); + Complex.times (Complex.nan Expr.I) (Complex.imag (f i))] + +(* Discrete Hartley Transform *) +let dht sign n input = + let f = Fft.dft sign n (Complex.real @@ input) in + (fun i -> + Complex.plus [Complex.real (f i); Complex.imag (f i)]) + +let trigI n input = + let twon = 2 * n in + let input' = Complex.hermitian twon input + in + Fft.dft 1 twon input' + +let interleave_zero input = fun i -> + if (i mod 2) == 0 + then Complex.zero + else + input ((i - 1) / 2) + +let trigII n input = + let fourn = 4 * n in + let input' = Complex.hermitian fourn (interleave_zero input) + in + Fft.dft 1 fourn input' + +let trigIII n input = + let fourn = 4 * n in + let twon = 2 * n in + let input' = Complex.hermitian fourn + (fun i -> + if (i == 0) then + Complex.real (input 0) + else if (i == twon) then + Complex.uminus (Complex.real (input 0)) + else + Complex.antihermitian twon input i) + in + let dft = Fft.dft 1 fourn input' + in fun k -> dft (2 * k + 1) + +let zero_extend n input = fun i -> + if (i >= 0 && i < n) + then input i + else Complex.zero + +let trigIV n input = + let fourn = 4 * n + and eightn = 8 * n in + let input' = Complex.hermitian eightn + (zero_extend fourn (Complex.antihermitian fourn + (interleave_zero input))) + in + let dft = Fft.dft 1 eightn input' + in fun k -> dft (2 * k + 1) + +let make_dct scale nshift trig = + fun n input -> + trig (n - nshift) (Complex.real @@ (Complex.times scale) @@ + (zero_extend n input)) +(* + * DCT-I: y[k] = sum x[j] cos(pi * j * k / n) + *) +let dctI = make_dct Complex.one 1 trigI + +(* + * DCT-II: y[k] = sum x[j] cos(pi * (j + 1/2) * k / n) + *) +let dctII = make_dct Complex.one 0 trigII + +(* + * DCT-III: y[k] = sum x[j] cos(pi * j * (k + 1/2) / n) + *) +let dctIII = make_dct Complex.half 0 trigIII + +(* + * DCT-IV y[k] = sum x[j] cos(pi * (j + 1/2) * (k + 1/2) / n) + *) +let dctIV = make_dct Complex.half 0 trigIV + +let shift s input = fun i -> input (i - s) + +(* DST-x input := TRIG-x (input / i) *) +let make_dst scale nshift kshift jshift trig = + fun n input -> + Complex.real @@ + (shift (- jshift) + (trig (n + nshift) (Complex.uminus @@ + (Complex.times Complex.i) @@ + (Complex.times scale) @@ + Complex.real @@ + (shift kshift (zero_extend n input))))) + +(* + * DST-I: y[k] = sum x[j] sin(pi * j * k / n) + *) +let dstI = make_dst Complex.one 1 1 1 trigI + +(* + * DST-II: y[k] = sum x[j] sin(pi * (j + 1/2) * k / n) + *) +let dstII = make_dst Complex.one 0 0 1 trigII + +(* + * DST-III: y[k] = sum x[j] sin(pi * j * (k + 1/2) / n) + *) +let dstIII = make_dst Complex.half 0 1 0 trigIII + +(* + * DST-IV y[k] = sum x[j] sin(pi * (j + 1/2) * (k + 1/2) / n) + *) +let dstIV = make_dst Complex.half 0 0 0 trigIV +