Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

I have a tensor, u, of rank one, meaning that I have a matrix whose elements are themselves matrices. I would like to select, and make a list of, only those sub-matrices whose indices comply with the condition j < k, i.e. the row index is always smaller than the column index.

This effectively corresponds to strictly upper-triangularising the tensor. Once I select the correct sub-matrices, I would like them to appear in a list sorted row by row. I.e., if each sub-matrix is called aXX, where XX are the row and column indices, and the tensor has dimensions NxN, then I want the list to look like this:

a12, a13, a14 ..., a1N, a23, a24, ..., a2N, a34, ..., a3N, ..., a(N-1)N.

I have tried using UpperTriangularize[] to no avail. I suspect the answer must be using Select[] or Pick[], but I am unsure of how to implement the condition based on testing the indices of the tensor. Any ideas would be much appreciated.

Here is my code which generates u. NLevel is the same as N that I mentioned above, and can be varied with each run of the programme.

 P = Table[SparseArray[{{j, k} -> 1}, {NLevel, NLevel}], {j, NLevel}, {k, NLevel}]
 u = Table[P[[1, j, k]] + P[[1, k, j]], {j, NLevel}, {k, NLevel}]
share|improve this question
up vote 2 down vote accepted

I think the following solution is easier to follow:

Join @@ Table[ u[[j,k]] , {j, NLevel}, {k, j + 1, NLevel}]

The Table part should be self-explanatory: it iterates through $a_{jk}$ for pairs $j < k$. However, it does not return a list of matrices. It returns a list of lists of matrices. These need to be joined together into a single list, which is what Join @@ does.

References:

share|improve this answer
    
I agree. It's much easier to see what is going on here. In my case, I find neverthess that I need to add a '1,' before 'j,k' in u[[j,k]], i.e.: Join @@ Table[ u[[1, j, k]], {j, NLevel}, {k, j + 1, NLevel}] // MatrixForm, otherwise I get an error. I think this has to do with the extra pair of brackets that Mathematica likes to put around P and u. – Mirella Oct 21 '15 at 18:05

I believe this does what you want (using your u example without the MatrixForm formatting):

Normal@Extract[#, Sort@Join[Array[{#, #} &, Length@#], Subsets[Range@Length@#, {2}]]] &[u]

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

Edit: Sorry, I think I misread your question. If it's strictly upper,

Normal@Extract[#, Subsets[Range@Length@#, {2}]] &[u]
share|improve this answer

You can also use Part:

NLevel = 3;
P = Table[SparseArray[{{j, k} -> 1}, {NLevel, NLevel}], {j, NLevel}, {k, NLevel}];

P[[##]] & @@@ Subsets[Range@Length@P, {2}] // Normal

(* {{{0, 1, 0}, {0, 0, 0}, {0, 0, 0}}, 
   {{0, 0, 1}, {0, 0, 0}, {0, 0, 0}},
   {{0, 0, 0}, {0, 0, 1}, {0, 0, 0}}} *)

Instead of Subsets[Range@Length@P, {2}] we can also use SparseArray[UpperTriangularize[ConstantArray[1, {NLevel, NLevel}], 1]]["NonzeroPositions"].

share|improve this answer

Your Answer

 
discard

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.