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

563580 views
1
#include "typedef.h"
2
#include "tools.h"
3
4
/**************************************************************************\
5
@---------------------------------------------------------------------------
6
@---------------------------------------------------------------------------
7
@ FILE: p_lse_solve.c
8
@---------------------------------------------------------------------------
9
@---------------------------------------------------------------------------
10
@
11
\**************************************************************************/
12
/********************************************************************\
13
@ The function 'matrix_TYP **p_lse_solve(A, B, anz, p)'
14
@ calculates for given matrices A and B the solutions of
15
@ A * X = B (modulo p)
16
@ where A is a (n x m)- matrix and B a (n x r) matrix with integral
17
@ entries (treated as elements of the field with p elements).
18
@ The number of the returned matrices is given back by the pointer 'anz'.
19
@
20
@ If no solution exists a NULL-pointer is returned, and 'anz' is
21
@ set to 0.
22
@
23
@ If a solution of the inhomogenous equation exists, it is
24
@ returned via the (m x r)-matrix X[0] ( X is the matrix_TYP ** returned by
25
@ the functions.
26
@ The (1 x m)-matrices X[1],...,X[anz-1] form a basis of the solutions of
27
@ the transposed homogenous equation X * A^{tr} = 0.
28
@
29
\********************************************************************/
30
matrix_TYP **p_lse_solve(A, B, anz, p)
31
matrix_TYP *A, *B;
32
int *anz, p;
33
{
34
matrix_TYP **X;
35
int **C, **D;
36
int i,j,k,step, cpos, f;
37
int m,n,r;
38
39
int inhomo,
40
found,
41
rang = 0, /* inserted tilman 21/07/97: if the matrix is zero mod p,
42
a different setting causes trouble */
43
Xsize;
44
45
int *tmp, *pos;
46
int phalbe, mphalbe;
47
48
extern matrix_TYP *init_mat();
49
50
phalbe = p/2;
51
mphalbe = -phalbe;
52
if(p == 2)
53
mphalbe = 0;
54
n = A->rows, m = A->cols;
55
if( (C = (int **)malloc(n *sizeof(int *))) == 0)
56
{
57
printf("malloc of C in 'p_lse_solve' failed\n");
58
exit(2);
59
}
60
for(i=0;i<n;i++)
61
{
62
if( (C[i] = (int *)malloc(m *sizeof(int))) == 0)
63
{
64
printf("malloc of C[%d] in 'p_lse_solve' failed\n", i);
65
exit(2);
66
}
67
for(j=0;j<m;j++)
68
C[i][j] = A->array.SZ[i][j];
69
}
70
if(B == NULL)
71
inhomo = FALSE;
72
else
73
{
74
inhomo = TRUE;
75
r = B->cols;
76
if( (D = (int **)malloc(n *sizeof(int *))) == 0)
77
{
78
printf("malloc of D in 'p_lse_solve' failed\n");
79
exit(2);
80
}
81
for(i=0;i<n;i++)
82
{
83
if( (D[i] = (int *)malloc(r *sizeof(int))) == 0)
84
{
85
printf("malloc of D[%d] in 'p_lse_solve' failed\n", i);
86
exit(2);
87
}
88
for(j=0;j<r;j++)
89
D[i][j] = B->array.SZ[i][j];
90
}
91
}
92
if(inhomo && n != B->rows)
93
{
94
printf("You tried to solve A * X = B, where A has %d rows and B has %d rows\n", A->rows, B->rows);
95
printf("exit in 'p_lse_solve':\n");
96
exit(3);
97
}
98
99
/*************************************************************************\
100
| reduce the entries in C and D modulo p
101
\*************************************************************************/
102
for(i=0;i<n;i++)
103
for(j=0;j<m;j++)
104
{
105
C[i][j] %= p;
106
if(C[i][j] > phalbe)
107
C[i][j] -= p;
108
if(C[i][j] < mphalbe)
109
C[i][j] += p;
110
}
111
if(inhomo)
112
{
113
for(i=0;i<n;i++)
114
for(j=0;j<r;j++)
115
{
116
D[i][j] %= p;
117
if(D[i][j] > phalbe)
118
D[i][j] -= p;
119
if(D[i][j] < mphalbe)
120
D[i][j] += p;
121
}
122
}
123
124
/*************************************************************************\
125
| Make a row-gauss-algorithm on C and do simultanous row operations on D.
126
\*************************************************************************/
127
cpos = 0;
128
for(step = 0; step < n; step++)
129
{
130
/**************************************************************\
131
| search first column 'cpos' in C with nonzero entry C[i][cpos]
132
| and permute the rows 'step' and 'i'
133
\**************************************************************/
134
found = FALSE;
135
while(cpos < m && found == FALSE)
136
{
137
for(i=step; i<n && C[i][cpos] == 0;i++);
138
if(i == n)
139
cpos++;
140
else
141
found = TRUE;
142
}
143
if(found == TRUE)
144
{
145
rang = step+1;
146
if(i!= step)
147
{
148
tmp = C[i]; C[i] = C[step]; C[step] = tmp; tmp = NULL;
149
if(inhomo)
150
{ tmp = D[i]; D[i] = D[step]; D[step] = tmp; tmp = NULL;}
151
}
152
/******************************************************************\
153
| Clear the entries C[step+1][cpos],....,C[n][cpos]
154
\******************************************************************/
155
f = p_inv(C[step][cpos], p);
156
if(f > phalbe) f -= p;
157
if(f < mphalbe) f += p;
158
if(f != 1)
159
{
160
C[step][cpos] = 1;
161
for(i=cpos+1;i<m; i++)
162
{
163
C[step][i] = (C[step][i] * f)%p;
164
if(C[step][i] > phalbe) C[step][i] -=p;
165
if(C[step][i] < mphalbe) C[step][i] +=p;
166
}
167
C[step][cpos] = 1;
168
if(inhomo)
169
{
170
for(i=0;i<r;i++)
171
{
172
D[step][i] = (D[step][i] * f)%p;
173
if(D[step][i] > phalbe) D[step][i] -=p;
174
if(D[step][i] < mphalbe) D[step][i] +=p;
175
}
176
}
177
}
178
for(i=step+1;i<n;i++)
179
{
180
if(C[i][cpos] != 0)
181
{
182
f = C[i][cpos];
183
C[i][cpos] = 0;
184
for(j=cpos+1; j<m;j++)
185
{
186
C[i][j] = ( C[i][j] - f * C[step][j])%p;
187
if(C[i][j] > phalbe) C[i][j] -=p;
188
if(C[i][j] < mphalbe) C[i][j] +=p;
189
}
190
if(inhomo)
191
{
192
for(j=0;j<r;j++)
193
{
194
D[i][j] = ( D[i][j] - f * D[step][j])%p;
195
if(D[i][j] > phalbe) D[i][j] -=p;
196
if(D[i][j] < mphalbe) D[i][j] +=p;
197
}
198
}
199
}
200
}
201
}
202
}
203
204
/********************************************************************\
205
| Now C is an upper triangular matrix and the number of nonzero rows
206
| is given by the variable 'rang'.
207
| If A[i][j] is the first non-zero entry in the i-th row (which has been
208
| made equal to 1),
209
| all the entries A[k][j] with k<i are made zero.
210
\********************************************************************/
211
for(i = rang-1; i >= 0; i--)
212
{
213
for(j=0; j<m && C[i][j] == 0; j++);
214
cpos = j;
215
for(j=0; j<i;j++)
216
{
217
f = C[j][cpos];
218
for(k=cpos+1;k<m;k++)
219
{
220
C[j][k] = (C[j][k] - f*C[i][k])%p;
221
if(C[j][k] > phalbe) C[j][k] -= p;
222
if(C[j][k] < mphalbe) C[j][k] += p;
223
}
224
C[j][cpos] = 0;
225
if(inhomo)
226
{
227
for(k=0;k<r;k++)
228
{
229
D[j][k] = (D[j][k] - f*D[i][k])%p;
230
if(D[j][k] > phalbe) D[j][k] -= p;
231
if(D[j][k] < mphalbe) D[j][k] += p;
232
}
233
}
234
}
235
}
236
/********************************************************************\
237
| Calculate a solution of the inhomogenous equation
238
\********************************************************************/
239
if(inhomo)
240
{
241
/********************************************************************\
242
| Check, whether a solution of the inhomogenous equation exists.
243
| If not return NULL-pointer
244
\********************************************************************/
245
found = FALSE;
246
for(i=rang;i<n && found == FALSE;i++)
247
for(j=0;j<r && found == FALSE; j++)
248
{
249
if(D[i][j] != 0) found = TRUE;
250
}
251
if(found == TRUE)
252
{
253
for(i=0;i<n;i++)
254
{ free(D[i]); free(C[i]);}
255
free(C); free(D);
256
*anz = 0;
257
return(NULL);
258
}
259
}
260
Xsize = m-rang+1;
261
*anz = Xsize;
262
if((X = (matrix_TYP **)malloc(Xsize *sizeof(matrix_TYP *))) == 0)
263
{
264
printf("malloc of X in 'p_lse_solve' failed\n");
265
exit(2);
266
}
267
268
/*******************************************************************\
269
| pos[i] is the index j such that C[i][j] is the first nonzero
270
| entry in the i-th row of C
271
\*******************************************************************/
272
pos = NULL;
273
if((pos = (int *)malloc((rang+2) *sizeof(int))) == 0)
274
{
275
printf("malloc of 'pos' in 'p_lse_solve' failed\n");
276
exit(2);
277
}
278
279
/* inserted tilman 11/4/97 */
280
pos++; pos[-1] = -1;
281
282
for(i=0;i<rang;i++)
283
{
284
for(j=0;j<m && C[i][j] == 0; j++);
285
pos[i] = j;
286
}
287
pos[rang] = m;
288
if(inhomo)
289
{
290
/****************************************************************\
291
| Find a solution of the inhomogenous equation
292
\****************************************************************/
293
X[0] = init_mat(m, r, "");
294
for(i=0;i<r;i++)
295
for(j=0;j<rang;j++)
296
X[0]->array.SZ[pos[j]][i] = D[j][i];
297
for(i=0;i<n;i++)
298
free(D[i]);
299
free(D);
300
}
301
else
302
X[0] = NULL;
303
/****************************************************************\
304
| Find the solutions of the homogenous equation
305
\****************************************************************/
306
step=1;
307
308
/* changed 11/4/97 tilman from
309
for(i=rang-1; i>= 0; i--) to */
310
for(i=rang-1; i>= (-1); i--)
311
{
312
for(j=pos[i]+1; j< pos[i+1]; j++)
313
{
314
X[step] = init_mat(1, m, "");
315
tmp = X[step]->array.SZ[0];
316
step++;
317
tmp[j] = -1;
318
for(k=0;k<=i;k++)
319
tmp[pos[k]] = C[k][j];
320
}
321
}
322
for(i=0;i<n;i++)
323
free(C[i]);
324
free(C);
325
326
/* inserted tilman 11/4/97 */
327
free(--pos);
328
return(X);
329
}
330
331