The Wayback Machine - https://web.archive.org/web/20230127153434/https://en.cppreference.com/w/cpp/algorithm/partial_sum
Namespaces
Variants
Views
Actions

std::partial_sum

From cppreference.com
< cpp‎ | algorithm
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Execution policies (C++17)
Non-modifying sequence operations
(C++11)(C++11)(C++11)
(C++17)
Modifying sequence operations
Partitioning operations
Sorting operations
(C++11)
Binary search operations
Set operations (on sorted ranges)
Heap operations
(C++11)
Minimum/maximum operations
(C++11)
(C++17)

Permutations
Numeric operations
partial_sum
Operations on uninitialized storage
(C++17)
(C++17)
(C++17)
C library
 
Defined in header <numeric>
(1)
template< class InputIt, class OutputIt >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first );
(until C++20)
template< class InputIt, class OutputIt >
constexpr OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first );
(since C++20)
(2)
template< class InputIt, class OutputIt, class BinaryOperation >

OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first,

                      BinaryOperation op );
(until C++20)
template< class InputIt, class OutputIt, class BinaryOperation >

constexpr OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first,

                                BinaryOperation op );
(since C++20)

Computes the partial sums of the elements in the subranges of the range [first, last) and writes them to the range beginning at d_first. The first version uses operator+ to sum up the elements, the second version uses the given binary function op, both applying std::move to their operands on the left hand side (since C++20).

Equivalent operation:

*(d_first)   = *first;
*(d_first+1) = *first + *(first+1);
*(d_first+2) = *first + *(first+1) + *(first+2);
*(d_first+3) = *first + *(first+1) + *(first+2) + *(first+3);
...

op must not invalidate any iterators, including the end iterators, or modify any elements of the range involved.

Contents

[edit] Parameters

first, last - the range of elements to sum
d_first - the beginning of the destination range; may be equal to first
op - binary operation function object that will be applied.

The signature of the function should be equivalent to the following:

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

The signature does not need to have const &.
The type Type1 must be such that an object of type iterator_traits<InputIt>::value_type can be implicitly converted to Type1 . The type Type2 must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type2 . The type Ret must be such that an object of type iterator_traits<InputIt>::value_type can be assigned a value of type Ret. ​

Type requirements
-
InputIt must meet the requirements of LegacyInputIterator.
-
OutputIt must meet the requirements of LegacyOutputIterator.

[edit] Return value

Iterator to the element past the last element written.

[edit] Complexity

Exactly (last - first) - 1 applications of the binary operation

[edit] Possible implementation

partial_sum (1)
template<class InputIt, class OutputIt>
constexpr // since C++20
OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first)
{
    if (first == last)
        return d_first;
 
    typename std::iterator_traits<InputIt>::value_type sum = *first;
    *d_first = sum;
 
    while (++first != last)
    {
        sum = std::move(sum) + *first; // std::move since C++20
        *++d_first = sum;
    }
 
    return ++d_first;
 
    // or, since C++14:
    // return std::partial_sum(first, last, d_first, std::plus<>());
}
partial_sum (2)
template<class InputIt, class OutputIt, class BinaryOperation>
constexpr // since C++20
OutputIt partial_sum(InputIt first, InputIt last, 
                     OutputIt d_first, BinaryOperation op)
{
    if (first == last)
        return d_first;
 
    typename std::iterator_traits<InputIt>::value_type sum = *first;
    *d_first = sum;
 
    while (++first != last)
    {
        sum = op(std::move(sum), *first); // std::move since C++20
        *++d_first = sum;
    }
 
    return ++d_first;
}

[edit] Example

#include <numeric>
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
 
int main()
{
    std::vector<int> v = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // or std::vector<int>v(10, 2);
 
    std::cout << "The first 10 even numbers are: ";
    std::partial_sum(v.begin(), v.end(), 
                     std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
 
    std::partial_sum(v.begin(), v.end(), v.begin(), std::multiplies<int>());
 
    std::cout << "The first 10 powers of 2 are: ";
    for (auto n : v)
        std::cout << n << " ";
    std::cout << '\n';
}

Output:

The first 10 even numbers are: 2 4 6 8 10 12 14 16 18 20 
The first 10 powers of 2 are: 2 4 8 16 32 64 128 256 512 1024

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 242 C++98 op cannot have side effects it cannot modify the ranges involved

[edit] See also

computes the differences between adjacent elements in a range
(function template) [edit]
sums up or folds a range of elements
(function template) [edit]
similar to std::partial_sum, includes the ith input element in the ith sum
(function template) [edit]
similar to std::partial_sum, excludes the ith input element from the ith sum
(function template) [edit]