static PointSet *knownIrreducible[10] /* Null terminated 0-base list of */
= {NULL}; /* point sets Lambda for which top */ /* partition on UpsilonStack is */ /* known to be SSS_Lambda irred. */
/* Function designAutoGroup. Returns a new permutation group representing theautomorphismgroupofthematrix/designD.Thealgorithmisbased onFigure9inthepaper"Permutationgroupalgorithmsbasedonpartitions"bythe
author. */
#define familyParm familyParm_L
PermGroup *designAutoGroup(
Matrix_01 *const D, /* The matrix whose group is to be found. */
PermGroup *const L, /* A (possibly trivial) known subgroup of the automorphismgroupofD.(Anullpointer
designates a trivial group.) */
Code *const C) /* If nonnull, the auto grp of the code C is computed,assumingitsgroupiscontained
in that of the design. */
{
RefinementFamily SSS_Lambda, III_D;
RefinementFamily *refnFamList[3];
ReducChkFn *reducChkList[3];
SpecialRefinementDescriptor *specialRefinement[3];
ExtraDomain *extra[1];
PointSet *Lambda = allocPointSet(); /* Set of rows. */
PermGroup *G; Unsigned degree = D->numberOfRows + D->numberOfCols; Unsigned i;
Property *pp;
/* Construct the symmetric group G of degree rows+cols. */
G = allocPermGroup();
sprintf( G->name, "%c%d", SYMMETRIC_GROUP_CHAR, degree);
G->degree = degree;
G->baseSize = 0;
/* Construct the set Lambda of points, ie. Lambda = {1,...,numberOfRows}. */
Lambda->degree = degree;
Lambda->size = D->numberOfRows;
Lambda->pointList = allocIntArrayDegree(); for ( i = 1 ; i <= D->numberOfRows ; ++i )
Lambda->pointList[i] = i;
Lambda->pointList[D->numberOfRows+1] = 0;
Lambda->inSet = allocBooleanArrayDegree(); for ( i = 1 ; i <= degree ; ++i )
Lambda->inSet[i] = ( i <= D->numberOfRows);
/* Function designIsomorphism. Returns a permutation mapping one specified matrix/designD_Ltoanothermatrix/designD_R.Thetwomatricesmusthave thesamenumberofrowsandthesamenumberofcolumns.Thealgorithmis basedonFigure9inthepaper"Permutationgroupalgorithmsbasedon
partitions" by the author. */
Permutation *designIsomorphism(
Matrix_01 *const D_L, /* The first design. */
Matrix_01 *const D_R, /* The second design. */
PermGroup *const L_L, /* A known subgroup of Aut(D_L), or NULL. */
PermGroup *const L_R, /* A known subgroup of Aut(D_R), or NULL. */
Code *const C_L, /* If nonnull, C_R must also be nonull, and */
Code *const C_R, /* any isomorphism of C_L to C_R must map */ /* D_L to D_R. A code isomorphism is */ /* computed. */ const BOOLEAN colInformFlag)
{
RefinementFamily SSS_Lambda_Lambda, III_DL_DR;
RefinementFamily *refnFamList[3];
ReducChkFn *reducChkList[3];
SpecialRefinementDescriptor *specialRefinement[3];
ExtraDomain *extra[1];
PointSet *Lambda = allocPointSet(); /* Set of rows. */
PermGroup *G; Unsigned degree = D_L->numberOfRows + D_L->numberOfCols; Unsigned i;
Property *pp;
/* Construct the symmetric group G of degree rows+cols. */
G = allocPermGroup();
sprintf( G->name, "%c%d", SYMMETRIC_GROUP_CHAR, degree);
G->degree = degree;
G->baseSize = 0;
/* Construct the set Lambda of points, ie. Lambda = {1,...,numberOfRows}. */
Lambda->degree = degree;
Lambda->size = D_L->numberOfRows;
Lambda->pointList = allocIntArrayDegree(); for ( i = 1 ; i <= D_L->numberOfRows ; ++i )
Lambda->pointList[i] = i;
Lambda->pointList[D_L->numberOfRows+1] = 0;
Lambda->inSet = allocBooleanArrayDegree(); for ( i = 1 ; i <= degree ; ++i )
Lambda->inSet[i] = ( i <= D_L->numberOfRows);
/* The function implements the refinement family setStabRefine (denoted SSS_Lambdainthereference).Thisfamilyconsistsoftheelementary refinementsssS_{Lambda,i},whereLambdafixed.(Itisthesettobe stabilized)andwhere1<=i<=degree.ApplicationofsSS_{Lambda,i}to UpsilonStacksplitsofffromUpsilonToptheintersectionofLambdaandthe i'thcellofUpsilonTopfromcelliofthetoppartitionofUpsilonStackand pushestheresultingpartitionontoUpsilonStack,unlesssSS_{Lambda,i}acts triviallyonUpsilonTop,inwhichcaseUpsilonStackremainsunchanged.
/* First check if the refinement acts nontrivially on UpsilonTop. If not
return immediately. */ for ( m = startCell[cellToSplit] , last = m + cellSize[cellToSplit] ;
m < last && (inLambdaCount == 0 || outLambdaCount == 0) ; ++m ) if ( inSet[pointList[m]] )
++inLambdaCount; else
++outLambdaCount; if ( inLambdaCount == 0 || outLambdaCount == 0 ) {
split.oldCellSize = cellSize[cellToSplit];
split.newCellSize = 0; return split;
}
/* Now split cell cellToSplit of UpsilonTop. A variation of the splitting
algorithm used in quicksort is applied. */
i = startCell[cellToSplit]-1;
j = last; while ( i < j ) { while ( !inSet[pointList[++i]] ); while ( inSet[pointList[--j]] ); if ( i < j ) {
EXCHANGE( pointList[i], pointList[j], temp)
EXCHANGE( invPointList[pointList[i]], invPointList[pointList[j]], temp)
}
}
++UpsilonStack->height; for ( m = i ; m < last ; ++m )
cellNumber[pointList[m]] = UpsilonStack->height;
startCell[UpsilonStack->height] = i;
parent[UpsilonStack->height] = cellToSplit;
cellSize[UpsilonStack->height] = last - i;
cellSize[cellToSplit] -= (last - i);
split.oldCellSize = cellSize[cellToSplit];
split.newCellSize = cellSize[UpsilonStack->height]; return split;
}
/* The function isSetStabReducible checks whether the top partition on a given partitionstackisSSS_Lambda-reducible,whereLambdaisafixedset.If so,itreturnsapairconsistingofarefinementactingnontriviallyon thetoppartitionandapriority.Otherwiseitreturnsastructureof typeRefinementPriorityPairinwhichthepriorityfieldisIRREDUCIBLE.Assuming thatareducingrefinementisfound,the(reverse)priorityissetvery low(1).Notethat,oncethisfunctionreturnsnegativeinthepriority fieldonce,itwilldosoonallsubsequentcalls.(Thestaticvariable knownIrreducibleissettotrueinthissituation.)Again,noattempt
at efficiency has been made. */
/* Check that the refinement mapping really is setStabRefn, as required. */ if ( family->refine != setStabRefine )
ERROR( "isSetStabReducible", "Error: incorrect refinement mapping");
/* If the top partition has previously been found to be SSS-irreducible, we
return immediately. */ for ( i = 0 ; knownIrreducible[i] && knownIrreducible[i] != Lambda ; ++i )
; if ( knownIrreducible[i] ) {
reducingRefn.priority = IRREDUCIBLE; return reducingRefn;
}
/* If we reach here, the top partition has not been previously found to be SSS-irreducible.Wecheckeachcellinturntoseeifitintersectsboth LambdaandOmega-Lambda.Ifsuchacellisfound,wereturn
immediately. */ for ( cellNo = 1 ; cellNo <= UpsilonStack->height ; ++cellNo ) {
ptsInLambda = ptsNotInLambda = FALSE; for ( position = startCell[cellNo] ; position < startCell[cellNo] +
cellSize[cellNo] ; ++position ) { if ( inSet[pointList[position]] )
ptsInLambda = TRUE; else
ptsNotInLambda = TRUE; if ( ptsInLambda && ptsNotInLambda ) {
reducingRefn.refn.family = (RefinementFamily *)(family);
reducingRefn.refn.refnParm[0].intParm = cellNo;
reducingRefn.priority = 1; return reducingRefn;
}
}
}
/* If we reach here, we have found the top partition to be SSS_Lambda
irreducible, so we add Lambda to the list knownIrreducible and return. */ for ( i = 0 ; knownIrreducible[i] ; ++i )
; if ( i < 9 ) {
knownIrreducible[i] = Lambda;
knownIrreducible[i+1] = NULL;
} else
ERROR( "isSetStabReducible", "Number of point sets exceeded max of 9.")
/* The function implements the refinement families III_RC and III_CR. Here III_RCconsistsoftheelementaryrefinementsIIi_RC_{D,i,j,m},where IIi_RC_{D,i,j,m}splitsfromrowcellithoserowsthathavemonesin columncellj,andIIi_CR_{D,i,j,m}splitsfromcolumncellithosecolumns thathavemonesinrowcellj.Notethatfromiandjtheroutinecan tellwhetherIII_RCorIII_CRshouldbeapplied. Thefamilyparameteris: familyParm[0].ptrParm:D(thematrix) Therefinementparametersare: refnParm[0].intParm:i. refnParm[1].intParm:j. refnParm[2].intParm:m.
/* Allocate list, freq, and nextCellSameType the first time. */ if ( !list )
list = allocIntArrayDegree(); if ( !freq )
freq = allocIntArrayDegree(); if ( !nextCellSameType ) {
nextCellSameType = allocIntArrayDegree();
nextCellSameType[0] = 0;
}
/* Check that the refinement mapping really is rowVsColRefine, as
required. */ if ( family->refine != rowVsColRefine )
ERROR( "isRowVsColReducible", "Error: incorrect refinement mapping");
/* If the height is 1 (row/col split not yet performed), return
irreducible. */ if ( UpsilonStack->height == 1 ) {
reducingRefn.priority = IRREDUCIBLE; return reducingRefn;
}
/* When the stack height reaches 2 (1 row cell, 1 col cell), perform
initializations for nextCellSameType, etc. */ if ( UpsilonStack->height == 2 ) {
firstRowCell = (CELL_TYPE(1) == ROW) ? 1 : 2;
firstColCell = 3 - firstRowCell;
lastRowCell = firstRowCell;
lastColCell = firstColCell;
nextCellSameType[1] = nextCellSameType[2] = 0;
}
/* If we can split the same cell as before using a different intersection
count, do so immediately (priority 1). */ if ( listSize > 0 ) {
reducingRefn.refn.family = (RefinementFamily *)(family);
reducingRefn.refn.refnParm[0].intParm = opposingCell;
reducingRefn.refn.refnParm[1].intParm = 0;
reducingRefn.refn.refnParm[2].intParm = list[listSize--];
reducingRefn.priority = 1;
skipFlag = TRUE; return reducingRefn;
}
/* Consider the next opposing cell for the cell being processed, or the nextcelltobeprocessediftherearenomoreopposingcells.First
we update nextCellSameType (Note this must be done only here). */ for (;;) { if ( nextCellSameType[opposingCell] != 0 )
opposingCell = nextCellSameType[opposingCell]; elseif ( processingCell < UpsilonStack->height ) {
++processingCell; for ( i = MAX(lastRowCell,lastColCell)+1 ; i <= UpsilonStack->height ;
++i ) switch( CELL_TYPE(i) ) { case ROW:
nextCellSameType[lastRowCell] = i;
lastRowCell = i;
nextCellSameType[i] = 0; break; case COL:
nextCellSameType[lastColCell] = i;
lastColCell = i;
nextCellSameType[i] = 0; break;
}
opposingCell = ( CELL_TYPE(processingCell) == ROW) ? firstColCell:
firstRowCell;
} else {
reducingRefn.priority = IRREDUCIBLE; return reducingRefn;
}
/* Now we try to split opposingCell using processingCell, and an intersectionCountthatguaranteesfailure.(ThisforcesrowVsColRefine
to compute the header, etc). */
reducingRefn.refn.refnParm[0].intParm = opposingCell;
reducingRefn.refn.refnParm[1].intParm = processingCell;
reducingRefn.refn.refnParm[2].intParm = UpsilonStack->degree + 1;
rowVsColRefine( family->familyParm, reducingRefn.refn.refnParm,
(PartitionStack *const)(UpsilonStack));
/* If no splitting occured of opposing cell via processing cell is possible,nonZeroCountwillbe1.Ifthisoccurs,skiptothenext
pair (processingCell,opposingCell). */ if ( nonZeroCount == 1 ) continue;
/* Now we consider all the possible splittings of opposingCell, reject
that giving the largest new cell, and put the others on the list. */ for ( k = 1 ; k <= nonZeroCount ; ++k) {
freq[k] = 1;
p = header[nonZeroPosition[k]]; while ( node[p].link != 0 ) {
++freq[k];
p = node[p].link;
}
}
maxPos = 1; for ( k = 2 ; k <= nonZeroCount ; ++k ) if ( freq[k] > freq[maxPos] )
maxPos = k;
listSize = 0; for ( k = 1 ; k <= nonZeroCount ; ++k ) if ( k != maxPos )
list[++listSize] = nonZeroPosition[k];
/* Finally return the first entry on the list. */
reducingRefn.refn.family = (RefinementFamily *)(family);
reducingRefn.refn.refnParm[0].intParm = opposingCell;
reducingRefn.refn.refnParm[1].intParm = processingCell;
reducingRefn.refn.refnParm[2].intParm = list[listSize--];
reducingRefn.priority = 1;
skipFlag = TRUE; return reducingRefn;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.