1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
* http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/dft/
Modification of Paul Bourkes FFT code by Peter Cusack
to utilise the Microsoft complex type.
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays of 2^m points.
dir = 1 gives forward transform
dir = -1 gives reverse transform
*/
import Math.{sqrt, pow}
/** Test that specialization handles tuples. Perform FFT transformation
* using pairs to represent complex numbers.
*/
object Test {
type Complex = (Double, Double)
def swap(x: Array[Complex], i: Int, j: Int) {
val tmp = x(i)
x(i) = x(j)
x(j) = tmp
}
def times(x: Complex, y: Complex): Complex =
(x._1 * y._1 - x._2 * y._2, x._1 * y._2 + x._2 * y._1)
def div(x: Complex, y: Complex): Complex = {
val num = pow(y._1, 2) + pow(y._2, 2)
((x._1 * y._1 + x._2 * y._2)/num,
(x._2 * y._1 - x._1 * y._2)/num)
}
def div(x: Complex, y: Long) =
(x._1 / y, x._2 / y)
def add(x: Complex, y: Complex) =
(x._1 + y._1, x._2 + y._2)
def minus(x: Complex, y: Complex) =
(x._1 - y._1, x._2 - y._2)
def FFT(dir: Int, m: Long, x: Array[(Double, Double)]) {
var i, i1, i2,j, k, l, l1, l2, n = 0l
// complex <double> tx, t1, u, c;
var tx, t1, u, c = (0.0, 0.0)
/*Calculate the number of points */
n = 1
for (i <- 0l until m)
n <<= 1
/* Do the bit reversal */
i2 = n >> 1
j = 0
for (i <- 0l until (n - 1)) {
if (i < j)
swap(x, i.toInt, j.toInt);
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
// c.real(-1.0);
// c.imag(0.0);
c = (-1.0, 0.0)
l2 = 1
for (l <- 0l until m) {
l1 = l2
l2 <<= 1;
// u.real(1.0);
// u.imag(0.0);
u = (1.0, 0.0)
for (j <- 0l until l1) {
for (i <- j.until(n, l2)) {
i1 = i + l1;
t1 = times(u, x(i1.toInt))
x(i1.toInt) = minus(x(i.toInt), t1)
x(i.toInt) = add(x(i.toInt), t1)
}
u = times(u, c)
}
// c.imag(sqrt((1.0 - c.real()) / 2.0));
c = (c._1, sqrt( (1.0 - c._1) / 2.0 ))
// if (dir == 1)
// c.imag(-c.imag());
if (dir == 1)
c = (c._1, -c._2)
// c.real(sqrt((1.0 + c.real()) / 2.0));
c = (sqrt( (1.0 + c._1) / 2.0), c._2)
}
/* Scaling for forward transform */
if (dir == 1) {
for (i <- 0l until n)
x(i.toInt) = div(x(i.toInt), n)
}
}
def run() {
FFT(1, 16, data)
}
var data: Array[Complex] = null
def inputFileName = {
val cwd = System.getProperty("partest.cwd")
if (cwd ne null) cwd + java.io.File.separator + "input2.txt"
else "input2.txt"
}
def setUp {
// print("Loading from %s.. ".format(inputFileName))
val f = io.Source.fromFile(inputFileName)
val lines = f.getLines
val n = lines.next.toInt
data = new Array[Complex](n)
var i = 0
for (line <- lines if line != "") {
val pair = line.trim.split(" ")
data(i) = (pair(0).trim.toDouble, pair(1).trim.toDouble)
i += 1
}
// println("[loaded]")
println("Processing " + n + " items")
}
def main(args: Array[String]) {
setUp
run()
println("Boxed doubles: " + runtime.BoxesRunTime.doubleBoxCount)
println("Boxed ints: " + runtime.BoxesRunTime.integerBoxCount)
println("Boxed longs: " + runtime.BoxesRunTime.longBoxCount)
}
}
|