inner_product [C++ Reference]
Keywords: stl,algorithm,inner_product
Date: 2009-10-09T00:38:18-0700

## inner_product

Syntax:

        #include <numeric>
        TYPE inner_product( input_iterator start1, input_iterator end1, input_iterator2 start2, TYPE val );
        TYPE inner_product( input_iterator start1, input_iterator end1, input_iterator2 start2, TYPE val, BinaryFunction f1, BinaryFunction2 f2 );

The inner_product function computes the inner product of `[start1,end1)` and a range of the same size starting at `start2`.

inner_product() runs in linear time.

For example, the following code shows how inner_product (or, alternatively, accumulate) can be used to compute the sums of squares of some data:

    // Examples of std::accumulate and std::inner_product from wordaligned.org
    #include <functional>
    #include <iostream>
    #include <numeric>
    #include <string>
    #include <valarray>
    #include <vector>

    typedef std::valarray<double> xyz;

    // Xyz output operator
    std::ostream & operator<<(std::ostream & os, xyz const & pt) {
        os << '(';
        char const * sep = "";
        for( size_t i = 0; i != pt.size(); sep = ", ", ++i ) {
            os << sep << pt[i];
        }
        os << ')';
        return os;
    }

    // Bitwise or function, for use in reductions
    unsigned bit_or(unsigned u, unsigned v) {
        return u | v;
    }

    // Create and return a triangle
    std::vector<xyz> create_triangle() {
        std::vector<xyz> pts;
        double const p[9] = {1.,1.,0.,1.,0.,1.,0.,1.,1.};
        pts.push_back(xyz(p + 0, 3));
        pts.push_back(xyz(p + 3, 3));
        pts.push_back(xyz(p + 6, 3));
        return pts;
    }

    // Set up some test arrays, accumulate them and print the results to stdout.
    int main() {
        int const a[3] = { 1, 2, 3 };
        int const b[3] = { 3, 2, 1 };
        std::string const s[3] = { "http://", "wordaligned", ".org" };
        bool const t[3] = { false, true, false };
        std::vector<xyz> tri = create_triangle();
        unsigned m[3] = { 1<<1, 1<<3, 1<<5 };

        std::cout
            << "sum(a) "
            << std::accumulate(a, a + 3, 0)
            << "\nprod(a) "
            << std::accumulate(a, a + 3, 1, std::multiplies<int>())
            << "\nsum_sqs(a) "
            << std::inner_product(a, a + 3, a, 0)
            << "\ndot(a, b) "
            << std::inner_product(a, a + 3, b, 0)
            << "\nconcat(s) "
            << std::accumulate(s, s + 3, std::string(""))
            << "\nany(t) " << std::boolalpha
            << std::accumulate(t, t + 3, false, std::logical_or<bool>())
            << "\ncentroid(tri) "
            << std::accumulate(tri.begin(), tri.end(), xyz(0., 3)) / 3.
            << "\nbitor(m) " << std::hex << "0x"
            << std::accumulate(m, m + 3, 0, bit_or)
            << '\n';

        return 0;
    }

When run, this code generates the following output:

    sum(a) 6
    prod(a) 6
    sum_sqs(a) 14
    dot(a, b) 10
    concat(s) http://wordaligned.org
    any(t) true
    centroid(tri) (0.666667, 0.666667, 0.666667)
    bitor(m) 0x2a

Related Topics: accumulate, adjacent_difference, count, partial_sum