I'm using FFTW3 to compute 2D real FFT in c++. I've read the manual but have some questions. From the manual: http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data
In exchange for these speed and space advantages, the user sacrifices
some of the simplicity of FFTW's complex transforms. First of all, the
input and output arrays are of different sizes and types: the input is
n real numbers, while the output is n/2+1 complex numbers (the
non-redundant outputs); this also requires slight “padding” of the
input array for in-place transforms. Second, the inverse transform
(complex to real) has the side-effect of overwriting its input array,
by default. Neither of these inconveniences should pose a serious
problem for users, but it is important to be aware of them.
I understand that I need to convert my input 2D matrix in into row-order 1D vector. But what does the output look like? What do the n/2 + 1 numbers mean? In other words, how do I reorder the output to get 2D matrix?
What specifically do I have to do to create this "padding"?
If your input is already in a normal C++ 2D array, all you should need to do is typecast it:
double twoDarray[10][10];
double *oneDarrayPointer = (double *)twoDarray;
If your input is 100 (like it is in the above example), your output array is going to be 51 complex numbers. The format of those numbers should be described by your library, but probably is an array of 102 doubles - 51 entries times 2 (real/imaginary parts).
Edit: Confirmed - fftw_complex is defined as:
typedef double fftw_complex[2];
So they're just consecutive pairs of doubles representing the real and imaginary parts of a complex number.
If you don't want to do it in place, you don't have to pad anything - just allocate an appropriately sized output array. If you do need to do it in place, your input buffer has to have space for the 2 extra doubles vs the input size. Assuming the declarations above, you'd want something like:
double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
I'm not sure if you'd need to make sure to have 0.0 in the last two entries or not, but that's easy enough to add.
You could have a look to the real-to-real transforms in FFTW3, that do exactly what you were asking for. These do not require padding and take into account that both the wavenumber 0 and the one that represents the Nyquist frequency have only a real component. Have a look here:
FFTW3 Real-to-Real Transforms
and for the layout in memory:
FFTW3 Real-to-Real Transform Kinds
Related
I have a geometric algorithm which takes as input a polygon. However, the files I am supposed to use as input files store the coordinates of the polygons in a rather peculiar way. Each file consists of one line, a counterclockwise sequence of the vertices. Each vertex is represented by its x and y coordinates each of which is written as the quotient of two integers int/int. However, these integers are incredibly large. I wrote a program that parses them from a string into long long using the function std::stoll. However, it appears that some of the numbers in the input file are larger than 2^64.
The output coordinates are usually quite small, in the range 0-1000. How do I go about parsing these numbers and then dividing them, obtaining doubles? Is there any standard library way of doing this, or should I use something like the boost library?
If you are after a ratio of two large numbers as string, you can shorten the strings:
"194725681173571753193674" divided by "635482929374729202" is the same as
"1947256811735717" divided by "6354829293" to at least 9 digits (I just removed the same amount of digits on both sides). Depending on the needed precision, this might be the simplest solution. Just remove digits before converting to long long.
You can parse the inputs directly into a long double I believe. However, that approach will introduce precision errors. If precision is important, then avoid this.
A general solution for precise results is to represent the large integer with an array of integers where one integer represents the lower order bytes, next integer represents the larger bytes etc. This is generally called arbitrary precision arithmetic.
Is there any standard library way of doing this
No, other than basic building blocks such as vector for storing the array.
or should I use something like the boost library?
That's often a good place to start. Boost happens to have a library for this.
I am novice in audio processing with mathematical background so I have few (a lot, but few for starters) questions about processing extracted samples with fft.
I am using fft implementation from http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199702312?pgno=1 with fixed array length.
I have some set of samples (lets say 1024 samples in set).
Fft algorithm which takes input complex values (real and imaginary), imaginary values are set to 0, because I don't have any and stripping fft output of it's imaginary part.
I have next questions:
1) Is my assumption that samples are real numbers correct?
2) Is there efficient implementation of FFT which work only on real
numbers? I mean there is no imaginary part at all in calculations.
3) If I continue using described process, is it correct assumption that if there is no imaginary data in input of fft (all zeros), imaginary part of fft output will be also zero for all values?
PS I am sorry if question already exist but I didn't find any satisfying answer on my questions.
1) Is my assumption that samples are real numbers correct?
Yes.
2) Is there efficient implementation of FFT which work only on real numbers? I mean there is no imaginary part at all in calculations.
If there was, it would still need to use imaginary numbers in the calculations. (Sure, it could do complex math with pairs of real numbers, and just label the second number something that isn't "imaginary", but what advantage would that have?)
3) If I continue using described process, is it correct assumption that if there is no imaginary data in input of fft (all zeros), imaginary part of fft output will be also zero for all values?
This is not correct.
The absolute value of each number in the FFT output is proportional to the amplitude of each frequency in the signal.
The phase of each frequency in the signal is also encoded in the output, as the argument of the complex numbers. That is, if some frequency is 90 degrees out-of-phase with a sine wave, the argument of that bin will be 90 degrees - that is, the real part will be 0 and the imaginary part will have the amplitude! And for phases that aren't multiples of 90 degrees, both the real and imaginary parts will be nonzero.
If you don't care about phase information, you can take the absolute value of each output number - that is, sqrt(real*real + imag*imag).
I have an array of doubles having 6 indices, and it is mostly filled with zeros. I don't know yet what type should I use to storage it in the memory.
But, most importantly:
I would like to save it into a file (a binary file?).
What is the most efficient way to save it?
One requirement is that I can run through all the non-zero entries without passing by the zeros.
If I run 6 nested for I'll need too many lives.
Moreover, I don't know how to practically save it: Do I need two files, one acting as an index and the second one containing all the values?
Thanks!
This is probably a solved problem; there are probably sparse-matrix libraries that give you efficient in-memory representations too. (e.g. each row is a list of index:value, stored in a std::vector, linked list, hash, or other data structure, depending on whether inserting single non-zero values in the middle is valuable or whatever other operation is important).
A binary format will be faster to store/load, but whether you go binary or text isn't important for some ways of representing a sparse array. If you write a binary format, endian-agnostic code is a good way to make sure it's portable and doesn't have bugs that only show up on some architectures.
Options:
Simple but kind of ugly: gzip / lz4 / lzma the buffer holding your multidimensional array, writing the result to disk. Convert to little-endian on the fly while saving/loading, or store an endianness flag in the format.
Same idea but store all 6 indices with each value. Good if many inner-most arrays have no non-zero values, this may be good. Every non-zero value has a separate record (line, in a text-based format). Sample line (triple-nested example for readability, extends to 6 just fine):
dimensions on the first line or something
a b c val
...
3 2 5 -3.1416
means: matrix[3][2][5] = -3.1416
Use a nested sparse-array representation: each row is a list of index:value. Non-present indices are zero. A text format could use spaces and newlines to separate things; a binary format could use a length field at the start of each row or a sentinel value at the end.
You could flatten the multidimensional array out to one linear index for storage with 32bit integer indices, or you could represent the nesting somehow. I'm not going to try to make up a text format for this, since it got ugly as I started to think about it.
A regular flat representation of a 6 dimension array ...
double[10][10][10][10][10][10] = 1million entries * 8 bytes ~= 8MB
An associative array Index:Value representation, assume 50% of entries are 0.0 ... using a 4 byte 32bit index ...
500,000 * 4 bytes + 500,000 * bytes ~= 6MB
A bit map representation of the sparse array, assume 50% of entries are 0.0 ... bits are set so that every byte represents 8 entries in the array 10000001b would mean 8 entries where only the first and last are represented and the 6 middle values are ignored since they are zero ...
ceil(1million / 8) bytes + 500,000 * 8 bytes ~= 4.125MB
I am up to about 8E10000 so how is it calculating such large number, there is no variable that can hold such large numbers.
Normal types in C can usually only store up to 64 bits, instead of a single variable, you can use an array of characters to store digits of your number and write functions for each operation (sum, minus and so on) in your program.
You may look at this: GNU Multiple Precision Arithmetic Library
In a nut shell they aren't using one variable to hold the operands but data structures than can probably hold arbitrary long numbers (like an array) and they evaluate operations by considering the number to be in a large radix system.
When you actually do a math operation the operands aren't variables but array (or any other data structure that is suitable) and you do it by doing the operation (where available) component wise.
When you want to add 2 array you choose a radix and then loop the arrays and add op1[i] to op2[i] then you take that value and check to see if it its bigger than your radix and compute a carriage that you add to next addition.
car = (op1[i] + op2[i])%radix
You need to be careful in choosing the radix and the underlaying data so an addition doesn't cause an overflow.
This how you also do when you add numbers in the base 10 by hand but without taking into account the radix.
You can also look over this for a bigint package.
My limited understanding of the Fourier transform is that you should be able to toggle between the time and frequency domain without changing the original data. So, here is a summary of what I (think I) am doing:
Using kiss_fft_next_fast_size(994) to determine that I should use 1000.
Using kiss_fft_alloc(...) to create a kiss_fft_cfg with nfft = 1000.
Extending my input data from size 994 to 1000 by padding extra points as zero.
Passing kiss_fft_cfg to kiss_fft(...) along with my input and output arrays.
Using kiss_fft_alloc(...) to create an inverse kiss_fft_cfg with nfft = 1000.
Passing the inverse kiss_fft_cfg to kiss_fft(...) inputting the previous output array.
Expecting the original data back, but getting each datum exactly 1000 times bigger!
I have put a full example here, and my 50-odd lines of code can be found right at the end. Although I can work around this by dividing each result by the value of OPTIMAL_SIZE (i.e. 1000) that fix makes me very uneasy without understanding why.
Please can you advise what simply stupid thing(s) I am doing wrong?
This is to be expected: the inverse discreet Fourier transform (which can be implemented using the Fast Fourier Transform), requires a division by 1/N:
The normalization factor multiplying the DFT and IDFT (here 1 and 1/N)
and the signs of the exponents are merely conventions, and differ in
some treatments. The only requirements of these conventions are that
the DFT and IDFT have opposite-sign exponents and that the product of
their normalization factors be 1/N. A normalization of \sqrt{1/N} for both the DFT and IDFT makes the transforms unitary,
which has some theoretical advantages. But it is often more practical
in numerical computation to perform the scaling all at once as above
(and a unit scaling can be convenient in other ways).
http://en.wikipedia.org/wiki/Dft