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


Quelle  lambda-rho.gi   Sprache: unbekannt

 
############################################################################
##
##  ideals/lambda-rho.gi
##  Copyright (C) 2013-2022                              James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

InstallMethod(AsList, "for an ideal orb", [IsIdealOrb],
o -> Concatenation(List(o!.orbits, AsList)));

InstallMethod(Enumerate, "for an ideal orb, and a number",
[IsIdealOrb, IsCyclotomic],
function(o, limit)
  local newlookfunc;

  if IsClosedOrbit(o) then
    return o;
  fi;

  newlookfunc := {data, x} -> IsClosedOrbit(o) or Length(o) >= limit;
  Enumerate(SemigroupData(o!.parent), infinity, newlookfunc);
  return o;
end);

InstallMethod(Enumerate, "for an ideal orb, a number, and a function",
[IsIdealOrb, IsCyclotomic, IsFunction],
function(o, limit, lookfunc)
  local newlookfunc;

  newlookfunc := {data, x} -> IsClosedOrbit(o) or Length(o) >= limit;
  if IsLambdaOrb(o) then
    Enumerate(SemigroupData(o!.parent), infinity,
              rec(lookfunc := newlookfunc, lambdalookfunc := lookfunc));
  elif IsRhoOrb(o) then
    Enumerate(SemigroupData(o!.parent), infinity,
              rec(lookfunc := newlookfunc, rholookfunc := lookfunc));
  fi;

  return o;
end);

InstallMethod(Length, "for a ideal orb",
[IsIdealOrb],
o -> Sum(o!.lens));

InstallMethod(Length, "for an ideal inverse orb",
[IsIdealOrb and IsInverseOrb],
o -> Length(o!.orbit));

InstallMethod(IsBound\[\], "for an ideal orb and positive integer",
[IsIdealOrb, IsPosInt],
function(o, i)
  local nr;

  nr := 1;
  while IsBound(o!.orbits[nr]) and i > Length(o!.orbits[nr]) do
    i := i - Length(o!.orbits[nr]);
    nr := nr + 1;
  od;
  return IsBound(o!.orbits[nr]) and IsBound(o!.orbits[nr][i]);
end);

InstallMethod(IsBound\[\], "for an inverse ideal orb and positive integer",
[IsIdealOrb and IsInverseOrb, IsPosInt],
{o, i} -> IsBound(o!.orbit[i]));

InstallMethod(ELM_LIST, "for an ideal orb and positive integer",
[IsIdealOrb, IsPosInt],
function(o, i)
  local nr;

  nr := 1;
  while i > Length(o!.orbits[nr]) do
    i := i - Length(o!.orbits[nr]);
    nr := nr + 1;
  od;
  return o!.orbits[nr][i];
end);

InstallMethod(ELM_LIST, "for an inverse ideal orb and positive integer",
[IsIdealOrb and IsInverseOrb, IsPosInt], {o, i} -> o!.orbit[i]);

# same method for inverse ideal orbs

InstallMethod(\in, "for an object and ideal orb",
[IsObject, IsIdealOrb], {obj, o} -> HTValue(o!.ht, obj) <> fail);

# same method for inverse ideal orbs

InstallMethod(Position, "for an ideal orb, object, zero cyc",
[IsIdealOrb, IsObject, IsZeroCyc], {o, obj, n} -> HTValue(o!.ht, obj));

# same method for inverse ideal orbs

InstallMethod(OrbitGraph, "for an ideal orb",
[IsIdealOrb], o -> o!.orbitgraph);

InstallMethod(ViewObj, "for a ideal orb",
[IsIdealOrb],
function(o)
  Print("<");
  if IsClosedOrbit(o) then
    Print("closed ");
  else
    Print("open ");
  fi;
  if IsInverseOrb(o) then
    Print("inverse ");
  fi;
  Print("ideal ");
  if IsLambdaOrb(o) then
    Print("lambda ");
  else
    Print("rho ");
  fi;
  Print("orbit with ", Length(o) - 1, " points");

  if not IsInverseOrb(o) then
    Print(" in ", Length(o!.orbits) - 1, " components");
  fi;
  Print(">");
  return;
end);

# different method for inverse semigroup ideals

