CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

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

Views: 418346
1
/****************************************************************************
2
**
3
*A compact_description.c ANUPQ source Eamonn O'Brien
4
**
5
*Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
6
*Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia
7
**
8
*/
9
10
#include "pq_defs.h"
11
#include "pcp_vars.h"
12
#include "pq_functions.h"
13
#include "constants.h"
14
15
/******************************************************************************
16
** AUTHOR: C. Rhodes
17
** DATE: 21/1/93
18
** REVISION: 1.0 (Release)
19
** STATUS: This code is designed to be an extension to the pq program
20
** by E.A. O'Brien. It encodes the pc-presentation into a
21
** sequence of integers and then appends that sequence to a
22
** file called gps<order>, where <order> is the order of the
23
** group. Note that existing files of this name are updated.
24
****************************************************************************/
25
26
#ifdef HAVE_GMP
27
28
MP_INT Encode(int p, int length, int *list)
29
{
30
MP_INT powers, code;
31
int i;
32
33
mpz_init_set_ui(&code, 0);
34
35
for (i = 1; i <= length; ++i) {
36
mpz_init_set_si(&powers, 0);
37
if (list[i] != 0)
38
mpz_ui_pow_ui(&powers, p, i - 1);
39
mpz_add(&code, &code, &powers);
40
}
41
/*
42
if (list[i] != 0) {
43
MP_INT factor;
44
mpz_init_set_si (&factor, list[i]);
45
mpz_ui_pow_ui (&powers, p, i);
46
mpz_mul (&powers, &powers, &factor);
47
mpz_add (&code, &code, &powers);
48
}
49
}
50
*/
51
return code;
52
}
53
#endif
54
55
/* construct a compact description of the group as a sequence;
56
if write_to_file TRUE, then write the compact description,
57
sequence, to file and also return it */
58
59
int *compact_description(Logical write_to_file, struct pcp_vars *pcp)
60
{
61
register int *y = y_address;
62
63
register int p1;
64
register int p2;
65
int *sequence;
66
int nmr_of_exponents;
67
int weight_g, weight_h;
68
int g, h;
69
int generator;
70
int offset;
71
int index; /* used to count current position in sequence of exponents */
72
int n;
73
#include "access.h"
74
75
n = pcp->lastg;
76
nmr_of_exponents = choose(n + 1, 3);
77
sequence = allocate_vector(nmr_of_exponents, 1, TRUE);
78
79
offset = 0;
80
index = 0;
81
82
if (pcp->cc == 1) {
83
/* write the sequence to a file */
84
output_information(sequence, nmr_of_exponents, pcp);
85
return sequence;
86
}
87
88
for (generator = 2; generator <= n; ++generator) {
89
90
/* examine all power relations g^p where g < generator and store
91
all exponents of generator which occur in these relations */
92
93
for (g = 1; g < generator; ++g) {
94
p1 = y[pcp->ppower + g];
95
96
trace_relation(sequence, &index, p1, generator, pcp);
97
98
/* examine all commutator relations [h, g] where g < h < generator
99
and store exponents of generator which occur in such relations */
100
101
weight_g = WT(y[pcp->structure + g]);
102
103
/* is the relation [h, g] stored? */
104
for (h = g + 1; h < generator; ++h) {
105
weight_h = WT(y[pcp->structure + h]);
106
if (weight_g + weight_h <= pcp->cc) {
107
p1 = y[pcp->ppcomm + h];
108
p2 = y[p1 + g];
109
trace_relation(sequence, &index, p2, generator, pcp);
110
} else
111
++index;
112
}
113
}
114
115
offset += (generator - 1) * (generator - 2) / 2 + (generator - 1);
116
index = offset;
117
}
118
119
#if defined(DEBUG)
120
print_array(sequence, 1, nmr_of_exponents);
121
#endif
122
123
/* write the sequence to a file */
124
if (write_to_file)
125
output_information(sequence, nmr_of_exponents, pcp);
126
127
return sequence;
128
}
129
130
/* find all occurences of generator in relation with address ptr */
131
132
void trace_relation(
133
int *sequence, int *index, int ptr, int generator, struct pcp_vars *pcp)
134
{
135
register int *y = y_address;
136
137
int i, gen, exp, count;
138
#include "access.h"
139
140
++(*index);
141
if (ptr == generator)
142
sequence[*index] = 1;
143
else if (ptr < 0) {
144
ptr = -ptr + 1;
145
count = y[ptr];
146
for (i = 1; i <= count; i++) {
147
gen = FIELD2(y[ptr + i]);
148
if (gen == generator) {
149
exp = FIELD1(y[ptr + i]);
150
sequence[*index] = exp;
151
}
152
}
153
}
154
}
155
156
/* append the sequence of length nmr_of_exponents to file with name
157
formed by concatenating "gps" and "p^n" */
158
159
void
160
output_information(int *sequence, int nmr_of_exponents, struct pcp_vars *pcp)
161
{
162
register int *y = y_address;
163
164
FILE *output_file;
165
char *file_name;
166
#ifdef HAVE_GMP
167
MP_INT code;
168
#else
169
register int count;
170
#endif
171
172
file_name = allocate_char_vector(MAXWORD + 1, 0, FALSE);
173
174
sprintf(file_name, "gps%d^%d", pcp->p, pcp->lastg);
175
176
/* open the file in update mode */
177
output_file = OpenFile(file_name, "a+");
178
179
/* write rank of Frattini quotient, number of pcp generators, prime,
180
and exponent-p class to file */
181
182
#ifdef HAVE_GMP
183
fprintf(
184
output_file, "[%d, %d, %d, ", y[pcp->clend + 1], pcp->lastg, pcp->cc);
185
code = Encode(pcp->p, nmr_of_exponents, sequence);
186
mpz_out_str(output_file, 10, &code);
187
fprintf(output_file, "],\n");
188
#else
189
fprintf(output_file,
190
"%d %d %d %d ",
191
y[pcp->clend + 1],
192
pcp->lastg,
193
pcp->p,
194
pcp->cc);
195
/* now write out the sequence of exponents */
196
for (count = 1; count <= nmr_of_exponents - 1; count++)
197
fprintf(output_file, "%d,", sequence[count]);
198
fprintf(output_file, "%d\n", sequence[nmr_of_exponents]);
199
#endif
200
201
CloseFile(output_file);
202
203
free(file_name);
204
}
205
206