00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "ggc.h"
00026 #include "varray.h"
00027 #include "tree.h"
00028 #include "lambda.h"
00029
00030 static void lambda_matrix_get_column (lambda_matrix, int, int,
00031 lambda_vector);
00032
00033
00034
00035 lambda_matrix
00036 lambda_matrix_new (int m, int n)
00037 {
00038 lambda_matrix mat;
00039 int i;
00040
00041 mat = ggc_alloc (m * sizeof (lambda_vector));
00042
00043 for (i = 0; i < m; i++)
00044 mat[i] = lambda_vector_new (n);
00045
00046 return mat;
00047 }
00048
00049
00050
00051 void
00052 lambda_matrix_copy (lambda_matrix mat1, lambda_matrix mat2,
00053 int m, int n)
00054 {
00055 int i;
00056
00057 for (i = 0; i < m; i++)
00058 lambda_vector_copy (mat1[i], mat2[i], n);
00059 }
00060
00061
00062
00063 void
00064 lambda_matrix_id (lambda_matrix mat, int size)
00065 {
00066 int i, j;
00067
00068 for (i = 0; i < size; i++)
00069 for (j = 0; j < size; j++)
00070 mat[i][j] = (i == j) ? 1 : 0;
00071 }
00072
00073
00074
00075 bool
00076 lambda_matrix_id_p (lambda_matrix mat, int size)
00077 {
00078 int i, j;
00079 for (i = 0; i < size; i++)
00080 for (j = 0; j < size; j++)
00081 {
00082 if (i == j)
00083 {
00084 if (mat[i][j] != 1)
00085 return false;
00086 }
00087 else
00088 {
00089 if (mat[i][j] != 0)
00090 return false;
00091 }
00092 }
00093 return true;
00094 }
00095
00096
00097
00098 void
00099 lambda_matrix_negate (lambda_matrix mat1, lambda_matrix mat2, int m, int n)
00100 {
00101 int i;
00102
00103 for (i = 0; i < m; i++)
00104 lambda_vector_negate (mat1[i], mat2[i], n);
00105 }
00106
00107
00108
00109
00110 void
00111 lambda_matrix_transpose (lambda_matrix mat1, lambda_matrix mat2, int m, int n)
00112 {
00113 int i, j;
00114
00115 for (i = 0; i < n; i++)
00116 for (j = 0; j < m; j++)
00117 mat2[i][j] = mat1[j][i];
00118 }
00119
00120
00121
00122
00123 void
00124 lambda_matrix_add (lambda_matrix mat1, lambda_matrix mat2,
00125 lambda_matrix mat3, int m, int n)
00126 {
00127 int i;
00128
00129 for (i = 0; i < m; i++)
00130 lambda_vector_add (mat1[i], mat2[i], mat3[i], n);
00131 }
00132
00133
00134
00135 void
00136 lambda_matrix_add_mc (lambda_matrix mat1, int const1,
00137 lambda_matrix mat2, int const2,
00138 lambda_matrix mat3, int m, int n)
00139 {
00140 int i;
00141
00142 for (i = 0; i < m; i++)
00143 lambda_vector_add_mc (mat1[i], const1, mat2[i], const2, mat3[i], n);
00144 }
00145
00146
00147
00148
00149
00150 void
00151 lambda_matrix_mult (lambda_matrix mat1, lambda_matrix mat2,
00152 lambda_matrix mat3, int m, int r, int n)
00153 {
00154
00155 int i, j, k;
00156
00157 for (i = 0; i < m; i++)
00158 {
00159 for (j = 0; j < n; j++)
00160 {
00161 mat3[i][j] = 0;
00162 for (k = 0; k < r; k++)
00163 mat3[i][j] += mat1[i][k] * mat2[k][j];
00164 }
00165 }
00166 }
00167
00168
00169
00170
00171 static void
00172 lambda_matrix_get_column (lambda_matrix mat, int n, int col,
00173 lambda_vector vec)
00174 {
00175 int i;
00176
00177 for (i = 0; i < n; i++)
00178 vec[i] = mat[i][col];
00179 }
00180
00181
00182
00183 void
00184 lambda_matrix_delete_rows (lambda_matrix mat, int rows, int from, int to)
00185 {
00186 int i;
00187 int dist;
00188 dist = to - from;
00189
00190 for (i = to; i < rows; i++)
00191 mat[i - dist] = mat[i];
00192
00193 for (i = rows - dist; i < rows; i++)
00194 mat[i] = NULL;
00195 }
00196
00197
00198
00199 void
00200 lambda_matrix_row_exchange (lambda_matrix mat, int r1, int r2)
00201 {
00202 lambda_vector row;
00203
00204 row = mat[r1];
00205 mat[r1] = mat[r2];
00206 mat[r2] = row;
00207 }
00208
00209
00210
00211
00212 void
00213 lambda_matrix_row_add (lambda_matrix mat, int n, int r1, int r2, int const1)
00214 {
00215 int i;
00216
00217 if (const1 == 0)
00218 return;
00219
00220 for (i = 0; i < n; i++)
00221 mat[r2][i] += const1 * mat[r1][i];
00222 }
00223
00224
00225
00226 void
00227 lambda_matrix_row_negate (lambda_matrix mat, int n, int r1)
00228 {
00229 lambda_vector_negate (mat[r1], mat[r1], n);
00230 }
00231
00232
00233
00234 void
00235 lambda_matrix_row_mc (lambda_matrix mat, int n, int r1, int const1)
00236 {
00237 int i;
00238
00239 for (i = 0; i < n; i++)
00240 mat[r1][i] *= const1;
00241 }
00242
00243
00244
00245 void
00246 lambda_matrix_col_exchange (lambda_matrix mat, int m, int col1, int col2)
00247 {
00248 int i;
00249 int tmp;
00250 for (i = 0; i < m; i++)
00251 {
00252 tmp = mat[i][col1];
00253 mat[i][col1] = mat[i][col2];
00254 mat[i][col2] = tmp;
00255 }
00256 }
00257
00258
00259
00260
00261 void
00262 lambda_matrix_col_add (lambda_matrix mat, int m, int c1, int c2, int const1)
00263 {
00264 int i;
00265
00266 if (const1 == 0)
00267 return;
00268
00269 for (i = 0; i < m; i++)
00270 mat[i][c2] += const1 * mat[i][c1];
00271 }
00272
00273
00274
00275 void
00276 lambda_matrix_col_negate (lambda_matrix mat, int m, int c1)
00277 {
00278 int i;
00279
00280 for (i = 0; i < m; i++)
00281 mat[i][c1] *= -1;
00282 }
00283
00284
00285
00286 void
00287 lambda_matrix_col_mc (lambda_matrix mat, int m, int c1, int const1)
00288 {
00289 int i;
00290
00291 for (i = 0; i < m; i++)
00292 mat[i][c1] *= const1;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 static int lambda_matrix_inverse_hard (lambda_matrix, lambda_matrix, int);
00311
00312 int
00313 lambda_matrix_inverse (lambda_matrix mat, lambda_matrix inv, int n)
00314 {
00315 if (n == 2)
00316 {
00317 int a, b, c, d, det;
00318 a = mat[0][0];
00319 b = mat[1][0];
00320 c = mat[0][1];
00321 d = mat[1][1];
00322 inv[0][0] = d;
00323 inv[0][1] = -c;
00324 inv[1][0] = -b;
00325 inv[1][1] = a;
00326 det = (a * d - b * c);
00327 if (det < 0)
00328 {
00329 det *= -1;
00330 inv[0][0] *= -1;
00331 inv[1][0] *= -1;
00332 inv[0][1] *= -1;
00333 inv[1][1] *= -1;
00334 }
00335 return det;
00336 }
00337 else
00338 return lambda_matrix_inverse_hard (mat, inv, n);
00339 }
00340
00341
00342
00343 static int
00344 lambda_matrix_inverse_hard (lambda_matrix mat, lambda_matrix inv, int n)
00345 {
00346 lambda_vector row;
00347 lambda_matrix temp;
00348 int i, j;
00349 int determinant;
00350
00351 temp = lambda_matrix_new (n, n);
00352 lambda_matrix_copy (mat, temp, n, n);
00353 lambda_matrix_id (inv, n);
00354
00355
00356
00357
00358 for (j = 0; j < n; j++)
00359 {
00360 row = temp[j];
00361
00362
00363 for (i = j; i < n; i++)
00364 if (row[i] < 0)
00365 {
00366 lambda_matrix_col_negate (temp, n, i);
00367 lambda_matrix_col_negate (inv, n, i);
00368 }
00369
00370
00371
00372 while (lambda_vector_first_nz (row, n, j + 1) < n)
00373 {
00374 int min_col = lambda_vector_min_nz (row, n, j);
00375 lambda_matrix_col_exchange (temp, n, j, min_col);
00376 lambda_matrix_col_exchange (inv, n, j, min_col);
00377
00378 for (i = j + 1; i < n; i++)
00379 {
00380 int factor;
00381
00382 factor = -1 * row[i];
00383 if (row[j] != 1)
00384 factor /= row[j];
00385
00386 lambda_matrix_col_add (temp, n, j, i, factor);
00387 lambda_matrix_col_add (inv, n, j, i, factor);
00388 }
00389 }
00390 }
00391
00392
00393
00394
00395
00396 determinant = 1;
00397 for (j = n - 1; j >= 0; j--)
00398 {
00399 int diagonal;
00400
00401 row = temp[j];
00402 diagonal = row[j];
00403
00404
00405 if (diagonal == 0)
00406 abort ();
00407
00408 determinant = determinant * diagonal;
00409
00410
00411
00412
00413 if (diagonal != 1)
00414 {
00415 for (i = 0; i < j; i++)
00416 lambda_matrix_col_mc (inv, n, i, diagonal);
00417 for (i = j + 1; i < n; i++)
00418 lambda_matrix_col_mc (inv, n, i, diagonal);
00419
00420 row[j] = diagonal = 1;
00421 }
00422
00423
00424 for (i = j - 1; i >= 0; i--)
00425 {
00426 if (row[i])
00427 {
00428 int factor = -row[i];
00429 lambda_matrix_col_add (temp, n, j, i, factor);
00430 lambda_matrix_col_add (inv, n, j, i, factor);
00431 }
00432
00433 }
00434 }
00435
00436 return determinant;
00437 }
00438
00439
00440
00441
00442
00443 void
00444 lambda_matrix_hermite (lambda_matrix mat, int n,
00445 lambda_matrix H, lambda_matrix U)
00446 {
00447 lambda_vector row;
00448 int i, j, factor, minimum_col;
00449
00450 lambda_matrix_copy (mat, H, n, n);
00451 lambda_matrix_id (U, n);
00452
00453 for (j = 0; j < n; j++)
00454 {
00455 row = H[j];
00456
00457
00458 for (i = j; i < n; i++)
00459 {
00460 if (row[i] < 0)
00461 {
00462 lambda_matrix_col_negate (H, n, i);
00463 lambda_vector_negate (U[i], U[i], n);
00464 }
00465 }
00466
00467
00468 while (lambda_vector_first_nz (row, n, j + 1) < n)
00469 {
00470 minimum_col = lambda_vector_min_nz (row, n, j);
00471 lambda_matrix_col_exchange (H, n, j, minimum_col);
00472 lambda_matrix_row_exchange (U, j, minimum_col);
00473
00474 for (i = j + 1; i < n; i++)
00475 {
00476 factor = row[i] / row[j];
00477 lambda_matrix_col_add (H, n, j, i, -1 * factor);
00478 lambda_matrix_row_add (U, n, i, j, factor);
00479 }
00480 }
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 void
00492 lambda_matrix_right_hermite (lambda_matrix A, int m, int n,
00493 lambda_matrix S, lambda_matrix U)
00494 {
00495 int i, j, i0 = 0;
00496
00497 lambda_matrix_copy (A, S, m, n);
00498 lambda_matrix_id (U, m);
00499
00500 for (j = 0; j < n; j++)
00501 {
00502 if (lambda_vector_first_nz (S[j], m, i0) < m)
00503 {
00504 ++i0;
00505 for (i = m - 1; i >= i0; i--)
00506 {
00507 while (S[i][j] != 0)
00508 {
00509 int sigma, factor, a, b;
00510
00511 a = S[i-1][j];
00512 b = S[i][j];
00513 sigma = (a * b < 0) ? -1: 1;
00514 a = abs (a);
00515 b = abs (b);
00516 factor = sigma * (a / b);
00517
00518 lambda_matrix_row_add (S, n, i, i-1, -factor);
00519 lambda_matrix_row_exchange (S, i, i-1);
00520
00521 lambda_matrix_row_add (U, m, i, i-1, -factor);
00522 lambda_matrix_row_exchange (U, i, i-1);
00523 }
00524 }
00525 }
00526 }
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 void
00537 lambda_matrix_left_hermite (lambda_matrix A, int m, int n,
00538 lambda_matrix S, lambda_matrix V)
00539 {
00540 int i, j, i0 = 0;
00541
00542 lambda_matrix_copy (A, S, m, n);
00543 lambda_matrix_id (V, m);
00544
00545 for (j = 0; j < n; j++)
00546 {
00547 if (lambda_vector_first_nz (S[j], m, i0) < m)
00548 {
00549 ++i0;
00550 for (i = m - 1; i >= i0; i--)
00551 {
00552 while (S[i][j] != 0)
00553 {
00554 int sigma, factor, a, b;
00555
00556 a = S[i-1][j];
00557 b = S[i][j];
00558 sigma = (a * b < 0) ? -1: 1;
00559 a = abs (a);
00560 b = abs (b);
00561 factor = sigma * (a / b);
00562
00563 lambda_matrix_row_add (S, n, i, i-1, -factor);
00564 lambda_matrix_row_exchange (S, i, i-1);
00565
00566 lambda_matrix_col_add (V, m, i-1, i, factor);
00567 lambda_matrix_col_exchange (V, m, i, i-1);
00568 }
00569 }
00570 }
00571 }
00572 }
00573
00574
00575
00576
00577 int
00578 lambda_matrix_first_nz_vec (lambda_matrix mat, int rowsize, int colsize,
00579 int startrow)
00580 {
00581 int j;
00582 bool found = false;
00583
00584 for (j = startrow; (j < rowsize) && !found; j++)
00585 {
00586 if ((mat[j] != NULL)
00587 && (lambda_vector_first_nz (mat[j], colsize, startrow) < colsize))
00588 found = true;
00589 }
00590
00591 if (found)
00592 return j - 1;
00593 return rowsize;
00594 }
00595
00596
00597
00598 void
00599 lambda_matrix_project_to_null (lambda_matrix B, int rowsize,
00600 int colsize, int k, lambda_vector x)
00601 {
00602 lambda_matrix M1, M2, M3, I;
00603 int determinant;
00604
00605
00606
00607
00608 M1 = lambda_matrix_new (colsize, colsize);
00609 lambda_matrix_transpose (B, M1, rowsize, colsize);
00610
00611
00612 M2 = lambda_matrix_new (colsize, colsize);
00613 lambda_matrix_mult (B, M1, M2, rowsize, colsize, rowsize);
00614
00615
00616 M3 = lambda_matrix_new (colsize, colsize);
00617 determinant = lambda_matrix_inverse (M2, M3, rowsize);
00618
00619
00620 lambda_matrix_mult (M1, M3, M2, colsize, rowsize, rowsize);
00621
00622
00623 lambda_matrix_mult (M2, B, M1, colsize, rowsize, colsize);
00624 lambda_matrix_negate (M1, M1, colsize, colsize);
00625
00626 I = lambda_matrix_new (colsize, colsize);
00627 lambda_matrix_id (I, colsize);
00628
00629 lambda_matrix_add_mc (I, determinant, M1, 1, M2, colsize, colsize);
00630
00631 lambda_matrix_get_column (M2, colsize, k - 1, x);
00632
00633 }
00634
00635
00636
00637
00638
00639 void
00640 lambda_matrix_vector_mult (lambda_matrix matrix, int m, int n,
00641 lambda_vector vec, lambda_vector dest)
00642 {
00643 int i, j;
00644
00645 lambda_vector_clear (dest, m);
00646 for (i = 0; i < m; i++)
00647 for (j = 0; j < n; j++)
00648 dest[i] += matrix[i][j] * vec[j];
00649 }
00650
00651
00652
00653 void
00654 print_lambda_matrix (FILE * outfile, lambda_matrix matrix, int m, int n)
00655 {
00656 int i;
00657
00658 for (i = 0; i < m; i++)
00659 print_lambda_vector (outfile, matrix[i], n);
00660 fprintf (outfile, "\n");
00661 }
00662