'fftw3 2D, how to normalize array of double for IDCT?

I have 2d array in python and a function that converts numbers by the IDCT. It works right. But I have to do the same in C ++ using a library fftw3. And I get wrong answer. It is not entirely wrong, if I remove the norm parameter from the python program, I get the same result. That is, on Python, the array is normalized, but on fftw3 it is not. How can I normalize it? The documentation only mentions that it needs to be done and no examples or explanations.

I tried to multiply and divide the input array in C ++ by 2 and by sqrt(2), by 4 (my N) and sqrt(N), but the result is not the same. I tried to divide it at the sqrt(2 / N). And I tried to apply multiplication and division only to the first row and column, but to no avail.

I tried to pass input_ and output_ as &input_[0], &output_[0].

Python OK example

from scipy import fftpack
import numpy as np

def idct2(f):
    """
    Inverse Discrete Cosine Transform in 2D.
    """
    return np.transpose(fftpack.idct(np.transpose(fftpack.idct(f, norm = "ortho")), norm = "ortho"))

data = [[110, 199, 22, 282],
         [30, 125, 239, 34],
         [79, 288, 174, 67],
         [175, 243, 134, 256]]

idct2(data)

# result
>>> array([[ 553.27655635, -132.45254006,    3.51123029, -101.4290401 ],
           [-219.14317857,   -8.74853673,   16.90900348,   29.57007596],
           [ 158.6797074 ,  -64.29020845,  239.1297417 ,  -90.10660479],
           [  51.81024507,   32.73855308,   89.2027567 , -118.65776132]])

C++ wrong code:

#include <fftw3.h>
#include <vector>
#include <fstream>
#include <iostream>

int main() {
    std::vector<double> input_;
    input_.resize(16);
    std::vector<double> output_;
    output_.resize(16);

    input_ = {110, 199, 22, 282,
            30, 125, 239, 34,
            79, 288, 174, 67,
            175, 243, 134, 256};

    fftw_plan plan = fftw_plan_r2r_2d(4, 4, input_.data(), output_.data(), FFTW_REDFT01,FFTW_REDFT01, FFTW_ESTIMATE);
    fftw_execute(plan);

    // result to file
    std::ofstream out("file.txt");
    for(size_t i=0; i<output_.size(); ++i) {
        out << output_[i] << std::endl;
    }

// result
/*
3936.9 -1128.71 -346.486 -817.328
-1947.04 156.35 56.1195 526.088
826.69 -536.84 1585.03 -680.182
82.0488 349.704 495.927 -798.277
*/

    return 0;
}

Any ideas?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source