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"symm.h"
4
#include "tools.h"
5
#include"bravais.h"
6
7
/****************************************************************************\
8
@ -----------------------------------------------------------------------
9
@ FILE: vor_neighbour.c:
10
@ -----------------------------------------------------------------------
11
@
12
\****************************************************************************/
13
14
/****************************************************************************\
15
@
16
@ matrix_TYP *voronoi_neighbour(A, X, Amin, lc, rc)
17
@ matrix_TYP *A, *X;
18
@ int Amin, *lc, *rc;
19
@
20
@ The arguments of 'voronoi_neigbour' are
21
@ A: a positiv definite matrix
22
@ Amin: The Minimum of A, min(A) := min{yAy^{tr} | y in Z^n, y not 0}
23
@ X: a symmetric matrix, which is not positiv semidefinite
24
@ lc, rc: These pointer to an integer return the values of the
25
@ coefficients N = lc * A + rc *X for the result N of the
26
@ function
27
@
28
@ For A positive definite let M(A) denote the set of all y in Z^n
29
@ with yAy^{tr} = min(A) and
30
@ Z(A, X) the set of all y in M(A) with yXy^{tr} = 0.
31
@ The function voronoi_neigbbour calculates a Matrix N = lc *A + rc * X
32
@ with positive integral coefficients lc and rc such that
33
@ Z(A, X) is a proper subset of M(N).
34
@ In particular min(N) = lc * min(A).
35
@-----------------------------------------------------------------------
36
@
37
\****************************************************************************/
38
matrix_TYP *voronoi_neighbour(A, X, Amin, lc, rc)
39
matrix_TYP *A, *X;
40
int Amin, *lc, *rc;
41
{
42
int i,j,n;
43
matrix_TYP *SV, *N;
44
int lo,ro, lu, ru;
45
int lm, rm;
46
int anz, found;
47
int merk, Xy, Ay;
48
49
50
j = definite_test(X);
51
if(j>= 0)
52
return(NULL);
53
n = A->rows;
54
N = init_mat(n,n,"");
55
N->flags.Integral = N->flags.Symmetric = TRUE;
56
N->flags.Diagonal = FALSE;
57
/************************************************************************\
58
| First calculate Form N = lm * A + rm * X, with N positiv definite
59
| and min(N) < lm * min(A)
60
\************************************************************************/
61
lu = 1; ru = 0;
62
lo = 0; ro = 1;
63
found = FALSE;
64
while(found == FALSE)
65
{
66
lm = lu + lo;
67
rm = ru + ro;
68
for(i=0;i<n;i++)
69
for(j=0;j<=i;j++)
70
N->array.SZ[i][j] = lm * A->array.SZ[i][j] + rm * X->array.SZ[i][j];
71
for(i=0;i<n;i++)
72
for(j=0;j<i;j++)
73
N->array.SZ[j][i] = N->array.SZ[i][j];
74
j = definite_test(N);
75
if(j == 2)
76
{
77
SV = short_vectors(N, (lm * Amin -1), 0, 1, 0, &anz);
78
if(anz > 0)
79
found = TRUE;
80
else
81
{ lu = lm; ru = rm; free_mat(SV);}
82
}
83
else
84
{ lo = lm; ro = rm;}
85
}
86
87
/************************************************************************\
88
| The 1st row of SV containes an vector y with
89
| lm * min(A) > yNy^{tr} = lm * yAy^{tr} + rm * yXy^{tr}
90
| Now yAy^{tr} > min(A) and yXy^{tr} < 0.
91
| Calculate the rational number p/q = (Amin - yAy^{tr}) / (yXy^{tr}) >= 0.
92
| Then y (q * A + p * X) y^{tr} = q * Amin
93
| Replace N by q * A + p X.
94
| If min(N) = q * min(A) we are done, otherwise caluclate vector y'
95
| with y'Ny'^{tr} < q * min(A) and repeat.
96
\************************************************************************/
97
found = FALSE;
98
while(found == FALSE)
99
{
100
/************************************************************************\
101
| calculate Ay = y A y^{tr}
102
\************************************************************************/
103
Ay = 0;
104
for(i=0;i<n;i++)
105
{
106
merk = 0;
107
for(j=0;j<n;j++)
108
merk += A->array.SZ[i][j] * SV->array.SZ[0][j];
109
Ay += SV->array.SZ[0][i] * merk;
110
}
111
/************************************************************************\
112
| calculate Xy = y X y^{tr}
113
\************************************************************************/
114
Xy = 0;
115
for(i=0;i<n;i++)
116
{
117
merk = 0;
118
for(j=0;j<n;j++)
119
merk += X->array.SZ[i][j] * SV->array.SZ[0][j];
120
Xy += SV->array.SZ[0][i] * merk;
121
}
122
/************************************************************************\
123
| calculate the new N
124
\************************************************************************/
125
Ay -= Amin;
126
Xy = -Xy;
127
merk = GGT(Ay, Xy);
128
if(merk != 1)
129
{
130
Ay /= merk;
131
Xy /= merk;
132
}
133
for(i=0;i<n;i++)
134
for(j=0;j<=i;j++)
135
{
136
N->array.SZ[i][j] = Xy * A->array.SZ[i][j] + Ay * X->array.SZ[i][j];
137
N->array.SZ[j][i] = N->array.SZ[i][j];
138
}
139
free_mat(SV);
140
SV = short_vectors(N, (Xy * Amin - 1), 0, 1, 0, &anz);
141
if(anz == 0)
142
{ free_mat(SV); found = TRUE; *lc = Xy; *rc = Ay;}
143
}
144
145
/* canceled these lines on 16/2/97 because they don't fit
146
to specification and cause problems: tilman
147
********************************************************************\
148
| calculate the gcd of the entries of N and divide N by it
149
\********************************************************************
150
g = N->array.SZ[0][0];
151
for(i=1;i<n;i++)
152
for(j=0;j<=i;j++)
153
g = GGT(g, N->array.SZ[i][j]);
154
if(g < 0)
155
g = -g;
156
if(g != 1)
157
{
158
for(i=0;i<n;i++)
159
for(j=0;j<n;j++)
160
N->array.SZ[i][j] /= g;
161
}
162
163
printf("in vor_nei g %d\n",g);
164
*/
165
166
return(N);
167
}
168
169