Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  matrices.gi   Sprache: unbekannt

 
#############################################################################
##
#A  matrices.gi             GUAVA library                       Reinald Baart
#A                                                        &Jasper Cramwinckel
#A                                                           &Erik Roijackers
##
##  This file contains functions for generating matrices
##

#############################################################################
##
#F  KrawtchoukMat( <n> [, <q>] )  . . . . . . .  matrix of Krawtchouk numbers
##
InstallMethod(KrawtchoukMat, "n,q", true, [IsInt, IsInt], 0,
function(n,q)
    local res,i,k;
    if not IsPrimePowerInt(q) then
        Error("q must be a prime power int");
    fi;
    res := NullMat(n+1,n+1);
    for k in [0..n] do
        res[1][k+1]:=1;
    od;
    for k in [0..n] do
        res[k+1][1] := Binomial(n,k)*(q-1)^k;
    od;
    for i in [2..n+1] do
        for k in [2..n+1] do
            res[k][i] := res[k][i-1] - (q-1)*res[k-1][i] - res[k-1][i-1];
        od;
    od;
    return res;
end);

InstallOtherMethod(KrawtchoukMat, "n", true, [IsInt], 0,
function(n)
    return KrawtchoukMat(n, 2);
end);


#############################################################################
##
#F  GrayMat( <n> [, <F>] )  . . . . . . . . .  matrix of Gray-ordered vectors
##
##  GrayMat(n [, F]) returns a matrix in which rows a(i) have the property
##  d( a(i), a(i+1) ) = 1 and a(1) = 0.
##

InstallMethod(GrayMat, "n,Field", true, [IsInt, IsField], 0,
function(n, F)
    local M, result, row, series, column, elem, q, elementnr, line,
          goingup;
    elem := AsSSortedList(F);
    q := Length(elem);
    M := q^n;
    result := NullMat(M,n);
    for column in [1..n] do
        goingup := true;
        row:=0;
        for series in [1..q^(column-1)] do
            for elementnr in [1..q] do
                for line in [1..q^(n-column)] do
                    row:=row+1;
                    if goingup then
                        result[row][column]:= elem[elementnr];
                    else
                        result[row][column]:= elem[q+1-elementnr];
                    fi;
                od;
            od;
            goingup:= not goingup;
        od;
    od;
    return result;
end);

InstallOtherMethod(GrayMat, "n", true, [IsInt], 0,
function(n)
    return GrayMat(n, GF(2));
end);


#############################################################################
##
#F  SylvesterMat( <n> ) . . . . . . . . . . . . Sylvester matrix of order <n>
##

InstallMethod(SylvesterMat, "order", true, [IsInt], 0,
function(n)
    local result, syl;
    if n = 1 then
        return [[1]];
    elif (n mod 2)=0 then
        syl:=SylvesterMat(n/2);
        result:=List(syl, x->Concatenation(x,x));
        Append(result,List(syl,x->Concatenation(x,-x)));
        return result;
    else
        Error("n must be a power of 2");
    fi;
end);

PaleyClasses@ := function(m)
  local k,e,q,n,l,M,L,ret;
  L:=PrimePowersInt(m);
  if L[1] <> 2 then
    Error("Argument must be even.\n");
  fi;
  l := L[2];
  if l < 2 then
    Error("Argument must be divisible by 4.\n");
  fi;
  q := 0;
  n := 0;
  k := 0;
  M:=m;
  if Length(L) = 2 then    #arg is a power of 2
    return [[0,L[2],0,0]]; #don't bother computing the rest of the Paley classes
  fi;
  ret:=[];
  for e in [0 .. l] do
    if IsPrimePowerInt(M-1) then
      L:=PrimePowersInt(M-1);
      q:=L[1];
      n:=L[2];
      if q mod 4 = 3 and n mod 2 = 1 then
        k:=1;
      else
        k:=2;
      fi;
      if q mod 2 <> 0 then
        Append(ret, [[k,e,q,n]]);
      fi;
    fi;
   M:=M/2;
  od;
  return ret;
end;;

