Skip to the content of the web site.

Partial sums

Given an array, suppose we want to replace the $k^\textrm{th}$ entry of the array with $\sum_{i = 0}^k a_i$, or perhaps $\sum_{i = 0}^{k - 1} a_i$; for example, given

    int array[10]{
        34, 67, 52, 28, 49, 73, 28, 61, 7, 61
    };

The first requirement would give

      34, 101, 153, 181, 230, 303, 331, 392, 399, 460

while the second would give

      0, 34, 101, 153, 181, 230, 303, 331, 392, 399

If you were to consider using a loop within a loop, this would work, but it would be expensive, especially for very large arrays.

Instead, consdier the following straight-forward implementation:

void partial_sum( double array[], std::size_t capacity ) {
    for ( std::size_t k{ 1 }; k < capacity; ++k ) {
        array[k] += array[k - 1];
    }
}

This requires only a single loop, so its run time will be very fast.

The second problem is a little more difficult to tackle, but here is one possible solution:

double partial_sum( double array[], std::size_t capacity ) {
    double sum{ 0.0 };

    for ( std::size_t k{ 0 }; k < capacity; ++k ) {
        double tmp{ array[k] };
        array[k] = sum;
        sum += tmp;
    }
    
    return sum;
}

This requires two assignments and one addition, so slightly more expensive than the first algorithm, but it is still efficient.

Warning, do not try to reduce the code by using two arithmetic operations, because floating-point arithmetic is not associative, so this may not actually give the best answer, even if it "appears" shorter:

double partial_sum( double array[], std::size_t capacity ) {
    double sum{ 0.0 };

    for ( std::size_t k{ 0 }; k < capacity; ++k ) {
        sum += array[k];
        array[k] = sum - array[k];
    }
    
    return sum;
}

Using the standard library

Now that we have seen how we can create a partial sum using the standard library.

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

template <typename T>
std::ostream &operator<<( std::ostream &out, std::vector<T> );

int main() {
	std::vector<int> vec{ 1,5,3,2,3,4,5,6,3,1,5,2,1,3 };
	std::cout << vec << std::endl;
	std::partial_sum( vec.begin(), vec.end(), vec.begin() );
	std::cout << vec << std::endl;
	return 0;
}

template <typename T>
std::ostream &operator<<( std::ostream &out, std::vector<T> vec ) {
    out << "{";

    if ( !vec.empty() ) {
	std::copy( vec.begin(), vec.end() - 1,
            std::ostream_iterator<T>( std::cout, ", " )
        );

	out << *vec.rbegin();
    }

    return out << "}";
}