【问题标题】:How to use boost::compute::atan2?如何使用 boost::compute::atan2?
【发布时间】:2019-03-17 01:35:22
【问题描述】:

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

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

【问题讨论】:

    标签: opencl boost-compute


    【解决方案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

    【讨论】:

      【解决方案2】:

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

      第一阶段:分配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();
      

      【讨论】:

        【解决方案3】:

        boost::computeatan2 would appear to be a binary function 就像std::atan2

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

        如果确实缺少arg(),你说得对,它是通过atan2 实现的——你需要先提取虚构的(boost::compute::imag()) 和真实的(boost::compute::real()) 组件,然后传递它们作为atan2 的单独参数。

        【讨论】:

        • 抱歉,我似乎无法从您的回答中推断出工作代码。你能添加一个小例子吗?
        猜你喜欢
        • 2018-12-25
        • 2017-01-17
        • 2018-12-20
        • 1970-01-01
        • 1970-01-01
        • 2015-08-08
        • 2017-11-16
        • 2017-04-05
        • 1970-01-01
        相关资源
        最近更新 更多