Skip to content

Commit e36897c

Browse files
authored
Add Transpose Matrix in M4 (#5058)
1 parent 9165cca commit e36897c

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

archive/m/m4/transpose-matrix.m4

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
divert(-1)
2+
define(`show_usage',
3+
`Usage: please enter the dimension of the matrix and the serialized matrix
4+
m4exit(`1')')
5+
6+
dnl Reference: https://www.gnu.org/software/m4/manual/m4.html#index-array
7+
dnl array_get(varname, idx)
8+
define(`array_get', `defn(format(``%s[%s]'', `$1', `$2'))')
9+
10+
dnl array_set(varname, idx, value)
11+
define(`array_set', `define(format(``%s[%s]'', `$1', `$2'), `$3')')
12+
13+
dnl 2D versions of "array_get" and "array_set"
14+
dnl array2_get(varname, idx1, idx2)
15+
define(`array2_get', `defn(format(``%s[%s][%s]'', `$1', `$2', `$3'))')
16+
17+
dnl array_set(varname, idx, value)
18+
define(`array2_set', `define(format(``%s[%s][%s]'', `$1', `$2', `$3'), `$4')')
19+
20+
dnl is_valid(n)
21+
define(`is_valid', `eval(regexp(`$1', `^\s*-?[0-9]+\s*$') >= 0)')
22+
23+
dnl parse_int_list(varname, args):
24+
dnl varname["length"] = 0
25+
dnl foreach arg in args:
26+
dnl if not is_valid(arg):
27+
dnl Return 0
28+
dnl varname[varname["length"]] = arg
29+
dnl varname["length"] = varname["length"] + 1
30+
dnl Return 1
31+
define(`parse_int_list',
32+
`array_set(`$1', `length', 0)dnl
33+
_parse_int_list(`$1', $2)'dnl
34+
)
35+
define(`_parse_int_list',
36+
`ifelse(is_valid(`$2'), 0, `0',
37+
`array_set(`$1', array_get(`$1', `length'), `$2')dnl
38+
array_set(`$1', `length', incr(array_get(`$1', `length')))dnl
39+
ifelse(eval($# > 2), 1, `_parse_int_list(`$1', shift(shift($@)))', `1')'dnl
40+
)'dnl
41+
)
42+
43+
dnl show_int_list(varname):
44+
dnl for i = 0 to varname["length"]-1:
45+
dnl if i > 0:
46+
dnl Output ", "
47+
dnl Output varname[i]
48+
define(`show_int_list', `_show_int_list(`$1', 0)')
49+
define(`_show_int_list',
50+
`ifelse(eval($2 < array_get(`$1', `length')), 1,
51+
`ifelse(eval($2 > 0), 1, `, ')dnl
52+
array_get(`$1', $2)`'dnl
53+
_show_int_list(`$1', incr($2))'`'dnl
54+
)'dnl
55+
)
56+
57+
dnl list_to_matrix(arrname, mtxname, rows, cols):
58+
dnl mtxname["rows"] = rows
59+
dnl mtxname["cols"] = cols
60+
dnl idx = 0
61+
dnl for i = 0 to rows-1:
62+
dnl for j = 0 to cols-1:
63+
dnl mtxname[i][j] = arrname[idx]
64+
dnl idx = idx + 1
65+
define(`list_to_matrix',
66+
`array_set(`$2', `rows', `$3')dnl
67+
array_set(`$2', `cols', `$4')dnl
68+
_list_to_matrix_outer(`$1', `$2', `$3', `$4', 0, 0)'dnl
69+
)
70+
71+
dnl arrname=$1, mtxname=$2, rows=$3, cols=$4, i=$5, idx=$6
72+
define(`_list_to_matrix_outer',
73+
`ifelse(eval($5 < $3), 1,
74+
`_list_to_matrix_inner(`$1', `$2', `$4', `$5', 0, `$6')dnl
75+
_list_to_matrix_outer(`$1', `$2', `$3', `$4', incr($5), eval($6 + $4))'dnl
76+
)'dnl
77+
)
78+
79+
dnl arrname=$1, mtxname=$2, cols=$3, i=$4, j=$5, idx=$6
80+
define(`_list_to_matrix_inner',
81+
`ifelse(eval($5 < $3), 1,
82+
`array2_set(`$2', `$4', `$5', array_get(`$1', `$6'))dnl
83+
_list_to_matrix_inner(`$1', `$2', `$3', `$4', incr($5), incr($6))'dnl
84+
)'dnl
85+
)
86+
87+
dnl transpose_matrix(mtxname1, mtxname2):
88+
dnl mtxname2["rows"] = mtxname1["cols"]
89+
dnl mtxname2["cols"] = mtxname2["rows"]
90+
dnl for i = 0 to mtxname1["rows"]-1:
91+
dnl for j = 0 to mtxname1["cols"]-1:
92+
dnl mtxname2[j][i] = mtxname1[i][j]
93+
define(`transpose_matrix',
94+
`array_set(`$2', `rows', array_get(`$1', `cols'))dnl
95+
array_set(`$2', `cols', array_get(`$1', `rows'))dnl
96+
_transpose_matrix_outer(`$1', `$2', 0)'dnl
97+
)
98+
99+
dnl mtxname1=$1, mtxname2=$2, i=$3
100+
define(`_transpose_matrix_outer',
101+
`ifelse(eval($3 < array_get(`$1', `rows')), 1,
102+
`_transpose_matrix_inner(`$1', `$2', `$3', 0)dnl
103+
_transpose_matrix_outer(`$1', `$2', incr($3))'dnl
104+
)'dnl
105+
)
106+
107+
dnl mtxname1=$1, mtxname2=$2, i=$3, j=$4
108+
define(`_transpose_matrix_inner',
109+
`ifelse(eval($4 < array_get(`$1', `cols')), 1,
110+
`array2_set(`$2', `$4', `$3', array2_get(`$1', `$3', `$4'))dnl
111+
_transpose_matrix_inner(`$1', `$2', `$3', incr($4))'dnl
112+
)'dnl
113+
)
114+
115+
dnl matrix_to_list(mtxname, arrname):
116+
dnl arrname["length"] = 0
117+
dnl idx = 0
118+
dnl for i = 0 to mtxname["rows"]-1:
119+
dnl for j = 0 to mtxname["cols"]-1:
120+
dnl arrname[arrname["length"]] = mtxname[i][j]
121+
dnl arrname["length"] = arrname["length"] + 1
122+
define(`matrix_to_list',
123+
`array_set(`$2', `length', 0)dnl
124+
_matrix_to_list_outer(`$1', `$2', 0)'dnl
125+
)
126+
127+
dnl mtxname=$1, arrname=$2, i=$3
128+
define(`_matrix_to_list_outer',
129+
`ifelse(eval($3 < array_get(`$1', `rows')), 1,
130+
`_matrix_to_list_inner(`$1', `$2', `$3', 0)dnl
131+
_matrix_to_list_outer(`$1', `$2', incr($3))'dnl
132+
)'dnl
133+
)
134+
135+
dnl mtxname=$1, arrname=$2, i=$3, j=$4
136+
define(`_matrix_to_list_inner',
137+
`ifelse(eval($4 < array_get(`$1', `cols')), 1,
138+
`array_set(`$2', array_get(`$2', `length'), array2_get(`$1', `$3', `$4'))dnl
139+
array_set(`$2', `length', incr(array_get(`$2', `length')))dnl
140+
_matrix_to_list_inner(`$1', `$2', `$3', incr($4))'dnl
141+
)'dnl
142+
)
143+
144+
divert(0)dnl
145+
ifelse(eval(ARGC < 3 || !is_valid(ARGV1) || !is_valid(ARGV2)), 1, `show_usage()')dnl
146+
ifelse(eval(len(ARGV3) < 1 || !parse_int_list(`arr', ARGV3)), 1, `show_usage()')dnl
147+
ifelse(eval(ARGV1 < 1 || ARGV2 < 1 || array_get(`arr', `length') != ARGV1 * ARGV2), 1, `show_usage()')dnl
148+
list_to_matrix(`arr', `mtx', ARGV2, ARGV1)dnl
149+
transpose_matrix(`mtx', `mtx_t')dnl
150+
matrix_to_list(`mtx_t', `arr_t')dnl
151+
show_int_list(`arr_t')

0 commit comments

Comments
 (0)