# Thread: How to rearrange one column into a matrix format?

1. Registered User
Join Date
Feb 2004
Posts
52

## Unanswered: How to rearrange one column into a matrix format?

Hi all.

I appreciate any help in this newbie problem :

Does someone know how to convert a single colum of numbers
like (the total number of lines, n, is known)

0
11
24
56
123
0
12
134
113
0
1123
876
0
345
0

to the matrix form :

0
11 0
24 12 0
56 134 1123 0
123 113 876 345 0

or

1 2 3 4 5
1 0 * * * *
2 11 0 * * *
3 24 12 0 * *
4 56 134 1123 0 *
5 123 113 876 345 0

(note that the zero's correspond to the main diagonal)

In my real problem, the matrix dimensions are 50x50
corresponding to a 1275 column. It's very hard
to get any good view of these number without the
matrix format.

Thanks !

2. Registered User
Join Date
Jan 2004
Location
Bordeaux, France
Posts
320
Try and adapt the following script :

Code:
Input_File=mat.txt
Input_Lines=`wc -l \$Input_File | awk '{print \$1}'`
awk -v LINES=\$Input_Lines '
# Initalisations
BEGIN {
# compute #lines of matrix
delta = 1 + 8*LINES;
if (delta < 0) {
print "Invalid input lines count"
exit;
}
matrix_lines = (sqrt(delta) -1)/2;
col   = 1
line  = 1
}
# Memorize value in matrix
{
matrix[line] = matrix[line] " " \$1;
line += 1;
if (line > matrix_lines)
line = ++col;
}
# Print full matrix
END {
for (line=1; line<=matrix_lines; line++)
print matrix[line];
}
' \$Input_File
With your datas example, the result is :
home/jp> mat.shl
0
11 0
24 12 0
56 134 1123 0
123 113 876 345 0
home/jp>

3. Registered User
Join Date
Feb 2004
Posts
52

## Thanks

Jean,

Your script works beautifully.
Thanks a lot again.

Serg

Join Date
Jun 2002
Location
UK
Posts
525
You could maybe simplify the above script a little. You might also want to format the output so that your pyramid does not become skewed...
Code:
awk '
\$0==0{i=++j}
{rows[i++]=rows[i]sprintf("%5s",\$0)}
END {
for (i=1; i<=j; i++) {
print rows[i]
}
}' yourFile
And if you wanted to reflect your pyramid, you would do it like this...
Code:
awk '
\$0==0{i=++j}
{rows[i++]=rows[i]sprintf("%5s",\$0)}
END {
for (i=1; i<=j; i++) {
printf rows[i]
for (k=i+1; k<=j; k++) {
\$0=rows[k]
printf("%5s",\$i)
}
printf"\n"
}
}' yourFile
Damian

Join Date
Jun 2002
Location
UK
Posts
525
A little enhancement as I have no idea how wide your pyramid columns might need to be...
Code:
awk '
\$0==0{i=++j}
{rows[i++]=rows[i]sprintf(formatString,\$0)}
END {
for (i=1; i<=j; i++) {
print rows[i]
}
}' yourFile formatString="%5s"

6. Registered User
Join Date
Jan 2004
Location
Bordeaux, France
Posts
320
Hi Damian,

Your script assume that value 0 may appear only in the diagonal !

If the file contains :
0
11
0
31
0
22
32
0
33
0

Your script display :
0
11 0
31 0
22 0
32 33 0

0
11 0
0 22 0
31 32 33 0

Join Date
Jun 2002
Location
UK
Posts
525
Originally posted by aigles
Hi Damian,

Your script assume that value 0 may appear only in the diagonal !
A very good point. I thought the OP suggested that 0's would make up the main diagonal which inferred that this would be the only place that 0's occur. That was why I decided that the script could be simplified.

I could be wrong but it was a fun little exercise even if I am!

8. Registered User
Join Date
Feb 2004
Posts
52
Thanks, Damian and Jean.

Your posts are amazing !

Serg

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•