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

563595 views
1
#include"typedef.h"
2
#include"matrix.h"
3
#include "bravais.h"
4
5
/**************************************************************************\
6
@---------------------------------------------------------------------------
7
@---------------------------------------------------------------------------
8
@ FILE: lincomb.c
9
@---------------------------------------------------------------------------
10
@---------------------------------------------------------------------------
11
@
12
\**************************************************************************/
13
14
/**************************************************************************\
15
@---------------------------------------------------------------------------
16
@ matrix_TYP *vec_to_form(v, F, Fanz)
17
@ int *v;
18
@ matrix_TYP **F;
19
@ int Fanz;
20
@
21
@ calculates the matrix v[1] F[1] + v[2] F[2] +....+v[Fanz-1] F[Fanz-1}
22
@---------------------------------------------------------------------------
23
@
24
\**************************************************************************/
25
26
matrix_TYP *vec_to_form(v, F, Fanz)
27
int *v;
28
matrix_TYP **F;
29
int Fanz;
30
{
31
int i,j,k, n,m;
32
matrix_TYP *M;
33
int sym;
34
35
n = F[0]->rows;
36
m = F[0]->cols;
37
for(i=1;i<Fanz;i++)
38
{
39
if(F[i]->rows != n || F[i]->cols != m)
40
{
41
printf(" Different size of matrices in vec_to_form\n");
42
exit(3);
43
}
44
}
45
i=0; sym = TRUE;
46
while(i<Fanz && F[i]->flags.Symmetric == TRUE)
47
i++;
48
if(i<Fanz)
49
sym = FALSE;
50
51
if(sym == FALSE)
52
{
53
M = init_mat(n,m, "");
54
for(i=0;i<Fanz;i++)
55
{
56
if(v[i] != 0)
57
{
58
for(j=0;j<n;j++)
59
for(k=0;k<m;k++)
60
M->array.SZ[j][k] += v[i] * F[i]->array.SZ[j][k];
61
}
62
}
63
}
64
else
65
{
66
M = init_mat(n,m, "s");
67
for(i=0;i<Fanz;i++)
68
{
69
if(v[i] != 0)
70
{
71
for(j=0;j<n;j++)
72
for(k=0; k<=j; k++)
73
M->array.SZ[j][k] += v[i] * F[i]->array.SZ[j][k];
74
}
75
}
76
for(j=0;j<n;j++)
77
for(k=0;k<j;k++)
78
M->array.SZ[k][j] = M->array.SZ[j][k];
79
}
80
Check_mat(M);
81
return(M);
82
}
83
84
85
86
/**************************************************************************\
87
@---------------------------------------------------------------------------
88
@ void form_to_vec(erg, A, F, Fanz, denominator)
89
@ int *erg;
90
@ matrix_TYP *A, **F;
91
@ int Fanz, *denominator;
92
@
93
@ calculates a vector v such that A = 1/d(v[0]F[0] +...+v[Fanz-1]F[Fanz-1]
94
@ and writes it onto the vector erg.
95
@ the space for erg must be allocated before using this function.
96
@ the integer d is returned via the pointer denominator.
97
@---------------------------------------------------------------------------
98
@
99
\**************************************************************************/
100
void form_to_vec(erg, A, F, Fanz, denominator)
101
int *erg;
102
matrix_TYP *A, **F;
103
int Fanz, *denominator;
104
{
105
int i,j,k,l, n,m,r;
106
matrix_TYP *X, *X1, *Trf;
107
int sym, rang;
108
109
n = F[0]->rows;
110
m = F[0]->cols;
111
for(i=1;i<Fanz;i++)
112
{
113
if(F[i]->rows != n || F[i]->cols != m)
114
{
115
printf(" Different size of matrices in form_to_vec\n");
116
exit(3);
117
}
118
}
119
i=0; sym = TRUE;
120
while(i<Fanz && F[i]->flags.Symmetric == TRUE)
121
i++;
122
if(i<Fanz)
123
sym = FALSE;
124
125
if(sym == FALSE)
126
{
127
r = n*m;
128
X = init_mat(r,Fanz+1, "");
129
for(i=0;i<Fanz;i++)
130
{
131
l = 0;
132
for(j=0;j<n;j++)
133
for(k=0;k<n;k++)
134
{ X->array.SZ[l][i] = F[i]->array.SZ[j][k]; l++;}
135
}
136
l = 0;
137
for(j=0;j<n;j++)
138
for(k=0;k<n;k++)
139
{ X->array.SZ[l][Fanz] = A->array.SZ[j][k]; l++;}
140
}
141
else
142
{
143
r = (n*(n+1))/2;
144
X = init_mat(r,Fanz+1, "");
145
for(i=0;i<Fanz;i++)
146
{
147
l = 0;
148
for(j=0;j<n;j++)
149
for(k=0;k<=j;k++)
150
{ X->array.SZ[l][i] = F[i]->array.SZ[j][k]; l++;}
151
}
152
l = 0;
153
for(j=0;j<n;j++)
154
for(k=0;k<=j;k++)
155
{ X->array.SZ[l][Fanz] = A->array.SZ[j][k]; l++;}
156
}
157
X->rows = Fanz-1;
158
do
159
{
160
X->rows++;
161
162
/* tilman: changed 02/09/97 from (to avoid overflow)
163
rang = long_row_gauss(X); */
164
rang = long_row_basis(X,FALSE);
165
166
}while(X->rows < r && rang != Fanz);
167
168
if(X->rows == r && rang != Fanz)
169
{
170
printf("Matrices F in form_to_vec are not linear independent\n");
171
exit(3);
172
}
173
X->rows = rang;
174
X1 = tr_pose(X);
175
X->rows = r;
176
free_mat(X);
177
Trf = init_mat(X1->rows, X1->rows, "");
178
long_row_trf_gauss(X1, Trf);
179
free_mat(X1);
180
if(Trf->array.SZ[Fanz][Fanz] == 0)
181
{
182
printf("Matrices F in form_to_vec are not linear independent\n");
183
exit(3);
184
}
185
if(Trf->array.SZ[Fanz][Fanz] < 0)
186
{
187
for(i=0;i<Fanz;i++)
188
erg[i] = Trf->array.SZ[Fanz][i];
189
*denominator = - Trf->array.SZ[Fanz][Fanz];
190
}
191
if(Trf->array.SZ[Fanz][Fanz] > 0)
192
{
193
for(i=0;i<Fanz;i++)
194
erg[i] = - Trf->array.SZ[Fanz][i];
195
*denominator = Trf->array.SZ[Fanz][Fanz];
196
}
197
free_mat(Trf);
198
}
199
200
/**************************************************************************\
201
@---------------------------------------------------------------------------
202
@ vertex_TYP *form_to_vertex(A, F, Fanz, denominator)
203
@ matrix_TYP *A, **F;
204
@
205
@ calculates a vector v such that A = 1/d(v[0]F[0] +...+v[Fanz-1]F[Fanz-1]
206
@ and returns it as V->v in a vertex_TYP V..
207
@ The integer d is returned via the pointer denominator.
208
@---------------------------------------------------------------------------
209
@
210
\**************************************************************************/
211
vertex_TYP *form_to_vertex(A, F, Fanz, denominator)
212
matrix_TYP *A, **F;
213
int Fanz, *denominator;
214
{
215
vertex_TYP *v;
216
extern vertex_TYP *init_vertex();
217
v = init_vertex(Fanz, 0);
218
form_to_vec(v->v, A, F, Fanz, denominator);
219
}
220
221
222
/**************************************************************************\
223
@---------------------------------------------------------------------------
224
@ void form_to_vec_modular(erg, A, F, Fanz)
225
@ matrix_TYP *A, **F;
226
@ int *erg, Fanz;
227
@
228
@ the same as form_to_vec, but works only if the linear combination is
229
@ integral, i.e. the denominator is assumed to be 1.
230
@ the function calculated the result modulo big primes and fits it
231
@ together with the chinese remainder theorem.
232
@ This is faster as form_to_vec and avoids overflow.
233
@---------------------------------------------------------------------------
234
@
235
\**************************************************************************/
236
void form_to_vec_modular(erg, A, F, Fanz)
237
matrix_TYP *A, **F;
238
int *erg, Fanz;
239
{
240
241
int i,j,k,l;
242
int p1, p2, a1, a2, y1, y2;
243
matrix_TYP **X1, **X2;
244
matrix_TYP *G1, *G2;
245
int X1anz, X2anz;
246
int n, m;
247
double q, res, q1, q2;
248
double waste;
249
int symmetric;
250
251
p1 = 65521; p2 = 65519;
252
n = A->cols;
253
for(i=0;i<Fanz;i++)
254
{
255
if(F[i]->cols != n)
256
{
257
printf("error: matrices in 'form_to_vec_modular' have different number of cols\n");
258
exit(3);
259
}
260
}
261
n = A->rows;
262
for(i=0;i<Fanz;i++)
263
{
264
if(F[i]->rows != n)
265
{
266
printf("error: matrices in 'form_to_vec_modular' have different number of rows\n");
267
exit(3);
268
}
269
}
270
271
symmetric = A->flags.Symmetric;
272
for(i=0;i<Fanz;i++)
273
{
274
if(F[i]->flags.Symmetric == FALSE)
275
symmetric = FALSE;
276
}
277
if(symmetric)
278
n = (A->cols * (A->cols + 1))/2;
279
else
280
n = A->cols * A->rows;
281
G1 = init_mat(n, Fanz, "");
282
G2 = init_mat(n, 1, "");
283
if(symmetric)
284
{
285
l = 0;
286
for(i=0;i<A->cols;i++)
287
for(j=0;j<=i;j++)
288
{
289
for(k=0;k<Fanz;k++)
290
G1->array.SZ[l][k] = F[k]->array.SZ[i][j];
291
G2->array.SZ[l][0] = A->array.SZ[i][j];
292
l++;
293
}
294
}
295
else
296
{
297
l = 0;
298
for(i=0;i<A->rows;i++)
299
for(j=0;j<A->cols;j++)
300
{
301
for(k=0;k<Fanz;k++)
302
G1->array.SZ[l][k] = F[k]->array.SZ[i][j];
303
G2->array.SZ[l][0] = A->array.SZ[i][j];
304
l++;
305
}
306
}
307
308
X1 = p_lse_solve(G1, G2, &X1anz, p1);
309
X2 = p_lse_solve(G1, G2, &X2anz, p2);
310
if(X1anz == 0 || X2anz == 0)
311
{
312
printf("error in 'form_to_vec_modular':\n");
313
printf("The matrix A is not in the Z-span of the matrices F[0],..,F[%d],\n", (Fanz-1));
314
exit(3);
315
}
316
if(X1anz != 1 || X2anz != 1)
317
{
318
printf("error in 'form_to_vec_modular':\n");
319
printf("The matrix A is not in the Z-span of the matrices F[0],..,F[%d],\n", (Fanz-1));
320
printf("or F[0],...,F[%d] are not independent over the field with");
321
if(X1anz != 1) printf(" %d ", p1);
322
if(X2anz != 1) printf(" %d ", p2);
323
printf("elements\n");
324
exit(3);
325
}
326
a1 = p_inv(p2, p1);
327
a2 = p_inv(p1, p2);
328
q = ((double) p1) * ((double) p2);
329
q1 = ((double) p2) * ((double) a1);
330
q2 = ((double) p1) * ((double) a2);
331
332
for(i=0;i<Fanz;i++)
333
{
334
erg[i] = 0;
335
y1 = X1[0]->array.SZ[i][0];
336
y2 = X2[0]->array.SZ[i][0];
337
if(y1 == y2)
338
erg[i] = y1;
339
else
340
{
341
res = ((double) y1) * q1 + ((double) y2) * q2;
342
modf(res/q, &waste);
343
res = res - waste * q;
344
while( (res/q) > 0.5)
345
res = res -q;
346
while( (res/q) < -0.5)
347
res = res + q;
348
erg[i] = ((int) res);
349
}
350
}
351
/*****************************************************************\
352
| Ckeck if the modular result is also integrally correct
353
\*****************************************************************/
354
for(i=0; i<n;i++)
355
{
356
y1 = -(G2->array.SZ[i][0]);
357
for(k=0;k<Fanz;k++)
358
y1 += G1->array.SZ[i][k] * erg[k];
359
if(y1 != 0)
360
{
361
printf("Sorry: Overflow in 'form_to_vec_modular'\n");
362
exit(3);
363
}
364
}
365
free_mat(X1[0]); free_mat(X2[0]);
366
free(X1); free(X2);
367
free_mat(G1); free_mat(G2);
368
}
369
370