/****************************************************************************
**
*A permute_subgroups.c ANUPQ source Eamonn O'Brien
**
*Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
*Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia
**
*/
#include "pq_defs.h"
#include "pcp_vars.h"
#include "pga_vars.h"
#include "pq_functions.h"
#include "constants.h"
/* compute all of the permutations of the allowable subgroups
induced by the extended automorphisms described in auts;
store them in image format in a 2-dimensional array, perms */
int **permute_subgroups(FILE *LINK_input,
int **a,
int **b,
char **c,
int ***auts,
struct pga_vars *pga,
struct pcp_vars *pcp)
{
register int alpha;
register int nmr_of_perms;
register int q = pga->q;
int **A; /* automorphism matrix */
int **perms;
Logical soluble_group;
soluble_group = (pga->soluble || pga->Degree == 1 || pga->nmr_of_perms == 0);
/* set up space for automorphism matrix */
A = allocate_matrix(q, q, 0, FALSE);
/* set up space for orbit and stabiliser information */
if (soluble_group && pga->space_efficient)
space_for_orbits(a, b, c, pga);
/* set up space to store permutations */
nmr_of_perms = (pga->space_efficient ? 1 : MAX(pga->nmr_of_perms, 1));
perms = allocate_matrix(nmr_of_perms, pga->Degree, 1, FALSE);
/* the stabiliser of a reduced p-covering group may be trivial */
if (pga->nmr_of_perms == 0)
setup_identity_perm(perms[nmr_of_perms], pga);
for (alpha = 1; alpha <= pga->m; ++alpha) {
if (pga->trace)
printf("Processing automorphism %d:\n", alpha);
assemble_matrix(A, q, auts[alpha], pcp);
/* check if the matrix passes some elementary tests */
if (!valid_matrix(A, q, pga->p, 0)) {
printf("The following automorphism matrix is invalid\n");
print_matrix(A, q, q);
exit(FAILURE);
}
if (pga->print_automorphism_matrix) {
printf("Automorphism matrix %d is\n", alpha);
print_matrix(A, q, q);
}
if (!soluble_group) {
#if defined(GAP_LINK) || defined(GAP_LINK_VIA_FILE)
write_GAP_matrix(LINK_input, "ANUPQglb.genQ", A, q, 0, alpha);
#endif
}
/* is the action on the p-multiplicator non-trivial? */
if (pga->map[alpha] != 0) {
nmr_of_perms = (pga->space_efficient ? 1 : pga->map[alpha]);
compute_permutation(perms[nmr_of_perms], A, pga);
if (pga->print_permutation) {
printf("Permutation %d is\n", alpha);
print_array(perms[nmr_of_perms], 1, pga->Degree + 1);
}
}
if (soluble_group && pga->space_efficient) {
if (pga->map[alpha] != 0)
orbits(perms[nmr_of_perms], *a, *b, *c, pga);
else
process_identity_perm(*a, *b, *c, pga);
}
}
free_matrix(A, q, 0);
return perms;
}
/* compute and store in image form the permutation that the extended
automorphism stored in A induces on the allowable subgroups */
void compute_permutation(int *permutation, int **A, struct pga_vars *pga)
{
register int i;
if (pga->s != 0) {
/* process each definition set in turn */
pga->nmr_subgroups = 0;
for (i = 0; i < pga->nmr_def_sets; ++i)
compute_images(A, pga->list[i], pga->available[i], permutation, pga);
} else {
permutation[1] = 1;
pga->nmr_subgroups = 1;
}
}
/* compute the images of all allowable subgroups having definition
set K under the action of automorphism matrix A */
void compute_images(
int **A, int K, int depth, int *permutation, struct pga_vars *pga)
/* number of available positions */
{
int **S; /* standard matrix */
int **Image; /* image of allowable subgroup under A */
int *row; /* indices of available positions in S */
int *column;
int *position; /* array to keep track of processed image */
int *subset; /* array to store definition set of image */
int K_Image; /* bit string representation of same */
int nmr_of_bytes = pga->q * sizeof(int);
register int i;
register int index;
register int s = pga->s;
register int q = pga->q;
register int p = pga->p;
register int nmr_subgroups = pga->nmr_subgroups;
S = allocate_matrix(s, q, 0, FALSE);
Image = allocate_matrix(s, q, 0, TRUE);
subset = allocate_vector(s, 0, 0);
position = allocate_vector(depth + 1, 0, 1);
/* set up row and column indices of available positions as
arrays of length depth + 1; also set up Image as image of
allowable subgroup with least label under action of A */
find_available_positions(K, A, Image, &row, &column, depth, pga);
/* for each allowable subgroup in turn, compute its image under A */
do {
/* make a copy of the image matrix and echelonise the copy */
for (i = 0; i < s; ++i)
memcpy(S[i], Image[i], nmr_of_bytes);
K_Image = echelonise_matrix(S, s, q, p, subset, pga);
/* compute and store the label of the resulting standard matrix */
++nmr_subgroups;
if (nmr_subgroups % 1000000 == 0)
printf("processing subgroup %d\n", nmr_subgroups);
permutation[nmr_subgroups] = subgroup_to_label(S, K_Image, subset, pga);
index = 0;
++position[0];
update_image(A, column[index], Image, row[index], pga);
while (index < depth && position[index] == p) {
position[index] = 0;
++index;
++position[index];
update_image(A, column[index], Image, row[index], pga);
}
} while (index < depth);
pga->nmr_subgroups = nmr_subgroups;
free_vector(row, 0);
free_vector(column, 0);
free_vector(subset, 0);
free_vector(position, 0);
free_matrix(S, s, 0);
free_matrix(Image, s, 0);
}
/* add column of A to row of Image */
void
update_image(int **A, int column, int **Image, int row, struct pga_vars *pga)
{
register int i;
register int q = pga->q;
register int p = pga->p;
for (i = 0; i < q; ++i)
Image[row][i] = (Image[row][i] + A[i][column]) % p;
}
/* set up the indices of the available positions of the standard matrices
determined by K as two arrays, row and column; also set up Image as
image of allowable subgroup with least label under action of A */
void find_available_positions(int K,
int **A,
int **Image,
int **row,
int **column,
int depth,
struct pga_vars *pga)
{
register int i, j;
register int index = 0;
register int s = pga->s;
register int q = pga->q;
int *subset;
subset = bitstring_to_subset(K, pga);
*row = allocate_vector(depth + 1, 0, 0);
*column = allocate_vector(depth + 1, 0, 0);
(*row)[depth] = 0;
(*column)[depth] = 0;
for (i = 0; i < s; ++i) {
update_image(A, subset[i], Image, i, pga);
for (j = subset[i] + 1; j < q; ++j) {
if (1 << j & K)
continue;
(*row)[index] = i;
(*column)[index] = j;
++index;
}
}
free_vector(subset, 0);
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|