Jacobsthal@ := function(m)
  local i, j, F, L, Lstar, Qr, M, qx, x, y;
  if not IsPrimePowerInt(m) then
    Error("Input must be the order of a finite field.\n");
  fi;
  if IsPrimeInt(m) then
    if 1 = m mod 4 then
      qx := function(x,y)
        if x=y then
          return 0;
        elif x=0 or y=0 then
          return 1;
        fi;
        return Legendre(x-y,m);
      end;
    else
      qx := function(x,y)
        if x=y then
          return 0;
        elif y=0 then
          return 1;
        elif x=0 then
          return -1;
        else
          return Legendre(x-y,m);
        fi;
      end;
    fi;
  else
    F:=GF(m);
    L:=Elements(F);
    Lstar:=Filtered(L, x -> x <> Zero(F));
    Qr:=Set(List(Lstar,i->i^2)); #non-zero quadratic residues in the Galois field.
    if -1*One(F) in Qr then      #matrix is symmetric
      qx := function(x,y)
        if x=y then
          return 0;
        elif x=0 or y=0 then
          return 1;
        elif (L[x]-L[y]) in Qr then
          return 1;
        else
          return -1;
        fi;
      end;
    else                         #matrix is anti-symmetric
      qx := function(x,y)
        if x=y then
          return 0;
        elif y=0 then
          return 1;
        elif x=0 then
          return -1;
        elif (L[x]-L[y]) in Qr then
          return 1;
        else
          return -1;
        fi;
      end;
    fi;
  fi;
  return List([0..m],j->List([0..m], i->qx(i,j)));
end;;

PaleyI@ := function(m)
  #local e, f, i, j, F, L, Qr, M;
  if not IsPrimePowerInt(m) then
    Error("Input must be the order of a finite field.\n");
  fi;
  if (m mod 4) <> 3 then
    Error("Input must be 3 mod 4 for the Paley I construction.\n");
  fi;
  return Jacobsthal@(m) + IdentityMat(m+1, Integers);
end;;

PaleyII@ := function(m)
  local S, I, M;
  if not IsPrimePowerInt(m) then
    Error("Input must be the order of a finite field.\n");
  fi;
  if (m mod 4) <> 1 then
    Error("Input must be 1 mod 4 for the Paley II construction.\n");
  fi;
  S:= Jacobsthal@(m);
  I := IdentityMat(m+1,Integers);
  M := BlockMatrix([[1,1,S+I],[1,2,S-I],[2,1,S-I],[2,2,-S-I]],2,2);
  return MatrixByBlockMatrix(M);
end;;

#############################################################################
##
#F  HadamardMat( <n> )  . . . . . . . . . . . .  Hadamard matrix of order <n>
##

InstallMethod(HadamardMat, "order", true, [IsInt], 0,
function(m)
  local L,k,e,q,n;
  if not (m=1 or m=2 or 0=(m mod 4)) then
    Error("Hadamard matrices exist only when the order is 1, 2 or a multiple of 4.\n");
  fi;
  if m=1 then
    return [[1]];
  fi;
  if m=2 then
    return [[1,1],[1,-1]];
  fi;
  L:=PaleyClasses@(m);
  if IsEmpty(L) then
    Print("The Paley-type constructions fail at this order.\n");
    return fail;
  fi;
  k:=L[1][1];
  e:=L[1][2];
  q:=L[1][3];
  n:=L[1][4];
  if k=0 then                # the order is a power of 2 -- go recursive
    return KroneckerProduct([[1,1],[1,-1]], HadamardMat(m/2) );
  elif k=1 then                # do the Paley type-I construction
    return KroneckerProduct(SylvesterMat(2^e), PaleyI@(q^n));
  elif k=2 then              # or the type-II
    return KroneckerProduct(SylvesterMat(2^(e-1)), PaleyII@(q^n));
  else                       # or punt
    Error("Something is very strange. This line should never be reached. \n");
  fi;
end);


#############################################################################
##
#F  IsLatinSquare( <M> )  . . . . . . .  determines if matrix is latin square
##
##  IsLatinSquare determines if M is a latin square, that is a q*q array whose
##  entries are from a set of q distinct symbols such that each row and each
##  column of the array contains each symbol exactly once
##

