2
$\begingroup$

I am interested in generating a 1D list of the upper-triangle elements of a matrix.

I can grab the indices of these elements by doing:

upperTrianglularIndices[dim_] := Subsets[Table[i, {i, val /. val -> dim}], {2}];

But I'm struggling to actually select the matrix elements using these indices.

If I have a function, then I know I can map-thread it using this code:

f @@ # & /@ upperTrianglularIndices[3]

which will return:

{f[1, 2], f[1, 3], f[2, 3]}

so my idea is to express my matrix as a function, function[matrix[[x]],x], and then use the above code to apply it to each index. I see that this works correctly like this:

(x \[Function] f[[x]]) @@ # & /@ upperTrianglularIndices[3]

But doesn't work when I specify that I want the function to be the selection of the matrix element:

(x \[Function] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}[[x]]) @@ # & /@ 
 upperTrianglularIndices[3]

This returns (with some errors):

{f[[1]], f[[1]], f[[2]]}

What is the problem here?

$\endgroup$
9
  • $\begingroup$ You could try using an undocumented internal function: Statistics`Library`UpperTriangularMatrixToVector[f] $\endgroup$
    – Carl Woll
    Aug 26 '20 at 17:43
  • $\begingroup$ What is the desired output? $\endgroup$
    – yarchik
    Aug 26 '20 at 18:07
  • $\begingroup$ @yarchik, the upper triangle (with or without diagonals) made to be a vector. So in this case, {2, 3, 6} or {1, 2, 3, 5, 6, 9} $\endgroup$ Aug 26 '20 at 18:11
  • $\begingroup$ @CarlWoll, I'm primarily interested in improving so my preference would be to learn how to do this using the basic syntax - but in the future, (when I'm confident but lazy) I would be interested in using that undocumented internal function. Do you happen to know if there's another command that grabs the diagonal elements too? $\endgroup$ Aug 26 '20 at 18:17
  • $\begingroup$ Diagonal returns the diagonal elements. $\endgroup$
    – Carl Woll
    Aug 26 '20 at 18:18
3
$\begingroup$
Clear["Global`*"]

Format[f[m_, n_]] := Subscript[f, m, n]

n = 3;

(mat = Array[f, {n, n}]) // MatrixForm

enter image description here

The indices are

upperTrianglularIndices[n_] :=
 Table[{i, j}, {i, n}, {j, i, n}] // Flatten[#, 1] &

upperTrianglularIndices[n]

(* {{1, 1}, {1, 2}, {1, 3}, {2, 2}, {2, 3}, {3, 3}} *)

The corresponding elements of the array are

mat[[##]] & @@@ upperTrianglularIndices[n]

enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you. This is what I was looking for. One question: how do you think about when to use # or ##? $\endgroup$ Aug 26 '20 at 18:56
  • $\begingroup$ # takes the first argument, ## takes all arguments. $\endgroup$
    – Bob Hanlon
    Aug 26 '20 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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