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 collectp2.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 "constants.h"
13
14
void
15
add_p2string(int string, int length, int collected_part, struct pcp_vars *pcp);
16
17
/* collection procedure for the prime 2;
18
this routine is documented in the file collect.c */
19
20
void collectp2(int pointer, int collected_part, struct pcp_vars *pcp)
21
{
22
register int *y = y_address;
23
24
register int p1; /* string pointer */
25
register int cg; /* collected generator */
26
register int ug; /* uncollected generator */
27
register int sp = 0; /* stack pointer */
28
register int len = 1; /* length */
29
register int str; /* string pointer */
30
register int halfwt; /* last generator with weight <= cc/2 */
31
register int weight_diff; /* current class - weight of ug */
32
register int firstcg; /* first collected generator for loop counter */
33
register int lastcg; /* last collected generator for loop counter */
34
35
register int cp = collected_part;
36
register int class_end = pcp->clend;
37
register int current_class = pcp->cc;
38
register int p_pcomm = pcp->ppcomm;
39
register int p_power = pcp->ppower;
40
register int structure = pcp->structure;
41
42
int strstk[STACK_SIZE]; /* string stack */
43
int lenstk[STACK_SIZE]; /* length stack */
44
45
register int i;
46
47
#include "access.h"
48
49
/* Step (0) --
50
initialize collector */
51
52
if (pointer < 0)
53
lenstk[0] = y[-pointer + 1];
54
else if (pointer == 0)
55
return;
56
57
halfwt = y[class_end + current_class / 2];
58
strstk[0] = pointer;
59
60
/* Step (1) --
61
process next word on stack */
62
63
while (sp >= 0) {
64
str = strstk[sp];
65
if (str < 0) {
66
/* we have a genuine string */
67
len = lenstk[sp];
68
sp--;
69
70
/* get first generator from string */
71
i = y[-str + 2];
72
ug = FIELD2(i);
73
/* if ug > halfwt, whole string can be added to the
74
collected part without creating any commutators */
75
if (ug > halfwt) {
76
add_p2string(str, len, cp, pcp);
77
continue;
78
}
79
80
if (len != 1) {
81
/* stack remainder of string */
82
strstk[++sp] = str - 1;
83
lenstk[sp] = len - 1;
84
}
85
} else {
86
/* str is a generator */
87
ug = str;
88
sp--;
89
/* if ug > halfwt, ug commutes with all higher generators */
90
if (ug > halfwt) {
91
add_p2string(ug, 1, cp, pcp);
92
continue;
93
}
94
}
95
96
/* Step (2) --
97
combinatorial collection;
98
move ug past entries in the collected part, adding
99
commutators directly to the collected part;
100
if 2 * WT(cg) + WT(ug) > current_class then [cg, ug]
101
commutes with all generators k such that k >= cg;
102
scan collected part towards the left, bypassing
103
generators we know must commute with ug */
104
105
weight_diff = current_class - WT(y[structure + ug]);
106
firstcg = y[class_end + weight_diff];
107
lastcg = y[class_end + weight_diff / 2];
108
109
for (cg = firstcg; cg > ug; cg--) {
110
if (y[cp + cg] != 0) {
111
/* add [cg, ug] directly to the collected part */
112
p1 = y[p_pcomm + cg];
113
p1 = y[p1 + ug];
114
if (p1 != 0) {
115
if (cg <= lastcg)
116
break;
117
if (p1 < 0)
118
len = y[-p1 + 1];
119
add_p2string(p1, len, cp, pcp);
120
}
121
}
122
}
123
124
if (cg == ug) {
125
/* we have reached the ug position during combinatorial collection;
126
check whether we can avoid stacking collected part */
127
if (y[cp + ug] == 0) {
128
y[cp + ug] = 1;
129
continue;
130
} else {
131
if (y[p_power + ug] == 0) {
132
y[cp + ug] = 0;
133
continue;
134
}
135
}
136
}
137
138
/* we do have to stack some of the collected part */
139
for (i = firstcg; i > cg; i--) {
140
if (y[cp + i] != 0) {
141
/* set entry to zero and stack i */
142
y[cp + i] = 0;
143
if (++sp >= STACK_SIZE)
144
stack_overflow();
145
strstk[sp] = i;
146
}
147
}
148
149
/* Step (3) --
150
ordinary collection; continue scanning towards the left,
151
stacking up commutators and entries in collected part
152
until we reach ug position */
153
154
for (; cg > ug; cg--) {
155
if (y[cp + cg] != 0) {
156
/* zero the cg entry of collected part */
157
y[cp + cg] = 0;
158
/* get [cg, ug] */
159
p1 = y[p_pcomm + cg];
160
p1 = y[p1 + ug];
161
162
/* move ug past cg stacking [cg, ug] and cg */
163
if (sp + 2 >= STACK_SIZE)
164
stack_overflow();
165
if (p1 != 0) {
166
/* stack [cg, ug] if it is non-trivial */
167
strstk[++sp] = p1;
168
if (p1 < 0)
169
lenstk[sp] = y[-p1 + 1];
170
}
171
172
/* stack cg */
173
strstk[++sp] = cg;
174
}
175
}
176
177
add_p2string(ug, 1, cp, pcp);
178
continue;
179
}
180
}
181
182
/* prime = 2;
183
add the string with address string and length length
184
directly to the collected part with base address collected_part,
185
recursively adding powers as required */
186
187
void
188
add_p2string(int string, int length, int collected_part, struct pcp_vars *pcp)
189
{
190
register int *y = y_address;
191
192
register int cp = collected_part;
193
register int str = string;
194
register int len = length;
195
register int ug;
196
197
register int class_begin = pcp->ccbeg;
198
register int p_power = pcp->ppower;
199
200
register int i;
201
int lower, upper;
202
#include "access.h"
203
204
if (str > 0) {
205
/* Step (4) --
206
we have moved generator str to the correct position;
207
add 1 to the str entry of the collected part; reduce
208
entry modulo 2 and add str^2 to collected part if necessary */
209
210
if (y[cp + str] == 0)
211
y[cp + str] = 1;
212
else {
213
/* we need to recursively add in str^2 */
214
y[cp + str] = 0;
215
if (str < class_begin) {
216
str = y[p_power + str];
217
if (str != 0) {
218
if (str < 0)
219
len = y[-str + 1];
220
add_p2string(str, len, cp, pcp);
221
}
222
}
223
}
224
} else {
225
/* Step (5) --
226
add string with base address -str and length len directly
227
to the collected part; if this creates an entry >= 2, reduce
228
entry modulo 2 and recursively add in the appropriate power */
229
230
lower = -str + 2;
231
upper = -str + len + 1;
232
233
/* get one generator exponent pair at a time from string */
234
235
for (i = lower; i <= upper; i++) {
236
ug = FIELD2(y[i]);
237
if (y[cp + ug] == 0)
238
y[cp + ug] = 1;
239
else {
240
y[cp + ug] = 0;
241
if (ug < class_begin) {
242
/* we need to recursively add in ug^2 */
243
str = y[p_power + ug];
244
if (str != 0) {
245
if (str < 0)
246
len = y[-str + 1];
247
add_p2string(str, len, cp, pcp);
248
}
249
}
250
}
251
}
252
}
253
}
254
255