繁体   English   中英

当传递给pgplot时,是否有O(1)方式将复杂数组的实部和虚部分开?

[英]Is there an O(1) way to separate real and imaginary parts of complex array when passed to pgplot?

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

float _Complex data[N];

为了将其作为具有实部和虚部的单独数组,我遍历该数组并采用以下值:

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

但是,这实际上是低效的,因为这从执行时间和空间上来说都是O(N)操作。 我想知道是否可以使用某些指针算术来分隔数组,从而减少执行时间和内存使用?

我需要分别绘制实数值和虚数值。 我的绘图库PGPLOT需要将值数组发送给它,因此我不能“就地”使用复杂的数组。

pgplot库提供了一个无边距的界面来绘制标记数组:

void cpgpt(int n, const float *xpts, const float *ypts, int symbol);

但这只是对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;
  }
}

当然,您将需要编写复杂的浮标转换的包装程序。 例如:

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

例:

// Plot the data as symbols on the Re-Im plane
cpgptsc(count, data, symbol);

您可以类似地重新实现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);
}

例:

// Plot the data as lines on the Re-Im plane
cpglinesc(count, data);

如果只绘制单个分量(实部或虚部),则为其创建合理的包装器也很简单:

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);
}

然后,要绘制以x = 0开头,增量为1.0的虚数分量,您需要执行以下操作:

// Plot the imaginary coordinates of all the data
cpglinesxim(count, 1.0, 0.0, data);

鉴于:

float _Complex data[N];

我们知道:

float *ptr = (float *) data;
ptr[2 * n + 0] <- real part.
ptr[2 * n + 1] <- imaginary part.

我们可以在这里看到一些合理化。 基本上, float _Complex具有与float[2]相同的内存布局。

修改此值以使所有实数都是连续的,将需要与问题中提到的O(n)版本相似的操作。

如果您有一个长度为N的输入数组,那么实际上就没有O(1)算法来处理所有输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM