############################################################################# ## #W FundamentalDomainStandardSP.gi HAPcryst package Marc Roeder ## ##
## ## #Y Copyright (C) 2006 Marc Roeder #Y #Y This program is free software; you can redistribute it and/or #Y modify it under the terms of the GNU General Public License #Y as published by the Free Software Foundation; either version 2 #Y of the License, or (at your option) any later version. #Y #Y This program is distributed in the hope that it will be useful, #Y but WITHOUT ANY WARRANTY; without even the implied warranty of #Y MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #Y GNU General Public License for more details. #Y #Y You should have received a copy of the GNU General Public License #Y along with this program; if not, write to the Free Software #Y Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ## ######################################################################## ######################################################################## #### #### #### ALL THIS DOES ONLY WORK FOR THE STANDARD SCALAR PRODUCT! #### #### #### ######################################################################## ########################################################################
# for a point <center> find the edge of the cube <center>+{-1/2,1/2}^n # with minimal euclidian norm. #
smallestPointOfOneCubeAroundCenter:=function(center)
local edge, i, entry, sign, minusentry, plusentry;
# middle:=List(center,i->0);
edge:=List(center); for i in [1..Size(center)] do
entry:=edge[i];
sign:=SignRat(entry); if sign=0then sign:=1; fi;
minusentry:=-sign/2+entry;
plusentry:=sign/2+entry; if AbsoluteValue(minusentry)<AbsoluteValue(plusentry) then
edge[i]:=minusentry; elif AbsoluteValue(minusentry)=AbsoluteValue(plusentry) then
edge[i]:=(minusentry+plusentry)/2; # middle[i]:=(minusentry+plusentry)/2; # edge[i]:=plusentry; else
edge[i]:=plusentry; # middle[i]:=plusentry; fi;
od;
return edge; # return rec(edge:=edge,middle:=middle); end;
NextLargerInteger:=function(rat) if IsInt(rat) then
return rat; else
return Int(rat+1); fi; end;
#given a point <center> and an offset vector <offset> as well as the part of # the orbit around <center>, the interesting inequalities induced by # <orbitpart>+offset are calculated, assuming that only points nearer # than <radius> can induce something interesting. #
inequalitiesFromVertices:=function(center,offset,signvectors,orbitpart,vertices,radiussquare)
local ineqs, inequalities, sign, off;
ineqs:=function(center,points,vertices,rsquare)
local returnlist, point, ineq;
returnlist:=[]; for point in points do if (point-center)^2<=rsquare then
ineq:=BisectorInequalityFromPointPair(center,point); if ineq<>fail and ForAny(vertices,thiscorner->WhichSideOfHyperplane(thiscorner,ineq)=-1) # if ForAny(vertices,thiscorner->WhichSideOfHyperplane(thiscorner,ineq)=-1) then
Add(returnlist,ineq); fi; fi;
od;
return returnlist; end;
inequalities:=[]; for sign in signvectors do
off:=List([1..Size(sign)],i->sign[i]*offset[i])+orbitpart;
Append(inequalities,ineqs(center,off,vertices,radiussquare));
od;
return Set(inequalities); end;
needsConsideration:=function(offset,radiussquare)
# edgeAndMiddle:=smallestPointOfOneCubeAroundCenter(offset); # if edgeAndMiddle.edge^2<radiussquare or # edgeAndMiddle.middle^2<=radiussquare if smallestPointOfOneCubeAroundCenter(offset)^2<=radiussquare then
return true; else
return false; fi; end;
reducePolytope:=function(poly,center,offset,signvectors,radiussquare,orbitpart)
local vertices, inequalities;
vertices:=Polymake(poly,"VERTICES");
inequalities:=inequalitiesFromVertices(center,offset,signvectors,orbitpart,vertices,radiussquare); if inequalities <> [] then
UniteSet(inequalities,Polymake(poly,"FACETS"));
ClearPolymakeObject(poly,["polytope","2.3","RationalPolytope"]);
AppendInequalitiesToPolymakeObject(poly,inequalities);
Polymake(poly,"VERTICES FACETS"); if InfoLevel(InfoHAPcryst)>1 then
Print("|",Size(Polymake(poly,"VERTICES")),":",Size(Polymake(poly,"FACETS")),">\c"); fi;
return true; else
return false; fi; end;
initialPolytope:=function(center)
local dim, poly, signvectors, cubevertices;
# this calculates the radius of the ball to be covered and the maximal # entry (and the maximal entry sum) in the offset vectors needed to cover # the ball. The maximum distance for offset vectors is 3*radius.
radiussquareMaxentryMaxsum:=function(poly,center,dim)
local x, vertices, radiussquare, outerradiussquare,
maxentry, maxsum, offsetradiussquare;
x:=Indeterminate(Rationals);
vertices:=Polymake(poly,"VERTICES"); # this is the radius of the smallest circle around the polygon:
radiussquare:=Maximum(List(vertices-center,v->v^2));
#now, we look at the offset vectors. #radius of the ball we want to cover (twice the radius of the polygon):
outerradiussquare:=4*radiussquare; #maximal entry of an offset vector (\infty - norm): # 1/2+2*radius(poly) (1/2=half the side length of the offset cube):
maxentry:=NextLargerInteger(1/2+ContinuedFractionApproximationOfRoot(
DenominatorRat(outerradiussquare)*x^2
-NumeratorRat(outerradiussquare), 10)
); #maximum sum of entries of offset vectors (1-norm): #=dim*((2*radius(poly))^2/dim+1/2)
maxsum:=NextLargerInteger(dim*(outerradiussquare/dim+1/2));
###################################################################### ###################################################################### ## Los gehts! ###################################################################### ######################################################################
dim:=Size(center);
# First, generate the initial (translation) cube.
partialFD:=initialPolytope(center);
radmax:=radiussquareMaxentryMaxsum(partialFD,center,dim);
orbitpartAroundCenter:=Set(ShiftedOrbitPart(center,orbitpart));
polyChanged:=reducePolytope(partialFD,
center,
List([1..dim],i->0),
[List([1..dim],i->1)],
radmax.radiussquare,
orbitpartAroundCenter);
radmax:=radiussquareMaxentryMaxsum(partialFD,center,dim);
sums:=Iterator([1..radmax.maxsum]);
currentsum:=1; if InfoLevel(InfoHAPcryst)>1 then
Print(radmax,"\n"); fi;
while currentsum<radmax.maxsum do
currentsum:=NextIterator(sums); if InfoLevel(InfoHAPcryst)>1 then
Print("\n",currentsum,"(",Int(radmax.radiussquare),"-",radmax.maxsum,"-",radmax.maxentry,")\n"); fi; for nrNon0 in [1..Minimum(currentsum,dim)] do
signs:=Tuples([1,-1],nrNon0);
signvectors:=NullMat(Size(signs),dim);
non0entries:=Iterator(RestrictedPartitions(currentsum,[1..radmax.maxentry],nrNon0));
offsetvector:=List(center,i->0); for non0part in non0entries do
offsetvector{[1..nrNon0]}:=non0part;
issmall:=(non0part^2<=radmax.radiussquare); for offset in PermutationsList(offsetvector) do if issmall or needsConsideration(offset,radmax.radiussquare) then
non0indices:=Positions(List(offset,i->i<>0),true);
Apply(signvectors,i->List(i,j->1)); for index in [1..Size(signs)] do
signvectors[index]{non0indices}:=signs[index];
od;
polyChanged:=reducePolytope(partialFD,
center,
offset,
signvectors,
radmax.radiussquare,
orbitpartAroundCenter); if polyChanged then
radmax:=radiussquareMaxentryMaxsum(partialFD,center,dim); fi; if radmax.maxsum<currentsum then
return partialFD; ## We found it! fi; fi;
od;
od;
od;
od;
return partialFD; end);
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.26Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-12)
¤
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.