Skip to content

Prefix sums

Store the total before each boundary to answer cash-flow window queries with two lookups and one subtraction.

A prefix sum is the total of the first several entries in an ordered sequence. Store one total at each boundary of an array, and a backtest or ledger report can sum any contiguous window with two lookups and one subtraction.

Put the totals at the boundaries

For nn cash flows indexed from 00 through n−1n-1, let P[j]P[j] be the total strictly before boundary jj. Start with P[0]=0P[0]=0, then build the other entries using P[j+1]=P[j]+xjP[j+1]=P[j]+x_j. There are n+1n+1 totals, including P[n]P[n] for the whole array. This is an exclusive prefix convention with the full total appended. Blelloch describes inclusive and exclusive scans.

The half-open window [l,r)[l,r) starts at entry ll and stops before entry rr. The prefix at rr contains the window and everything before it. Subtract the prefix at ll to remove everything before the window.

∑i=lr−1xi=P[r]−P[l],0≤l≤r≤n.\sum_{i=l}^{r-1} x_i = P[r]-P[l], \qquad 0\le l\le r\le n.

A window starting at zero uses the same formula because P[0]=0P[0]=0. When l=rl=r, both lookups read the same total and the empty window sums to zero.

Net cash in a window

Take a fictional single-currency ledger with flows (3,−2,5,−4)(3,-2,5,-4) in USD, with inflows positive. The boundary totals are (0,3,1,6,2)(0,3,1,6,2). The query [1,3)[1,3) includes entries 1 and 2, so the net flow is P[3]−P[1]=6−3=3P[3]-P[1]=6-3=3 USD. Adding the entries directly gives −2+5=3-2+5=3 USD.

Fictional cash flows of plus 3, minus 2, plus 5 and minus 4 USD. The prefix totals at boundaries 0 through 4 are 0, 3, 1, 6 and 2 USD. Subtracting the prefix at boundary 1 from the prefix at boundary 3 leaves the two middle flows, worth 3 USD in total.
Fictional cash flows of plus 3, minus 2, plus 5 and minus 4 USD. The prefix totals at boundaries 0 through 4 are 0, 3, 1, 6 and 2 USD. Subtracting the prefix at boundary 1 from the prefix at boundary 3 leaves the two middle flows, worth 3 USD in total.
The two prefixes share the first cash flow. Subtracting the shorter prefix cancels that overlap.
These are undiscounted cash amounts in a common currency. Across successive periods, simple investment returns compound by multiplying gross returns. See time-weighted return for how performance calculations link subperiod returns across external cash flows.
The same running total can count displayed shares across the price levels of a frozen order book. The SelfMadeQuant Order Books lesson uses cumulative depth to work out the cost of a hypothetical fill. The preview is public and the full lesson requires membership.

What changes when the data change?

For a fixed array, building the prefix totals takes O(n)O(n) time and O(n)O(n) extra space, and each window sum takes O(1)O(1) time. A correction to entry kk changes every stored prefix at boundaries j>kj>k, so a correction near the start can take O(n)O(n) work. A Fenwick tree handles single-entry additions and range sums in O(log⁡n)O(\log n) time per operation. Laaksonen covers both cases in Chapter 9.
Adding an amount to every entry in a window is a different update. If all such updates arrive before any queries, a difference array can record each addition at its start and cancel it at its exclusive end, then a single prefix pass recovers the per-entry changes. When window additions and window-sum queries arrive interleaved, a segment tree with lazy propagation can handle both in O(log⁡n)O(\log n) per operation. Laaksonen explains lazy propagation in Chapter 28.

Sources

Last updated
  • algorithms
  • range queries
  • cash flows
← Back to the glossaryBack to top ↑