Additive SparseArray Assembly

There is actually an undocumented System Option that tells Mathematica to do this automatically. The default behavior:

ind = {{3, 1}, {3, 3}, {1, 3}, {2, 1}, {3, 2}, {3, 1}, {3, 2}, {3, 3}, {1, 3}, {3, 1}};
val = {1, 1, 3, 0, 3, 4, 3, 1, 1, 1};

SparseArray[ind -> val] // Grid

$ \begin{matrix} 0 & 0 & 3 \\ 0 & 0 & 0 \\ 1 & 3 & 1 \end{matrix} $

Now with our "magic" Option (learned from Oliver Ruebenkoenig):

SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> 1}];
(* equivalently:
   SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}] *)
SparseArray[ind -> val] // Grid

$ \begin{matrix} 0 & 0 & 4 \\ 0 & 0 & 0 \\ 6 & 6 & 2 \end{matrix} $

Arbitrary functions are accepted by version 9 and later; see: Optimising 2D binning code

SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> (# - +##2 &)}];

SparseArray[ind -> val] // Grid

$\begin{matrix} 0 & 0 & 2 \\ 0 & 0 & 0 \\ -4 & 0 & 0 \\ \end{matrix}$

To restore the default behavior set:

SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> 0}];
(* equivalently:
   SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> First}] *)

To encapsulate this setting, use Internal`WithLocalSettings: SetOptions locally?


n=4;    
ind = RandomInteger[{1, n}, {10, 2}]
val = RandomReal[{-1, 1}, Length[ind]]

#[[1, 1]] -> Total[#[[;; , 2]]] & /@ GatherBy[Thread[{ind, val}], First]

a = SparseArray[%, {n, n}]

or quite ugly but compact:

b = SparseArray[#, {n, n}] & /@ Thread[ind -> val] // Total

a == b
True