Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/difsets/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 14.8.2019 mit Größe 11 kB image not shown  

Quelle  refine.gi   Sprache: unbekannt

 
#############################################################################
##
#W  refine.gi                DifSets Package                     Dylan Peifer
##
##  Functions find all possible difference set/sum preimages of difference
##  sums.
##

#############################################################################
##
#F  AllRefineDifferenceSets( <G>, <N>, <difsums> )
##
InstallGlobalFunction( AllRefinedDifferenceSets, function (G, N, difsums)
    local v, k, lambda, dif, cosets, difsets, S, opts, opt, D;

    # handle special case of empty input
    if Length(difsums) = 0 then return []; fi;

    v := Size(G);
    k := Sum(difsums[1]); # assume all difsums have same k
    lambda := k*(k-1)/(v-1);
    dif := DifferenceTable(G);
    cosets := CosetsTable(G, N);

    difsets := []; # will store found difsets

    for S in difsums do

        # iterate through preimages D of S
        opts := List([1..Size(cosets)], x->Combinations(cosets[x], S[x]));
        for opt in IteratorOfCartesianProduct(opts) do
            D := Flat(opt);

            # if D is a difset then add it to list
            if IsDifferenceSetByTable(dif, D, v, lambda) then
                Add(difsets, D);
            fi;

        od;

    od;

    return difsets;
end );

#############################################################################
##
#F  NrAllRefinedSets( <G>, <N>, <difsums> )
##
InstallGlobalFunction( NrAllRefinedSets, function (G, N, difsums)
    return Sum(difsums, S->Product(S, x->Binomial(Size(N), x)));
end );

#############################################################################
##
#F  SomeRefinedDifferenceSets( <G>, <N>, <difsums> )
##
InstallGlobalFunction( SomeRefinedDifferenceSets, function (G, N, difsums)
    local v, k, lambda, dif, cosets, difsets, S, opts, opt, D;

    # handle special case of empty input
    if Length(difsums) = 0 then return []; fi;

    v := Size(G);
    k := Sum(difsums[1]); # assume all difsums have same k
    lambda := k*(k-1)/(v-1);
    dif := DifferenceTable(G);
    cosets := CosetsTable(G, N);

    difsets := []; # will store found difsets

    for S in difsums do

        # iterate through preimages D of S, forcing choice of identity
        opts := List([1..Size(cosets)], x->Combinations(cosets[x], S[x]));
        if S[1] > 0 then opts[1] := Filtered(opts[1], x->(1 in x)); fi;

        for opt in IteratorOfCartesianProduct(opts) do
            D := Flat(opt);

            # if D is a difset then add it to list
            if IsDifferenceSetByTable(dif, D, v, lambda) then
                Add(difsets, D);
            fi;

        od;

    od;

    return difsets;
end );

#############################################################################
##
#F  NrSomeRefinedSets( <G>, <N>, <difsums> )
##
InstallGlobalFunction( NrSomeRefinedSets, function (G, N, difsums)
    local f;

    f := function(S)
        if S[1] > 0 then
            return Binomial(Size(N)-1, S[1]-1)
                   * Product(S{[2..Length(S)]}, x->Binomial(Size(N), x));
        else
            return Product(S, x->Binomial(Size(N), x));
        fi;
    end;

    return Sum(difsums, S->f(S));
end );

#############################################################################
##
#F  IsDifferenceSetByTable( <table>, <D>, <v>, <lambda> )
##
InstallGlobalFunction( IsDifferenceSetByTable, function (table, D, v, lambda)
    # method is identical to IsDifferenceSet but uses precomputed values
    local count, i, j, index;

    count := List([1..v], x->0);

    for i in D do
    for j in D do

        index := table[i][j];
        count[index] := count[index] + 1;

        if not index = 1 and count[index] > lambda then
            return false;
        fi;

    od;
    od;

    return true;
end );

