/****************************************************************************
**
*A soluble_orbits.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 "constants.h"
#include "pq_functions.h"
/* compute the orbits of the allowable subgroups,
where the permutation group is soluble */
void
compute_orbits(int **a, int **b, char **c, int **perms, struct pga_vars *pga)
{
register int alpha;
int perm_number;
/* set up space for orbit and stabiliser information */
space_for_orbits(a, b, c, pga);
/* now compute the orbits */
for (alpha = 1; alpha <= pga->m; ++alpha) {
if ((perm_number = pga->map[alpha]) != 0)
orbits(perms[perm_number], *a, *b, *c, pga);
else
process_identity_perm(*a, *b, *c, pga);
}
}
/* allocate and initialise space for orbit and stabiliser calculations */
void space_for_orbits(int **a, int **b, char **c, struct pga_vars *pga)
{
register int i;
register int Degree = pga->Degree;
*a = allocate_vector(Degree, 1, FALSE);
*b = allocate_vector(Degree, 1, TRUE);
*c = allocate_char_vector(Degree, 1, FALSE);
for (i = 1; i <= Degree; ++i) {
*(*a + i) = i;
*(*c + i) = 1;
}
}
/* process identity permutation -- we need only to update c[j] which is the
number of times j has been last image in orbit with leading term a[j] */
void process_identity_perm(int *a, int *b, char *c, struct pga_vars *pga)
{
register int Degree = pga->Degree;
int j, last, element;
/* find the last entry, last, for each orbit, and increment c[last] */
for (j = 1; j <= Degree; ++j) {
if (a[j] == j) {
/* trace this orbit */
last = j;
element = j;
while (element != 0) {
last = element;
element = b[element];
}
++c[last];
}
}
}
/* trace the action of the supplied permutation
on the existing orbits where
a[j] = leading term of existing orbit containing j
b[j] = next term in existing orbit containing j
c[j] = number of times j has been last image in orbit
with leading term a[j] */
void orbits(int *permutation, int *a, int *b, char *c, struct pga_vars *pga)
{
register int j;
for (j = 1; j <= pga->Degree; ++j)
if (a[j] == j)
trace_action(permutation, j, a, b, c);
}
/* trace the action of the permutation on the orbit whose leading term is j */
void trace_action(int *permutation, int j, int *a, int *b, char *c)
{
register int k, lead, image;
Logical merge;
/* find the last term, k, in the orbit of j */
k = j;
while (b[k] != 0)
k = b[k];
/* while the image of k lies outside the orbit whose leading term is j,
merge the existing orbit of k with that of j by running through
each element of the existing orbit of k and updating its entry
in array a so that it now lies in the orbit with leading term j;
let k be the last entry of the existing orbit */
merge = TRUE;
while (merge) {
image = permutation[k];
lead = a[image];
if (lead != j) {
b[k] = lead;
while (b[k] != 0) {
a[b[k]] = j;
c[b[k]] = 0;
k = b[k];
}
} else {
++c[k];
merge = FALSE;
}
}
}
/* list the orbit with leading term j and return its length */
int soluble_list_orbit(int j, int *b, struct pga_vars *pga)
{
register int orbit_length = 0;
while (j != 0) {
++orbit_length;
if (pga->print_orbits)
printf("%d ", j);
j = b[j];
}
return orbit_length;
}
/* find the orbit representatives, number of orbits, and orbit lengths;
also list the individual orbits */
int *soluble_find_orbit_reps(int *a, int *b, struct pga_vars *pga)
{
register int j;
register int counter = 0;
int *orbit_length;
/* find the number of orbits */
pga->nmr_orbits = 0;
for (j = 1; j <= pga->Degree; ++j)
if (a[j] == j)
++pga->nmr_orbits;
/* set up space to store orbit representatives and orbit lengths */
pga->rep = allocate_vector(pga->nmr_orbits, 1, 0);
orbit_length = allocate_vector(pga->nmr_orbits, 1, 0);
/* list the elements of each orbit and find its length */
for (j = 1; j <= pga->Degree && counter <= pga->nmr_orbits; ++j) {
if (a[j] == j) {
++counter;
pga->rep[counter] = j;
if (pga->print_orbits)
printf("\nOrbit %d:\n", counter);
orbit_length[counter] = soluble_list_orbit(j, b, pga);
if (pga->print_orbits)
printf("\nLength is %d\n", orbit_length[counter]);
}
}
return orbit_length;
}
/* print out contents of three arrays created during orbit calculation */
void print_orbit_information(int *a, int *b, char *c, struct pga_vars *pga)
{
printf("The array A is \n");
print_array(a, 1, pga->nmr_subgroups + 1);
printf("The array B is \n");
print_array(b, 1, pga->nmr_subgroups + 1);
printf("The array C is \n");
print_chars(c, 1, pga->nmr_subgroups + 1);
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|