Annotation of OpenXM/src/Ti/Ihermite.c, Revision 1.1.1.1
1.1 maekawa 1: /*
2: ** Ihermite.c Birk Huber, 2/99
3: ** -- compute hermite normal form of an integer matrix
4: **
5: **
6: ** TiGERS, Toric Groebner Basis Enumeration by Reverse Search
7: ** copyright (c) 1999 Birk Huber
8: **
9: */
10: #include<stdio.h>
11: #include<stdlib.h>
12: #include "utils.h"
13:
14:
15: /*
16: **
17: ** Imatrix_hermite:
18: ** Input: S an n by m Imatrix.
19: ** Output: True
20: **
21: ** Sidefects: U points to a unitary nxn matrix
22: ** S gets replaced by its hermite normal form (U*S)
23: **
24: ** Method:
25: ** U = Inxn
26: ** c = 1
27: ** while (c<=n) do
28: ** find mc>=c such that abs(S(mc,c)) has minimum non-zero value
29: ** if (mc!=c) then switch rows mc and c (in S, and U)
30: ** if (S(c,c)<0) then multiply row c by -1
31: ** if (S(c,c)!=0) then
32: ** for i in c+1:n add S(i,c)/S(c,c) times row c to row i;
33: ** end(if)
34: ** if S(i,c)==0 for all i in c+1 ... n set c=c+1
35: ** end(while)
36: **
37: */
38: #define Mref(U,i,j) U[(i)-1][(j)-1]
39: #define Mrows(U) m
40: #define Mcols(U) n
41:
42:
43:
44: int ihermite(int **S,int **U,int m, int n){
45: int c=1,mc,i,j,done,sign;
46: int t=0,mv=0, mn,crk=0;
47:
48: if (m>n) mn=n; else mn=m;
49:
50: /* Initialize U to nxn identity */
51: for(i=1;i<=n;i++){
52: for(j=1;j<=n;j++){
53: if (i==j) Mref(U,i,j)=1;
54: else Mref(U,i,j)=0;
55: }
56: }
57:
58: while(c<=mn){
59: /* find minimum entry in col c */
60: mv=Mref(S,c,c);
61: if (mv<0) mv*=-1;
62: mc=c;
63: for(i=c+1;i<=n;i++){
64: t=Mref(S,i,c);
65: if (t<0) t*=-1;
66: if(mv==0 || (mv>t && t!=0)){
67: mv=t;
68: mc=i;
69: }
70: }
71:
72: /* if nescesary pivot to put min in row c and multiply by+-1
73: to ensure diagonal entry is positive */
74: if (mc!=c||Mref(S,mc,c)<0){
75: if (Mref(S,mc,c)<0) sign=-1;
76: else sign=+1;
77: for(j=c;j<=m;j++){
78: t=Mref(S,mc,j);
79: Mref(S,mc,j)=Mref(S,c,j);
80: Mref(S,c,j)=sign*t;
81: }
82: for(j=1;j<=n;j++){
83: t=Mref(U,mc,j);
84: Mref(U,mc,j)=Mref(U,c,j);
85: Mref(U,c,j)=sign*t;
86: }
87: }
88:
89: /* if collumb is not zero do a reduction step */
90: done=TRUE;
91: if (Mref(S,c,c)!=0){
92: crk=c;
93: for(i=c+1;i<=n;i++){
94: t=Mref(S,i,c)/Mref(S,c,c);
95: for(j=c;j<=m;j++){
96: Mref(S,i,j)-=t*Mref(S,c,j);
97: }
98: for(j=1;j<=n;j++){
99: Mref(U,i,j)-=t*Mref(U,c,j);
100: }
101: if (Mref(S,i,c)!=0) done=FALSE;
102: }
103: }
104: /* if all entrees of col c bellow row c are zero go tonext col */
105: if (done==TRUE) c++;
106: }
107: return crk;
108: }
109:
110:
111:
112:
113:
114:
115:
116:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>