InstallMethod(LambdaOrb, "for an acting semigroup ideal",
[IsActingSemigroup and IsSemigroupIdeal],
function(I)
  local S, gens, record, htopts, fam;

  S := SupersemigroupOfIdeal(I);
  gens := List(GeneratorsOfSemigroup(S), x -> ConvertToInternalElement(S, x));

  record := rec();
  record.orbits := [[fail]];
  record.lens := [1];
  record.parent := I;
  record.scc := [[1]];
  record.scc_reps := [fail];
  record.scc_lookup := [1];
  record.schreiergen := [fail];
  record.schreierpos := [fail];
  record.orbitgraph := [[]];
  record.looking := false;
  record.gens := gens;
  record.orbschreierpos := [];
  record.orbschreiergen := [];
  record.orbschreiercmp := [];
  # <o!.orbits[i]> is obtained from the component
  # <o!.orbits[o!.orbschreiercmp[i]]> by applying right multiplying some
  # element of the ideal with lambda value in position <o!.schreierpos[i]> by
  # <o!.schreiergen[i]>.
  record.orbtogen := [];
  # ComponentOfIndex(o, Position(o, LambdaFunc(M)(gens[orbtogen[i]])))=i
  # and <orbtogen[ComponentOfIndex(Position(o, LambdaFunc(I)(gens[i])))]=i>
  # i.e. component <i> arises from <gens[orbtogen[i]]>.

  htopts := ShallowCopy(LambdaOrbOpts(I));
  htopts.treehashsize := SEMIGROUPS.OptionsRec(I).hashlen;
  record.ht := HTCreate(LambdaFunc(I)(gens[1]), htopts);

  fam := CollectionsFamily(FamilyObj(LambdaFunc(I)(Representative(I))));

  return Objectify(NewType(fam, IsIdealOrb and IsLambdaOrb), record);
end);

InstallMethod(RhoOrb, "for an acting semigroup ideal",
[IsActingSemigroup and IsSemigroupIdeal],
function(I)
  local S, gens, record, htopts, fam;

  S := SupersemigroupOfIdeal(I);
  gens := List(GeneratorsOfSemigroup(S), x -> ConvertToInternalElement(S, x));

  record := rec();
  record.orbits := [[fail]];
  record.lens := [1];
  record.parent := I;
  record.scc := [[1]];
  record.scc_reps := [fail];
  record.scc_lookup := [1];
  record.schreiergen := [fail];
  record.schreierpos := [fail];
  record.orbitgraph := [[]];
  record.looking := false;
  record.gens := gens;
  record.orbschreierpos := [];
  record.orbschreiergen := [];
  record.orbschreiercmp := [];
  # <o!.orbits[i]> is obtained from the component
  # <o!.orbits[o!.orbschreiercmp[i]]> by applying left multiplying some
  # element of the ideal with rho value in position <o!.schreierpos[i]> by
  # <o!.schreiergen[i]>.
  record.orbtogen := [];
  # <ComponentOfIndex(o, Position(o, RhoFunc(I)(gens[orbtogen[i]])))=i>
  # and <orbtogen[ComponentOfIndex(Position(o, RhoFunc(I)(gens[i])))]=i>
  # i.e. component <i> arises from <gens[orbtogen[i]]>.
  htopts := ShallowCopy(RhoOrbOpts(I));
  htopts.treehashsize := SEMIGROUPS.OptionsRec(I).hashlen;
  record.ht := HTCreate(RhoFunc(I)(gens[1]), htopts);

  fam := CollectionsFamily(FamilyObj(RhoFunc(I)(Representative(I))));
  return Objectify(NewType(fam, IsIdealOrb and IsRhoOrb), record);
end);

# The entire lambda orbit of an ideal of an inverse semigroup is obtained from
# the lambda values of the generators (and their inverses) of the ideal by
# acting on the right by the generators (and their inverses) of the
# supersemigroup. Hence we require a different case here.

# Don't think that this applies to semigroups of matrices over finite fields,
# so this doesn't require us to use ConvertToInternalElement
# TODO(FixExtremeTests): check that this is really correct

