1 /* file "int_matrix.cc" */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
12 #define _MODULE_ "libsuifmath.a"
13 #pragma implementation "int_matrix.h"
23 int compose_print_flag
= FALSE
;
25 void init_suifmath(int & /* argc */, char * /* argv */ [])
27 // k_named_sc_merge_mark_annote = lexicon->enter("named_sc_merge_mark")->sp;
28 ANNOTE(k_named_sc_merge_mark_annote
, "named_sc_merge_mark", FALSE
);
30 STRUCT_ANNOTE(code_context_annote::k_annote
,
33 code_context_annote_from
,
34 code_context_annote_to
,
35 code_context_annote_free
,
36 code_context_annote_print
);
39 void exit_suifmath(void)
44 /********************************************************************************
45 * gcd (Gratest Common Dinominator) *
46 ********************************************************************************/
49 assert((a
>=0)&&(b
>=0));
61 /********************************************************************************
62 * lcm (Least Common Multiple) *
63 ********************************************************************************/
66 assert((a
>=0)&&(b
>=0));
68 long gcdab
= gcd(a
,b
);
72 assert(out
/bL
== aL
); // check for overflow
78 /* ##################################################
79 ##### integer_row #####
80 ################################################## */
82 /********************************************************************************
84 ********************************************************************************/
85 void integer_row::mknew(int s
)
95 integer_row::integer_row()
102 integer_row::integer_row(const integer_row
& rw
)
110 integer_row::integer_row(const integer_row
* rw
)
118 integer_row::integer_row(int s
)
126 void integer_row::clear()
136 void integer_row::init(const integer_row
& rw
)
141 memcpy(R
, rw
.R
, n()*sizeof(int));
150 memcpy(R
, rw
.R
, n()*sizeof(int));
155 void integer_row::init(int s
)
161 memset(R
, 0, n()*sizeof(int));
169 memset(R
, 0, n()*sizeof(int));
172 void integer_row::init(const int * ilist
, int s
)
178 memcpy(R
, ilist
, n()*sizeof(int));
186 memcpy(R
, ilist
, n()*sizeof(int));
192 /********************************************************************************
194 ********************************************************************************/
195 boolean
integer_row::operator==(const integer_row
& a
) const
197 return ((a
.n() == n()) &&
198 (memcmp(&a
.R
[0], &R
[0], sizeof(int)*n()) == 0));
202 for(int i=0; i<n(); i++)
203 if(a.R[i] != R[i]) return 0;
210 integer_row
& integer_row::operator=(const integer_row
& row
)
212 if(&row
== this) return *this;
216 memcpy(R
, row
.R
, n()*sizeof(int));
223 void integer_row::operator^=(integer_row
& row
)
225 // assert(n() == row.n());
239 integer_row
integer_row::swap_col(int i
, int j
) const
247 void integer_row::do_swap_col(int i
, int j
)
251 assert((i
>=0)&&(i
<n()));
252 assert((j
>=0)&&(j
<n()));
255 int tmp
= (*this)[i
];
256 (*this)[i
] = (*this)[j
];
262 integer_row
integer_row::operator+(const integer_row
& row
) const
264 assert(n() == row
.n());
265 integer_row
result(n());
267 for(int i
=0; i
<n(); i
++)
268 result
[i
] = R
[i
] + row
.c(i
);
273 integer_row
integer_row::operator-(const integer_row
& row
) const
275 assert(n() == row
.n());
277 integer_row
result(n());
279 for(int i
=0; i
<n(); i
++)
280 result
[i
] = R
[i
] - row
.c(i
);
286 integer_row
integer_row::operator*(const integer_row
& row
) const
288 assert(n() == row
.n());
290 integer_row
result(n());
292 for(int i
=0; i
<n(); i
++)
293 result
[i
] = R
[i
] * row
.c(i
);
299 integer_row
integer_row::operator/(const integer_row
& row
) const
301 assert(n() == row
.n());
303 integer_row
result(n());
304 for(int i
=0; i
<n(); i
++)
305 result
[i
] = R
[i
] / row
.c(i
);
311 // shuffle operator ret[x] = this[row[x]]
312 integer_row
integer_row::operator%(const integer_row
& row
) const
314 assert(n() == row
.n());
316 integer_row
result(n());
318 for(int i
=0; i
<n(); i
++) {
319 assert((row
.R
[i
] >= 0)&&(row
.R
[i
] < n()));
320 result
[i
] = R
[row
.R
[i
]];
327 integer_row
& integer_row::operator+=(const integer_row
& row
)
329 assert(n() == row
.n());
331 for(int i
=0; i
<n(); i
++)
337 integer_row
& integer_row::operator-=(const integer_row
& row
)
339 assert(n() == row
.n());
341 for(int i
=0; i
<n(); i
++)
348 integer_row
& integer_row::operator*=(const integer_row
& row
)
350 assert(n() == row
.n());
352 for(int i
=0; i
<n(); i
++)
359 integer_row
& integer_row::operator/=(const integer_row
& row
)
361 assert(n() == row
.n());
363 for(int i
=0; i
<n(); i
++)
369 void integer_row::do_addmul(const integer_row
& row
, int mul
)
371 assert(n() == row
.n());
376 for(int i
=0; i
<n(); i
++)
377 R
[i
] += mul
*row
.c(i
);
380 integer_row
& integer_row::operator=(int val
)
382 for(int i
=0; i
<n(); i
++)
387 integer_row
& integer_row::operator+=(int val
)
389 for(int i
=0; i
<n(); i
++)
394 integer_row
& integer_row::operator-=(int val
)
396 for(int i
=0; i
<n(); i
++)
401 integer_row
& integer_row::operator*=(int val
)
403 for(int i
=0; i
<n(); i
++)
408 integer_row
& integer_row::operator/=(int val
)
410 for(int i
=0; i
<n(); i
++)
417 /********************************************************************************
419 ********************************************************************************/
420 integer_row
integer_row::del_col(int i
, int j
) const
423 assert((i
>=0)&&(j
<n()));
424 integer_row
ret(n() - (j
- i
+ 1));
428 for(a
= 0; a
< i
; a
++)
431 for(a
= j
+1; a
< n(); a
++)
434 assert(cnt
== ret
.n());
439 void integer_row::do_del_col(int i
, int j
)
442 assert((i
>=0)&&(j
<n()));
445 for (st
= i
, fn
= j
+1; (fn
< sz
); st
++, fn
++)
448 sz
= sz
- (j
- i
+ 1);
451 void integer_row::do_del_columns(const integer_row
& mask
)
454 assert(mask
.n() == n());
456 for (dst
=0, src
=0; (src
< n()); src
++) {
466 /********************************************************************************
468 ********************************************************************************/
469 integer_row
integer_row::insert_col(int i
) const
471 assert((i
>=0)&&(i
<=n()));
472 integer_row
ret(n()+1);
476 for(a
= 0; a
< i
; a
++)
481 for(a
= i
; a
< n(); a
++)
484 assert(cnt
== ret
.n());
489 void integer_row::do_insert_col(int i
)
491 assert((i
>=0)&&(i
<=n()));
495 for (src
=sz
-2, dst
=sz
-1; src
>= i
; --dst
, --src
)
499 assert((i
>=0)&&(i
<=n()));
500 integer_row
ret(MAX(n()+1,n()*2));
505 for(a
= 0; a
< i
; a
++)
510 for(a
= i
; a
< n(); a
++)
513 assert(cnt
== ret
.n());
520 int integer_row::hashkey() const
523 for(int i
=0; i
<n(); i
++)
528 /* ##################################################
529 ##### integer_matrix #####
530 ################################################## */
533 integer_row
*integer_matrix::alloc_rows(int num_rows
)
536 return new integer_row
[num_rows
];
540 /********************************************************************************
542 ********************************************************************************/
543 integer_matrix::integer_matrix(int rows
,int cols
)
546 nn
= mm
= realmm
= 0;
551 integer_matrix::integer_matrix(const integer_matrix
*m
)
554 nn
= mm
= realmm
= 0;
559 integer_matrix::integer_matrix(const integer_matrix
& m
)
562 nn
= mm
= realmm
= 0;
566 integer_matrix::integer_matrix(const integer_matrix
*m
, int rows
)
569 nn
= mm
= realmm
= 0;
573 integer_matrix::integer_matrix(const integer_matrix
& m
, int rows
)
576 nn
= mm
= realmm
= 0;
580 integer_matrix::integer_matrix(const coeff
* c
)
583 nn
= mm
= realmm
= 0;
587 integer_matrix::integer_matrix()
590 mm
= nn
= realmm
= 0;
593 integer_matrix::~integer_matrix()
598 mm
= nn
= realmm
= 0;
603 void integer_matrix::clear()
608 mm
= nn
= realmm
= 0;
610 assert((mm
== 0) && (realmm
== 0));
613 /********************************************************************************
615 ********************************************************************************/
617 void integer_matrix::mknew(int rows
, int cols
)
619 assert((rows
>= 0)&&(cols
>= 0));
622 if((rows
<=realmm
)&&(cols
<=n())) {
623 mm
= rows
; nn
= cols
;
624 for(int i
=0; i
<mm
; i
++) A
[i
].mknew(cols
);
631 A
= alloc_rows(rows
);
632 for(int i
=0; i
<rows
; i
++) A
[i
].mknew(cols
);
638 void integer_matrix::init(int rows
,int cols
)
640 assert((rows
>= 0)&&(cols
>= 0));
643 if((rows
<=realmm
)&&(cols
<=n())) {
644 mm
= rows
; nn
= cols
;
645 for(int i
=0; i
<mm
; i
++) A
[i
].init(cols
);
652 A
= alloc_rows(rows
);
653 for(int i
=0; i
<rows
; i
++) A
[i
].init(cols
);
660 void integer_matrix::init(const integer_matrix
& M
)
665 if((M
.m()<=realmm
)&&(M
.n()<=n())) {
666 mm
= M
.m(); nn
= M
.n();
667 for(int i
=0; i
<m(); i
++) A
[i
] = M
.r(i
);
675 A
= alloc_rows(M
.m());
676 for(int i
=0; i
<M
.m(); i
++) A
[i
] = M
.r(i
);
685 void integer_matrix::init(const integer_matrix
& M
, int rows
)
691 if((M
.m()<=realmm
)&&(M
.n()<=n())) {
692 mm
= M
.m(); nn
= M
.n();
693 for(int i
=0; i
<m(); i
++) A
[i
] = M
.r(i
);
704 for(int i
=0; i
<m(); i
++) A
[i
] = M
.r(i
);
707 for(i
=0; i
< M
.m(); i
++) A
[i
] = M
.r(i
);
708 for(i
=M
.m(); i
< m(); i
++) A
[i
].init(n());
713 void integer_matrix::init(const coeff
* c
)
717 for(int i
=0; i
<c
->m
; i
++) {
718 (*this)[i
][0] = (c
->constant
)[i
];
719 for(int j
=0; j
<c
->n
; j
++)
720 (*this)[i
][j
+1] = *((c
->vars
)+i
*(c
->n
)+j
);
726 void integer_matrix::init(FILE * fp
)
730 fscanf(fp
, "%d %d\n", &r
, &c
);
731 fprintf(stderr
,"(%d x %d)\n", r
, c
);
737 void integer_matrix::init(FILE * fp
, int r
, int c
)
740 assert((r
>= 0)&&(c
>= 0));
742 for(int i
=0; i
<r
; i
++)
743 for(int j
=0; j
<c
; j
++)
744 fscanf(fp
, "%d ", &(*this)[i
][j
]);
747 void integer_matrix::init(const int * data
, int rows
, int cols
)
749 assert((rows
>= 0)&&(cols
>= 0));
751 for(int i
=0; i
<rows
; i
++)
752 for(int j
=0; j
<cols
; j
++)
753 A
[i
][j
] = (*this)[i
][j
];
756 if((rows
<=realmm
)&&(cols
<=n())) {
757 mm
= rows
; nn
= cols
;
758 for(int i
=0; i
<mm
; i
++)
759 A
[i
].init(data
+i
*cols
,cols
);
766 A
= alloc_rows(rows
);
767 for(int i
=0; i
<rows
; i
++)
768 A
[i
].init(data
+i
*cols
,cols
);
776 /********************************************************************************
778 ********************************************************************************/
779 integer_matrix
& integer_matrix::operator=(const integer_matrix
& in
)
788 boolean
integer_matrix::operator==(const integer_matrix
& a
) const
790 if((a
.n() == n()) && (a
.m() == m())) {
792 for(int i
=0; i
<a
.m(); i
++) if(a
.r(i
) != r(i
)) noeq
= 1;
798 integer_matrix
integer_matrix::operator%(const integer_row
& shuffle
) const
800 assert(n() == shuffle
.n());
802 integer_matrix
result(m(), n());
804 for(int i
=0; i
<m(); i
++) {
805 result
[i
] = r(i
) % shuffle
;
813 /********************************************************************************
815 ********************************************************************************/
816 integer_matrix
integer_matrix::del_col(int i
, int j
) const
819 assert((i
>=0)&&(j
<n()));
820 integer_matrix
ret(m(), n() - (j
- i
+ 1));
822 for(int a
=0; a
<m(); a
++)
823 ret
[a
] = r(a
).del_col(i
, j
);
828 integer_matrix
integer_matrix::insert_col(int i
) const
830 assert((i
>=0)&&(i
<=n()));
831 integer_matrix
ret(m(), n() + 1);
833 for(int a
=0; a
<m(); a
++)
834 ret
[a
] = r(a
).insert_col(i
);
839 integer_matrix
integer_matrix::del_columns(const integer_row
& mask
) const
843 assert(mask
.n() == n());
844 for(j
=0; j
<mask
.n(); j
++)
845 if(!mask
.c(j
)) cnt
++;
847 integer_matrix
ret(m(), cnt
);
853 ret
[i
][c
] = this->r(i
).c(j
);
862 integer_matrix
integer_matrix::swap_col(int i
, int j
) const
864 assert((i
>=0)&&(i
<n()));
865 assert((j
>=0)&&(j
<n()));
867 integer_matrix
ret(this);
869 for(int a
=0; a
<m(); a
++)
870 ret
[a
].do_swap_col(i
, j
);
875 /* in-place versions */
877 void integer_matrix::do_del_col(int i
, int j
)
880 assert((i
>=0)&&(j
<n()));
882 for(int a
=0; a
<m(); a
++)
883 A
[a
].do_del_col(i
, j
);
885 nn
= nn
- (j
- i
+ 1);
888 void integer_matrix::do_insert_col(int i
)
890 assert((i
>=0)&&(i
<=n()));
892 for(int a
=0; a
<m(); a
++)
893 A
[a
].do_insert_col(i
);
897 void integer_matrix::do_del_columns(const integer_row
& mask
)
901 assert(mask
.n() == n());
903 for(j
=0; j
<mask
.n(); j
++)
904 if(!mask
.c(j
)) cnt
++;
907 A
[j
].do_del_columns(mask
);
911 void integer_matrix::do_swap_col(int i
, int j
)
913 assert((i
>=0)&&(i
<n()));
914 assert((j
>=0)&&(j
<n()));
916 for(int a
=0; a
<m(); a
++)
917 A
[a
].do_swap_col(i
, j
);
920 void integer_matrix::do_swap_row(int i
, int j
)
922 assert((i
>=0)&&(i
<m()));
923 assert((j
>=0)&&(j
<m()));
928 void integer_matrix::do_add_rows(int rws
)
932 if (newmm
> realmm
) {
933 integer_row
*A1
= alloc_rows(MAX(newmm
,mm
*2));
934 for (i
=0; i
<mm
; i
++) {
940 for (i
=mm
; i
<newmm
; i
++) {
946 /********************************************************************************
948 ********************************************************************************/
949 integer_matrix
integer_matrix::del_row(int i
, int j
) const
952 assert((i
>=0)&&(j
<m()));
953 integer_matrix
ret(m() - (j
- i
+ 1), n());
957 for(a
= 0; a
< i
; a
++)
960 for(a
= j
+1; a
< m(); a
++)
963 assert(cnt
== ret
.m());
968 void integer_matrix::do_del_row(int i
, int j
)
971 assert((i
>=0)&&(j
<m()));
975 for (dst
=i
, src
=j
+1; src
< m(); dst
++, src
++)
978 mm
= m() - (j
- i
+ 1);
981 void integer_matrix::do_del_rows(const integer_row
& mask
)
984 assert(mask
.n() == m());
987 while (dst
< m() && !mask
.R
[dst
])
1002 void integer_matrix::do_rowadd(int rto
, int radd
, int mul
)
1004 assert((radd
>=0)&&(radd
<m()));
1005 assert((rto
>=0)&&(rto
<m()));
1006 A
[rto
].do_addmul(A
[radd
],mul
);
1009 void integer_matrix::do_coladd(int cto
, int cadd
, int mul
)
1011 assert((cto
>=0)&&(cto
<n()));
1012 assert((cadd
>=0)&&(cadd
<n()));
1014 for (int i
=0; i
<m(); i
++)
1015 A
[i
][cto
] += A
[i
][cadd
];
1017 for (int i
=0; i
<m(); i
++)
1018 A
[i
][cto
] += A
[i
][cadd
] * mul
;
1023 /********************************************************************************
1025 ********************************************************************************/
1026 void integer_matrix::print(FILE *fp
, int flag
) const
1028 for (int i
=0; i
<mm
; i
++) {
1029 if(flag
== 1) fprintf(fp
,"%2d: ", i
);
1030 for (int j
=0; j
<nn
; j
++) {
1031 fprintf(fp
," %6d",r(i
).c(j
));
1039 void integer_matrix::check() const
1042 if((n() == 0)||(m() == 0)) return;
1046 for(int i
=0; i
<m(); i
++) {
1047 assert(A
[i
].n() == n());
1054 integer_matrix
integer_matrix::operator+(const integer_matrix
& a
) const
1059 integer_matrix
res(mm
, nn
);
1061 for(int i
=0; i
<m(); i
++)
1062 res
.A
[i
] = A
[i
] + a
.A
[i
];
1068 integer_matrix
integer_matrix::operator-(const integer_matrix
& a
) const
1073 integer_matrix
res(mm
, nn
);
1075 for(int i
=0; i
<m(); i
++)
1076 res
.A
[i
] = A
[i
] - a
.A
[i
];
1082 integer_matrix
integer_matrix::operator*(const integer_matrix
& a
) const
1087 integer_matrix
res(mm
, a
.nn
);
1089 for(int i
=0; i
<m(); i
++)
1090 for(int j
=0; j
<a
.n(); j
++) {
1092 for(int k
=0; k
<n(); k
++)
1093 acc
+= r(i
).c(k
) * a
.r(k
).c(j
);
1102 integer_matrix
integer_matrix::operator*(int val
) const
1104 integer_matrix
res(this);
1106 for(int i
=0; i
<res
.m(); i
++)
1107 for(int j
=0; j
<res
.n(); j
++) {
1114 integer_matrix
integer_matrix::operator/(int val
) const
1116 integer_matrix
res(this);
1118 for(int i
=0; i
<res
.m(); i
++)
1119 for(int j
=0; j
<res
.n(); j
++) {
1126 integer_matrix
integer_matrix::operator+(int val
) const
1128 integer_matrix
res(this);
1130 for(int i
=0; i
<res
.m(); i
++)
1131 for(int j
=0; j
<res
.n(); j
++) {
1138 integer_matrix
integer_matrix::operator-(int val
) const
1140 integer_matrix
res(this);
1142 for(int i
=0; i
<res
.m(); i
++)
1143 for(int j
=0; j
<res
.n(); j
++) {
1150 integer_matrix
& integer_matrix::operator+=(const integer_matrix
& in
)
1152 assert(m() == in
.m());
1153 assert(n() == in
.n());
1155 for(int i
=0; i
<m(); i
++)
1156 for(int j
=0; j
<n(); j
++)
1157 (*this)[i
][j
] += in
.r(i
).c(j
);
1162 integer_matrix
& integer_matrix::operator-=(const integer_matrix
& in
)
1164 assert(m() == in
.m());
1165 assert(n() == in
.n());
1167 for(int i
=0; i
<m(); i
++)
1168 for(int j
=0; j
<n(); j
++)
1169 (*this)[i
][j
] -= in
.r(i
).c(j
);
1174 integer_matrix
& integer_matrix::operator+=(int x
)
1176 for(int i
=0; i
<m(); i
++)
1177 for(int j
=0; j
<n(); j
++)
1182 integer_matrix
& integer_matrix::operator-=(int x
)
1184 for(int i
=0; i
<m(); i
++)
1185 for(int j
=0; j
<n(); j
++)
1190 integer_matrix
& integer_matrix::operator*=(int x
)
1192 for(int i
=0; i
<m(); i
++)
1193 for(int j
=0; j
<n(); j
++)
1198 integer_matrix
& integer_matrix::operator/=(int x
)
1200 for(int i
=0; i
<m(); i
++)
1201 for(int j
=0; j
<n(); j
++)
1206 integer_matrix
integer_matrix::transpose() const
1208 integer_matrix
res(nn
, mm
);
1210 for(int i
=0; i
<m(); i
++)
1211 for(int j
=0; j
<n(); j
++)
1212 res
.A
[j
][i
] = A
[i
][j
];
1217 int integer_matrix::determinant() const
1221 if(n() == 1) return A
[0][0];
1223 integer_matrix rdel
;
1224 rdel
= this->del_row(0);
1227 for(int sign
=1, i
=0; i
<n();i
++, sign
*= -1)
1228 ret
+= sign
*A
[0][i
]*rdel
.del_col(i
).determinant();
1238 integer_matrix
integer_matrix::inverse(int * det
) const
1241 integer_matrix
curr(this);
1244 res
.ident(curr
.m());
1248 for(i
=0; i
<m(); i
++) {
1249 if(curr
[i
][i
] == 0) {
1250 for(int j
=i
+1; j
<m(); j
++)
1251 if(curr
[j
][i
] != 0) {
1252 curr
.do_swap_row(i
,j
);
1253 res
.do_swap_row(i
,j
);
1258 for(int j
=0; j
<m(); j
++) {
1259 if((i
!= j
)&&(curr
[j
][i
])){
1260 int g
= gcd(ABS(curr
[i
][i
]), ABS(curr
[j
][i
]));
1261 curr
[j
] *= ABS(curr
[i
][i
])/g
;
1262 res
[j
] *= ABS(curr
[i
][i
])/g
;
1264 int mul
= -curr
[j
][i
]/curr
[i
][i
];
1265 curr
.do_rowadd(j
, i
, mul
);
1266 res
.do_rowadd(j
, i
, mul
);
1274 for(i
=0; i
<m(); i
++) {
1275 l
= lcm(l
, ABS(curr
[i
][i
]));
1277 fprintf(stderr
, "Error lcm getting too large\n");
1278 this->print(stderr
);
1285 for(i
=0; i
<m(); i
++) {
1286 int norm
= curr
[i
][i
];
1291 for(i
=0; i
<m(); i
++) {
1292 int norm
= curr
[i
][i
];
1301 void integer_matrix::ident(int v
)
1305 for(int i
=0; i
<m(); i
++) {
1312 integer_matrix
integer_matrix::resize_offset(int r1
, int r2
, int c1
, int c2
,
1316 assert(mm
-r1
+r2
>=0);
1317 assert(nn
-c1
+c2
>=0);
1319 // if((mm-r1+r2 ==0)||(nn-c1+c2 ==0)) {
1320 // integer_matrix res;
1324 integer_matrix
res(mm
-r1
+r2
, nn
-c1
+c2
);
1327 for(i
=0; i
<res
.m(); i
++) res
.A
[i
] = fill
;
1329 for(i
=MAX(0,r1
); i
< mm
+MIN(0,r2
); i
++)
1330 for(int j
=MAX(0,c1
); j
< nn
+MIN(0,c2
); j
++)
1331 res
.A
[i
-r1
][j
-c1
] = A
[i
][j
];
1337 integer_matrix
integer_matrix::r_merge(const integer_matrix
& a1
,
1338 const integer_matrix
& a2
) const
1340 assert(a1
.n() == a2
.n());
1341 integer_matrix
res(a1
.m()+a2
.m(),0);
1343 for (i
=0; i
<a1
.m(); i
++)
1345 for (j
=0; j
<a2
.m(); j
++,i
++)
1351 integer_matrix
integer_matrix::c_merge(const integer_matrix
& a1
,
1352 const integer_matrix
& a2
) const
1354 assert(a1
.m() == a2
.m());
1355 integer_matrix
res(a1
.m(),a1
.n()+a2
.n());
1357 int off1
= a1
.n()*sizeof(int);
1358 int off2
= a2
.n()*sizeof(int);
1359 for (int i
=0; i
<a1
.m(); i
++) {
1360 memcpy(res
.A
[i
].R
, a1
.A
[i
].R
, off1
);
1361 memcpy(res
.A
[i
].R
+a1
.n(), a2
.A
[i
].R
, off2
);
1368 // Permutation matricies
1370 integer_matrix
doswitch(int i
, int x1
, int x2
)
1383 integer_matrix
rowswitch(const integer_matrix
& A
, int r1
, int r2
)
1385 assert((r1
>=0)&&(r1
<A
.m()));
1386 assert((r2
>=0)&&(r2
<A
.m()));
1388 return doswitch(A
.m(), r1
, r2
);
1392 integer_matrix
colswitch(const integer_matrix
& A
, int c1
, int c2
)
1394 assert((c1
>=0)&&(c1
<A
.n()));
1395 assert((c2
>=0)&&(c2
<A
.n()));
1397 return doswitch(A
.n(), c1
, c2
);
1400 integer_matrix
doadd(int i
, int r
, int c
, int val
)
1412 integer_matrix
rowadd(const integer_matrix
& A
, int r1
, int r2
, int val
)
1414 assert((r1
>=0)&&(r1
<A
.m()));
1415 assert((r2
>=0)&&(r2
<A
.m()));
1417 return doadd(A
.m(), r1
, r2
, val
);
1420 integer_matrix
coladd(const integer_matrix
& A
, int c1
, int c2
, int val
)
1422 assert((c1
>=0)&&(c1
<A
.n()));
1423 assert((c2
>=0)&&(c2
<A
.n()));
1425 return doadd(A
.n(), c2
, c1
, val
);
1428 void compose_print(int fg
)
1430 compose_print_flag
= fg
;
1433 integer_matrix
Compose(int r_comp
, int c_comp
,
1434 const integer_matrix
* m1
, const integer_matrix
* m2
,
1435 const integer_matrix
* m3
, const integer_matrix
* m4
,
1436 const integer_matrix
* m5
, const integer_matrix
* m6
,
1437 const integer_matrix
* m7
, const integer_matrix
* m8
,
1438 const integer_matrix
* m9
, const integer_matrix
* m10
,
1439 const integer_matrix
* m11
, const integer_matrix
* m12
,
1440 const integer_matrix
* m13
, const integer_matrix
* m14
,
1441 const integer_matrix
* m15
, const integer_matrix
* m16
,
1442 const integer_matrix
* m17
, const integer_matrix
* m18
,
1443 const integer_matrix
* m19
, const integer_matrix
* m20
,
1444 const integer_matrix
* m21
, const integer_matrix
* m22
,
1445 const integer_matrix
* m23
, const integer_matrix
* m24
,
1446 const integer_matrix
* m25
, const integer_matrix
* m26
,
1447 const integer_matrix
* m27
, const integer_matrix
* m28
,
1448 const integer_matrix
* m29
, const integer_matrix
* m30
,
1449 const integer_matrix
* m31
, const integer_matrix
* m32
)
1453 return R
.compose(r_comp
, c_comp
,
1454 m1
, m2
, m3
, m4
, m5
, m6
, m7
, m8
,
1455 m9
, m10
, m11
, m12
, m13
, m14
, m15
, m16
,
1456 m17
, m18
, m19
, m20
, m21
, m22
, m23
, m24
,
1457 m25
, m26
, m27
, m28
, m29
, m30
, m31
, m32
);
1460 integer_matrix
integer_matrix::compose(int r_comp
, int c_comp
,
1461 const integer_matrix
* m1
,
1462 const integer_matrix
* m2
,
1463 const integer_matrix
* m3
,
1464 const integer_matrix
* m4
,
1465 const integer_matrix
* m5
,
1466 const integer_matrix
* m6
,
1467 const integer_matrix
* m7
,
1468 const integer_matrix
* m8
,
1469 const integer_matrix
* m9
,
1470 const integer_matrix
* m10
,
1471 const integer_matrix
* m11
,
1472 const integer_matrix
* m12
,
1473 const integer_matrix
* m13
,
1474 const integer_matrix
* m14
,
1475 const integer_matrix
* m15
,
1476 const integer_matrix
* m16
,
1477 const integer_matrix
* m17
,
1478 const integer_matrix
* m18
,
1479 const integer_matrix
* m19
,
1480 const integer_matrix
* m20
,
1481 const integer_matrix
* m21
,
1482 const integer_matrix
* m22
,
1483 const integer_matrix
* m23
,
1484 const integer_matrix
* m24
,
1485 const integer_matrix
* m25
,
1486 const integer_matrix
* m26
,
1487 const integer_matrix
* m27
,
1488 const integer_matrix
* m28
,
1489 const integer_matrix
* m29
,
1490 const integer_matrix
* m30
,
1491 const integer_matrix
* m31
,
1492 const integer_matrix
* m32
) const
1496 int val
= r_comp
*c_comp
;
1498 const integer_matrix
**list
= new const integer_matrix
*[val
];
1501 if(val
>1) list
[1] = m2
;
1502 if(val
>2) list
[2] = m3
;
1503 if(val
>3) list
[3] = m4
;
1504 if(val
>4) list
[4] = m5
;
1505 if(val
>5) list
[5] = m6
;
1506 if(val
>6) list
[6] = m7
;
1507 if(val
>7) list
[7] = m8
;
1508 if(val
>8) list
[8] = m9
;
1509 if(val
>9) list
[9] = m10
;
1510 if(val
>10) list
[10] = m11
;
1511 if(val
>11) list
[11] = m12
;
1512 if(val
>12) list
[12] = m13
;
1513 if(val
>13) list
[13] = m14
;
1514 if(val
>14) list
[14] = m15
;
1515 if(val
>15) list
[15] = m16
;
1516 if(val
>16) list
[16] = m17
;
1517 if(val
>17) list
[17] = m18
;
1518 if(val
>18) list
[18] = m19
;
1519 if(val
>19) list
[19] = m20
;
1520 if(val
>20) list
[20] = m21
;
1521 if(val
>21) list
[21] = m22
;
1522 if(val
>22) list
[22] = m23
;
1523 if(val
>23) list
[23] = m24
;
1524 if(val
>24) list
[24] = m25
;
1525 if(val
>25) list
[25] = m26
;
1526 if(val
>26) list
[26] = m27
;
1527 if(val
>27) list
[27] = m28
;
1528 if(val
>28) list
[28] = m29
;
1529 if(val
>29) list
[29] = m30
;
1530 if(val
>30) list
[30] = m31
;
1531 if(val
>31) list
[31] = m32
;
1533 integer_matrix ret
= composeL(r_comp
, c_comp
, list
);
1540 // DECLARE_DLIST_CLASSES(nim_list_base, nim_e,
1541 // nim_list_iter, integer_matrix *);
1543 // class nim_list: public nim_list_base {
1548 // void nim_list::clear()
1550 // nim_list_iter iter(this);
1551 // while(!iter.is_empty()) {
1552 // integer_matrix * m = iter.step();
1558 // nim_list NIM_List;
1563 if(next
) delete next
;
1566 integer_matrix
* nim_op::NIM(const integer_matrix
& A
)
1568 nim_op
* no
= new nim_op(this);
1569 no
->m
= new integer_matrix(A
);
1573 integer_matrix
* nim_op::NIM(const integer_matrix
* A
)
1576 nim_op
* no
= new nim_op(this);
1577 no
->m
= new integer_matrix(A
);
1581 integer_matrix
* nim_op::NIM(int i
, int j
)
1583 nim_op
* no
= new nim_op(this);
1584 no
->m
= new integer_matrix(i
, j
);
1588 integer_matrix
* nim_op::NIM(int i
)
1590 nim_op
* no
= new nim_op(this);
1591 no
->m
= new integer_matrix(1, 1);
1596 integer_matrix
* NIM(const integer_matrix
& A
)
1598 integer_matrix
* m
= new integer_matrix(A
);
1603 integer_matrix
* NIM(const integer_matrix
* A
)
1606 integer_matrix
* m
= new integer_matrix(A
);
1610 integer_matrix
* NIM(int i
, int j
)
1612 integer_matrix
* m
= new integer_matrix(i
, j
);
1616 integer_matrix
* NIM(int i
)
1618 integer_matrix
* m
= new integer_matrix(1, 1);
1625 #define ELEM(i, j) list[i*c_comp+j]
1627 integer_matrix
integer_matrix::composeL(int r_comp
, int c_comp
,
1628 const integer_matrix
*const * list
,
1629 int exit_on_error
) const
1633 // int val = r_comp*c_comp;
1635 int * r_seg_sz
= new int[r_comp
];
1636 int * c_seg_sz
= new int[c_comp
];
1641 for(i
=0; i
<r_comp
; i
++) {
1643 for(j
=0; j
<c_comp
; j
++)
1644 if(ELEM(i
,j
) != 0) {
1645 if(rseg
== -1) rseg
= ELEM(i
,j
)->m();
1646 if(rseg
!= ELEM(i
,j
)->m()) {
1647 composeL_print(TRUE
, r_comp
, c_comp
, list
);
1649 error_line(1, NULL
, "Row has unmached row count: element [%d, %d] row count %d, should be %d\n", i
, j
, ELEM(i
,j
)->m(), rseg
);
1650 else return integer_matrix(0, 0);
1656 composeL_print(TRUE
, r_comp
, c_comp
, list
);
1658 error_line(1, NULL
, "Row %d has no row count\n", i
);
1659 else return integer_matrix(0, 0);
1666 for(j
=0; j
<c_comp
; j
++) {
1668 for(i
=0; i
<r_comp
; i
++)
1669 if(ELEM(i
,j
) != 0) {
1670 if(cseg
== -1) cseg
= ELEM(i
,j
)->n();
1671 if(cseg
!= ELEM(i
, j
)->n()) {
1672 composeL_print(TRUE
, r_comp
, c_comp
, list
);
1674 error_line(1, NULL
,"Column has unmatched column count: element [%d, %d] column count %d, should be %d\n", i
, j
, ELEM(i
,j
)->n(), cseg
);
1675 else return integer_matrix(0, 0);
1679 composeL_print(TRUE
, r_comp
, c_comp
, list
);
1681 error_line(1, NULL
, "Column %d has no column count \n", j
);
1682 else return integer_matrix(0, 0);
1688 integer_matrix
ret(rsz
, csz
);
1691 for(i
=0; i
<r_comp
; i
++) {
1693 for(j
=0; j
<c_comp
; j
++) {
1694 const integer_matrix
* M
;
1695 if((M
= ELEM(i
, j
)) != 0) {
1696 for(int ii
= 0; ii
< r_seg_sz
[i
]; ii
++)
1697 for(int jj
= 0; jj
< c_seg_sz
[j
]; jj
++)
1698 ret
[ii
+rorg
][jj
+corg
] = M
->r(ii
).c(jj
);
1700 corg
+= c_seg_sz
[j
];
1702 rorg
+= r_seg_sz
[i
];
1709 if(compose_print_flag
)
1710 composeL_print(FALSE
, r_comp
, c_comp
, list
);
1714 void integer_matrix::composeL_print(int er
, int r_comp
, int c_comp
,
1715 const integer_matrix
*const * list
) const
1719 if(er
) fprintf(stderr
, "Composing error:\n");
1720 for(i
=0; i
< r_comp
; i
++) {
1721 for(j
=0; j
< c_comp
; j
++)
1723 fprintf(stderr
, " ----- ");
1725 fprintf(stderr
, "[%2dx%2d] ", ELEM(i
,j
)->m(), ELEM(i
,j
)->n());
1726 fprintf(stderr
, "\n");
1728 fprintf(stderr
, "\n");
1732 int integer_matrix::init(const immed_list
& ilist
, int c
)
1734 int xm
= ilist
[c
++].integer();
1735 int xn
= ilist
[c
++].integer();
1737 for(int i
=0; i
<m(); i
++)
1738 for(int j
=0; j
<n(); j
++)
1739 (*this)[i
][j
] = ilist
[c
++].integer();
1745 immed_list
* integer_matrix::cvt_immed_list() const
1747 immed_list
* il
= new immed_list
;
1748 il
->append(immed(m()));
1749 il
->append(immed(n()));
1750 for(int i
=0; i
<m(); i
++)
1751 for(int j
=0; j
<n(); j
++)
1752 il
->append(immed(r(i
).c(j
)));
1757 integer_matrix
Compose(int r_comp
, int c_comp
,
1758 int a1
, int a2
, int a3
, int a4
, int a5
, int a6
,
1759 int a7
, int a8
, int a9
, int a10
, int a11
, int a12
,
1760 int a13
, int a14
, int a15
, int a16
, int a17
, int a18
,
1761 int a19
, int a20
, int a21
, int a22
, int a23
, int a24
,
1762 int a25
, int a26
, int a27
, int a28
, int a29
, int a30
,
1763 int a31
, int a32
, int a33
, int a34
, int a35
, int a36
,
1764 int a37
, int a38
, int a39
, int a40
, int a41
, int a42
,
1765 int a43
, int a44
, int a45
, int a46
, int a47
, int a48
,
1766 int a49
, int a50
, int a51
, int a52
, int a53
, int a54
,
1767 int a55
, int a56
, int a57
, int a58
, int a59
, int a60
)
1832 assert(r_comp
*c_comp
<= 60);
1833 integer_matrix
M(r_comp
, c_comp
);
1835 for(int i
=0; i
<r_comp
; i
++)
1836 for(int j
=0; j
<c_comp
; j
++)