1 /* file "fract_matrix.cc" */
3 /* Copyright (c) 1994,95 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 #pragma implementation "fract_matrix.h"
14 #define RCS_BASE_FILE fract_matrix_cc
16 #include "fract_matrix.h"
19 RCS_BASE("$Id: fract_matrix.cc,v 1.1.1.1 1998/07/07 05:09:27 brm Exp $")
22 * Private member functions
25 void fract_matrix::create_columns()
27 col_list
= new fract_vector
[cols
];
29 for (int i
= 0; i
< cols
; i
++) {
30 col_list
[i
] = fract_vector(rows
);
35 void fract_matrix::copy_fract_matrix(const fract_matrix
&mat
)
37 assert(rows
== mat
.m() && cols
== mat
.n());
39 for (int j
= 0; j
< cols
; j
++) {
40 col_list
[j
] = mat
.col_list
[j
];
44 void fract_matrix::copy_int_matrix(const integer_matrix
&mat
)
46 assert(rows
== mat
.m() && cols
== mat
.n());
48 for (int j
= 0; j
< cols
; j
++)
49 for (int i
= 0; i
< rows
; i
++) {
50 elt(i
,j
) = mat
.r(i
).c(j
);
56 * Public member functions
63 fract_matrix::fract_matrix()
70 fract_matrix::fract_matrix(int r
, int c
)
72 assert(r
>= 0 && c
>= 0);
79 fract_matrix::fract_matrix(const integer_matrix
&mat
)
81 assert(mat
.m() >= 0 && mat
.n() >= 0);
89 fract_matrix::fract_matrix(const integer_matrix
&mat
, int div
)
91 assert(mat
.m() >= 0 && mat
.n() >= 0);
101 fract_matrix::fract_matrix(const fract_matrix
&mat
)
106 copy_fract_matrix(mat
);
109 fract_matrix::fract_matrix(const fract_matrix
&mat
, int c
)
116 col_list
= new fract_vector
[cols
];
118 if (cols
<= mat
.cols
) {
119 for (int i
= 0; i
< cols
; i
++) col_list
[i
] = mat
.col_list
[i
];
123 for (i
= 0; i
< mat
.cols
; i
++) col_list
[i
] = mat
.col_list
[i
];
124 for (i
= mat
.cols
; i
< cols
; i
++) col_list
[i
] = fract_vector(rows
);
129 // Equality and assignment operators:
132 boolean
fract_matrix::operator==(const fract_matrix
&mat
) const
134 if ((rows
!= mat
.rows
) || (cols
!= mat
.cols
)) return FALSE
;
136 for (int i
= 0; i
< cols
; i
++) {
137 if (mat
.col_list
[i
] != col_list
[i
]) return FALSE
;
143 fract_matrix
& fract_matrix::operator=(const fract_matrix
&mat
)
145 if (&mat
== this) return *this;
147 if ((rows
!= mat
.rows
) || (cols
!= mat
.cols
)) {
154 copy_fract_matrix(mat
);
160 // Matrix-Matrix operations:
163 fract_matrix
fract_matrix::operator*(const fract_matrix
&mat
) const
165 assert(cols
== mat
.rows
);
167 fract_matrix
result(rows
, mat
.cols
);
169 for (int i
= 0; i
< rows
; i
++) {
170 for (int j
= 0; j
< mat
.cols
; j
++) {
171 fract temp
= fract(0);
172 for (int k
= 0; k
< cols
; k
++) {
173 temp
+= rc(i
,k
) * mat
.rc(k
,j
);
175 result
.elt(i
,j
) = temp
;
182 fract_matrix
fract_matrix::operator+(const fract_matrix
&mat
) const
184 fract_matrix result
= *this;
190 fract_matrix
fract_matrix::operator-(const fract_matrix
&mat
) const
192 fract_matrix result
= *this;
198 fract_matrix
& fract_matrix::operator+=(const fract_matrix
&mat
)
200 assert(rows
== mat
.rows
);
201 assert(cols
== mat
.cols
);
203 for (int j
= 0; j
< cols
; j
++)
204 for (int i
= 0; i
< rows
; i
++)
205 elt(i
,j
) += mat
.rc(i
,j
);
210 fract_matrix
& fract_matrix::operator-=(const fract_matrix
&mat
)
212 assert(rows
== mat
.rows
);
213 assert(cols
== mat
.cols
);
215 for (int j
= 0; j
< cols
; j
++)
216 for (int i
= 0; i
< rows
; i
++)
217 elt(i
,j
) -= mat
.rc(i
,j
);
223 // Element-wise operations:
226 fract_matrix
fract_matrix::operator*(fract val
) const
228 fract_matrix result
= *this;
234 fract_matrix
fract_matrix::operator/(fract val
) const
236 fract_matrix result
= *this;
242 fract_matrix
fract_matrix::operator+(fract val
) const
244 fract_matrix result
= *this;
250 fract_matrix
fract_matrix::operator-(fract val
) const
252 fract_matrix result
= *this;
258 fract_matrix
&fract_matrix::operator+=(fract val
)
260 for (int j
= 0; j
< cols
; j
++)
261 for (int i
= 0; i
< rows
; i
++)
267 fract_matrix
&fract_matrix::operator-=(fract val
)
269 for (int j
= 0; j
< cols
; j
++)
270 for (int i
= 0; i
< rows
; i
++)
276 fract_matrix
&fract_matrix::operator*=(fract val
)
278 for (int j
= 0; j
< cols
; j
++)
279 for (int i
= 0; i
< rows
; i
++)
285 fract_matrix
&fract_matrix::operator/=(fract val
)
287 for (int j
= 0; j
< cols
; j
++)
288 for (int i
= 0; i
< rows
; i
++)
298 fract_vector
fract_matrix::operator*(const fract_vector
&vec
) const
300 fract_vector
result(rows
);
301 assert(cols
== vec
.n());
303 for (int i
= 0; i
< rows
; i
++) {
305 for (int j
= 0; j
< cols
; j
++) {
306 f
+= rc(i
,j
) * vec
.c(j
);
315 // Other useful functions:
317 void fract_matrix::ident(int n
)
319 if ((rows
!= n
) || (cols
!= n
)) {
326 for (int j
= 0; j
< cols
; j
++) {
331 fract_matrix
fract_matrix::transpose() const
333 fract_matrix
result(cols
, rows
);
335 for (int j
= 0; j
< cols
; j
++)
336 for (int i
= 0; i
< rows
; i
++)
337 result
.elt(j
,i
) = rc(i
,j
);
342 fract_matrix
fract_matrix::operator%(const integer_row
&rw
) const
344 fract_matrix
result(rows
, cols
);
346 for (int j
= 0; j
< cols
; j
++) {
347 result
.col_list
[j
] = col_list
[j
] % rw
;
353 fract_matrix
fract_matrix::del_row(int i
, int j
) const
356 assert((i
>= 0) && (j
< rows
));
358 fract_matrix
result(rows
- (j
- i
+ 1), cols
);
360 for (int k
= 0; k
< cols
; k
++)
361 result
.col_list
[k
] = col_list
[k
].del_pos(i
, j
);
367 fract_matrix
fract_matrix::del_col(int i
, int j
) const
370 assert((i
>= 0) && (j
< cols
));
372 fract_matrix
result(rows
, cols
- (j
- i
+ 1));
376 for (k
= 0; k
< i
; k
++)
377 result
.col_list
[count
++] = col_list
[k
];
379 for (k
= j
+1; k
< cols
; k
++)
380 result
.col_list
[count
++] = col_list
[k
];
382 assert(count
== result
.cols
);
387 fract_matrix
fract_matrix::del_columns(const integer_row
&rw
) const
389 assert(rw
.n() == cols
);
393 for (int i
= 0; i
< cols
; i
++) {
394 if (rw
.c(i
)) col_count
++;
397 fract_matrix
result(rows
, col_count
);
400 for (int j
= 0; j
< cols
; j
++)
401 if (rw
.c(j
)) result
.col_list
[count
++] = col_list
[j
];
403 assert(count
== result
.cols
);
407 fract_matrix
fract_matrix::insert_col(int i
) const
409 assert(i
>= 0 && i
<= cols
);
410 fract_matrix
result(rows
, cols
+1);
414 for (j
= 0; j
< i
; j
++)
415 result
.col_list
[count
++] = col_list
[j
];
417 result
.col_list
[count
++] = fract_vector(rows
);
419 for (j
= i
+1; j
< cols
; j
++)
420 result
.col_list
[count
++] = col_list
[j
];
422 assert(count
== result
.cols
);
426 fract_matrix
fract_matrix::swap_col(int i
, int j
) const
428 assert(i
>= 0 && i
< cols
);
429 assert(j
>= 0 && j
< cols
);
430 fract_matrix result
= *this;
432 result
.col_list
[i
] = col_list
[j
];
433 result
.col_list
[j
] = col_list
[i
];
438 fract_matrix
fract_matrix::swap_row(int i
, int j
) const
440 assert(i
>= 0 && i
< rows
);
441 assert(j
>= 0 && j
< rows
);
442 fract_matrix
result(rows
, cols
);
444 for(int k
= 0; k
< cols
; k
++)
445 result
.col_list
[j
] = col_list
[j
].swap_pos(i
, j
);
451 fract_vector
fract_matrix::get_row(int i
) const
453 assert(i
>= 0 && i
< rows
);
454 fract_vector
the_row(cols
);
456 for (int j
= 0; j
< cols
; j
++) {
457 the_row
[j
] = rc(i
,j
);
464 fract_vector
fract_matrix::get_col(int i
) const
466 assert(i
>= 0 && i
< cols
);
471 void fract_matrix::set_col(int i
, const fract_vector
&vec
)
473 assert(i
>= 0 && i
< cols
);
474 assert(vec
.n() == rows
);
480 void fract_matrix::set_row(int i
, const fract_vector
&vec
)
482 assert(i
>= 0 && i
< rows
);
483 assert(vec
.n() == cols
);
485 for (int j
= 0; j
< cols
; j
++) {
491 fract_matrix
fract_matrix::resize_offset(int r1
, int r2
, int c1
, int c2
,
494 assert(rows
-r1
+r2
>=0);
495 assert(cols
-c1
+c2
>=0);
497 fract_matrix
result(rows
-r1
+r2
, cols
-c1
+c2
);
500 for (j
= 0; j
< result
.cols
; j
++) result
.col_list
[j
] = fill
;
502 for (j
= MAX(0,c1
); j
< cols
+MIN(0,c2
); j
++)
503 for (int i
= MAX(0,r1
); i
< rows
+MIN(0,r2
); i
++)
504 result
.elt(i
-r1
,j
-c1
) = rc(i
,j
);
509 fract_matrix
fract_matrix::r_merge(const fract_matrix
&mat
) const
511 assert(cols
== mat
.cols
);
513 return (resize_offset(0, mat
.rows
, 0, 0) +
514 mat
.resize_offset(-rows
, 0, 0, 0));
518 fract_matrix
fract_matrix::c_merge(const fract_matrix
&mat
) const
520 assert(rows
== mat
.rows
);
522 return (resize_offset(0, 0, 0, mat
.cols
) +
523 mat
.resize_offset(0, 0, -cols
, 0));
526 immed_list
*fract_matrix::cvt_immed_list() const
528 immed_list
*il
= new immed_list
;
530 il
->append(immed("rows"));
531 il
->append(immed(rows
));
532 il
->append(immed("cols"));
533 il
->append(immed(cols
));
535 // Find lcm of denoms
537 for (int j
= 0; j
< cols
; j
++) {
538 for (int i
= 0; i
< rows
; i
++) {
539 curr_lcm
= lcm(curr_lcm
, rc(i
,j
).denom());
544 il
->append(immed("divisor"));
545 il
->append(immed(curr_lcm
));
548 il
->append(immed("matrix"));
549 for (int i
= 0; i
< rows
; i
++) {
550 for (int j
= 0; j
< cols
; j
++) {
551 fract temp
= rc(i
,j
);
552 temp
*= curr_lcm
; // fract "*=" operator reduces fraction
553 assert(temp
.denom() == 1);
554 il
->append(immed(temp
.num()));
561 fract_matrix
cvt_fract_matrix(immed_list
*il
)
563 assert(il
->count() >= 5); // at least: "rows" #rows "cols" #cols "matrix"
565 immed temp
= il
->pop();
566 assert(temp
.is_string() && !strcmp(temp
.string(), "rows"));
570 assert(temp
.is_string() && !strcmp(temp
.string(), "cols"));
573 assert(r
.is_integer() && c
.is_integer());
575 fract_matrix
result(r
.integer(), c
.integer());
577 assert(temp
.is_string());
579 // Grab divisor, if any
582 if (!strcmp(temp
.string(), "divisor")) {
583 assert(il
->count() >= 2);
584 immed div
= il
->pop();
585 assert(div
.is_integer());
586 divisor
= div
.integer();
588 assert(temp
.is_string());
591 assert(!strcmp(temp
.string(), "matrix"));
592 assert(il
->count() >= result
.rows
* result
.cols
);
594 for (int i
= 0; i
< result
.rows
; i
++) {
595 for (int j
= 0; j
< result
.cols
; j
++) {
596 immed val
= il
->pop();
597 assert(val
.is_integer());
598 result
.elt(i
,j
) = fract(val
.integer(), divisor
);
605 void fract_matrix::print(FILE *fp
) const
607 for (int i
= 0; i
< rows
; i
++) {
608 for (int j
= 0; j
< cols
; j
++) {
616 void fract_matrix::clear()