[英]How to use boost::compute::atan2?
I would like to compute the phase of a complex number using boost::compute 我想使用boost :: compute计算复数的相位
here is my attempt, I expect the result to be equal to atan2(0.5f): 这是我的尝试,我希望结果等于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>());
but I get a compilation error claiming "Non-unary function invoked one argument" 但是我收到一个编译错误,声称“非一元函数调用了一个参数”
boost::compute
's atan2
would appear to be a binary function just like std::atan2
. boost::compute
的atan2
似乎是一个二进制函数 ,就像std::atan2
。
I'm assuming you're trying to obtain the phase angle of your complex number? 我假设您正在尝试获取复数的相位角? The standard C++ function for this would be
std::arg()
- I don't see this one being defined in boost::compute
, though I might have missed it. 用于此目的的标准C ++函数为
std::arg()
-我看不到boost::compute
定义了该boost::compute
,尽管我可能会错过它。
If arg()
is indeed missing, you're quite right it's implemented via atan2
- you'll need to extract the imaginary ( boost::compute::imag()
) and real ( boost::compute::real()
) components first though, and pass them as individual arguments to atan2
. 如果确实缺少
arg()
,那么您完全可以通过atan2
实现-您需要提取虚构的( boost::compute::imag()
)和real( boost::compute::real()
)组件首先,然后将它们作为单独的参数传递给atan2
。
I found a way to make it work. 我找到了使之工作的方法。
stage 1: allocate 2 vectors: 阶段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);
stage 2: interpret the complex vector as a float buffer iterator 阶段2:将复数向量解释为浮点缓冲区迭代器
buffer_iterator
is quite useful when you have a strongly typed vector and would like to pass it to an algorithm as a different type. 当您有一个强类型的向量并将其作为另一种类型传递给算法时,
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
stage 3: define strided iterators so that we can use the same buffer as the argument for tan2. 阶段3:定义跨步迭代器,以便我们可以使用与tan2参数相同的缓冲区。 each iterator iterates the buffers in strides of 2 indices, and they supply tan2 with interleaved access to the buffer:
每个迭代器以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
finally, call transform: 最后,调用转换:
bc::transform(begin_a, end_a, begin_b, result.begin(), bc::atan2<float>()); // atan(b/a)
bc::system::default_queue().finish();
I think you can also use Boost.Compute's lambda expressions for this: 我认为您也可以为此使用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
is bassically a complex in Boost.Compute. float2
在Boost.Compute中非常复杂。 You can also check test_lambda.cpp . 您还可以检查test_lambda.cpp 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.