InstallMethod(IsLatinSquare, "method for matrix", true, [IsMatrix], 0,
function(M)

    local i, j, s, n, isLS, MT;
    n:=Length(M);
    s:=Set(M[1]);
    isLS:= (Length(s) = n and Length(s) = Length(M[1]) );
    i:=2;
    if isLS then
        MT:=TransposedMat(M);
    fi;
    while isLS and i<=n do
        isLS:= (Set(M[i]) = s);
        i:=i+1;
    od;
    i := 1;
    while isLS and i<=n do
        isLS:= (Set(MT[i]) = s);
        i:=i+1;
    od;
    return isLS;
end);

InstallOtherMethod(IsLatinSquare, "generic method, any object", true,
    [IsObject], 0,
function(obj)
    if IsMatrix(obj) then
        TryNextMethod();
    fi;
    return false;
end);


#############################################################################
##
#F  AreMOLS( <matlist> )  . . . . . . . . .  determines if arguments are MOLS
##
##  AreMOLS(M1, M2, ...) determines if the arguments are mutually orthogonal
##  latin squares.
##

##LR - doesn't handle case where arg is list of one matrix.  Is this a prob?
InstallGlobalFunction(AreMOLS,
function(arg)
    local i, j, s, M, n, q2, first, second, max, fast;
    if Length(arg) = 1 then
        M:=arg[1];
    else
        M:=List([1..Length(arg)],i->arg[i]);
    fi;
    n:=Length(M);
    if ( n >= Length(M[1]) ) or not ForAll(M, i-> IsLatinSquare(i)) then
        return false; #this is right
    fi;
    q2 := Length(M[1])^2;
    max := Maximum(M[1][1]) + 1;
    M := List(M, i -> Flat(i));
    fast := (DefaultField(Flat(M)) = Rationals);
    first := 1;
    repeat
        second := first+1;
        if fast then
            repeat
                s := Set( M[first] * max + M[second] );
                second := second + 1;
            until (Length(s) < q2) or (second > n);
        else
            repeat
                s:=Set([]);
                for i in [1 .. q2] do
                    AddSet(s, [  M[first][i], M[second][i] ]);
                od;
                second := second + 1;
            until (Length(s) < q2) or (second > n);
        fi;
        first:=first + 1;
    until (Length(s) < q2) or (first >= n);
    return Length(s) = q2;
end);


#############################################################################
##
#F  MOLS( <q> [, <n>] ) . . . . . . . . . .  list of <n> MOLS of size <q>*<q>
##
##  MOLS( q [, n]) returns a list of n Mutually Orthogonal Latin
##  Squares of size q * q. If n is omitted, MOLS will return a list
##  of two MOLS. If it is not possible to return n MOLS of size q,
##  MOLS will return a boolean false.
##

InstallMethod(MOLS, "size, number", true, [IsInt, IsInt], 0,
function(q, n)
    local facs, res, Merged, Squares, nr, S, ToInt;

    ToInt := function(M)
        local res, els, q, i, j;
        q:=Length(M);
        els:=AsSSortedList(GF(q));
        res := NullMat(q,q)+1;
        for i in [1..q] do
            for j in [1..q] do
                while els[res[i][j]] <> M[i][j] do
                    res[i][j]:=res[i][j]+1;
                od;
            od;
        od;
        return res-1;
    end;

    Squares := function(q, n)
        local els, res, i, j, k;
        els:=AsSSortedList(GF(q));
        res:=List([1..n], x-> NullMat(q,q,GF(q)));
        for i in [1..q] do
            for j in [1..q] do
                for k in [1..n] do
                    res[k][i][j] := els[i] + els[k+1] * els[j];
                od;
            od;
        od;
        return List([1..n],x -> ToInt(res[x]));
    end;

    Merged := function(A, B)
        local i, j, q1, q2, res;
        q1:=Length(A);
        q2:=Length(B);
        res:=KroneckerProduct(A,NullMat(q2,q2)+1);
        for i in [1 .. q1*q2] do
            for j in [1 .. q1*q2] do
                res[i][j]:= res[i][j] + q1 *
                            B[((i-1) mod q2)+1][((j-1) mod q2)+1];
            od;
        od;
        return res;
    end;

    if n <= 0 then
        return false;
    elif (q < 3) or (q = 6) or (q mod 4) = 2 then
        return false; #this must be so
    elif n <> 2 then
        if (not IsPrimePowerInt(q)) or (n >= q) then
            return false; #this is right
        elif IsPrimeInt(q) then
            return List([1..n],i -> List([0..q-1], y -> List([0..q-1], x ->
                           (x+i*y) mod q)));
        else
            return Squares(q,n);
        fi;
    else
        res:=[[[0]],[[0]]];
        facs:=Collected(Factors(q));
        for nr in facs do
            if nr[2] = 1 then
                S:= List([1..2], i -> List([0..nr[1]-1],y ->
                            List([0..nr[1]-1], x -> (x+i*y) mod nr[1])));
            else
                S:=Squares(nr[1]^nr[2],2);
            fi;
            res:=[Merged(res[1],S[1]),Merged(res[2],S[2])];
        od;
        return res;
    fi;
end);

