polylib 7.01
Matop.c
Go to the documentation of this file.
1#include <polylib/polylib.h>
2#include <stdlib.h>
3
4/* computes c = lcm(a,b) using Gcd(a,b,&c) */
5void Lcm3(Value a, Value b, Value *c) {
6 Value tmp;
7
8 if (value_zero_p(a)) {
9 value_assign(*c, b);
10 return;
11 }
12 if (value_zero_p(b)) {
13 value_assign(*c, a);
14 return;
15 }
16 value_init(tmp);
17 value_multiply(tmp, a, b);
18 value_absolute(tmp, tmp);
19 Gcd(a, b, c);
20 value_division(*c, tmp, *c);
21 value_clear(tmp);
22}
23
24/*
25 * Return the lcm of 'i' and 'j'
26 */
28 Value *tmp;
29
30 tmp = (Value *)malloc(sizeof(Value));
31 value_init(*tmp);
32 Lcm3(i, j, tmp);
33 return tmp;
34} /* Lcm */
35
36/*
37 * Return an identity matrix of size 'size'.
38 */
39Matrix *Identity(unsigned size) {
40 unsigned i;
41 Matrix *A;
42
43 A = Matrix_Alloc(size, size);
44 for (i = 0; i < size; i++)
45 value_set_si(A->p[i][i], 1);
46 return A;
47} /* Identity */
48
49/*
50 * Exchange the rows 'Row1' and 'Row2' of the matrix 'M'
51 */
52void ExchangeRows(Matrix *M, int Row1, int Row2) {
53
54 int i;
55 Value temp;
56
57 value_init(temp);
58 for (i = 0; i < (int)M->NbColumns; i++) {
59 value_assign(temp, M->p[Row1][i]);
60 value_assign(M->p[Row1][i], M->p[Row2][i]);
61 value_assign(M->p[Row2][i], temp);
62 }
63 value_clear(temp);
64 return;
65} /* ExchangeRows */
66
67/*
68 * Exchange the columns 'Column1' and 'Column2' of the matrix 'M'
69 */
70void ExchangeColumns(Matrix *M, int Column1, int Column2) {
71
72 int i;
73
74 for (i = 0; i < M->NbRows; i++)
75 value_swap(M->p[i][Column1], M->p[i][Column2]);
76
77 return;
78} /* ExchangeColumns */
79
80/*
81 * Return the Transpose of a matrix 'A'
82 */
84
85 int i, j;
86 Matrix *transpose;
87
88 transpose = Matrix_Alloc(A->NbColumns, A->NbRows);
89 for (i = 0; i < (int)A->NbRows; i++)
90 for (j = 0; j < (int)A->NbColumns; j++)
91 value_assign(transpose->p[j][i], A->p[i][j]);
92 return transpose;
93} /* Transpose */
94
95/*
96 * Return a copy of the contents of a matrix 'Src'.
97 */
99 Matrix *Dst;
100 unsigned i, j;
101
102 Dst = Matrix_Alloc(Src->NbRows, Src->NbColumns);
103
104 for (i = 0; i < Src->NbRows; i++)
105 for (j = 0; j < Src->NbColumns; j++)
106 value_assign(Dst->p[i][j], Src->p[i][j]);
107 return Dst;
108} /* Matrix_copy */
109
110/*
111 * Test if the input matrix is integral or not.
112 */
114
115 unsigned i, j;
116 Value divisor, tmp;
117
118 value_init(divisor);
119 value_init(tmp);
120 value_assign(divisor, A->p[A->NbRows - 1][A->NbColumns - 1]);
121
122 for (i = 0; i < A->NbRows; i++)
123 for (j = 0; j < A->NbColumns; j++) {
124 value_modulus(tmp, A->p[i][j], divisor);
125 if (value_notzero_p(tmp)) {
126 value_clear(divisor);
127 value_clear(tmp);
128 return False;
129 }
130 }
131 value_clear(divisor);
132 value_clear(tmp);
133 return True;
134} /* isIntegral */
135
136
137/*
138 * Remove the row 'Rownumber' and place it at the end of the matrix 'X'
139 */
140void PutRowLast(Matrix *X, int Rownumber) {
141
142 int i, j;
143 Value temp;
144
145 if (Rownumber == X->NbRows - 1)
146 return;
147
148 value_init(temp);
149 for (j = 0; j < X->NbColumns; j++) {
150 value_assign(temp, X->p[Rownumber][j]);
151 for (i = Rownumber; i < X->NbRows - 1; i++)
152 value_assign(X->p[i][j], X->p[i + 1][j]);
153 value_assign(X->p[i][j], temp);
154 }
155 value_clear(temp);
156 return;
157} /* PutRowLast */
158
159/*
160 * Remove the row 'Rownumber' and place it at the begining of the matrix 'X'
161 */
162void PutRowFirst(Matrix *X, int Rownumber) {
163
164 int i, j;
165 Value temp;
166
167 value_init(temp);
168 for (j = 0; j < X->NbColumns; j++) {
169 value_assign(temp, X->p[Rownumber][j]);
170 for (i = Rownumber; i > 0; i--)
171 value_assign(X->p[i][j], X->p[i - 1][j]);
172 value_assign(X->p[i][j], temp);
173 }
174 value_clear(temp);
175 return;
176} /* PutRowFirst */
177
178/*
179 * Remove the column 'Columnnumber' and place it at the begining of the matrix
180 * 'X'
181 */
182void PutColumnFirst(Matrix *X, int Columnnumber) {
183
184 int i, j;
185 Value temp;
186
187 value_init(temp);
188 for (i = 0; i < X->NbRows; i++) {
189 value_assign(temp, X->p[i][Columnnumber]);
190 for (j = Columnnumber; j > 0; j--)
191 value_assign(X->p[i][j], X->p[i][j - 1]);
192 value_assign(X->p[i][0], temp);
193 }
194 value_clear(temp);
195 return;
196} /* PutColumnFirst */
197
198/*
199 * Remove the column 'Columnnumber' and place it at the end of the matrix 'X'
200 */
201void PutColumnLast(Matrix *X, int Columnnumber) {
202
203 int i, j;
204 Value temp;
205
206 value_init(temp);
207 for (i = 0; i < X->NbRows; i++) {
208 value_assign(temp, X->p[i][Columnnumber]);
209 for (j = Columnnumber; j < X->NbColumns - 1; j++)
210 value_assign(X->p[i][j], X->p[i][j + 1]);
211 value_assign(X->p[i][X->NbColumns - 1], temp);
212 }
213 value_clear(temp);
214 return;
215} /* PutColumnLast */
216
217/*
218 * Add a row of zeros at the end of the matrix 'M' and return the new matrix
219 */
221
222 int i, j;
223 Matrix *Result;
224
225 Result = Matrix_Alloc(M->NbRows + 1, M->NbColumns);
226 for (i = 0; i < M->NbRows; i++)
227 for (j = 0; j < M->NbColumns; j++)
228 value_assign(Result->p[i][j], M->p[i][j]);
229 for (j = 0; j < M->NbColumns; j++)
230 value_set_si(Result->p[i][j], 0);
231 return Result;
232} /* AddANullRow */
233
234/*
235 * Add a column of zeros at the end of the matrix 'M' and return the new
236 * matrix
237 */
239
240 int i, j;
241 Matrix *Result;
242
243 Result = Matrix_Alloc(M->NbRows, M->NbColumns + 1);
244 for (i = 0; i < M->NbRows; i++)
245 for (j = 0; j < M->NbColumns; j++)
246 value_assign(Result->p[i][j], M->p[i][j]);
247 for (i = 0; i < M->NbRows; i++)
248 value_set_si(Result->p[i][M->NbColumns], 0);
249 return Result;
250} /* AddANullColumn */
251
252/*
253 * Remove a row 'Rownumber' from matrix 'M' and return the new matrix.
254 */
255Matrix *RemoveRow(Matrix *M, int Rownumber) {
256
257 Matrix *Result;
258 int i;
259
260 Result = Matrix_Alloc(M->NbRows - 1, M->NbColumns);
261
262 for (i = 0; i < Rownumber; i++)
263 Vector_Copy(M->p[i], Result->p[i], M->NbColumns);
264 for (; i < Result->NbRows; i++)
265 Vector_Copy(M->p[i + 1], Result->p[i], M->NbColumns);
266
267 return Result;
268} /* RemoveRow */
269
270/*
271 * Remove NumColumns columns starting at column number 'FirstColumnnumber' from
272 * matrix 'M' and return the new matrix.
273 */
274Matrix *RemoveNColumns(Matrix *M, int FirstColumnnumber, int NumColumns) {
275
276 Matrix *Result;
277 int i;
278
279 Result = Matrix_Alloc(M->NbRows, M->NbColumns - NumColumns);
280
281 for (i = 0; i < Result->NbRows; i++) {
282 Vector_Copy(M->p[i], Result->p[i], FirstColumnnumber);
283 Vector_Copy(M->p[i] + FirstColumnnumber + NumColumns,
284 Result->p[i] + FirstColumnnumber,
285 M->NbColumns - NumColumns - FirstColumnnumber);
286 }
287 return Result;
288} /* RemoveColumn */
289
290/*
291 * Remove a column 'Columnnumber' from matrix 'M' and return the new matrix.
292 */
293Matrix *RemoveColumn(Matrix *M, int Columnnumber) {
294
295 Matrix *Result;
296 int i;
297
298 Result = Matrix_Alloc(M->NbRows, M->NbColumns - 1);
299
300 for (i = 0; i < Result->NbRows; i++) {
301 Vector_Copy(M->p[i], Result->p[i], Columnnumber);
302 Vector_Copy(M->p[i] + Columnnumber + 1, Result->p[i] + Columnnumber,
303 M->NbColumns - 1 - Columnnumber);
304 }
305 return Result;
306} /* RemoveColumn */
307
308// /*
309// * Given a Matrix M of dimension n * l and rank l1, find a unimodular matrix
310// * 'Result' such that the Vector Space spanned by M is the subset of the vector
311// * Space spanned by the first l1 Rows of Result. The function returns the rank
312// * l1 and the Matrix Result.
313// */
314// int findHermiteBasis(Matrix *M, Matrix **Result) {
315
316// int i, j;
317// Matrix *C, *curMat, *temp1, *temp2;
318// Matrix *H, *U;
319// Vector *V;
320// int dim, curDim, curVect, rank;
321
322// if (M->NbRows == 0) {
323// Result[0] = Identity(M->NbColumns);
324// return 0;
325// }
326
327// if (M->NbRows <= M->NbColumns) {
328// Hermite(M, &H, &U);
329
330// for (i = 0; i < H->NbRows; i++)
331// if (value_zero_p(H->p[i][i]))
332// break;
333
334// if (i == H->NbRows) {
335// Result[0] = Transpose(U);
336// Matrix_Free(H);
337// Matrix_Free(U);
338// return (i);
339// }
340// Matrix_Free(H);
341// Matrix_Free(U);
342// }
343
344// /* Eliminating the Zero Rows */
345
346// C = Matrix_Copy(M);
347// for (i = 0; i < C->NbRows; i++) {
348// for (j = 0; j < C->NbColumns; j++)
349// if (value_notzero_p(C->p[i][j]))
350// break;
351// if (j == C->NbColumns) {
352// Matrix *temp;
353// temp = RemoveRow(C, i);
354// Matrix_Free(C);
355// C = Matrix_Copy(temp);
356// Matrix_Free(temp);
357// i--;
358// }
359// }
360
361// /* Eliminating the Redundant Rows */
362
363// curDim = 1;
364// curVect = 1;
365// dim = C->NbColumns;
366
367// curMat = Matrix_Alloc(1, C->NbColumns);
368// for (i = 0; i < C->NbColumns; i++)
369// value_assign(curMat->p[0][i], C->p[0][i]);
370
371// while ((curVect < C->NbRows) && (curDim < dim)) {
372// Matrix *temp;
373// temp = AddANullRow(curMat);
374// for (i = 0; i < C->NbColumns; i++)
375// value_assign(temp->p[temp->NbRows - 1][i], C->p[curVect][i]);
376
377// temp1 = AddANullRow(temp);
378// temp2 = AddANullColumn(temp1);
379// rank = SolveDiophantine(temp2, &U, &V);
380// if (rank == temp->NbRows) {
381// Matrix_Free(curMat);
382// curMat = Matrix_Copy(temp);
383// curDim++;
384// }
385// curVect++;
386// Matrix_Free(U);
387// Vector_Free(V);
388// Matrix_Free(temp1);
389// Matrix_Free(temp);
390// Matrix_Free(temp2);
391// }
392// Matrix_Free(C);
393
394// Hermite(curMat, &H, &U);
395// rank = curMat->NbRows;
396// Matrix_Free(curMat);
397
398// Result[0] = Transpose(U);
399// Matrix_Free(H);
400// Matrix_Free(U);
401// return (rank);
402// } /* findHermiteBasis */
void PutRowLast(Matrix *X, int Rownumber)
Definition: Matop.c:140
Matrix * AddANullRow(Matrix *M)
Definition: Matop.c:220
void PutColumnLast(Matrix *X, int Columnnumber)
Definition: Matop.c:201
void Lcm3(Value a, Value b, Value *c)
Definition: Matop.c:5
Matrix * RemoveRow(Matrix *M, int Rownumber)
Definition: Matop.c:255
Matrix * Identity(unsigned size)
Definition: Matop.c:39
Matrix * Transpose(Matrix *A)
Definition: Matop.c:83
Value * Lcm(Value i, Value j)
Definition: Matop.c:27
Bool isIntegral(Matrix *A)
Definition: Matop.c:113
void PutRowFirst(Matrix *X, int Rownumber)
Definition: Matop.c:162
void PutColumnFirst(Matrix *X, int Columnnumber)
Definition: Matop.c:182
Matrix * RemoveColumn(Matrix *M, int Columnnumber)
Definition: Matop.c:293
void ExchangeRows(Matrix *M, int Row1, int Row2)
Definition: Matop.c:52
Matrix * AddANullColumn(Matrix *M)
Definition: Matop.c:238
Matrix * Matrix_Copy(Matrix const *Src)
Definition: Matop.c:98
Matrix * RemoveNColumns(Matrix *M, int FirstColumnnumber, int NumColumns)
Definition: Matop.c:274
void ExchangeColumns(Matrix *M, int Column1, int Column2)
Definition: Matop.c:70
#define value_swap(v1, v2)
Definition: arithmetique.h:491
#define value_notzero_p(val)
Definition: arithmetique.h:579
#define value_absolute(ref, val)
Definition: arithmetique.h:556
#define value_zero_p(val)
Definition: arithmetique.h:578
#define value_assign(v1, v2)
Definition: arithmetique.h:485
int Value
Definition: arithmetique.h:294
#define value_set_si(val, i)
Definition: arithmetique.h:486
#define value_clear(val)
Definition: arithmetique.h:488
#define value_division(ref, val1, val2)
Definition: arithmetique.h:550
#define value_multiply(ref, val1, val2)
Definition: arithmetique.h:546
#define value_modulus(ref, val1, val2)
Definition: arithmetique.h:552
#define value_init(val)
Definition: arithmetique.h:484
Matrix * Matrix_Alloc(unsigned NbRows, unsigned NbColumns)
Definition: matrix.c:24
Definition: types.h:88
unsigned NbRows
Definition: types.h:89
Value ** p
Definition: types.h:90
unsigned NbColumns
Definition: types.h:89
Bool
Definition: types.h:45
@ True
Definition: types.h:45
@ False
Definition: types.h:45
void Gcd(Value a, Value b, Value *result)
Definition: vector.c:96
void Vector_Copy(Value *p1, Value *p2, unsigned length)
Definition: vector.c:276