0
$\begingroup$

I inherited the following FFT code to get the magnitude frequency response of a sample window. I understand what fft() does. What I don't understand are the lines marked with a "???". What do they do? In particular the "real[i]/real.length/2" portion and the multiplication and division by 1000 portion.

double[] real = new double[_FFTSize];
double[] imaginary = new double[_FFTSize];

loadDataIntoReal(real);

fft(real, imaginary); // in-place FFT

for (int i = 0; i < spectrum.length; i++)
{
    double reValue =((int)((real[i]/(real.length/2))*1000)/1000.0); // ???
    double imValue =((int)((imaginary[i]/(real.length/2))*1000)/1000.0); // ???
    double value = Math.sqrt(reValue * reValue + imValue * imValue);
    spectrum[i] = value;
}

Each line seems to have a redundant multiplication and division by 1000. However, if I change the code to be the following, then I get slightly different floating-point results, so I guess they must provide some sort of precision.

    double reValue =(real[i]/(real.length/2));
    double imValue =(imaginary[i]/(real.length/2));
$\endgroup$

2 Answers 2

2
$\begingroup$

It looks like this mul-floor-div is an incorrect attempt to limit some numeric print-out to 3 or 6 decimal places. Better to do that during the print formatting.

$\endgroup$
1
  • 1
    $\begingroup$ I think I may have found the "inspiration": ee.columbia.edu/~ronw/code/MEAPsoft/doc/html/… . Look at line 216 and below. It looks like the author of that code was indeed trying to limit the printout to a few decimal places. He should have used other Java functionality for that, such as System.out.printf(). $\endgroup$ Commented Mar 23, 2012 at 0:41
1
$\begingroup$

It's probably a quantizer. It multiplies by 1000, converts to integer (hence the quantization), and then divides by 1000 again (in floating point).

However, this feels like awkwardly written code as it depends on operator precedence. I think typecast has precedence 3 with right-to-left associativity and division has precedence 5 with left-to-right associativity, and it's not entirely clear to me what comes first.

If the type cast happens before the division than it's quantizer (to 1/1000). If the division comes first, than it simply truncates the result to the nearest smaller whole number.

It would be much cleaner if the last bracket would move in front of the division sign like this:

double reValue =((int)((real[i]/(real.length/2))*1000))/1000.0;

If one was worried about efficiency and readability, one could also do something like this

// outside the loop
double scale = 1000/(realLength/2);
// inside the loop
double reValue =((int)(real[i]*scale))*.001;
$\endgroup$
2
  • $\begingroup$ What would be the point of performing that quantization? If I change the code to be: "double value = Math.sqrt(real[i] * real[i] + imaginary[i] * imaginary[i]);" then the result would exactly match the Matlab output of "y = abs(fft(samples));" ? By the way, I'm a software engineer with just a bit of DSP knowledge. $\endgroup$ Commented Mar 21, 2012 at 17:18
  • $\begingroup$ Difficult to say why one would quantize. Could be a reference code or a model for a fixed point implementation. Could be part of a quantization noise study. Could be some data watermarking or embedding. $\endgroup$
    – Hilmar
    Commented Mar 22, 2012 at 0:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.