numeric


Header: <numeric>

The <numeric> header is part of the C++ Standard Library that provides a set of numeric algorithms. These algorithms are designed to perform various numeric operations on ranges of elements, such as computing sums, products, inner products, and partial sums. The functions in this header are particularly useful for mathematical computations and data analysis tasks.

Key Characteristics

Example 1: Basic Usage of std::accumulate

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

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // Sum of all elements
    int sum = std::accumulate(numbers.begin(), numbers.end(), 0);
    std::cout << "Sum: " << sum << std::endl;

    // Product of all elements
    int product = std::accumulate(numbers.begin(), numbers.end(), 1, std::multiplies<int>());
    std::cout << "Product: " << product << std::endl;

    return 0;
}

Explanation:

Example 2: Using std::inner_product

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

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {10, 20, 30, 40, 50};

    // Compute inner product
    int inner_prod = std::inner_product(v1.begin(), v1.end(), v2.begin(), 0);
    std::cout << "Inner product: " << inner_prod << std::endl;

    // Custom inner product: sum of products of corresponding elements minus 1
    int custom_prod = std::inner_product(v1.begin(), v1.end(), v2.begin(), 0,
                                         std::plus<>(),
                                         [](int a, int b) { return a * b - 1; });
    std::cout << "Custom inner product: " << custom_prod << std::endl;

    return 0;
}

Explanation:

Example 3: Partial Sums and Adjacent Differences

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

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // Compute partial sums
    std::vector<int> partial_sums;
    std::partial_sum(numbers.begin(), numbers.end(), std::back_inserter(partial_sums));

    std::cout << "Partial sums: ";
    for (int num : partial_sums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Compute adjacent differences
    std::vector<int> adjacent_diffs;
    std::adjacent_difference(numbers.begin(), numbers.end(), std::back_inserter(adjacent_diffs));

    std::cout << "Adjacent differences: ";
    for (int num : adjacent_diffs) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

4. Using GCD and LCM (C++17)

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

int main() {
    int a = 48, b = 18;

    // Compute GCD
    int gcd_result = std::gcd(a, b);
    std::cout << "GCD of " << a << " and " << b << ": " << gcd_result << std::endl;

    // Compute LCM
    int lcm_result = std::lcm(a, b);
    std::cout << "LCM of " << a << " and " << b << ": " << lcm_result << std::endl;

    // GCD of multiple numbers
    std::vector<int> numbers = {24, 36, 48, 60};
    int multi_gcd = std::accumulate(numbers.begin(), numbers.end(), numbers[0], 
                                    [](int a, int b) { return std::gcd(a, b); });
    std::cout << "GCD of multiple numbers: " << multi_gcd << std::endl;

    return 0;
}

Explanation:

Example 4: Iota and Midpoint (C++20)

#include <iostream>
#include <vector>
#include <numeric>
#include <cstdint>

int main() {
    std::vector<int> numbers(5);

    // Fill vector with sequential values
    std::iota(numbers.begin(), numbers.end(), 10);

    std::cout << "Iota result: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Compute midpoint
    int a = 10, b = 20;
    int mid = std::midpoint(a, b);
    std::cout << "Midpoint of " << a << " and " << b << ": " << mid << std::endl;

    // Midpoint for pointers
    int arr[] = {1, 2, 3, 4, 5};
    int* start = &arr[0];
    int* end = &arr[4];
    int* mid_ptr = std::midpoint(start, end);
    std::cout << "Midpoint element: " << *mid_ptr << std::endl;

    return 0;
}

Explanation:

Additional Considerations

  1. Type Requirements: Most algorithms in <numeric> require the elements to support basic arithmetic operations.

  2. Iterator Requirements: The algorithms typically require at least input iterators, with some needing forward iterators.

  3. Overflow Considerations: Be aware of potential overflow issues, especially with accumulate and partial_sum.

  4. Parallel Execution: Many algorithms support parallel execution policies in C++17 and later, potentially improving performance on multi-core systems.

  5. Custom Operations: Most algorithms allow custom binary operations, enabling flexible and powerful computations.

Summary

The <numeric> header in C++ provides a set of powerful algorithms for numeric computations:

These algorithms offer efficient and flexible ways to perform common numeric operations on ranges of data. They are particularly useful in scientific computing, data analysis, and any scenario involving mathematical operations on collections of numbers.

The <numeric> header complements other parts of the C++ Standard Library, working seamlessly with containers and iterators. Its algorithms are designed to be both efficient and generic, allowing them to work with a wide variety of data types and containers.

By leveraging the algorithms in <numeric>, C++ programmers can write more concise, efficient, and readable code for numeric computations, often avoiding the need for manual loop implementations of common mathematical operations.

Related

Previous Page | Course Schedule | Course Content