annotate src/fftw-3.3.3/genfft/complex.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 (* abstraction layer for complex operations *)
Chris@10 23 open Littlesimp
Chris@10 24 open Expr
Chris@10 25
Chris@10 26 (* type of complex expressions *)
Chris@10 27 type expr = CE of Expr.expr * Expr.expr
Chris@10 28
Chris@10 29 let two = CE (makeNum Number.two, makeNum Number.zero)
Chris@10 30 let one = CE (makeNum Number.one, makeNum Number.zero)
Chris@10 31 let i = CE (makeNum Number.zero, makeNum Number.one)
Chris@10 32 let zero = CE (makeNum Number.zero, makeNum Number.zero)
Chris@10 33 let make (r, i) = CE (r, i)
Chris@10 34
Chris@10 35 let uminus (CE (a, b)) = CE (makeUminus a, makeUminus b)
Chris@10 36
Chris@10 37 let inverse_int n = CE (makeNum (Number.div Number.one (Number.of_int n)),
Chris@10 38 makeNum Number.zero)
Chris@10 39
Chris@10 40 let inverse_int_sqrt n =
Chris@10 41 CE (makeNum (Number.div Number.one (Number.sqrt (Number.of_int n))),
Chris@10 42 makeNum Number.zero)
Chris@10 43 let int_sqrt n =
Chris@10 44 CE (makeNum (Number.sqrt (Number.of_int n)),
Chris@10 45 makeNum Number.zero)
Chris@10 46
Chris@10 47 let nan x = CE (NaN x, makeNum Number.zero)
Chris@10 48
Chris@10 49 let half = inverse_int 2
Chris@10 50
Chris@10 51 let times3x3 (CE (a, b)) (CE (c, d)) =
Chris@10 52 CE (makePlus [makeTimes (c, makePlus [a; makeUminus (b)]);
Chris@10 53 makeTimes (b, makePlus [c; makeUminus (d)])],
Chris@10 54 makePlus [makeTimes (a, makePlus [c; d]);
Chris@10 55 makeUminus(makeTimes (c, makePlus [a; makeUminus (b)]))])
Chris@10 56
Chris@10 57 let times (CE (a, b)) (CE (c, d)) =
Chris@10 58 if not !Magic.threemult then
Chris@10 59 CE (makePlus [makeTimes (a, c); makeUminus (makeTimes (b, d))],
Chris@10 60 makePlus [makeTimes (a, d); makeTimes (b, c)])
Chris@10 61 else if is_constant c && is_constant d then
Chris@10 62 times3x3 (CE (a, b)) (CE (c, d))
Chris@10 63 else (* hope a and b are constant expressions *)
Chris@10 64 times3x3 (CE (c, d)) (CE (a, b))
Chris@10 65
Chris@10 66 let ctimes (CE (a, _)) (CE (c, _)) =
Chris@10 67 CE (CTimes (a, c), makeNum Number.zero)
Chris@10 68
Chris@10 69 let ctimesj (CE (a, _)) (CE (c, _)) =
Chris@10 70 CE (CTimesJ (a, c), makeNum Number.zero)
Chris@10 71
Chris@10 72 (* complex exponential (of root of unity); returns exp(2*pi*i/n * m) *)
Chris@10 73 let exp n i =
Chris@10 74 let (c, s) = Number.cexp n i
Chris@10 75 in CE (makeNum c, makeNum s)
Chris@10 76
Chris@10 77 (* various trig functions evaluated at (2*pi*i/n * m) *)
Chris@10 78 let sec n m =
Chris@10 79 let (c, s) = Number.cexp n m
Chris@10 80 in CE (makeNum (Number.div Number.one c), makeNum Number.zero)
Chris@10 81 let csc n m =
Chris@10 82 let (c, s) = Number.cexp n m
Chris@10 83 in CE (makeNum (Number.div Number.one s), makeNum Number.zero)
Chris@10 84 let tan n m =
Chris@10 85 let (c, s) = Number.cexp n m
Chris@10 86 in CE (makeNum (Number.div s c), makeNum Number.zero)
Chris@10 87 let cot n m =
Chris@10 88 let (c, s) = Number.cexp n m
Chris@10 89 in CE (makeNum (Number.div c s), makeNum Number.zero)
Chris@10 90
Chris@10 91 (* complex sum *)
Chris@10 92 let plus a =
Chris@10 93 let rec unzip_complex = function
Chris@10 94 [] -> ([], [])
Chris@10 95 | ((CE (a, b)) :: s) ->
Chris@10 96 let (r,i) = unzip_complex s
Chris@10 97 in
Chris@10 98 (a::r), (b::i) in
Chris@10 99 let (c, d) = unzip_complex a in
Chris@10 100 CE (makePlus c, makePlus d)
Chris@10 101
Chris@10 102 (* extract real/imaginary *)
Chris@10 103 let real (CE (a, b)) = CE (a, makeNum Number.zero)
Chris@10 104 let imag (CE (a, b)) = CE (b, makeNum Number.zero)
Chris@10 105 let iimag (CE (a, b)) = CE (makeNum Number.zero, b)
Chris@10 106 let conj (CE (a, b)) = CE (a, makeUminus b)
Chris@10 107
Chris@10 108
Chris@10 109 (* abstraction of sum_{i=0}^{n-1} *)
Chris@10 110 let sigma a b f = plus (List.map f (Util.interval a b))
Chris@10 111
Chris@10 112 (* store and assignment operations *)
Chris@10 113 let store_real v (CE (a, b)) = Expr.Store (v, a)
Chris@10 114 let store_imag v (CE (a, b)) = Expr.Store (v, b)
Chris@10 115 let store (vr, vi) x = (store_real vr x, store_imag vi x)
Chris@10 116
Chris@10 117 let assign_real v (CE (a, b)) = Expr.Assign (v, a)
Chris@10 118 let assign_imag v (CE (a, b)) = Expr.Assign (v, b)
Chris@10 119 let assign (vr, vi) x = (assign_real vr x, assign_imag vi x)
Chris@10 120
Chris@10 121
Chris@10 122 (************************
Chris@10 123 shortcuts
Chris@10 124 ************************)
Chris@10 125 let (@*) = times
Chris@10 126 let (@+) a b = plus [a; b]
Chris@10 127 let (@-) a b = plus [a; uminus b]
Chris@10 128
Chris@10 129 (* type of complex signals *)
Chris@10 130 type signal = int -> expr
Chris@10 131
Chris@10 132 (* make a finite signal infinite *)
Chris@10 133 let infinite n signal i = if ((0 <= i) && (i < n)) then signal i else zero
Chris@10 134
Chris@10 135 let hermitian n a =
Chris@10 136 Util.array n (fun i ->
Chris@10 137 if (i = 0) then real (a 0)
Chris@10 138 else if (i < n - i) then (a i)
Chris@10 139 else if (i > n - i) then conj (a (n - i))
Chris@10 140 else real (a i))
Chris@10 141
Chris@10 142 let antihermitian n a =
Chris@10 143 Util.array n (fun i ->
Chris@10 144 if (i = 0) then iimag (a 0)
Chris@10 145 else if (i < n - i) then (a i)
Chris@10 146 else if (i > n - i) then uminus (conj (a (n - i)))
Chris@10 147 else iimag (a i))