I'm trying to use a SparseArray
for some large homological algebra calculations. I'd like to find indices of a SparseArray
whose entries are equal to 1. If I were operating naively on the ArrayRules
version of the array, I'd just need do something like Cases[sparserules, HoldPattern[_List -> 1]]
and that would give me what I want. (FWIW: here's why you need the HoldPattern.)
If it helps, I am also happy with just being able to pull off one such element at a time - Cases[sparserules, HoldPattern[_List -> 1], All, 1]
does what I want on ArrayRules
output. The order is not important - if this returns a random entry that's equal to 1, that's also fine by me.
Unfortunately, this doesn't seem to work on SparseArray
objects, and I don't want to be packing and unpacking SparseArray
s all the time. Is there an efficient way to get all (or just one) indices of a SparseArray
whose entries are equal to a given element?
Some possible starting points: SparseArrays are atomic; using Pick on SparseArrays. Both of these are a bit beyond my level of sophistication, however.
(SparseArray[Unitize[#1 - #2], Automatic, 1]["NonzeroPositions"]) &
should fit your needs - call with array and value to index. $\endgroup$ – ciao May 3 '16 at 5:52"NonzeroPositions"
- that could be useful. Unfortunately the array is not numeric - mostly polynomials, so Unitize won't work. I like the trick, though. $\endgroup$ – dvitek May 3 '16 at 7:10Map[Boole[#===1]&, sparsearray, {2}]["NonzeroPositions"]
, which fixed the non-numeric problem. If you put your comment as an answer I'd be happy to accept it. $\endgroup$ – dvitek May 3 '16 at 16:46Map
inSparseArray
? Otherwise, it's possibly not doing what you think... and even if it is, if you're going to map over the array, might as well justMapIndexed
over it, and return the index for elements that match your tests. In any case, feel free to use the ideas in a self-answer... $\endgroup$ – ciao May 3 '16 at 23:32Map
inSparseArray
- it will automatically thread overSparseArray
objects, whereasMapIndexed
will convert them to lists. If you want a concrete demonstration, run the following:a = SparseArray[(# -> RandomInteger[{1, 200}]) & /@ RandomInteger[{1, 2000}, {4000, 2}]]; a1 = Map[#^2&, a, {2}]; a2 = MapIndexed[#1^2&, a, {2}];
If you do this,a1
will have headSparseArray
, and the command will execute quickly. Buta2
will take a while and have headList
. See reference.wolfram.com/language/tutorial/…. $\endgroup$ – dvitek May 4 '16 at 0:11