InstallMethod(LambdaOrb, "for an inverse acting semigroup rep ideal",
[IsInverseActingSemigroupRep and IsSemigroupIdeal],
function(I)
  local record, gens, lambdafunc, o, ht, nr, nrgens, lambda, InstallPointInOrb,
   x, i;

  record := ShallowCopy(LambdaOrbOpts(I));
  record.scc_reps := [FakeOne(GeneratorsOfSemigroupIdeal(I))];

  record.schreier := true;
  record.orbitgraph := true;
  record.storenumbers := true;
  record.log := true;
  record.parent := I;
  record.treehashsize := SEMIGROUPS.OptionsRec(I).hashlen;
  record.orbtogen := [];
  # orbtogen[Position(o, LambdaFunc(I)(gens[i]))]=i and

  gens := GeneratorsOfSemigroupIdeal(I);
  lambdafunc := LambdaFunc(I);

  o := Orb(GeneratorsOfSemigroup(SupersemigroupOfIdeal(I)),
           LambdaOrbSeed(I),
           LambdaAct(I),
           record);

  # install the lambda values of the generators
  ht := o!.ht;
  nr := 1;
  nrgens := Length(gens);
  lambdafunc := LambdaFunc(I);

  #
  InstallPointInOrb := function(lambda)
    nr := nr + 1;
    HTAdd(ht, lambda, nr);
    Add(o!.orbit, lambda);
    Add(o!.schreierpos, fail);
    Add(o!.schreiergen, fail);
    Add(o!.orbitgraph, []);
  end;
  #

  for i in [1 .. nrgens] do
    x := gens[i];
    lambda := lambdafunc(x);
    if HTValue(ht, lambda) = fail then
      InstallPointInOrb(lambda);
      o!.orbtogen[nr] := i;
    fi;

    lambda := lambdafunc(x ^ -1);
    if HTValue(ht, lambda) = fail then
      InstallPointInOrb(lambda);
      o!.orbtogen[nr] := nrgens + i;
    fi;
  od;

  o!.pos := 2;
  # don't apply the generators of the supersemigroup of <I> to the dummy point
  # at the start of the orbit (otherwise we just get the lambda orbit of the
  # supersemigroup

  SetFilterObj(o, IsLambdaOrb and IsInverseOrb and IsIdealOrb);
  return o;
end);

# For an ideal rho orb <o>, rho value <pt> of <x>, <x> itself an element of the
# ideal, <pos> is the position in <o> of the rho value from which <x> was
# obtained by right multiplication by, the <gen>th generator of the parent of
# <o>, <ind> is the index of the generator of the ideal which we are adding (if
# applicable).
#
# This assumes that <pt> is not in <o> already, and that either:
#
#   - <pos=gen=fail> and we are updating with the <ind>th generator of the
#     *ideal*; or
#
#   - <pos>, <gen> are positive integers and <ind=fail>

InstallGlobalFunction(UpdateIdealLambdaOrb,
function(o, pt, x, pos, gen, ind, lookfunc)
  local I, record, len, S, gens, new, ht, found, nrorb, cmp, i;

  I := o!.parent;
  record := ShallowCopy(LambdaOrbOpts(I));
  record.schreier := true;
  record.orbitgraph := true;
  record.storenumbers := true;
  record.log := true;
  record.parent := I;
  record.treehashsize := SEMIGROUPS.OptionsRec(I).hashlen;

  len := Length(o);

  if len <> 0 then
    record.gradingfunc    := {new, x} -> HTValue(o!.ht, x) <> fail;
    record.onlygrades     := {x, data} -> not x;
    record.onlygradesdata := fail;
  fi;

  S := SupersemigroupOfIdeal(I);
  gens := List(GeneratorsOfSemigroup(S), x -> ConvertToInternalElement(S, x));
  new := Orb(gens, pt, LambdaAct(I), record);
  Enumerate(new);

  ht := o!.ht;

  if lookfunc = ReturnFalse then
    for i in [1 .. Length(new)] do
      HTAdd(ht, new[i], i + len);
    od;
  else
    o!.looking := true;
    o!.found := false;
    found := false;
    for i in [1 .. Length(new)] do
      HTAdd(ht, new[i], i + len);
      if not found and lookfunc(new, new[i]) then
        o!.found := i;
        found := true;
      fi;
    od;
  fi;

  o!.scc_reps[Length(o!.scc) + 1] := x;

  Append(o!.scc_lookup, OrbSCCLookup(new) + Length(o!.scc));
  Append(o!.scc, OrbSCC(new) + len);
  Append(o!.schreiergen, new!.schreiergen);
  Add(o!.schreierpos, fail);
  for i in [2 .. Length(new)] do
    Add(o!.schreierpos, new!.schreierpos[i] + len);
  od;
  Append(o!.orbitgraph, new!.orbitgraph + len);

  Unbind(new!.scc);
  Unbind(new!.trees);
  Unbind(new!.scc_lookup);
  Unbind(new!.mults);
  Unbind(new!.schutz);
  Unbind(new!.reverse);
  Unbind(new!.rev);
  Unbind(new!.schutzstab);
  Unbind(new!.factorgroups);
  Unbind(new!.factors);
  Unbind(new!.orbitgraph);
  Unbind(new!.schreiergen);
  Unbind(new!.schreierpos);

  o!.orbits[Length(o!.orbits) + 1] := new;
  o!.lens[Length(o!.orbits)] := Length(new);

  nrorb := Length(o!.orbits);
  o!.orbschreierpos[nrorb] := pos;
  o!.orbschreiergen[nrorb] := gen;

  if pos <> fail then
    # find the component containing <pos>
    cmp := 1;
    while pos > Length(o!.orbits[cmp]) do
      pos := pos - Length(o!.orbits[cmp]);
      cmp := cmp + 1;
    od;
    o!.orbschreiercmp[nrorb] := cmp;
  else
    o!.orbschreiercmp[nrorb] := fail;
  fi;

  if ind <> fail then
    o!.orbtogen[nrorb] := ind;
  fi;
  return len + 1;
end);