InstallOtherMethod(MOLS, "size", true, [IsInt], 0,
function(q)
    return MOLS(q, 2);
end);


#############################################################################
##
#F  VerticalConversionFieldMat( <M> ) . . . . . . .  converts matrix to GF(q)
##
##  VerticalConversionFieldMat (M) converts a matrix over GF(q^m) to a matrix
##  over GF(q) with vertical orientation of the tuples
##

InstallMethod(VerticalConversionFieldMat, "method for matrix and field", true,
    [IsMatrix, IsField], 0,
function(M, F)
    local res, q, Fq, m, n, r, ConvTable, x, temp, i, j, k, zero;
    q := Characteristic(F);
    Fq := GF(q);
    zero := Zero(Fq);
    m := Dimension(F);
    n := Length(M[1]);
    r := Length(M);

    ConvTable := [];
    x := Indeterminate(Fq);
    temp := MinimalPolynomial(Fq, Z(q^m));
    for i in [1.. q^m - 1] do
        ConvTable[i] := VectorCodeword(Codeword(x^(i-1) mod temp, m+1));
    od;

    res := NullMat(r * m, n, Fq);
    for i in [1..r] do
        for j in [1..n] do
            if M[i][j] <> zero then
                temp := ConvTable[LogFFE(M[i][j], Z(q^m)) + 1];
                for k in [1..m] do
                    res[(i-1)*m + k][j] := temp[k];
                od;
            fi;
        od;
    od;
    return res;
end);

InstallOtherMethod(VerticalConversionFieldMat, "method for matrix", true,
    [IsMatrix], 0,
function(M)
    return VerticalConversionFieldMat(M, DefaultField(Flat(M)));
end);


#############################################################################
##
#F  HorizontalConversionFieldMat( <M>, <F> )  . . .  converts matrix to GF(q)
##
##  HorizontalConversionFieldMat (M, F) converts a matrix over GF(q^m) to a
##  matrix over GF(q) with horizontal orientation of the tuples
##

InstallMethod(HorizontalConversionFieldMat, "method for matrix and field",
    true, [IsMatrix, IsField], 0,
function(M, F)
    local res, vec, k, n, coord, i, p, q, m, zero, g, Nul, ConvTable,
          x;
    q := Characteristic(F);
    m := Dimension(F);
    zero := Zero(F);
    g := MinimalPolynomial(GF(q), Z(q^m));
    Nul := List([1..m], i -> zero);
    ConvTable := [];
    x := Indeterminate(GF(q));
    for i in [1..Size(F) - 1] do
        ConvTable[i] := VectorCodeword(Codeword(x^(i-1) mod g, m));
    od;
    res := [];
    n := Length(M[1]);
    k := Length(M);
    for vec in [0..k-1] do
        for i in [1..m] do res[m*vec+i] := []; od;
        for coord in [1..n] do
            if M[vec+1][coord] <> zero then
                p := LogFFE(M[vec+1][coord], Z(q^m));
                for i in [1..m] do
                    if (p+i) mod q^m = 0 then p := p+1; fi;
                    Append(res[m*vec+i], ConvTable[(p + i) mod (q^m)]);
                od;
            else
                for i in [1..m] do
                    Append(res[m*vec+i], Nul);
                od;
            fi;
        od;
    od;
    return res;
end);

