如何使用boost :: compute :: atan2?

时间:2018-10-11 21:15:30

标签: opencl boost-compute

我想使用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>());

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

3 个答案:

答案 0 :(得分:2)

boost::compute的{​​{1}} would appear to be a binary function就像std::atan2

我假设您正在尝试获取复数的相位角?用于此目的的标准C ++函数为std::arg()-尽管我可能会错过它,但我没有在atan2中定义此函数。

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

答案 1 :(得分:1)

我找到了使其工作的方法。

阶段1:分配2个向量:

INSERT

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

bc::vector<std::complex<float>> vec{ {1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f} }; bc::vector<float> result(3); 在具有强类型的向量并将其作为另一种类型传递给算法时非常有用。

buffer_iterator

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

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

最后,调用转换:

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

答案 2 :(得分: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