#############################################################################
##
#F  AllRefinedDifferenceSums( <G>, <N1>, <N2>, <difsums> )
##
InstallGlobalFunction( AllRefinedDifferenceSums, function (G, N1, N2, difsums)
    local v, k, lambda, dif, cosets, w2, u1, u2, u3, id, nonid, newdifsums, S, opts, opt, perms, perm, s;

    # handle special case of empty input
    if Length(difsums) = 0 then return []; fi;

    v := Size(G);
    k := Sum(difsums[1]); # assume all difsums have same k
    lambda := k*(k-1)/(v-1);
    dif := DifferenceTable(G/N2);
    cosets := CosetsToCosetsTable(G, N1, N2);

    # compute some numbers for function calls below
    w2 := Size(N2);
    u1 := Size(G/N1);
    u2 := Size(G/N2);
    u3 := Size(N1/N2);
    id := lambda*Size(N2) + k - lambda;
    nonid := lambda*Size(N2);
 
    newdifsums := []; # will store found difsums

    for S in difsums do

        # iterate through all partitions of S into new cosets
        opts := DifferenceSumPreImagesOptions(u3, w2,  S);
        for opt in IteratorOfCartesianProduct(opts) do

            # testing identity coeff can be done before permutations
            if not Sum(Flat(opt), x->x^2) = id then
                continue;
            fi;

            # iterate through all permutations of this partition
            perms := DifferenceSumPreImagesPermutations(opt);
            for perm in IteratorOfCartesianProduct(perms) do

                # if difference sum is found then add to list
                s := DifferenceSumPreImagesTranslate(cosets, u1, u2, u3, perm);
                if IsDifferenceSumByTable(dif, s, u2, nonid) then
                    Add(newdifsums, s);
                fi;

            od;

        od;

    od;

    return newdifsums;
end );

#############################################################################
##
#F  NrAllRefinedSums( <G>, <N1>, <N2>, <difsums> )
##
InstallGlobalFunction( NrAllRefinedSums, function (G, N1, N2, difsums)
    local v, k, lambda, total, S, opts, opt, perms;

    if Length(difsums) = 0 then return 0; fi;

    v := Size(G);
    k := Sum(difsums[1]);
    lambda := k*(k-1)/(v-1);

    total := 0;
    for S in difsums do
        opts := DifferenceSumPreImagesOptions(Size(N1/N2), Size(N2), S);

        for opt in IteratorOfCartesianProduct(opts) do
            if not Sum(Flat(opt), x->x^2) = lambda*Size(N2)+k-lambda then
                continue;
            fi;

            perms := DifferenceSumPreImagesPermutations(opt);
            total := total + Product(perms, x->Length(x));

        od;

    od;

    return total;
end );

#############################################################################
##
#F  SomeRefinedDifferenceSums( <G>, <N1>, <N2>, <difsums> )
##
InstallGlobalFunction( SomeRefinedDifferenceSums, function (G, N1, N2, difsums)
    local v, k, lambda, dif, cosets, w2, u1, u2, u3, id, nonid, newdifsums, S, opts, opt, perms, perm, s;

    # handle special case of empty input
    if Length(difsums) = 0 then return []; fi;

    v := Size(G);
    k := Sum(difsums[1]); # assume all difsums have same k
    lambda := k*(k-1)/(v-1);
    dif := DifferenceTable(G/N2);
    cosets := CosetsToCosetsTable(G, N1, N2);

    # compute some numbers for function calls below
    w2 := Size(N2);
    u1 := Size(G/N1);
    u2 := Size(G/N2);
    u3 := Size(N1/N2);
    id := lambda*Size(N2) + k - lambda;
    nonid := lambda*Size(N2);
 
    newdifsums := []; # will store found difsums

    for S in difsums do

        # iterate through all partitions of S into new cosets
        opts := DifferenceSumPreImagesOptions(u3, w2,  S);
        for opt in IteratorOfCartesianProduct(opts) do

            # testing identity coeff can be done before permutations
            if not Sum(Flat(opt), x->x^2) = id then
                continue;
            fi;

            # iterate through all permutations of this partition
            perms := DifferenceSumPreImagesPermutationsForced(opt);
            for perm in IteratorOfCartesianProduct(perms) do

                # if difference sum is found then add to list
                s := DifferenceSumPreImagesTranslate(cosets, u1, u2, u3, perm);
                if IsDifferenceSumByTable(dif, s, u2, nonid) then
                    Add(newdifsums, s);
                fi;

            od;

        od;

    od;

    return newdifsums;
end );