InstallOtherMethod(HorizontalConversionFieldMat, "method for matrix", true,
    [IsMatrix], 0,
function(M)
    return HorizontalConversionFieldMat(M, DefaultField(Flat(M)));
end);


#############################################################################
##
#F  IsInStandardForm( <M> [, <boolean>] ) . . . . is matrix in standard form?
##
##  IsInStandardForm(M [, identityleft]) determines if M is in standard form;
##  if identityleft = false, the identitymatrix must be at the right side
##  of M; otherwise at the left side.
##

InstallMethod(IsInStandardForm, "method for matrix and boolean", true,
    [IsMatrix, IsBool], 0,
function(M, identityleft)
    local l;
    l := Length(M);
    if identityleft = false then
        return IdentityMat(l, DefaultField(Flat(M))) =
               M{[1..l]}{[Length(M[1])-l+1..Length(M[1])]};
    else
        return IdentityMat(l, DefaultField(Flat(M))) = M{[1..l]}{[1..l]};
    fi;
end);

InstallOtherMethod(IsInStandardForm, "method for matrix", true, [IsMatrix], 0,
function(M)
    return IsInStandardForm(M, true);
end);


#############################################################################
##
#F  PutStandardForm( <M> [, <boolean>] [, <F>] )  .  put <M> in standard form
##
##  PutStandardForm(Mat [, idleft] [, F]) puts matrix Mat in standard form,
##  the size of Mat being (n x m). If idleft is true or is omitted, the
##  the identity matrix is put left, else right. The permutation is returned.
##

InstallMethod(PutStandardForm, "method for matrix, idleft and field", true,
    [IsMatrix, IsBool, IsField], 0,
function(Mat, idleft, F)
    local n, m, row, i, j, h, hp, s, zero, P;
    n := Length(Mat);   # not the word length!
    m := Length(Mat[1]);
    if idleft then
        return PutStandardForm(Mat,F);
     else
        s := m-n;
    fi;
    zero := Zero(F);
    P := ();
    for j in [1..n] do
        if Mat[j][j+s] =zero then
            i := j+1;
            while (i <= n) and (Mat[i][j+s] = zero) do
                i := i + 1;
            od;
            if i <= n then
                row := Mat[j];
                Mat[j] := Mat[i];
                Mat[i] := row;
            else
                h := j+s;
                while Mat[j][h] = zero do
                    h := h + 1;
                    if h > m then h := 1; fi;
                od;
                for i in [1..n] do
                    Mat[i] := Permuted(Mat[i],(j+s,h));
                od;
                P := P*(j+s,h);
            fi;
        fi;
        Mat[j] := Mat[j]/Mat[j][j+s];
        for i in [1..n] do
            if i <> j then
                if Mat[i][j+s] <> zero then
                    Mat[i] := Mat[i]-Mat[i][j+s]*Mat[j];
                fi;
            fi;
        od;
    od;
    return P;
end);

##
##Thanks to Frank Luebeck for this code:
##
InstallOtherMethod(PutStandardForm, "method for matrix and Field", true,
    [IsMatrix, IsField], 0,
function(mat, F)
    local perm, k, i, j, d ;

    if IsMutable(mat)=false then
       Error("Argument to PutStandardForm() must be mutable");
    fi;
    
    d := Length(mat[1]);
    TriangulizeMat(mat);
    perm := ();
    k := Length(mat[1]);
    for i in [1..Length(mat)] do
        j := PositionNonZero(mat[i]);
        if (j <= d and i <> j) then
            perm := perm * (i,j);
        fi;
    od;
    if perm <> () then
        for i in [1..Length(mat)] do
            mat[i] := Permuted(mat[i], perm);
        od;
    fi;
    return perm;
end);

InstallOtherMethod(PutStandardForm, "method for matrix and idleft", true,
    [IsMatrix, IsBool], 0,
function(M, idleft)
    return PutStandardForm(M, idleft, DefaultField(Flat(M)));
end);

InstallOtherMethod(PutStandardForm, "method for matrix", true, [IsMatrix], 0,
function(M)
    return PutStandardForm(M, true, DefaultField(Flat(M)));
end);



[ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge