传递给pgplot时是否有O(1)方法来分离复数数组的实部和虚部?

Viv*_*V K 1 c arrays time-complexity complex-numbers

我的代码中有一个复杂的float数组,一个库为我生成.考虑它是这样的:

float _Complex data[N];
Run Code Online (Sandbox Code Playgroud)

为了将它作为具有实部和虚部的单独数组,我迭代数组并获取如下值:

float real[N];
float imag[N];
for (int pt=0;pt<N;pt++) {
  real[pt] = creal(data[pt]);
  imag[pt] = cimag(data[pt]));    
}
Run Code Online (Sandbox Code Playgroud)

但这实际上是低效的,因为这是一个O(N)执行时间和空间的操作.我想知道是否可以使用一些指针算法分离数组,以便减少执行时间和内存使用量?

我需要分别绘制实数和虚数值.我的绘图库PGPLOT需要将一组值发送给它,因此我无法"就地"使用复杂数组.

Rei*_*ica 5

pgplot库提供了绘制标记数组的无间隙界面:

void cpgpt(int n, const float *xpts, const float *ypts, int symbol);
Run Code Online (Sandbox Code Playgroud)

但这只是个别电话的薄包装cpgpt1.因此,添加一个大踏步的界面很容易:

void cpgpts(int n, int stride, const float *xpts, const float *ypts, int symbol) {
  for (int i = 0; i < n; ++i) {
    cpgpt1(*xpts, *ypts, symbol);
    xpts += stride;
    ypts += stride;
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,你会想要围绕复杂浮动铸造的丑陋写封皮.例如:

void cpgptsc(int n, const float _Complex *pts, int symbol) {
  cpgpts(n, 2, (const float*)pts, ((const float*)pts)+1, symbol);
}
Run Code Online (Sandbox Code Playgroud)

例:

// Plot the data as symbols on the Re-Im plane
cpgptsc(count, data, symbol);
Run Code Online (Sandbox Code Playgroud)

您可以类似地重新实现cpgline:

void cpglines(int n, int stride, const float *xpts, const float *ypts, int symbol) {
  cpgmove(*xpts, *ypts);
  for (int i = 1; i < n; ++ i) {
    xpts += stride;
    ypts += stride;
    cpgdraw(*xpts, *ypts);
  }
}

void cpglinesc(int n, const float _Complex *pts, int symbol) {
  cpglines(n, 2, (const float*)pts, ((const float*)pts)+1, symbol);
}
Run Code Online (Sandbox Code Playgroud)

例:

// Plot the data as lines on the Re-Im plane
cpglinesc(count, data);
Run Code Online (Sandbox Code Playgroud)

如果您只绘制单个组件(实数或虚数),那么为它创建一个合理的包装器同样简单:

void cpglinesx(int n, int stride, float dx, float x0, const float *ypts) {
  cpgmove(x0, *ypts);
  for (int i = 1; i < n; ++ i) {
    x0 += dx;
    ypts += stride;
    cpgdraw(x0, *ypts);
  }
}

void cpglinesxre(int n, float dx, float x0, const float _Complex *pts) {
  cpglinesx(n, 2, dx, x0, (const float*)pts);
}

void cpglinesxim(int n, float dx, float x0, const float _Complex *pts) {
  cpglinesx(n, 2, dx, x0, ((const float*)pts)+1);
}
Run Code Online (Sandbox Code Playgroud)

然后,为了绘制,例如,从x = 0开始的虚部,增量为1.0,你会做:

// Plot the imaginary coordinates of all the data
cpglinesxim(count, 1.0, 0.0, data);
Run Code Online (Sandbox Code Playgroud)