Take upper triangular part of matrix
Is using an internal, undocumented symbol acceptable?
r1 = Statistics`Library`UpperTriangularMatrixToVector[mat]; //RepeatedTiming
r2 = Statistics`Library`UpperTriangularMatrixToVector[mat2]; //RepeatedTiming
r3 = takeUpper3[mat]; //RepeatedTiming
r4 = takeUpper3[mat2]; //RepeatedTiming
r1 === r2 === r3 === r4
{0.00039, Null}
{0.0027, Null}
{0.017, Null}
{0.018, Null}
True
I tried the following; for packed arrays, it appears to be on par with takeUpper3
, but it needs twice the time for unpacked arrays. So I think, your trick using Pick
is already pretty good.
LinearToTriangularIndexing[k_?VectorQ, n_Integer] := Module[{i, j},
i = n - 1 - Floor[Sqrt[4. n (n - 1) - 8. k + 1.]/2.0 - 0.5];
j = Subtract[
k + i + Quotient[Subtract[n + 1, i] Subtract[n, i], 2],
Quotient[n (n - 1), 2]];
Transpose[{i, j}]
];
takeUpper5[mat_?SquareMatrixQ] := With[{n = Length[mat]},
Extract[mat, LinearToTriangularIndexing[Range[1, n (n - 1)/2], n]]
]