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
/***** This file includes some basic routines
2
for matrix and vector operations *****/
3
#include"typedef.h"
4
5
/********************************************************************\
6
| multiplies 1xn-vector x with nxn-matrix A and puts result on y
7
\********************************************************************/
8
static void vecmatmul(x, A, n, y)
9
int *x, **A, n, *y;
10
{
11
int i, j, xi, *Ai;
12
13
for (j = 0; j < n; ++j)
14
y[j] = 0;
15
for (i = 0; i < n; ++i)
16
{
17
if ((xi = x[i]) != 0)
18
{
19
Ai = A[i];
20
for (j = 0; j < n; ++j)
21
y[j] += xi * Ai[j];
22
}
23
}
24
}
25
26
/********************************************************************\
27
| multiplies nxn-matrices A and B and puts result on C
28
\********************************************************************/
29
static void matmul(A, B, n, C)
30
int **A, **B, n, **C;
31
{
32
int i, j, k, *Ai, *Bk, *Ci, Aik;
33
34
for (i = 0; i < n; ++i)
35
{
36
Ai = A[i];
37
Ci = C[i];
38
for (j = 0; j < n; ++j)
39
Ci[j] = 0;
40
for (k = 0; k < n; ++k)
41
{
42
if ((Aik = Ai[k]) != 0)
43
{
44
Bk = B[k];
45
for (j = 0; j < n; ++j)
46
Ci[j] += Aik * Bk[j];
47
}
48
}
49
}
50
}
51
52
/********************************************************************\
53
| returns scalar product of 1xn-vectors x and y
54
| with respect to Gram-matrix F
55
\********************************************************************/
56
static int scp(x, F, y, n)
57
int *x, **F, *y, n;
58
{
59
int i, j, sum, xi, *Fi;
60
61
sum = 0;
62
for (i = 0; i < n; ++i)
63
{
64
if ((xi = x[i]) != 0)
65
{
66
Fi = F[i];
67
for (j = 0; j < n; ++j)
68
sum += xi * Fi[j] * y[j];
69
}
70
}
71
return(sum);
72
}
73
74
/********************************************************************\
75
| returns standard scalar product of 1xn-vectors x and y, heavily used
76
\********************************************************************/
77
static int sscp(x, y, n)
78
int *x, *y, n;
79
{
80
int i, sum;
81
82
sum = 0;
83
for (i = 0; i < n; ++i)
84
sum += *(x++) * *(y++);
85
/* sum += x[i] * y[i]; */
86
return(sum);
87
}
88
89
/********************************************************************\
90
| computes X = B*A^-1 modulo the prime p, for nxn-matrices A and B,
91
| where A is invertible, A and B are modified !!!
92
\********************************************************************/
93
static void psolve(X, A, B, n, p)
94
int **X, **A, **B, n, p;
95
{
96
int i, j, k, tmp, sum, ainv, *Xi, *Bi;
97
98
/* convert A to lower triangular matrix and change B accordingly */
99
for (i = 0; i < n-1; ++i)
100
{
101
for (j = i; A[i][j] % p == 0; ++j);
102
if (j == n)
103
{
104
fprintf(stderr, "Error: matrix is singular modulo %d\n", p);
105
exit (3);
106
}
107
if (j != i)
108
/* interchange columns i and j such that A[i][i] is != 0 */
109
{
110
for (k = i; k < n; ++k)
111
{
112
tmp = A[k][i];
113
A[k][i] = A[k][j];
114
A[k][j] = tmp;
115
}
116
for (k = 0; k < n; ++k)
117
{
118
tmp = B[k][i];
119
B[k][i] = B[k][j];
120
B[k][j] = tmp;
121
}
122
}
123
pgauss(i, A, B, n, p);
124
}
125
/* compute X recursively */
126
for (i = 0; i < n; ++i)
127
{
128
Xi = X[i];
129
Bi = B[i];
130
for (j = n-1; j >= 0; --j)
131
{
132
sum = 0;
133
for (k = n-1; k > j; --k)
134
sum = (sum + Xi[k] * A[k][j]) % p;
135
/* ainv is the inverse of A[j][j] modulo p */
136
for (ainv = 1; abs(A[j][j]*ainv-1) % p != 0; ++ainv);
137
Xi[j] = (Bi[j] - sum) * ainv % p;
138
/* make sure that -p/2 < X[i][j] <= p/2 */
139
if (2*Xi[j] > p)
140
Xi[j] -= p;
141
else if (2*Xi[j] <= -p)
142
Xi[j] += p;
143
}
144
}
145
}
146
147
/********************************************************************\
148
| clears row nr. r of A assuming that the
149
| first r-1 rows of A are already cleared
150
| and that A[r][r] != 0 modulo p,
151
| A and B are changed !!!
152
\********************************************************************/
153
static void pgauss(r, A, B, n, p)
154
int r, **A, **B, n, p;
155
{
156
int i, j, f, ainv, *Ar;
157
158
Ar = A[r];
159
/* ainv is the inverse of A[r][r] modulo p */
160
for (ainv = 1; abs(Ar[r]*ainv-1) % p != 0; ++ainv);
161
for (j = r+1; j < n; ++j)
162
{
163
if (Ar[j] % p != 0)
164
{
165
f = Ar[j] * ainv % p;
166
for (i = r+1; i < n; ++i)
167
A[i][j] = (A[i][j] - f * A[i][r]) % p;
168
for (i = 0; i < n; ++i)
169
B[i][j] = (B[i][j] - f * B[i][r]) % p;
170
Ar[j] = 0;
171
}
172
}
173
}
174
175
/********************************************************************\
176
| checks, whether n is a prime
177
\********************************************************************/
178
static int isprime(n)
179
int n;
180
{
181
int i;
182
183
for (i = 2; i <= n/i; ++i)
184
{
185
if (n % i == 0)
186
return 0;
187
}
188
return 1;
189
}
190
191