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 asked this question before, but i was closed because it the question was not comprehensible enough. So i reworded it, hope that's ok.


I have a list with 6 elements.

{a1, a2, a3, a4, a5, a6}

Now, I want to generate a upper triangle matrix with the elements above as matrix elements, so that the matrix reads

{{a1, a4, a6}, {0, a2, a5}, {0, 0, a3}}

That is, the triangle upper matrix matrix shall be filled up with the elements of the list. It is not important where each element is placed.

I want to do this also with larger matrices, so for example a list with 36 elements shall form a 8 x 8 upper triangle matrix.

Any ideas?

share|improve this question
    
Related: (55659) – Mr.Wizard Aug 2 '14 at 14:12

For the filling pattern you showed:

x = {a1, a2, a3, a4, a5, a6};

n = 3;

x ~Internal`PartitionRagged~ Range[n, 1, -1] ~Flatten~ {2} // PadLeft
{{a1, a4, a6}, {0, a2, a5}, {0, 0, a3}}

To find n given a complete input list x you can use:

n = Sqrt[1 + 8 Length@x]/2 - 1/2
share|improve this answer
    
I get the same result without the Flatten which would make your +1 answer even shorter. – eldo Aug 2 '14 at 15:00
    
@eldo Thanks for vote. However Flatten is needed for the filling order shown in the question. I'll leave the "any order" filling to others, unless I think of something particularly clean. – Mr.Wizard Aug 2 '14 at 15:05
    
@Mr.Wizard you many need to generalize n. +1 for the Partition trick. – Algohi Aug 2 '14 at 15:09
    
@Algohi Updated. – Mr.Wizard Aug 3 '14 at 0:02

Since "It is not important where each element is placed":

a = {a1, a2, a3, a4, a5, a6}
mat = SparseArray[
        Rule[#, #2] & @@@ Thread@{Flatten[Table[{i, j}, {i, 3}, {j, i, 3}], 1], a}];
mat // MatrixForm

$\left( \begin{array}{ccc} \text{a1} & \text{a2} & \text{a3} \\ 0 & \text{a4} & \text{a5} \\ 0 & 0 & \text{a6} \\ \end{array} \right)$

If you have a list of 36 elements that you want to turn into a 8x8 upper triangle matrix:

l = Range@36;
mat = SparseArray[
   Rule[#, #2] & @@@ Thread@{Flatten[Table[{i, j}, {i, 8}, {j, i, 8}], 1], l}];
mat // MatrixForm

$\left( \begin{array}{cccccccc} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ 0 & 9 & 10 & 11 & 12 & 13 & 14 & 15 \\ 0 & 0 & 16 & 17 & 18 & 19 & 20 & 21 \\ 0 & 0 & 0 & 22 & 23 & 24 & 25 & 26 \\ 0 & 0 & 0 & 0 & 27 & 28 & 29 & 30 \\ 0 & 0 & 0 & 0 & 0 & 31 & 32 & 33 \\ 0 & 0 & 0 & 0 & 0 & 0 & 34 & 35 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 36 \\ \end{array} \right)$


Here is an attempt to make it more robust:

mat[l_] := Module[{n = Abs[1/2 (1 - Sqrt[1 + 8*Length@l])]},
   If[IntegerQ@n, 
     SparseArray[Rule[#, #2] & @@@ Thread@{Flatten[Table[{i, j}, {i, n}, {j, i, n}], 1], l}], 
     "Wrong length. The length should be " <>
      ToString[Or @@ ((#[n]*(#[n] + 1)/2) & /@ {Ceiling, Floor})] <> "."]]

Usage:

l = Range@11;
mat@l

Wrong length. The length should be 15 || 10.

l = Range@10;
mat@l

$\left( \begin{array}{cccc} 1 & 2 & 3 & 4 \\ 0 & 5 & 6 & 7 \\ 0 & 0 & 8 & 9 \\ 0 & 0 & 0 & 10 \\ \end{array} \right)$

share|improve this answer
    
Your answer only functions when there are exactly 6 elements. But the OP wants a more general solution: "... so for example a list with 36 elements shall form a 8x8 upper triangle matrix." – eldo Aug 2 '14 at 13:39
    
@eldo I assumed that you were capable of replacing 3 by 8 ;o) But there you go. – Öskå Aug 2 '14 at 13:46
    
Now I can see +1 – eldo Aug 2 '14 at 13:56

You should try to avoid procedural language in mathematica. I think this should work, but maybe it is not the most efficient:

Code edited for clarity

utMatrix[list_List] := With[{matrixsize = -1/2 + 1/2 Sqrt[1 + 8*Length@list]}, 
PadLeft[Take[list, #], matrixsize, 0] & /@ (Transpose@{Most@#, Rest@# - 1} &
[Accumulate@Join[{1}, Range[matrixsize, 1, -1]]]) 
/;IntegerQ[matrixsize]]

Basically this function partitions the list in sublists of appropriate lengths and then pads them with 0s on the left. The condition at the end checks for lists of wrong lengths.

share|improve this answer

This is if you car about order.

list = {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10};

s = 1/2 (1 + Sqrt[1 + 8 Length@list]);
l = list[[1 + # s - (# (1 + #))/2 ;; (1 + #) s - ((# + 1) (2 + #))/
         2]] & /@ Range[0, s - 2];
SparseArray[Band[{1, #}] -> l[[#]] & /@ Range[Length@l]] // 
  Normal


(* {{a1, a5, a8, a10}, {0, a2, a6, a9}, {0, 0, a3, a7}, {0, 0, 0, a4}}*)
share|improve this answer

Inspired by Mr. Wizard's solution this is a certain generalization:

rag[v_, w_] := 
 MapThread[v[[#1 ;; #2]] &, With[{a = Accumulate[w]}, {a - w + 1, a}]]

tri[n_Integer /; n > 0, order_: True, s_Symbol: a] :=
 Module[{x, y},
  x = Range[n, 1, -1];
  y = rag[ToExpression[ToString@s <> # & /@ ToString /@ Range@Total@x], x];
  PadLeft@If[order, Flatten[y, {2}], y]
  ]

tri[3] // MatrixForm

enter image description here

tri[8, False] // MatrixForm

enter image description here

share|improve this answer
    
Nice extension. – Mr.Wizard Aug 2 '14 at 18:35
toUpperMatrix[l_List] := Module[{i, n, m, k, t},
    n = Length[l];
    m = {};
    k = 1/2 (-1 + Sqrt[1 + 8 n]);
    t = {};
    For[i = 1, i <= n, i++,
        AppendTo[t, l[[i]]];
        If[Length[t] == k,
            AppendTo[m, Join[Table[0, {i, 1, 1/2 (-1 + Sqrt[1 + 8 n]) - k}], t]];
            t = {};
            k--;
        ];
    ];
    Return[m];
];

This is the only method I can figure out. Looking forward to better solutions.

share|improve this answer

If you don't care the order you can use the following function:

tpart[list_ /; VectorQ[list] && OddQ[Sqrt[1 + 8 Length[list]]]] := 
 Module[{m = (-1 + Sqrt[1 + 8 Length[list]])/2},
  SparseArray[
   Thread[Flatten[Table[{i, j}, {i, 1, m}, {j, i, m}], 1] -> 
     list], {m, m}]
  ]

For example

tpart[{a1, a2, a3, a4, a5, a6}] // MatrixForm
tpart[Array[a, 36]] // MatrixForm

gives:

Mathematica graphics

If you do care about your order this one (this function is not robust: be sure to pass an appropriately sized list or add a condition):

tpart2[list_] := Module[{m = (-1 + Sqrt[1 + 8 Length[list]])/2, s},
  s = Range[m, 1, -1] //Prepend[1 + Accumulate[#], 1] & //Partition[#, 2, 1] &;
  SparseArray[
   Thread[Array[Band[{1, #}] &, m] -> (Take[list, # - {0, 1}] & /@ s)]
   , {m, m}]
  ]

tpart2[list]
tpart2[list] // MatrixForm
tpart2[list] // Normal

The result is:

share|improve this answer
  n = 6
  vals = Array[a, {n (n + 1)/2}]
  SparseArray[
       SortBy[Tuples[Range[n], {2}] ,
         #[[2]] - #[[1]] &][[-n (n + 1)/2 ;;]] -> vals ] // MatrixForm

enter image description here

without using SparseArray:

 ReplacePart[ConstantArray[0, {n, n}],
      MapThread[#1 -> #2 &, {
         SortBy[Tuples[Range[n], {2}] ,
         #[[2]] - #[[1]] &][[-n (n + 1)/2 ;;]], vals}]] // MatrixForm
share|improve this answer

If the length of your vector can always be guaranteed to be correct (exactly good for an upper triangular matrix), then the following will work.

v = {a1, a2, a3, a4, a5, a6};
d = (-1 + Sqrt[1 + 8*Length[v]])/2;
Array[If[#1 <= #2, v[[(2*d - #1 + 2)*(#1 - 1)/2 + #2 - #1 + 1]], 0] &, {d,d}]

Please test it yourself and write it into a function if you need to repeatedly use it.

Regards,

Kuo Kan LIANG

share|improve this answer
    
@Shutao, doesn't it depend on the dialect? – J. M. Apr 22 at 4:17
    
Sorry guys I have not been wanting to reply to these comments on the spelling of my name, not because I am arrogant, but because I thought it irrelevant to the discussion. – 梁國淦 Apr 26 at 0:59
    
Actually when I was small and tried to figure out the spelling of my name in English, most people still used old Roman system for spelling non-Latin language pronunciation. There is nothing to fight about this. Why do you care how well the foreigners pronounce your name? It sounds weird anyway. I hope that this is a discussion of knowledge, even if it were not of programming or mathematics. – 梁國淦 Apr 26 at 1:06
    
@ShutaoTANG To be more precise, 梁國淦 is using Wade–Giles. And, well, with all due respect, if you really care about the standard, then you should be TANG Shutao: fdcollege.fudan.edu.cn/_upload/article/1e/26/… – xzczd May 8 at 6:02
    
@xzczd 谢谢你的姓名解释! – Shutao TANG May 9 at 0:49

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.