Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563604 views
1
#include "typedef.h"
2
#include "gmp.h"
3
/* #include "gmp-impl.h" */
4
5
extern int INFO_LEVEL;
6
7
/**************************************************************************\
8
@---------------------------------------------------------------------------
9
@---------------------------------------------------------------------------
10
@ FILE: MP_solve.c
11
@---------------------------------------------------------------------------
12
@---------------------------------------------------------------------------
13
@
14
\**************************************************************************/
15
16
/************************************************************************\
17
@-------------------------------------------------------------------------
18
@ MP_INT ***MP_solve_mat(M, rows, cols, B, Bcols, X1cols, X0kgv)
19
@ MP_INT **M, **B, *X0kgv;
20
@ int rows, cols, Bcols, *X1cols;
21
@
22
@ MP_solve_mat(M) calculates Matrix X[0] with MX[0] = B, and
23
@ a matrix X[1] with MX[1] = 0, such that
24
@ the cols of X[1] are a Z-basis of the solution space.
25
@ The number of the cols of X[1] are returned via the pointer 'X1cols'.
26
@ CAUTION: the function changes the values of M;
27
@-------------------------------------------------------------------------
28
@
29
\************************************************************************/
30
MP_INT ***MP_solve_mat(M, rows, cols, B, Bcols, X1cols, X0kgv)
31
MP_INT **M, **B, *X0kgv;
32
int rows, cols, Bcols, *X1cols;
33
{
34
MP_INT **Mt, **Trf, ***erg, *Y, *Z;
35
MP_INT kgv, altkgv, merk, merk1, g;
36
MP_INT zaehler, nenner, b;
37
int i,j,k,l,rang, n;
38
int tester, dim;
39
int waste;
40
41
extern matrix_TYP *copy_mat();
42
extern matrix_TYP *tr_pose();
43
extern matrix_TYP *init_mat();
44
extern matrix_TYP *mat_mul();
45
46
mpz_init(&zaehler); mpz_init(&nenner); mpz_init(&b);
47
if(B == NULL || Bcols == 0)
48
rang = MP_row_gauss(M, rows, cols);
49
else
50
rang = MP_row_gauss_simultaneous(M, rows, cols, B, Bcols);
51
if((Mt = (MP_INT **)malloc(cols *sizeof(MP_INT *))) == 0)
52
{
53
printf("malloc of 'Mt' in 'MP_solve_mat' failed\n");
54
exit(2);
55
}
56
for(i=0;i<cols;i++)
57
{
58
if((Mt[i] = (MP_INT *)malloc(rows *sizeof(MP_INT))) == 0)
59
{
60
printf("malloc of 'Mt[%d]' in 'MP_solve_mat' failed\n", i);
61
exit(2);
62
}
63
}
64
for(i=0;i<rows;i++)
65
for(j=0;j<cols;j++)
66
mpz_init_set(&Mt[j][i], &M[i][j]);
67
if((Trf = (MP_INT **)malloc(cols *sizeof(MP_INT *))) == 0)
68
{
69
printf("malloc of 'Trf' in 'MP_solve_mat' failed\n");
70
exit(2);
71
}
72
for(i=0;i<cols;i++)
73
{
74
if((Trf[i] = (MP_INT *)malloc(cols *sizeof(MP_INT))) == 0)
75
{
76
printf("malloc of 'Trf[%d]' in 'MP_solve_mat' failed\n", i);
77
exit(2);
78
}
79
for(j=0;j<cols;j++)
80
mpz_init(&Trf[i][j]);
81
mpz_set_si(&Trf[i][i], 1);
82
}
83
mpz_init_set_si(&kgv,1);
84
85
/* transform the transposed Mt of M to be gauss reduced */
86
rang = MP_trf_gauss(Mt, Trf, cols, rows);
87
88
/* now we are able to predict the dimension of the homogenous solution */
89
dim = cols - rang;
90
*X1cols = dim;
91
92
if((erg = (MP_INT ***)malloc(2 *sizeof(MP_INT **))) == 0)
93
{
94
printf("malloc of 'erg' in 'MP_solve_mat' failed\n");
95
exit(2);
96
}
97
98
{
99
/*********************************************************************\
100
| calculate a solution of the homogenous equation
101
| Write this solution to erg[1]
102
\*********************************************************************/
103
if(dim == 0)
104
{
105
erg[1] = NULL;
106
}
107
else
108
{
109
if((erg[1] = (MP_INT **)malloc(dim *sizeof(MP_INT *))) == 0)
110
{
111
printf("malloc of 'erg[1]' in 'MP_solve_mat' failed\n");
112
exit(2);
113
}
114
115
for(i=0;i<dim;i++)
116
{
117
if((erg[1][i] = (MP_INT *)malloc(cols *sizeof(MP_INT))) == 0)
118
{
119
printf("malloc of 'erg[1][%d]' in 'MP_solve_mat' failed\n", i);
120
exit(2);
121
}
122
}
123
for(i=0;i<dim;i++)
124
for(j=0;j<cols;j++)
125
mpz_init_set(&erg[1][i][j], &Trf[i+rang][j]);
126
}
127
if(dim > 1)
128
MP_hnf(erg[1], dim, cols);
129
}
130
if(B != NULL && Bcols != 0)
131
{
132
133
/* test whether there is an solution at all */
134
/* does work this way because M and B were gauss reduced
135
simultaneusly */
136
tester = TRUE;
137
for(i=rang;i<rows && tester == TRUE;i++)
138
for(j=0;j<Bcols && tester == TRUE;j++)
139
{
140
if(mpz_cmp_si(&B[i][j], 0) != 0)
141
tester = FALSE;
142
}
143
144
if(tester == FALSE)
145
erg[0] = NULL;
146
else
147
{
148
/*********************************************************************\
149
| calculate a solution of the inhomogenous equation
150
| Write this solution to erg[0]
151
\*********************************************************************/
152
if ((erg[0] = (MP_INT **)malloc(cols *sizeof(MP_INT *))) == NULL)
153
{
154
printf("malloc of 'erg[0]' in 'MP_solve_mat' failed\n");
155
exit(2);
156
}
157
158
for(i=0;i<cols;i++)
159
{
160
if((erg[0][i] = (MP_INT *)malloc(Bcols *sizeof(MP_INT))) == 0)
161
{
162
printf("malloc of 'erg[0][%d]' in 'MP_solve_mat' failed\n", i);
163
exit(2);
164
}
165
for(j=0;j<Bcols;j++)
166
mpz_init(&erg[0][i][j]);
167
}
168
if ((Y = (MP_INT *)malloc(cols *sizeof(MP_INT))) == NULL)
169
{
170
printf("malloc of 'Y' in 'MP_solve_mat' failed\n");
171
exit(2);
172
}
173
for(i=0;i<cols;i++)
174
mpz_init(&Y[i]);
175
if ((Z = (MP_INT *)malloc(cols *sizeof(MP_INT))) == NULL)
176
{
177
printf("malloc of 'Z' in 'MP_solve_mat' failed\n");
178
exit(2);
179
}
180
for(i=0;i<cols;i++)
181
mpz_init(&Z[i]);
182
mpz_init_set_si(&altkgv,1);
183
mpz_init(&merk); mpz_init(&merk1);
184
mpz_init(&g);
185
for(i=0;i<Bcols;i++)
186
{
187
188
/* output for debugging */
189
if (INFO_LEVEL & 4){
190
dump_MP_mat(M,rows,cols,"M");
191
dump_MP_mat(Mt,cols,rows,"Mt");
192
dump_MP_mat(B,rows,Bcols,"B");
193
}
194
195
/* changed 30/1/97 tilman from
196
for(j=0;j<cols && j< rows;j++)
197
to : */
198
for(j=0;j<cols && j< rang;j++)
199
{
200
201
if (INFO_LEVEL & 4){
202
dump_MP_mat(&Y,1,cols,"Y");
203
dump_MP_mat(&Z,1,cols,"Z");
204
}
205
206
mpz_set_si(&Y[j], 0);
207
mpz_set_si(&Z[j], 1);
208
for(k=0;k<j;k++)
209
{
210
mpz_mul(&merk1, &Y[k], &Mt[k][j]);
211
mpz_mul(&merk1, &merk1, &Z[j]);
212
mpz_mul(&Y[j], &Y[j], &Z[k]);
213
mpz_add(&Y[j], &Y[j], &merk1);
214
mpz_mul(&Z[j], &Z[j], &Z[k]);
215
216
mpz_gcd(&g, &Y[j], &Z[j]);
217
mpz_div(&Y[j], &Y[j], &g);
218
mpz_div(&Z[j], &Z[j], &g);
219
}
220
mpz_mul(&merk, &B[j][i], &Z[j]);
221
mpz_sub(&Y[j], &merk, &Y[j]);
222
mpz_mul(&Z[j], &Z[j], &Mt[j][j]);
223
224
mpz_gcd(&g, &Y[j], &Z[j]);
225
226
mpz_div(&Y[j], &Y[j], &g);
227
mpz_div(&Z[j], &Z[j], &g);
228
229
/* normalising the sign of Z[j] */
230
if(mpz_cmp_si(&Z[j], 0) < 0){
231
mpz_neg(&Y[j], &Y[j]);
232
mpz_neg(&Z[j], &Z[j]);
233
}
234
}
235
236
/* changed 30/1/97 from:
237
for(j=rows;j<cols;j++)
238
to :*/
239
for(j=rang;j<cols;j++)
240
{
241
mpz_set_si(&Y[j], 0);
242
mpz_set_si(&Z[j], 1);
243
}
244
/* calculate the lcm of kgv and Z[j], 1<=j<=cols */
245
mpz_set(&merk, &kgv);
246
for(j=0;j<cols && j < rows;j++)
247
{
248
mpz_gcd(&g, &Z[j], &merk);
249
mpz_div(&merk1, &Z[j], &g);
250
mpz_mul(&merk, &merk, &merk1);
251
}
252
for(j=0;j<cols;j++)
253
{
254
mpz_div(&g, &merk, &Z[j]);
255
mpz_mul(&Y[j], &Y[j], &g);
256
}
257
if(mpz_cmp(&merk, &kgv) != 0)
258
{
259
mpz_div(&g, &merk, &kgv);
260
mpz_set(&kgv, &merk);
261
for(j=0;j<Bcols;j++)
262
{
263
if(j != i)
264
{
265
for(k=0;k<cols;k++)
266
mpz_mul(&erg[0][k][j], &erg[0][k][j], &g);
267
}
268
}
269
}
270
for(j=0;j<cols;j++)
271
{
272
mpz_set_si(&erg[0][j][i], 0);
273
for(k=0;k<cols;k++)
274
{
275
mpz_mul(&merk, &Y[k], &Trf[k][j]);
276
mpz_add(&erg[0][j][i], &erg[0][j][i], &merk);
277
}
278
}
279
}
280
281
/* output for debugging */
282
if (INFO_LEVEL & 4){
283
fprintf(stderr,"kgv = ");
284
mpz_out_str(stderr,10,&kgv);
285
fprintf(stderr,"\n");
286
dump_MP_mat(erg[0],cols,Bcols,"erg[0]");
287
}
288
289
mpz_clear(&altkgv);
290
mpz_clear(&merk); mpz_clear(&merk1);
291
mpz_clear(&g);
292
for(i=0;i<cols;i++)
293
mpz_clear(&Y[i]);
294
free(Y);
295
for(i=0;i<cols;i++)
296
mpz_clear(&Z[i]);
297
free(Z);
298
}
299
mpz_set(X0kgv, &kgv);
300
}
301
else
302
erg[0] = NULL;
303
304
for(i=0;i<cols;i++)
305
{
306
for(j=0;j<cols;j++)
307
mpz_clear(&Trf[i][j]);
308
free(Trf[i]);
309
}
310
free(Trf);
311
for(i=0;i<rows;i++)
312
for(j=0;j<cols;j++)
313
mpz_clear(&Mt[j][i]);
314
for(i=0;i<cols;i++)
315
free(Mt[i]);
316
free(Mt);
317
318
mpz_clear(&zaehler);
319
mpz_clear(&nenner);
320
mpz_clear(&b);
321
mpz_clear(&kgv);
322
323
return(erg);
324
}
325
326