如何使用boost::compute::atan2?
How to use boost::compute::atan2?
我想使用 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>());
但我收到一个编译错误,声称 "Non-unary function invoked one argument"
boost::compute
的atan2
would appear to be a binary function just like std::atan2
.
我假设您正在尝试获取复数的相位角?这个的标准 C++ 函数是 std::arg()
- 我没有看到这个函数在 boost::compute
中定义,尽管我可能错过了它。
如果 arg()
确实丢失了,你说得对,它是通过 atan2
实现的 - 你需要提取虚数 (boost::compute::imag()
) 和实数 (boost::compute::real()
) 组件,然后将它们作为单独的参数传递给 atan2
.
我找到了让它工作的方法。
第 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();
我认为您也可以为此使用 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.
我想使用 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>());
但我收到一个编译错误,声称 "Non-unary function invoked one argument"
boost::compute
的atan2
would appear to be a binary function just like std::atan2
.
我假设您正在尝试获取复数的相位角?这个的标准 C++ 函数是 std::arg()
- 我没有看到这个函数在 boost::compute
中定义,尽管我可能错过了它。
如果 arg()
确实丢失了,你说得对,它是通过 atan2
实现的 - 你需要提取虚数 (boost::compute::imag()
) 和实数 (boost::compute::real()
) 组件,然后将它们作为单独的参数传递给 atan2
.
我找到了让它工作的方法。
第 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();
我认为您也可以为此使用 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.