While comparing the results of MATLAB and Mathematica for a little experiment the other day, I got bitten by an error, which in hindsight was because I did not pay attention to this part of the help file for MATLAB's sparse()
:
sparse
adds together elements in v
that have duplicate subscripts in i
and j
.
As a demonstration, here's a small MATLAB example:
il = [1 2 2 3];
jl = [1 2 2 3];
vv = [5 1 -1 4];
full(sparse(il, jl, vv))
ans =
5 0 0
0 0 0
0 0 4
The ostensible Mathematica equivalent is
Normal[SparseArray[{{1, 1} -> 5, {2, 2} -> 1, {2, 2} -> -1, {3, 3} -> 4}]]
{{5, 0, 0},
{0, 1, 0},
{0, 0, 4}}
Did you notice the difference? As previously noted, MATLAB adds up entries with the same indices, and you thus get 0
as the middle of the diagonal matrix. Mathematica, OTOH, retains the first one.
In fact, this behavior is controlled by the internal setting "TreatRepeatedEntries"
:
SystemOptions["SparseArrayOptions" -> "TreatRepeatedEntries"]
{"SparseArrayOptions" -> {"TreatRepeatedEntries" -> First}}
(See e.g. this thread and this thread, among others.)
To get behavior similar to MATLAB, we need to modify this setting. If you are wary of modifying internal settings like these, the device of this answer can be used to localize this effect:
With[{spopt = SystemOptions["SparseArrayOptions"]},
Internal`WithLocalSettings[
SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}],
Normal[SparseArray[{{1, 1} -> 5, {2, 2} -> 1, {2, 2} -> -1, {3, 3} -> 4}]],
SetSystemOptions[spopt]]]
{{5, 0, 0},
{0, 0, 0},
{0, 0, 4}}
and we now get the same result as MATLAB.