2 4ti2 -- A software package for algebraic, geometric and combinatorial
3 problems on linear spaces.
5 Copyright (C) 2006 4ti2 team.
6 Main author(s): Matthias Walter.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 VectorArray
generateLattice(LinearSystem system
)
35 int currentindex
, bestindex
, currentvalue
, bestvalue
;
44 assert(normVector(system
->b
, system
->Equations
)==0);
46 n
= system
->Variables
;
47 e
= system
->Equations
;
49 array
= createVectorArray(n
);
51 array
->Properties
[i
] = system
->VarProperties
[i
];
54 H
= createMatrix(n
, e
);
57 H
->Data
[i
+n
*j
] = system
->A
[i
][j
];
59 // search for columns with norm 1 and use them to row-echelonize to lower right
61 for (i
=n
-1; i
>=0; i
--)
64 for (j
=0; j
<identities
; j
++)
65 if (H
->Data
[i
+(j
+e
-identities
)*n
]!=0)
70 for (j
=0; j
<e
-identities
; j
++)
72 if (k
==-1 && abs(H
->Data
[i
+j
*n
])==1)
74 else if (H
->Data
[i
+j
*n
]!=0)
82 swapMatrixRows(H
, k
, e
-identities
-1);
83 swapVariableProperties(array
->Properties
, i
, n
-identities
-1);
84 swapMatrixColumns(H
, i
, n
-identities
-1);
89 // copy H for later usage
98 I
= createIdentityMatrix(n
);
100 // hermite the matrix H[identities .. n-1][identities .. e-1]
102 for (i
=0; i
<minm(n
,e
); i
++)
104 // find gcd-minimal row
107 for (currentindex
=i
; currentindex
<e
; currentindex
++)
109 currentvalue
= gcdVector(H
->Data
+i
+H
->Width
*currentindex
, n
-i
);
110 if (currentvalue
!=0 && (bestvalue
==0 || currentvalue
<bestvalue
))
112 bestvalue
= currentvalue
;
113 bestindex
= currentindex
;
120 // swap this with i-th
121 swapMatrixRows(H
, bestindex
, i
);
128 for (currentindex
=i
; currentindex
<n
; currentindex
++)
130 currentvalue
= abs(H
->Data
[currentindex
+H
->Width
*i
]);
131 if (currentvalue
!=0 && (bestvalue
<=0 || currentvalue
<bestvalue
))
133 bestindex
= currentindex
;
134 bestvalue
= currentvalue
;
137 assert(bestvalue
!=0);
139 // if negative, change sign of column
140 if (H
->Data
[bestindex
+H
->Width
*i
]<0)
142 negateMatrixColumn(H
, bestindex
);
143 negateMatrixColumn(I
, bestindex
);
152 factor
= H
->Data
[j
+H
->Width
*i
] / -bestvalue
;
153 if (H
->Data
[j
+H
->Width
*i
] % bestvalue
!= 0 && j
>i
)
155 combineMatrixColumns(H
, j
, factor
, bestindex
);
156 combineMatrixColumns(I
, j
, factor
, bestindex
);
163 swapMatrixColumns(H
, i
, bestindex
);
164 swapMatrixColumns(I
, i
, bestindex
);
170 vec
= createVector(H
->Width
);
173 vec
[j
] = I
->Data
[i
+j
*n
];
174 // fill identity part from system
175 for (j
=0; j
<identities
; j
++)
179 factor
-= vec
[k
]*C
->Data
[C
->Width
*(e
+j
)+k
];
180 vec
[n
+j
] = factor
*H
->Data
[H
->Width
*(e
+j
)+n
+j
];
182 appendToVectorArray(array
, vec
);