#############################################################################
##
#F  NrSomeRefinedSums( <G>, <N1>, <N2>, <difsums> )
##
InstallGlobalFunction( NrSomeRefinedSums, function (G, N1, N2, difsums)
    local v, k, lambda, total, S, opts, opt, perms;

    if Length(difsums) = 0 then return 0; fi;

    v := Size(G);
    k := Sum(difsums[1]);
    lambda := k*(k-1)/(v-1);

    total := 0;
    for S in difsums do
        opts := DifferenceSumPreImagesOptions(Size(N1/N2), Size(N2), S);

        for opt in IteratorOfCartesianProduct(opts) do
            if not Sum(Flat(opt), x->x^2) = lambda*Size(N2)+k-lambda then
                continue;
            fi;

            perms := DifferenceSumPreImagesPermutationsForced(opt);
            total := total + Product(perms, x->Length(x));

        od;

    od;

    return total;
end );

#############################################################################
##
#F  DifferenceSumPreImagesOptions( <u>, <w>, <S> )
##
InstallGlobalFunction( DifferenceSumPreImagesOptions, function (u, w, S)
    local opts, i, parts;

    opts := [1..Length(S)];
    for i in [1..Length(S)] do
        # partition the large coset coeff into the new small coset coeffs
        # adjust call to RestrictedPartitions since it won't use 0 as a summand
        parts := RestrictedPartitions(S[i]+u, [1..w+1], u);
        parts := List(parts, x->List(x, y->y-1));
        opts[i] := parts;
    od;

    return opts;
end );

#############################################################################
##
#F  DifferenceSumPreImagesPermutations( <opt> )
##
InstallGlobalFunction( DifferenceSumPreImagesPermutations, function (opt)
    local perms;

    perms := List(opt, x->PermutationsList(x));

    return perms;
end ); 

#############################################################################
##
#F  DifferenceSumPreImagesPermutationsForced( <opt> )
##
InstallGlobalFunction( DifferenceSumPreImagesPermutationsForced, function (opt)
    local perms;

    perms := List(opt, x->PermutationsList(x));

    # if the trivial coset contains anything we can force pick 1
    if Sum(perms[1][1]) > 0 then
        perms[1] := Filtered(perms[1], x->(x[1] > 0));
    fi;

    return perms;
end ); 

#############################################################################
##
#F  DifferenceSumPreImagesTranslate( <cosets>, <u1>, <u2>, <u3>, <perm> )
##
InstallGlobalFunction( DifferenceSumPreImagesTranslate, function (cosets, u1, u2, u3, perm)
    local S, i, j;

    # map the small coset values from the permutation to the appropriate
    # places in the list representing the new potential difference sum
    S := List([1..u2]);
    for i in [1..u1] do
    for j in [1..u3] do
        S[cosets[i][j]] := perm[i][j];
    od;
    od;

    return S;
end );
 
#############################################################################
##
#F  IsDifferenceSumByTable( <table>, <S>, <v>, <k>, <lambda>, <w> )
##
InstallGlobalFunction( IsDifferenceSumByTable, function (table, S, u, nonid)
    # method is identical to IsDifferenceSum but uses precomputed values
    local i, j, index, count;

    count := List([1..u], x->0);

    for i in [1..u] do
    for j in [1..u] do

        index := table[i][j];
        count[index] := count[index] + S[i]*S[j];

        if not index = 1 and count[index] > nonid then
            return false;
        fi;

    od;
    od;

    return true;
end );

#############################################################################
##
#E


[ Dauer der Verarbeitung: 0.29 Sekunden  (vorverarbeitet)  ]