Как использовать boost :: compute :: atan2? - PullRequest
0 голосов
/ 12 октября 2018

Я хотел бы вычислить фазу комплексного числа, используя 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 голосов
/ 13 октября 2018

Я нашел способ заставить его работать.

этап 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

наконец, вызовите transform:

bc::transform(begin_a, end_a, begin_b, result.begin(), bc::atan2<float>()); // atan(b/a)
bc::system::default_queue().finish();
0 голосов
/ 24 октября 2018

Я думаю, вы также можете использовать лямбда-выражения Boost.Compute для этого:

  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 .

0 голосов
/ 12 октября 2018

boost::compute atan2 может быть двоичной функцией , как std::atan2.

Я предполагаю, что вы пытаетесьполучить фазовый угол вашего комплексного числа?Стандартная функция C ++ для этого будет std::arg() - я не вижу, чтобы эта функция определялась в boost::compute, хотя я мог бы ее пропустить.

Если arg()на самом деле отсутствует, вы совершенно правы: он реализован через atan2 - вам нужно сначала извлечь мнимые (boost::compute::imag()) и реальные (boost::compute::real()) компоненты и передать их в качестве отдельных аргументов atan2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...