Calcular Ponto Produto de Dois Vectores em C++

  1. Utilize std::inner_product para calcular o produto de ponto de dois vectores em C++
  2. Utilize std::transform_reduce para calcular o produto de pontos de dois vectores em C++
  3. Utilizar std::transform_reduce e std::execution::par Calcular Produto Ponto de Dois Vectores

Este artigo irá demonstrar múltiplos métodos para calcular o produto ponto de dois vectores em C++.

O produto ponto é a soma dos produtos dos elementos correspondentes dos dois vectores. Suponhamos que temos dois vectores - {1, 2, 3} e {4, 5, 6}, e o produto ponto destes vectores é 1*4 + 2*5 + 3*6 = 32.

Utilize std::inner_product para calcular o produto de ponto de dois vectores em C++

std::inner_product faz parte da biblioteca de algoritmos numéricos C++ incluídos no cabeçalho <numeric>. O método calcula a soma dos produtos em duas gamas, a primeira das quais é especificada com iteradores begin/end e a segunda gama com apenas begin. A função também toma o init como quarto parâmetro para inicializar o valor do acumulador. O valor de retorno é o valor final do produto de ponto das gamas dadas. Note-se que std::inner_product realiza sempre operações numa dada ordem.

#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>

using std::cout;
using std::endl;
using std::vector;
using std::copy;

int main(){
    vector<int> vec1 { 1, 2, 3, 4, 5 };
    vector<int> vec2 { 2, 4, 6, 8, 10 };

    copy(vec1.begin(), vec1.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    copy(vec2.begin(), vec2.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    cout << "Scalar product is: "
              << inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
    cout << endl;

    return EXIT_SUCCESS;
}

Resultado:

1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110

Utilize std::transform_reduce para calcular o produto de pontos de dois vectores em C++

Ao contrário do método anterior, std::transform_reduce pode realizar operações em intervalos fora de ordem, maximizando assim o desempenho. O método std::transform_reduce é essencialmente a versão paralela do algoritmo std::inner_product. O exemplo seguinte demonstra a execução da função com os mesmos argumentos que foram passados no exemplo anterior.

#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>

using std::cout;
using std::endl;
using std::vector;
using std::copy;
using std::inner_product;

int main(){
    vector<int> vec1 { 1, 2, 3, 4, 5 };
    vector<int> vec2 { 2, 4, 6, 8, 10 };

    copy(vec1.begin(), vec1.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    copy(vec2.begin(), vec2.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    cout << "Scalar product is: "
            << std::transform_reduce(vec1.begin(),
             vec1.end(), vec2.begin(), 0);

    return EXIT_SUCCESS;
}

Resultado:

1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110

Utilizar std::transform_reduce e std::execution::par Calcular Produto Ponto de Dois Vectores

Em alternativa, pode-se especificar adicionalmente uma política de execução para o algoritmo std::transform_reduce. Este método oferece mais controlo ao programador uma vez que o fluxo do programa pode ser personalizado com regras de execução tal como definidas neste manual. Ainda que haja ganhos de desempenho na utilização do transform_reduce, deve-se sempre ter em conta as condições de corrida potenciais ao especificar a política de execução paralela.

#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
#include <execution>

using std::cout;
using std::endl;
using std::vector;
using std::copy;
using std::inner_product;

int main(){
    vector<int> vec1 { 1, 2, 3, 4, 5 };
    vector<int> vec2 { 2, 4, 6, 8, 10 };

    copy(vec1.begin(), vec1.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    copy(vec2.begin(), vec2.end(),
         std::ostream_iterator<int>(cout,"; "));
    cout << endl;

    cout << "Scalar product is: "
            << std::transform_reduce(std::execution::par,
                        vec1.begin(), vec1.end(),
                        vec2.begin(), 0);

    return EXIT_SUCCESS;
}

Resultado:

1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110

Artigo relacionado - C++ Vector

  • Vector de embaralhamento em C++