Prefix sum

Share on Facebook Share on Twitter Email
Top

In computer science, the prefix sum, of a sequence of numbers x0, x1, x2, ... is a second sequence of numbers y0, y1, y2, ..., the sums of prefixes (running totals) of the input sequence:

y0 = x0
y1 = x0 + x1
y2 = x0 + x1+ x2
...

Prefix sums are trivial to compute in sequential models of computation, by using the formula yi = yi − 1 + xi to compute each number in the prefix sum in sequence. However, despite their ease of computation, prefix sums are a useful primitive in certain algorithms such as counting sort,[1] and they form the basis of the scan higher-order function in functional programming languages. Prefix sums have also been much studied in parallel algorithms, both as a test problem to be solved and as a useful primitive to be used as a subroutine in other parallel algorithms.[2][3]

Mathematically, the operation of taking prefix sums can be generalized from finite to infinite sequences; in that context, a prefix sum is known as a partial sum of a series. Prefix summation or partial summation form linear operators on the vector spaces of finite or infinite sequences; their inverses are finite difference operators.

Contents

Functional programming

In functional programming terms, the prefix sum may be generalized to any binary operation (not just the addition operation); the higher order function resulting from this generalization is called a scan, and it is closely related to the fold operation. For instance, in Haskell, there are two variants of scan, called scanl and scanl1, differing slightly in their argument signature, and the prefix sum operation may be written scanl1 (+). The corresponding suffix operations are also available as scanr and scanr1.[4] Both the scan and the fold operations apply the given binary operation to the same sequence of values, but differ in that the scan returns the whole sequence of results from the binary operation, whereas the fold returns only the final result.

Parallel algorithm

Circuit representation of a 16-input parallel prefix sum

A prefix sum can be calculated in parallel by the following steps.[2][5][6]

  1. Compute the sums of consecutive pairs of items in which the first item of the pair has an even index: z0 = x0 + x1, z1 = x2 + x3, etc.
  2. Recursively compute the prefix sum w0, w1, w2, ... of the sequence z0, z1, z2, ...
  3. Expand each term of the sequence w0, w1, w2, ... into two terms of the overall prefix sum: y0 = x0, y1 = w0, y2 = w0 + x2, y3 = w1, etc. After the first value, each successive number yi is either copied from a position half as far through the w sequence, or is the previous value added to one value in the x sequence.

If the input sequence has n steps, then the recursion continues to a depth of O(log n), which is also the bound on the parallel running time of this algorithm. The number of steps of the algorithm is O(n), and it can be implemented on a parallel random access machine with O(n/log n) processors without any asymptotic slowdown by assigning multiple indices to each processor in rounds of the algorithm for which there are more elements than processors.[2]

Parallel algorithms for prefix sums can often be generalized to other scan operations on associative binary operations,[2][3] and they can also be computed efficiently on modern parallel hardware such as a GPU.[7]

Applications

Counting sort is an integer sorting algorithm that uses the prefix sum of a histogram of key frequencies to calculate the position of each key in the sorted output array. It runs in linear time for integer keys that are smaller than the number of items, and is frequently used as part of radix sort, a fast algorithm for sorting integers that are less restricted in magnitude.[1]

List ranking, the problem of transforming a linked list into an array that represents the same sequence of items, can be viewed as computing a prefix sum on the sequence 1, 1, 1, ... and then mapping each item to the array position given by its prefix sum value; by combining list ranking, prefix sums, and Euler tours, many important problems on trees may be solved by efficient parallel algorithms.[3]

An early application of parallel prefix sum algorithms was in the design of binary adders, Boolean circuits that can add two n-bit binary numbers. In this application, the sequence of carry bits of the addition can be represented as a scan operation on the sequence of pairs of input bits, using the majority function to combine the previous carry with these two bits. Each bit of the output number can then be found as the exclusive or of two input bits with the corresponding carry bit. By using a circuit that performs the operations of the parallel prefix sum algorithm, it is possible to design an adder that uses O(n) logic gates and O(log n) time steps.[2][5][6]

In the parallel random access machine model of computing, prefix sums can be used to simulate parallel algorithms that assume the ability for multiple processors to access the same memory cell at the same time, on parallel machines that forbid simultaneous access. By means of a sorting network, a set of parallel memory access requests can be ordered into a sequence such that accesses to the same cell are contiguous within the sequence; scan operations can then be used to determine which of the accesses succeed in writing to their requested cells, and to distribute the results of memory read operations to multiple processors that request the same result.[8]

In the construction of Gray codes, sequences of binary values with the property that consecutive sequence values differ from each other in a single bit position, a number n can be converted into the Gray code value at position n of the sequence simply by taking the exclusive or of n and n/2 (the number formed by shifting n right by a single bit position). The reverse operation, decoding a Gray-coded value x into a binary number, is more complicated, but can be expressed as the prefix sum of the bits of x, where each summation operation within the prefix sum is performed modulo two. A prefix sum of this type may be performed efficiently using the bitwise Boolean operations available on modern computers, by computing the exclusive or of x with each of the numbers formed by shifting x to the left by a number of bits that is a power of two.[9]

References

  1. ^ a b Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2001), "8.2 Counting Sort", Introduction to Algorithms (2nd ed.), MIT Press and McGraw-Hill, pp. 168–170, ISBN 0-262-03293-7 .
  2. ^ a b c d e Ladner, R. E.; Fischer, M. J. (1980), "Parallel Prefix Computation", Journal of the ACM 27 (4): 831–838, doi:10.1145/322217.322232, MR 0594702 .
  3. ^ a b c Tarjan, Robert E.; Vishkin, Uzi (1985), "An efficient parallel biconnectivity algorithm", SIAM Journal on Computing 14 (4): 862–874, doi:10.1137/0214061 .
  4. ^ Jones, Simon Peyton, ed. (2002), "Standard Prelude", Haskell 98 Language and Libraries: The Revised Report, http://www.haskell.org/onlinereport/standard-prelude.html .
  5. ^ a b Ofman, Yu. (1962), "Об алгоритмической сложности дискретных функций" (in Russian), Doklady Akademii Nauk SSSR 145 (1): 48–51, MR 0168423 . English translation, "On the algorithmic complexity of discrete functions", Soviet Physics Doklady 7: 589–591 1963.
  6. ^ a b Khrapchenko, V. M. (1967), "Asymptotic Estimation of Addition Time of a Parallel Adder" (in Russian), Problemy Kibernet. 19: 107–122 . English translation in Syst. Theory Res. 19; 105–122, 1970.
  7. ^ Sengupta, Shubhabrata; Harris, Mark; Zhang, Yao; Owens, John D. (2007), "Scan primitives for GPU computing", Proceedings of the 22nd ACM SIGGRAPH/EUROGRAPHICS Symposium on Graphics Hardware, pp. 97–106, http://graphics.idav.ucdavis.edu/publications/print_pub?pub_id=915 .
  8. ^ Vishkin, Uzi (1983), "Implementation of simultaneous memory address access in models that forbid it", Journal of Algorithms 4 (1): 45–50, doi:10.1016/0196-6774(83)90033-0, MR 689265 .
  9. ^ Warren, Henry S. (2003), Hacker's Delight, Addison-Wesley, p. 236, ISBN 978-0-201-91465-8, http://books.google.com/books?id=iBNKMspIlqEC&pg=PA236 .

Post a question - any question - to the WikiAnswers community:

Copyrights: