创建一个包含特定订单的旋转表?

时间:2017-07-04 16:11:56

标签: c arrays

我希望创建一个特定用途的旋转表,这是最初的代码:

#define TWIDDLE_LIMIT 64
#define PI 3.1415927

float *twiddle_real;
float *twiddle_imag;

void main()
{
  int N = 256;
  int TW_size = TWIDDLE_LIMIT + (TWIDDLE_LIMIT>>2);

  twiddle_real  = malloc(TW_size * sizeof(float));
  twiddle_imag  = malloc(TW_size * sizeof(float));

  int i;
  for(i=0; i<TWIDDLE_LIMIT; i++)
  {
    twiddle_real[i] = (float)   cos((float)i * 2.0 * PI / (float)N);
    twiddle_imag[i] = (float) - sin((float)i * 2.0 * PI / (float)N);
  }
  for(int a=0; a<TWIDDLE_LIMIT; a++)
    printf("RE = %f \t IM = %f \n",twiddle_real[a],twiddle_imag[a]);
}

我得到了这样的结果:

RE = 1.000000    IM = -0.000000 //64 lines
RE = 0.999699    IM = -0.024541 
RE = 0.998795    IM = -0.049068 
RE = 0.997290    IM = -0.073565 
RE = 0.995185    IM = -0.098017 
RE = 0.992480    IM = -0.122411 
RE = 0.989177    IM = -0.146730 
RE = 0.985278    IM = -0.170962 
RE = 0.980785    IM = -0.195090 
RE = 0.975702    IM = -0.219101 
RE = 0.970031    IM = -0.242980 
RE = 0.963776    IM = -0.266713 
RE = 0.956940    IM = -0.290285 
RE = 0.949528    IM = -0.313682 
RE = 0.941544    IM = -0.336890 
RE = 0.932993    IM = -0.359895 
RE = 0.923880    IM = -0.382683 
RE = 0.914210    IM = -0.405241 
RE = 0.903989    IM = -0.427555 
RE = 0.893224    IM = -0.449611 
RE = 0.881921    IM = -0.471397 
RE = 0.870087    IM = -0.492898 
RE = 0.857729    IM = -0.514103 
RE = 0.844854    IM = -0.534998 
RE = 0.831470    IM = -0.555570 
RE = 0.817585    IM = -0.575808 
RE = 0.803208    IM = -0.595699 
RE = 0.788346    IM = -0.615232 
RE = 0.773010    IM = -0.634393 
RE = 0.757209    IM = -0.653173 
RE = 0.740951    IM = -0.671559 
RE = 0.724247    IM = -0.689541 
RE = 0.707107    IM = -0.707107 
RE = 0.689541    IM = -0.724247 
RE = 0.671559    IM = -0.740951 
RE = 0.653173    IM = -0.757209 
RE = 0.634393    IM = -0.773010 
RE = 0.615232    IM = -0.788346 
RE = 0.595699    IM = -0.803208 
RE = 0.575808    IM = -0.817585 
RE = 0.555570    IM = -0.831470 
RE = 0.534998    IM = -0.844854 
RE = 0.514103    IM = -0.857729 
RE = 0.492898    IM = -0.870087 
RE = 0.471397    IM = -0.881921 
RE = 0.449611    IM = -0.893224 
RE = 0.427555    IM = -0.903989 
RE = 0.405241    IM = -0.914210 
RE = 0.382683    IM = -0.923880 
RE = 0.359895    IM = -0.932993 
RE = 0.336890    IM = -0.941544 
RE = 0.313682    IM = -0.949528 
RE = 0.290285    IM = -0.956940 
RE = 0.266713    IM = -0.963776 
RE = 0.242980    IM = -0.970031 
RE = 0.219101    IM = -0.975702 
RE = 0.195090    IM = -0.980785 
RE = 0.170962    IM = -0.985278 
RE = 0.146730    IM = -0.989177 
RE = 0.122411    IM = -0.992480 
RE = 0.098017    IM = -0.995185 
RE = 0.073565    IM = -0.997290 
RE = 0.049068    IM = -0.998795 
RE = 0.024541    IM = -0.999699 

这只是一个极小的问题,我可以尽可能多地解释你。

我想要并尝试创建的是一个以较早的行开头的表格,resdt将如下所示:

(早期行)表示如下(idx:0 ---&gt; 64)

    re[idx] = (float) cos((float)i * (2*pi)/(float)N);
    im[idx] = (float)-sin((float)i * (2*pi)/(float)N);

