Espacios de nombres
Variantes
Acciones

std::inner_product

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
(C++11)
inner_product
Bibliotecas C
 
Definido en el archivo de encabezado <numeric>
(1)
template< class InputIt1, class InputIt2, class T >

T inner_product( InputIt1 first1, InputIt1 last1,

                 InputIt2 first2, T init );
(hasta C++20)
template< class InputIt1, class InputIt2, class T >

constexpr T inner_product( InputIt1 first1, InputIt1 last1,

                           InputIt2 first2, T init );
(desde C++20)
(2)
template< class InputIt1, class InputIt2, class T,

          class BinaryOperation1, class BinaryOperation2 >
T inner_product( InputIt1 first1, InputIt1 last1,
                 InputIt2 first2, T init,
                 BinaryOperation1 op1,

                 BinaryOperation2 op2 );
(hasta C++20)
template< class InputIt1, class InputIt2, class T,

          class BinaryOperation1, class BinaryOperation2 >
constexpr T inner_product( InputIt1 first1, InputIt1 last1,
                           InputIt2 first2, T init,
                           BinaryOperation1 op1,

                           BinaryOperation2 op2 );
(desde C++20)

Calcula el producto interno (es decir, la suma de los productos) o realiza una operación ordenada de mapa/reducción en el rango [first1, last1) y el rango que comienza en first2.

1) Inicializa el acumulador acc con el valor inicial init y luego

lo modifica con la expresión acc = acc + *first1 * *first2, luego lo modifica de nuevo con la expresión acc = acc + *(first1+1) * *(first2+1), etc.

(hasta C++20)

lo modifica con la expresión acc = std::move(acc) + *first1 * *first2, luego lo modifica de nuevo con la expresión acc = std::move(acc) + *(first1+1) * *(first2+1), etc.,

(desde C++20)
hasta llegar a last1. Para el significado integrado de + y *, esto calcula el producto interno de los dos rangos.
2) Inicializa el acumulador acc con el valor inicial init y luego

lo modifica con la expresión acc = op1(acc, op2(*first1, *first2)), luego lo modifica de nuevo con la expresión acc = op1(acc, op2(*(first1+1), *(first2+1))), etc.,

(hasta C++20)

lo modifica con la expresión acc = op1(std::move(acc), op2(*first1, *first2)), luego lo modifica de nuevo con la expresión acc = op1(std::move(acc), op2(*(first1+1), *(first2+1))), etc.,

(desde C++20)
hasta llegar a last1.

op1 o op2 no debe tener efectos secundarios.

(hasta C++11)

op1 o op2 no deben invalidar ningún iterador, incluidos los iteradores finales, ni modificar ningún elemento del rango involucrado.

(desde C++11)

Contenido

[editar] Parámetros

first1, last1 - El primer rango de elementos.
first2 - El comienzo del segundo rango de elementos.
init - El valor inicial de la suma de los productos.
op1 - Función objeto de operación binaria que se aplicará. Esta función "suma" toma un valor devuelto por op2 y el valor actual del acumulador y produce un nuevo valor para ser almacenado en el acumulador.

La signatura de la función deberá ser equivalente a lo siguiente:

 Ret fun(const Type1 &a, const Type2 &b);

La signatura no necesita tener const &.
Los tipos Type1 y Type2 deben ser tales que objetos de tipo T y Type3 puedan convertirse implícitamente a Type1 y Type2 respectivamente. El tipo Ret debe ser tal que un objeto de tipo T puede ser asignado un valor de tipo Ret. ​

op2 - Función objeto de operación binaria que se aplicará. Esta función "producto" toma un valor de cada rango y produce un nuevo valor.

La signatura de la función deberá ser equivalente a lo siguiente:

 Ret fun(const Type1 &a, const Type2 &b);

La signatura no necesita tener const &.
Los tipos Type1 y Type2 deben ser tales que objetos de tipo InputIt1 y InputIt2 pueden ser desreferenciados y luego convertidos implícitamente a Type1 and Type2 respectively. El tipo Ret debe ser tal que un objeto de tipo Type3 puede ser asignado un valor de tipo Ret. ​

Requisitos de tipo
-
InputIt1, InputIt2 debe satisfacer los requisitos de InputIterator.
-
ForwardIt1, ForwardIt2 debe satisfacer los requisitos de ForwardIterator.
-
T debe satisfacer los requisitos de CopyAssignable y CopyConstructible.

[editar] Valor de retorno

El valor final de acc como se describe arriba.

[editar] Posible implementación

Primera versión
template<class InputIt1, class InputIt2, class T>
constexpr // desde C++20
T inner_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T init)
{
    while (first1 != last1) {
         init = std::move(init) + *first1 * *first2; // std::move desde C++20
         ++first1;
         ++first2;
    }
    return init;
}
Segunda versión
template<class InputIt1, class InputIt2,
         class T,
         class BinaryOperation1, class BinaryOperation2>
constexpr // desde C++20
T inner_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T init,
                BinaryOperation1 op1
                BinaryOperation2 op2)
{
    while (first1 != last1) {
         init = op1(std::move(init), op2(*first1, *first2)); // std::move desde C++20
         ++first1;
         ++first2;
    }
    return init;
}

[editar] Notas

La versión paralelizable de este algoritmo, std::transform_reduce, requiere que op1 y op2 sean conmutativos y asociativos, pero {{tt|std::inner_product} } no tiene tal requisito y siempre realiza las operaciones en el orden dado.

[editar] Ejemplo

#include <numeric>
#include <iostream>
#include <vector>
#include <functional>
int main()
{
    std::vector<int> a{0, 1, 2, 3, 4};
    std::vector<int> b{5, 4, 2, 3, 1};
 
    int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
    std::cout << "Producto interno de a y b: " << r1 << '\n';
 
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Número de coincidencias por pares entre a y b: " <<  r2 << '\n';
}

Salida:

Producto interno de a y b: 21
Número de coincidencias por pares entre a y b: 2

[editar] Véase también

Aplica un invocable, luego reduce fuera de orden
(plantilla de función) [editar]
Suma un rango de elementos
(plantilla de función) [editar]
Calcula la suma parcial de un rango de elementos
(plantilla de función) [editar]