Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How to select all elements above the main diagonal of matrix? I need to create a list of them.

share|improve this question
up vote 11 down vote accepted

The Diagonal command has a second argument that allows listing the elements of the jth superdiagonal. So we can map over all the superdiagonals:

n = 4;
mat = Array[a, {n, n}];
Flatten[Diagonal[mat, #] & /@ Range[n-1]]

which gives a list of all the elements above the diagonal:

{a[1, 2], a[2, 3], a[3, 4], a[1, 3], a[2, 4], a[1, 4]}
share|improve this answer
Niiiiice, I learned something new – Rojo Jan 30 '14 at 1:49

Let's use Span with Part:

mat=RandomInteger[{0, 100}, {5, 5}];

Flatten[mat[[#, # + 1 ;;]] & /@ Range[5]]
share|improve this answer
Nice, clean, clever, and faster than the naive solution. +1 – ciao Jan 30 '14 at 5:32

I believe that kale's approach is the best, but it can be improved with Join which is considerably faster than Flatten on packed lists, and it is a bit cleaner when written with Array:

Join @@ Array[mat[[#, # + 1 ;;]] &, n - 1]

To make this into a fast function it seems that one needs a Hold attribute (pass-by-reference):

SetAttributes[aboveDiag, HoldFirst];
aboveDiag[a_] := Join @@ Array[a[[#, # + 1 ;;]] &, Length[a] - 1]

Compare timings (done in v7) with bill s's code and R.M's upperElements function. (I left MatrixQ out of upperElements in these tests to eliminate overhead and level the field.)

n = 5000;
mat = RandomInteger[999, {n, n}];

Flatten[Diagonal[mat, #] & /@ Range[n - 1]] // Timing // First

upperElements[mat]                          // Timing // First

aboveDiag[mat]                              // Timing // First



Not quite as superior on non-packed data, but still a good bit faster than the others.

n = 2000;
mat = Developer`FromPackedArray @ RandomInteger[999, {n, n}];

Flatten[Diagonal[mat, #] & /@ Range[n - 1]] // Timing // First

upperElements[mat]                          // Timing // First

aboveDiag[mat]                              // Timing // First



Inspired by rasher's use of MapIndexed, here is another one that tests the fastest on unpacked data on my system (using last mat above):

Join @@ MapIndexed[Drop[#, #2[[1]]] &, mat] // Timing // First

It is much slower than aboveDiag on packed data.

share|improve this answer
Join is not only faster but better than flatten (with no second arg) if the matrix can have list elements – Rojo Jan 30 '14 at 6:47
@Rojo Good point. – Mr.Wizard Jan 30 '14 at 7:05
Nice tuning, as usual! For non-huge arrays, I use (filter matching this particular problem in this case): FilterRules[ArrayRules[yourArrayHere], {a_, b_} /; b > a] Just seems... neat, if not a hot-rod. – ciao Jan 30 '14 at 7:53
@rasher You should post that ArrayRules method; it does have flair. – Mr.Wizard Jan 30 '14 at 7:54
I don't know but I've ran this and upperElemets and aboveDiag have comparable timings for PackedArray. Also in packed case my Pick is two times faster, unless I'm doing something wrong. – Kuba Jan 30 '14 at 8:35
n = 4;
mat = Array[a, {n, n}];

Flatten@Table[If[j > i, mat[[i, j]], {}], {i, n}, {j, n}]

Mathematica graphics

share|improve this answer
I liked the replacing by {} for future flattening. +1 – Rojo Jan 30 '14 at 2:09

Here's an option for square matrices using undocumented properties of SparseArray, which clocks in slightly faster for me than Mr.Wizard's solution:

upperElements[mat_?MatrixQ] := With[{n = Length@mat}, 
    SparseArray[UpperTriangularize[mat, 1]]["NonzeroValues"] ~PadRight~ (n (n - 1)/2)];

This constructs a sparse strictly upper triangular matrix, extracts the non-zero values and then pads it to a length of $n(n-1)/2$, where $n$ is the dimension of the matrix (to account for any upper element that might have been zero).

For non-square matrices of dimension $m\times n$, you might try using a closed form expression for the number of upper triangular entries (see here, for instance).

share|improve this answer
How come I didn't think of padright and worried about deleting extra zeros. +1 – Rojo Jan 30 '14 at 7:01
On my system (v7) this is about six to seven times slower than aboveDiag with n = 5000; mat = RandomInteger[999, {n, n}]; (and leaving out MatrixQ for a fair test). What data are you testing with, and what timings do you get for my data in v9? – Mr.Wizard Jan 30 '14 at 7:04
@Mr.Wizard I don't have the timings right now, but it was very close to yours, but a wee bit faster. I see from the comments under yours that Kuba got similar results. I don't have v7 installed, so I can't confirm your findings. – R. M. Jan 30 '14 at 16:55

Variation of Nasser answer:

n = 4;
m = Array[a, {n, n}];
Join @@ Table[m[[ i, j]], {i, n}, {j, i + 1, n}]
{a[1, 2], a[1, 3], a[1, 4], a[2, 3], a[2, 4], a[3, 4]}

just another way:

Join @@ Pick[
  UpperTriangularize[ConstantArray[1, {n, n}], 1],
share|improve this answer
n = 4;
mat = Array[a, {n, n}];
mat[[##]] & @@@ Subsets[Range[n], {2}]
(* {a[1,2],a[1,3],a[1,4],a[2,3],a[2,4],a[3,4]} *)
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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