2
$\begingroup$

The sparse function in MATLAB does the following:

S = sparse(i,j,v) generates a sparse matrix S from the triplets i, j, and v such that S(i(k),j(k)) = v(k). The max(i)-by-max(j) output matrix has space allotted for length(v) nonzero elements. sparse adds together elements in v that have duplicate subscripts in i and j. If the inputs i, j, and v are vectors or matrices, they must have the same number of elements. Alternatively, the argument v and/or one of the arguments i or j can be scalars.

I would like to have a fairly equivalent function in Mathematica. Has anyone tried to do this beforehand?

$\endgroup$
9
  • 1
    $\begingroup$ Isn't SparseArray close enough? $\endgroup$
    – Kuba
    May 26, 2016 at 9:53
  • $\begingroup$ I'm not sure. What questions me is the different output of the Matlab function. $\endgroup$ May 26, 2016 at 10:35
  • $\begingroup$ The output in matlab. It's something different, perhaps because it is compressed. $\endgroup$ May 26, 2016 at 10:55
  • $\begingroup$ I think the difference lays in the compression of the memory. $\endgroup$ May 26, 2016 at 11:01
  • 1
    $\begingroup$ Then ask that question :) It is possible that there is someone around who knows both but this is MMA related site so you will gather more attention bringing info about Matlab side yourself. Moreover a motiviation would be good, e.g. specific example which Matlab handles way better than MMA and you want to know why. $\endgroup$
    – Kuba
    May 26, 2016 at 11:12

2 Answers 2

5
$\begingroup$

Mathematica has sparse arrays not just sparse matrices:

Here are links to some tutorials:

The ability to use high-dimensional sparse array sometimes is very useful. (E.g. see "Markov chains n-gram model implementation".)

Most competitors of Mathematica support only sparse matrices.

Yifan Hu and Robert Knapp were the original designers of the functionality. I mention Yifan because before moving to Wolfram Research he worked with some of the originators and creators of the sparse matrices field (like John Reid).

$\endgroup$
3
  • 1
    $\begingroup$ Slightly off-topic: if memory serves, wasn't the graph-plotting stuff an outgrowth of their work on sparse matrices? $\endgroup$ May 26, 2016 at 12:29
  • $\begingroup$ @J.M. Yes, I would say so. Yifan designed and implemented GraphPlot and he was using it to demonstrate the origins of some of the matrices from Matrix Market. $\endgroup$ May 26, 2016 at 12:41
  • 2
    $\begingroup$ The original GraphPlot design, and the graph visualization stuff that was implemented at that time, is still excellent. Things added afterwards ... so-so ... $\endgroup$
    – Szabolcs
    May 11, 2020 at 16:13
4
$\begingroup$

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.

$\endgroup$
2
  • 1
    $\begingroup$ For code that relies on "NonzeroPositions" and the like, note in the last example, the {2, 2} entry is listed among the "NonzeroPositions". Use SparseArray[ SparseArray[{{1, 1} -> 5, {2, 2} -> 1, {2, 2} -> -1, {3, 3} -> 4}]] to reset. $\endgroup$
    – Michael E2
    May 11, 2020 at 17:19
  • $\begingroup$ The issue noted by Michael has also been discussed in other threads, like this one. $\endgroup$ May 11, 2020 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.