annotate src/fftw-3.3.3/genfft/conv.ml @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 37bf6b4a2645
children
rev   line source
Chris@10 1 (*
Chris@10 2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
Chris@10 3 * Copyright (c) 2003, 2007-11 Matteo Frigo
Chris@10 4 * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology
Chris@10 5 *
Chris@10 6 * This program is free software; you can redistribute it and/or modify
Chris@10 7 * it under the terms of the GNU General Public License as published by
Chris@10 8 * the Free Software Foundation; either version 2 of the License, or
Chris@10 9 * (at your option) any later version.
Chris@10 10 *
Chris@10 11 * This program is distributed in the hope that it will be useful,
Chris@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@10 14 * GNU General Public License for more details.
Chris@10 15 *
Chris@10 16 * You should have received a copy of the GNU General Public License
Chris@10 17 * along with this program; if not, write to the Free Software
Chris@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@10 19 *
Chris@10 20 *)
Chris@10 21
Chris@10 22 open Complex
Chris@10 23 open Util
Chris@10 24
Chris@10 25 let polyphase m a ph i = a (m * i + ph)
Chris@10 26
Chris@10 27 let rec divmod n i =
Chris@10 28 if (i < 0) then
Chris@10 29 let (a, b) = divmod n (i + n)
Chris@10 30 in (a - 1, b)
Chris@10 31 else (i / n, i mod n)
Chris@10 32
Chris@10 33 let unpolyphase m a i = let (x, y) = divmod m i in a y x
Chris@10 34
Chris@10 35 let lift2 f a b i = f (a i) (b i)
Chris@10 36
Chris@10 37 (* convolution of signals A and B *)
Chris@10 38 let rec conv na a nb b =
Chris@10 39 let rec naive na a nb b i =
Chris@10 40 sigma 0 na (fun j -> (a j) @* (b (i - j)))
Chris@10 41
Chris@10 42 and recur na a nb b =
Chris@10 43 if (na <= 1 || nb <= 1) then
Chris@10 44 naive na a nb b
Chris@10 45 else
Chris@10 46 let p = polyphase 2 in
Chris@10 47 let ee = conv (na - na / 2) (p a 0) (nb - nb / 2) (p b 0)
Chris@10 48 and eo = conv (na - na / 2) (p a 0) (nb / 2) (p b 1)
Chris@10 49 and oe = conv (na / 2) (p a 1) (nb - nb / 2) (p b 0)
Chris@10 50 and oo = conv (na / 2) (p a 1) (nb / 2) (p b 1) in
Chris@10 51 unpolyphase 2 (function
Chris@10 52 0 -> fun i -> (ee i) @+ (oo (i - 1))
Chris@10 53 | 1 -> fun i -> (eo i) @+ (oe i)
Chris@10 54 | _ -> failwith "recur")
Chris@10 55
Chris@10 56
Chris@10 57 (* Karatsuba variant 1: (a+bx)(c+dx) = (ac+bdxx)+((a+b)(c+d)-ac-bd)x *)
Chris@10 58 and karatsuba1 na a nb b =
Chris@10 59 let p = polyphase 2 in
Chris@10 60 let ae = p a 0 and nae = na - na / 2
Chris@10 61 and ao = p a 1 and nao = na / 2
Chris@10 62 and be = p b 0 and nbe = nb - nb / 2
Chris@10 63 and bo = p b 1 and nbo = nb / 2 in
Chris@10 64 let ae = infinite nae ae and ao = infinite nao ao
Chris@10 65 and be = infinite nbe be and bo = infinite nbo bo in
Chris@10 66 let aeo = lift2 (@+) ae ao and naeo = nae
Chris@10 67 and beo = lift2 (@+) be bo and nbeo = nbe in
Chris@10 68 let ee = conv nae ae nbe be
Chris@10 69 and oo = conv nao ao nbo bo
Chris@10 70 and eoeo = conv naeo aeo nbeo beo in
Chris@10 71
Chris@10 72 let q = function
Chris@10 73 0 -> fun i -> (ee i) @+ (oo (i - 1))
Chris@10 74 | 1 -> fun i -> (eoeo i) @- ((ee i) @+ (oo i))
Chris@10 75 | _ -> failwith "karatsuba1" in
Chris@10 76 unpolyphase 2 q
Chris@10 77
Chris@10 78 (* Karatsuba variant 2:
Chris@10 79 (a+bx)(c+dx) = ((a+b)c-b(c-dxx))+x((a+b)c-a(c-d)) *)
Chris@10 80 and karatsuba2 na a nb b =
Chris@10 81 let p = polyphase 2 in
Chris@10 82 let ae = p a 0 and nae = na - na / 2
Chris@10 83 and ao = p a 1 and nao = na / 2
Chris@10 84 and be = p b 0 and nbe = nb - nb / 2
Chris@10 85 and bo = p b 1 and nbo = nb / 2 in
Chris@10 86 let ae = infinite nae ae and ao = infinite nao ao
Chris@10 87 and be = infinite nbe be and bo = infinite nbo bo in
Chris@10 88
Chris@10 89 let c1 = conv nae (lift2 (@+) ae ao) nbe be
Chris@10 90 and c2 = conv nao ao (nbo + 1) (fun i -> be i @- bo (i - 1))
Chris@10 91 and c3 = conv nae ae nbe (lift2 (@-) be bo) in
Chris@10 92
Chris@10 93 let q = function
Chris@10 94 0 -> lift2 (@-) c1 c2
Chris@10 95 | 1 -> lift2 (@-) c1 c3
Chris@10 96 | _ -> failwith "karatsuba2" in
Chris@10 97 unpolyphase 2 q
Chris@10 98
Chris@10 99 and karatsuba na a nb b =
Chris@10 100 let m = na + nb - 1 in
Chris@10 101 if (m < !Magic.karatsuba_min) then
Chris@10 102 recur na a nb b
Chris@10 103 else
Chris@10 104 match !Magic.karatsuba_variant with
Chris@10 105 1 -> karatsuba1 na a nb b
Chris@10 106 | 2 -> karatsuba2 na a nb b
Chris@10 107 | _ -> failwith "unknown karatsuba variant"
Chris@10 108
Chris@10 109 and via_circular na a nb b =
Chris@10 110 let m = na + nb - 1 in
Chris@10 111 if (m < !Magic.circular_min) then
Chris@10 112 karatsuba na a nb b
Chris@10 113 else
Chris@10 114 let rec find_min n = if n >= m then n else find_min (2 * n) in
Chris@10 115 circular (find_min 1) a b
Chris@10 116
Chris@10 117 in
Chris@10 118 let a = infinite na a and b = infinite nb b in
Chris@10 119 let res = array (na + nb - 1) (via_circular na a nb b) in
Chris@10 120 infinite (na + nb - 1) res
Chris@10 121
Chris@10 122 and circular n a b =
Chris@10 123 let via_dft n a b =
Chris@10 124 let fa = Fft.dft (-1) n a
Chris@10 125 and fb = Fft.dft (-1) n b
Chris@10 126 and scale = inverse_int n in
Chris@10 127 let fab i = ((fa i) @* (fb i)) @* scale in
Chris@10 128 Fft.dft 1 n fab
Chris@10 129
Chris@10 130 in via_dft n a b