# For an ideal rho orb <o>, rho value <pt> of <x>, <x> itself an element of the
# ideal, <pos> is the position in <o> of the rho value from which <x> was
# obtained by right multiplication by, the <gen>th generator of the parent of
# <o>, <ind> is the index of the generator of the ideal which we are adding (if
# applicable).
#
# This assumes that <pt> is not in <o> already, and that either:
#
#   - <pos=gen=fail> and we are updating with the <ind>th generator of the
#     *ideal*; or
#
#   - <pos>, <gen> are positive integers and <ind=fail>

InstallGlobalFunction(UpdateIdealRhoOrb,
function(o, pt, x, pos, gen, ind, lookfunc)
  local I, record, len, S, gens, new, ht, found, nrorb, cmp, i;

  I := o!.parent;
  record := ShallowCopy(RhoOrbOpts(I));
  record.schreier := true;
  record.orbitgraph := true;
  record.storenumbers := true;
  record.log := true;
  record.parent := I;
  record.treehashsize := SEMIGROUPS.OptionsRec(I).hashlen;

  len := Length(o);

  if len <> 0 then
    record.gradingfunc    := {new, x} -> HTValue(o!.ht, x) <> fail;
    record.onlygrades     := {x, data} -> not x;
    record.onlygradesdata := fail;
  fi;

  S := SupersemigroupOfIdeal(I);
  gens := List(GeneratorsOfSemigroup(S), x -> ConvertToInternalElement(S, x));
  new := Orb(gens, pt, RhoAct(I), record);
  Enumerate(new);

  ht := o!.ht;

  if lookfunc = ReturnFalse then
    for i in [1 .. Length(new)] do
      HTAdd(ht, new[i], i + len);
    od;
  else
    o!.looking := true;
    o!.found := false;
    found := false;
    for i in [1 .. Length(new)] do
      HTAdd(ht, new[i], i + len);
      if not found and lookfunc(new, new[i]) then
        o!.found := i;
        found := true;
      fi;
    od;
  fi;

  o!.scc_reps[Length(o!.scc) + 1] := x;

  Append(o!.scc_lookup, OrbSCCLookup(new) + Length(o!.scc));
  Append(o!.scc, OrbSCC(new) + len);
  Append(o!.schreiergen, new!.schreiergen);
  Add(o!.schreierpos, fail);
  for i in [2 .. Length(new)] do
    Add(o!.schreierpos, new!.schreierpos[i] + len);
  od;
  Append(o!.orbitgraph, new!.orbitgraph + len);

  Unbind(new!.scc);
  Unbind(new!.trees);
  Unbind(new!.scc_lookup);
  Unbind(new!.mults);
  Unbind(new!.schutz);
  Unbind(new!.reverse);
  Unbind(new!.rev);
  Unbind(new!.schutzstab);
  Unbind(new!.factorgroups);
  Unbind(new!.factors);
  Unbind(new!.orbitgraph);
  Unbind(new!.schreiergen);
  Unbind(new!.schreierpos);

  o!.orbits[Length(o!.orbits) + 1] := new;
  o!.lens[Length(o!.orbits)] := Length(new);

  nrorb := Length(o!.orbits);
  o!.orbschreierpos[nrorb] := pos;
  o!.orbschreiergen[nrorb] := gen;

  if pos <> fail then
    # find the component containing <pos>
    cmp := 1;
    while pos > Length(o!.orbits[cmp]) do
      pos := pos - Length(o!.orbits[cmp]);
      cmp := cmp + 1;
    od;
    o!.orbschreiercmp[nrorb] := cmp;
  else
    o!.orbschreiercmp[nrorb] := fail;
  fi;

  # jj assume that if a generator is passed into UpadateIdealRhoOrb then
  # pos = the index of the generator and ind<>fail.
  if ind <> fail then
    o!.orbtogen[nrorb] := ind;
  fi;
  return len + 1;
end);

