9

I have a matrix stored in row-major order. I am trying to compute the DCT of a ub-matrix using FFTW, and I get nonsense. In the following paragraphs I will describe the problem and my solution, and I would like your help in understanding why it does not work.

Given some i and l, I would like to compute the DCT of a sub-matrix which consists of all rows k for which k mod l == i. For example, assume that l = 3 and i = 2. In the following matrix, the sub-matrix which I wish to transform is marked in red (2 mod 3 = 2, 5 mod 3 = 2, 8 mod 3 = 2).

Matrix

The source and destination arrays have the same layout, and the transformed matrix should be stored in the same location in the destination array.

void transform(double* src, double* dest, size_t rows, size_t cols, size_t l, size_t i)
{
    int rank = 2;
    fftw_iodim64 dims[] = {
        { rows / l, l, l },
        { cols, rows, rows } };
    fftw_r2r_kind kind = FFTW_REDFT10;

    fftw_plan plan = fftw_plan_guru64_r2r(rank, dims, 0, NULL, src + l, dest + l, &kind, FFTW_ESTIMATE | FFTW_UNALIGNED | FFTW_PRESERVE_INPUT);
    fftw_execute(plan);
    fftw_destroy_plan(pla);
}

Update

I tested it for the simple case when i=l=1. Even in that case I get nonsense. I tested with a 3x4 matrix which is exactly one of the DCT basis vectors:

A(i,j) = cos((i + 0.5)*2*pi/3) * cos((j + 0.5)*3*pi/4)

I expected to get a result where all elements are (close to) zero except for one. But I get a resulting matrix that looks like this:

0             -2.22045e-016  1.33227e-015  2.22045e-016
2.22045e-016  -2.77556e-016  9.99201e-016  5.55112e-017
-8.88178e-016 -1.62359       7.83938       1.62359

Seems quite weird.

Update 2

I also tested with a simple matrix where the (0,0) element is 1 and the rest are zero. In this case, too, i=l=1 (the sub-matrix is the whole matrix). Here is the result:

      2       2       2       0
1.73205 1.73205 1.73205       0
      1       1       1       0
Alex Shtoff
  • 2,520
  • 1
  • 25
  • 53
  • Can you test with some obvious input (simple patterns of 1s and 0s) and see what output you get? Maybe post it here so that one might get an idea what is going wrong? – Jonas Schäfer Jul 30 '15 at 09:21
  • I did something else. I filled the sub-matrix with one of the DCT basis vectors. What I get is something which is *not* all zeros except for a single non-zero element. I get many non-zero elements in the result. – Alex Shtoff Jul 30 '15 at 09:26
  • You are not specifying anywhere that your input stride is 2*rows. – Jens Munk Jul 31 '15 at 13:15
  • @JensMunk, What do you mean by "input stride"? I have a stride in each dimension. In the 1st dimension the stride is rows / l, in the 2nd dimension the stride is rows. What did you mean? – Alex Shtoff Jul 31 '15 at 16:21
  • From what you supply, there is no way FFTW can know that you need every 3rd row. – Jens Munk Jul 31 '15 at 17:39
  • Why not? I am specifying the stride between consecutive elements in each row (3 in this case) and the stride between consecutive elements in each column. Except for the size and stride in each dimension, what other info does FFTW need? – Alex Shtoff Aug 01 '15 at 19:07
  • @Alex You are not specifying that you need every third row. Your input stride for should be `{cols, 3*rows, rows}` and not `{cols, rows, rows}`as you have. – Jens Munk Aug 03 '15 at 00:42
  • I see what you mean. Will check it out (I think that my code is right, and the code here in the question is wrong). – Alex Shtoff Aug 03 '15 at 13:59
  • @Alex That's what I pictured. If you upload an example which compiles, I will fix it for you. If I make a working example from scratch, I will take me about an hour. Usually, I supply everything when working with fftw, i.e. no NULL pointers. The Guru interface is pretty neat. Note also, that when you index inside an array, you get a performance drop, if the addresses are not 16-byte aligned. – Jens Munk Aug 03 '15 at 17:42
  • @JensMunk,after checking the code, it is correct. `rows` is the correct column stride, since `rows` is the total number of rows in the matrix, not the number of red rows. Anyway, it works now, due to Oliver's answer below. – Alex Shtoff Aug 04 '15 at 13:52

1 Answers1

0

kind is supposed to be an array of size rank. See e.g. http://www.fftw.org/doc/Guru-Real_002dto_002dreal-Transforms.html#Guru-Real_002dto_002dreal-Transforms.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680