Как использовать std :: pow в std :: transform в качестве унарной функции? - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь написать функцию, которая возвращает n-ую норму вектора, где n на входе функции.

double n_norm = N_Norm(std::vector< double > x, double n);

Я пытаюсь использовать метод std :: transform и std :: pow для вычисления n-й степени всех элементов входного вектора.

return (std::pow(std::transform(x.begin(), x.end(), x.begin(), std::bind2nd(std::pow<double>(), n)), 1/n));

Но я получаю эту ошибку:

ни один экземпляр перегруженной функции "std :: pow" не соответствует списку аргументов.

Кто-нибудь знает, как я могу исправить свою унарную функцию?

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Как я понял, вы хотели написать:

double N_Norm(std::vector<double> v, double n)
{
    std::transform(v.begin(), v.end(), [n](double d) { std::pow(d, n); });
    double sum = std::accumulate(v.begin(), v.end(), 0.);
    return std::pow(sum, 1 / n);
}

Но это делает дополнительную копию вектора.

В c ++ 17 вы можете сделать:

double N_Norm(std::vector<double> v, double n)
{
    return std::pow(std::transform_reduce(v.begin(),
                                          v.end(),
                                          0.,
                                          std::plus<>{},
                                          [n](double d){ return std::pow(d, n); }),
                    1 / n);
}
0 голосов
/ 07 сентября 2018

std::transform здесь не подходит. Вы должны использовать std::accumulate. Также начиная с C ++ 11 у вас есть лямбды, которые гораздо удобнее, чем std::bind1st или std::bind2d или std::bind.

double N_NormAcc(const std::vector< double > &v, double n) {
    auto sum = std::accumulate(v.begin(), v.end(), 0.0, [n](auto sum, auto x) { 
        return sum + std::pow(std::fabs(x), n);
    });
    return std::pow(sum, 1.0 / n);
}

https://wandbox.org/permlink/yhJIZrMcgNT9GznF

...