0

我想使用 boost::compute 计算复数的相位

这是我的尝试,我希望结果等于 atan2(0.5f):

namespace bc = boost::compute;

bc::vector<std::complex<float>> vec{ {1.0f, 2.0f} };
bc::vector<float> result(1);
bc::transform(vec.begin(), vec.end(), result.begin(), bc::atan2<float>());

但我收到一个编译错误,声称“非一元函数调用了一个参数”

4

3 回答 3

2

boost::compute'satan2 似乎是一个二进制函数,就像std::atan2.

我假设您正在尝试获得复数的相位角?用于此的标准 C++ 函数是std::arg()- 我没有看到在 中定义这个函数boost::compute,尽管我可能错过了它。

如果arg()确实缺少,那么您是完全正确的,它是通过atan2- 您需要先提取虚 ( boost::compute::imag()) 和实 ( boost::compute::real()) 组件,并将它们作为单独的参数传递给atan2.

于 2018-10-12T12:51:32.120 回答
1

我找到了让它工作的方法。

阶段 1:分配 2 个向量:

bc::vector<std::complex<float>> vec{ {1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f} };
bc::vector<float> result(3);

第 2 阶段:将复数向量解释为浮点缓冲区迭代器

buffer_iterator当您有一个强类型向量并希望将其作为不同类型传递给算法时非常有用。

auto beginf = bc::make_buffer_iterator<float>(vec.get_buffer(), 0);
auto endf = bc::make_buffer_iterator<float>(vec.get_buffer(), 6); // note end point to final index + 1

第 3 阶段:定义跨步迭代器,以便我们可以使用与 tan2 的参数相同的缓冲区。每个迭代器以 2 个索引的步幅迭代缓冲区,并且它们为 tan2 提供对缓冲区的交错访问:

auto begin_a = bc::make_strided_iterator(beginf + 1, 2); // access imaginary part
auto end_a = bc::make_strided_iterator_end(beginf + 1, endf , 2);
auto begin_b = bc::make_strided_iterator(beginf, 2); // access real part

最后,调用变换:

bc::transform(begin_a, end_a, begin_b, result.begin(), bc::atan2<float>()); // atan(b/a)
bc::system::default_queue().finish();
于 2018-10-13T18:43:20.113 回答
1

我认为您也可以为此使用 Boost.Compute 的 lambda 表达式:

  bc::vector<float2> input{ {1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f} };
  bc::vector<float> output(3); 

  using boost::compute::lambda::atan2;
  using boost::compute::_1;
  using boost::compute::lambda::get;

  bc::transform(
    float2_input.begin(),
    float2_input.end(),
    float_output.begin(),
    atan2(get<1>(_1), get<0>(_1)),
    queue
  );

float2基本上是 Boost.Compute 中的一个复合体。您还可以检查test_lambda.cpp

于 2018-10-24T05:05:17.100 回答