Random`Private`PositionsOf[Unitize[Differences[a["RowPointers"]]], 1]
A timing example:
n = 100000;
m = 6000000;
a = AdjacencyMatrix@RandomGraph[{n, m}];
a[[RandomInteger[{1, n}, 1000], All]] = 0;
r = DeleteDuplicates@Flatten@Transpose[a]["ColumnIndices"]; // AbsoluteTiming // First
r1 = RandomPrivatePositionsOf[Unitize[Differences[a["RowPointers"]]], 1]; // AbsoluteTiming // First
Sort[r] == r1
0.579587
0.002103
True
Edit
The undocumented function Random`Private`PositionsOf may be replaced by the following compiled function.
PositionsOfInteger = Compile[{{a, _Integer, 1}, {x, _Integer}},
Block[{b, i = 0},
b = Table[0, {Length[a]}];
Do[If[Compile`GetElement[a, j] == x, b[[++i]] = j], {j, 1,
Length[a]}];
If[i > 0, b[[1 ;; i]], Most[{0}]]
],
CompilationTarget -> "C",
RuntimeOptions -> "Speed"
];
Indeed, this turns out to be even a bit faster:
r2 = PositionsOfInteger[Unitize[Differences[a["RowPointers"]]], 1]; //
AbsoluteTiming // First
r1 == r2
0.001647
True
"ColumnIndices"do? In this post, it says "gives the row pointers array from the compressed sparse row data", but I don't understand how it works. – Leo Jan 02 '19 at 17:42RandomPrivatePositionsOf? I can't find these commands in the documentation. – Leo Jan 02 '19 at 18:03True):Flatten[a["ColumnIndices"]] == a["NonzeroPositions"][[All, 2]]andPrepend[Accumulate[Total[Unitize[a], {2}]], 0] == a["RowPointers"]. – Henrik Schumacher Jan 02 '19 at 18:03Random`Private`PositionsOf; it is an undocumented funtion.Random`Private`PositionsOf[#, 0] &does essentially the same asFlatten[Position[#, 0]] &- but it is ten times faster. – Henrik Schumacher Jan 02 '19 at 18:05"System`"context, this risk is rather small. While there are several prominent examples of undocumented symbols that appear to have been ''stable'' for several major realeases, the risk of future changes of these symbols is certainly much higher. This is why I added a compiled functionPositionsOfIntegeras substitute forRandom`Private`PositionsOf. – Henrik Schumacher Jan 27 '19 at 11:50