InstallMethod(EvaluateWord, "for an ideal orb and an ideal word (Semigroups)",
[IsIdealOrb, IsList], 2,  # to beat the methods for lambda/rho orbs below
function(o, w)
  local super_gens, I, ideal_gens, res, i;
  # it is safe to use <GeneratorsOfSemigroup> here since an ideal can't be
  # obtained using <ClosureSemigroup>
  super_gens := o!.gens;
  # = GeneratorsOfSemigroup(SupersemigroupOfIdeal(o!.parent));
  I := o!.parent;
  ideal_gens := List(GeneratorsOfSemigroupIdeal(I),
                     x -> ConvertToInternalElement(I, x));
  res := ideal_gens[AbsInt(w[2])] ^ SignInt(w[2]);

  for i in [1 .. Length(w[1])] do
    res := super_gens[w[1][i]] * res;
  od;
  for i in [1 .. Length(w[3])] do
    res := res * super_gens[w[3][i]];
  od;
  return res;
end);

InstallMethod(EvaluateWord, "for a lambda orb and a word (Semigroups)",
[IsLambdaOrb, IsList], 1,
# to beat the methods for IsXCollection
{o, w} -> EvaluateWord(o!.gens, w));

InstallMethod(EvaluateWord, "for a rho orb and a word (Semigroups)",
[IsRhoOrb, IsList], 1,
# to beat the methods for IsXCollection
{o, w} -> EvaluateWord(o!.gens, w));

# returns a triple [leftword, nr, rightword] where <leftword>, <rightword> are
# words in the generators of the supersemigroup of the ideal, and <nr> is the
# index of a generator of the ideal.

InstallMethod(TraceSchreierTreeForward,
"for an inverse semigroup ideal orbit and a positive integer",
[IsInverseOrb and IsIdealOrb, IsPosInt],
function(o, i)
  local schreierpos, schreiergen, rightword, nr;

  schreierpos := o!.schreierpos;
  schreiergen := o!.schreiergen;

  rightword := [];

  while schreierpos[i] <> fail do
    Add(rightword, schreiergen[i]);
    i := schreierpos[i];
  od;

  if o!.orbtogen[i] > Length(GeneratorsOfSemigroupIdeal(o!.parent)) then
    nr := -o!.orbtogen[i] + Length(GeneratorsOfSemigroupIdeal(o!.parent));
  else
    nr := o!.orbtogen[i];
  fi;

  return [[], nr, Reversed(rightword)];
end);

# returns a triple [leftword, nr, rightword] where <leftword>, <rightword> are
# words in the generators of the supersemigroup of the ideal, and <nr> is the
# index of a generator of the ideal.

InstallMethod(TraceSchreierTreeForward,
"for an ideal orbit and positive integer",
[IsIdealOrb, IsPosInt],
function(o, i)
  local orbschreierpos, orbschreiergen, orbschreiercmp, schreierpos,
  schreiergen, leftword, rightword, nr, j;

  orbschreierpos := o!.orbschreierpos;
  orbschreiergen := o!.orbschreiergen;
  orbschreiercmp := o!.orbschreiercmp;

  schreierpos := o!.schreierpos;
  schreiergen := o!.schreiergen;

  leftword := [];
  rightword := [];

  # find the component <nr> containing <i>
  nr := 1;
  j := i;
  while j > Length(o!.orbits[nr]) do
    j := j - Length(o!.orbits[nr]);
    nr := nr + 1;
  od;

  # trace back to the start of the component
  while schreierpos[i] <> fail do
    Add(rightword, schreiergen[i]);
    i := schreierpos[i];
  od;

  while orbschreiergen[nr] <> fail do
    Add(leftword, orbschreiergen[nr]);

    i := orbschreierpos[nr];
    nr := orbschreiercmp[nr];

    while schreierpos[i] <> fail do
      Add(rightword, schreiergen[i]);
      i := schreierpos[i];
    od;

  od;

  return [Reversed(leftword), o!.orbtogen[nr], Reversed(rightword)];
end);

[ Dauer der Verarbeitung: 0.39 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