(第2组线)表示如下重复4次

    re[idx] = (float) cos(4 * (float)i * (2*pi)/(float)N);
    im[idx] = (float)-sin(4 * (float)i * (2*pi)/(float)N);

(第3组线)表示如下重复16次

    re[idx] = (float) cos(16 * (float)i * (2*pi)/(float)N);
    im[idx] = (float)-sin(16 * (float)i * (2*pi)/(float)N);

结果预计如下:

//set 1 as above  repeated just 1 time
// ....
//set 2 repeated 4 times
RE = 1.000000    IM = -0.000000 //1st ligne of set 1
RE = 0.995185    IM = -0.098017 //4th ligne of set 1
RE = 0.980785    IM = -0.195090 //8th ligne of set 1
RE = 0.956940    IM = -0.290285 //12th ligne of set 1 ...
RE = 0.923880    IM = -0.382683 
RE = 0.881921    IM = -0.471397 
RE = 0.831470    IM = -0.555570 
RE = 0.773010    IM = -0.634393 
RE = 0.707107    IM = -0.707107 
RE = 0.634393    IM = -0.773010 
RE = 0.555570    IM = -0.831470 
RE = 0.471397    IM = -0.881921 
RE = 0.382683    IM = -0.923880 
RE = 0.290285    IM = -0.956940 
RE = 0.195090    IM = -0.980785 
RE = 0.098017    IM = -0.995185
// set 3 repeated 16 times
RE = 1.000000    IM = -0.000000 //1st ligne of set 1
RE = 0.923880    IM = -0.382683 //16th ligne of set 1
RE = 0.707107    IM = -0.707107 //38th ligne of set 1
RE = 0.382683    IM = -0.923880 //64th ligne of set 1

我已经尝试了几次,但我一直得到错误的结果,我不知道这是否是精确问题还是其他问题。

2 个答案:

答案 0 :(得分:1)

您可以在附加(外部)循环中维护因子和设置大小:

// you will need more than you calculated previously!
float twiddle_real[TWIDDLE_LIMIT * 3];
float twiddle_imag[TWIDDLE_LIMIT * 3];

// pointer arithmetic...
float* real = twiddle_real;
float* imag = twiddle_imag;

double factor = 1.0;
for(int size = TWIDDLE_LIMIT; size > 1; size /= 4)
{
    for(int j = 0; j < 64; ++j)
    {
        *real++ = (float)  cos((j % size) * factor * 2.0 * PI / N);
        *imag++ = (float) -sin((j % size) * factor * 2.0 * PI / N);
    }
    factor *= 4.0;
}

顺便说一句,你不需要所有这些演员阵容 - 因为因素是双倍的,(j % size)会被隐式转换为N

建议:由于re和img属于一起,我会代表他们:

struct Complex
{
    double re;
    double im;
};

然后你可以有一个这样的数组:

struct Complex twiddle[TW_size]; // no need for malloc, by the way...

您可能已经注意到:我也改为加倍。没有理由使用float(精度更有限),除非你的内存有限(微控制器)......

替代方案(为什么重新发明轮子?):使用complex.h

答案 1 :(得分:0)

它不起作用,因为你的数学错了。第一个表仅涵盖复平面的第一个象限。当你将所需输出的第二段乘以4时,你将不会得到第一象限的4次重复,你将得到所有四个象限。

这与您指定的内容更接近。它解决了使用C的一些问题:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define N_ROOTS_OF_UNITY 64
#define PI 3.14159265358979323846264338327950

float *twiddle_real;
float *twiddle_imag;

int main()
{
  size_t table_size = N_ROOTS_OF_UNITY * 3;

  twiddle_real  = malloc(table_size * sizeof(float));
  twiddle_imag  = malloc(table_size * sizeof(float));

  size_t i, incr, repeat, k = 0;
  for (incr = 1; incr <= 16; incr *= 4) {
    for (repeat = 0; repeat < incr; ++repeat) {
      for(i = 0; i < N_ROOTS_OF_UNITY; i += incr) {
        twiddle_real[k] = (float) cos(i * (PI / 2) / N_ROOTS_OF_UNITY);
        twiddle_imag[k] = (float) -sin(i * (PI / 2) / N_ROOTS_OF_UNITY);
        ++k;
      }
    }
  }
  for (int a = 0; a < table_size; a++)
    printf("%d: RE = %f\tIM = %f\n", a, twiddle_real[a], twiddle_imag[a]);
  return 0;
}