1############################################################################# 2## 3#W plane_isomorphisms.gi RDS Package Marc Roeder 4## 5## Methods for calculations with projective planes 6## 7## 8#Y Copyright (C) 2006-2011 Marc Roeder 9#Y 10#Y This program is free software; you can redistribute it and/or 11#Y modify it under the terms of the GNU General Public License 12#Y as published by the Free Software Foundation; either version 2 13#Y of the License, or (at your option) any later version. 14#Y 15#Y This program is distributed in the hope that it will be useful, 16#Y but WITHOUT ANY WARRANTY; without even the implied warranty of 17#Y MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18#Y GNU General Public License for more details. 19#Y 20#Y You should have received a copy of the GNU General Public License 21#Y along with this program; if not, write to the Free Software 22#Y Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23## 24############################################################################## 25### 26##O DualPlane( <plane> ) generate dual plane 27### 28#InstallMethod(DualPlane, 29# "for projective planes", 30# [IsRecord], 31# function(plane) 32# local points, returnblocks, image, p, locblocks, dualblock; 33# if not IsBlockDesign(plane) 34# then 35# Error("projective plane must be a block design"); 36# fi; 37# points:=[1..plane.v]; 38# returnblocks:=[]; 39# image:=ListWithIdenticalEntries(Size(points),0);; 40# for p in points 41# do 42# locblocks:=Filtered(blocks,b->p in b); 43# dualblock:=Set(locblocks,b->Position(blocks,b)); 44# Add(returnblocks,dualblock); 45# image[p]:=dualblock; 46# od; 47# return rec(blocks:=Set(returnblocks),image:=image);; 48#end); 49# 50############################################################################# 51## 52#O ProjectiveClosureOfPointSet(<points>,<plane>) 53## 54InstallMethod(ProjectiveClosureOfPointSet, 55 "for projective planes", 56 [IsDenseList,IsRecord], 57 function(points,plane) 58 return ProjectiveClosureOfPointSet(points,0,plane); 59end); 60 61############################################################################# 62## 63#O ProjectiveClosureOfPointSet(<points>,<maxsize>,<plane>) 64## 65InstallMethod(ProjectiveClosureOfPointSet, 66 "for projective planes", 67 [IsDenseList,IsInt,IsRecord], 68 function(points,maxsize,plane) 69 local newpoints, oldpoints, newblocks, oldblocks, 70 returnplane, embedding, invemb; 71 72 if not IsProjectivePlane(plane) 73 then 74 TryNextMethod(); 75 fi; 76 newpoints:=[]; 77 oldpoints:=Set(points); 78 newblocks:=Set(Combinations(oldpoints,2),i->plane.jblock[i[1]][i[2]]); 79 oldblocks:=[]; 80 if maxsize=0 81 then 82 maxsize:=plane.v-1; 83 fi; 84 repeat 85 newpoints:=Set(Cartesian(oldblocks,newblocks),i->Intersection(plane.blocks[i[1]],plane.blocks[i[2]])[1]); 86 UniteSet(newpoints,List(Combinations(newblocks,2),i->Intersection(plane.blocks[i[1]],plane.blocks[i[2]])[1])); 87 SubtractSet(newpoints,oldpoints); 88 UniteSet(oldblocks,newblocks); 89 newblocks:=Set(Cartesian(oldpoints,newpoints),i->plane.jblock[i[1]][i[2]]); 90 UniteSet(newblocks,List(Combinations(newpoints,2),i->plane.jblock[i[1]][i[2]])); 91 SubtractSet(newblocks,oldblocks); 92 UniteSet(oldpoints,newpoints); 93 until newpoints=[] or newblocks=[] or Size(oldpoints)>maxsize; 94 95 if Size(oldpoints)>maxsize 96 then 97 oldpoints:=[1..plane.v]; 98 fi; 99 if oldpoints=[1..plane.v] 100 then 101 returnplane:=plane; 102 embedding:=(); 103 elif Size(oldpoints)=1 104 then 105 embedding:=(1,oldpoints[1]); 106 returnplane:=BlockDesign(1,[[1]]); 107 else 108 newblocks:=Set(plane.blocks,i->Intersection(i,oldpoints)); 109 newblocks:=Filtered(newblocks,i->Size(i)>1); 110 embedding:=MappingPermListList([1..Size(oldpoints)],Set(oldpoints)); 111 invemb:=embedding^-1; 112 Apply(newblocks,i->OnSets(i,invemb)); 113 if Number(newblocks,b->Size(b)>2)<7 114 then 115 returnplane:=BlockDesign(Size(oldpoints),newblocks); 116 else 117 newblocks:=Filtered(newblocks,i->Size(i)>2); 118 returnplane:=ProjectivePlane(newblocks); 119 if IsBound(plane.jpoint) 120 then 121 PointJoiningLinesProjectivePlane(returnplane); 122 fi; 123 fi; 124 fi; 125 if IsBound(plane.pointNames) 126 then 127 returnplane.pointNames:=Immutable(List([1..returnplane.v],i-> 128 plane.pointNames[i^embedding])); 129 fi; 130 return rec(closure:=returnplane,embedding:=embedding); 131end); 132 133 134############################################################################# 135## 136#O IsIsomorphismOfProjectivePlanes( <perm>,<plane1>,<plane2> ) test for isomorphism of projective planes. 137## 138InstallMethod(IsIsomorphismOfProjectivePlanes, 139 "for projective planes", 140 [IsPerm,IsRecord,IsRecord], 141 function(perm,plane1,plane2) 142 local points, point, pointblocks, pointblocks_image; 143 144 if not IsBlockDesign(plane1) and IsBlockDesign(plane2) 145 then 146 Error("this does just work for block designs"); 147 fi; 148 points:=[1..plane1.v]; 149 return ForAll(plane1.blocks,b->OnSets(b,perm) in plane2.blocks); 150end); 151 152 153############################################################################# 154## 155#O IsCollineationOfProjectivePlane( <perm>,<plane> ) test if a permutation is a collineation of a projective plane 156## 157InstallMethod(IsCollineationOfProjectivePlane, 158 "for projective planes", 159 [IsPerm,IsRecord], 160 function(perm,plane) 161 return IsIsomorphismOfProjectivePlanes(perm,plane,plane); 162end); 163 164 165############################################################################# 166## 167#O ElationByPair( <centre>,<axis>,<pair>,<plane>) calculate elations of projective planes. 168## 169InstallMethod(ElationByPair, 170 "for projective planes", 171 [IsInt,IsVector,IsVector,IsRecord], 172 function(centre,axis,pair,plane) 173 local points, blockslist, axispos, init_cblocks, axispoints, 174 returnlist, permlist, cblocks, projpairs, pairblock, 175 point, pblock1, pblock2, cblock, x, y, cblockpair, 176 nogood, ppair, perm; 177 178 if not IsProjectivePlane(plane) 179 then 180 Error("this is not a projective plane"); 181 fi; 182 183 if not IsBound(plane.jpoint) 184 then 185 TryNextMethod(); 186 fi; 187 188 points:=[1..plane.v]; 189 190 if not IsSubset(points,pair) 191 then 192 Error("<pair> must be a pair of points"); 193 fi; 194 195 if not axis in plane.blocks 196 then 197 Error("The axis must be a block"); 198 fi; 199 blockslist:=[1..plane.v]; 200 axispos:=Position(plane.blocks,axis); 201 202 init_cblocks:=Difference(Set(plane.jblock[centre]),[0]); 203 RemoveSet(init_cblocks,axispos); 204 205 axispoints:=Difference(axis,[centre]); 206 207 returnlist:=[]; 208 209 if Intersection(pair,axis)<>[] 210 then 211 Error("The axis must be fixed pointwise"); 212 fi; 213 permlist:=[1..plane.v]; 214 cblocks:=ShallowCopy(init_cblocks); 215 projpairs:=[]; 216 pairblock:=plane.jblock[pair[1]][pair[2]]; 217 218 if not centre in plane.blocks[pairblock] 219 then 220 Error("The centre must be fixed blockwise"); 221 fi; 222 RemoveSet(cblocks,pairblock); 223 224 for point in axispoints 225 do 226 pblock1:=plane.jblock[point][pair[1]]; 227 pblock2:=plane.jblock[point][pair[2]]; 228 for cblock in cblocks 229 do 230 x:=plane.jpoint[cblock][pblock1]; 231 y:=plane.jpoint[cblock][pblock2]; 232 Add(projpairs,[x,y]); 233 od; 234 od; 235 cblockpair:=Representative(projpairs); 236 cblock:=plane.jblock[cblockpair[1]][cblockpair[2]]; 237 238 for point in axispoints 239 do 240 pblock1:=plane.jblock[point][cblockpair[1]]; 241 pblock2:=plane.jblock[point][cblockpair[2]]; 242 x:=plane.jpoint[pblock1][pairblock]; 243 y:=plane.jpoint[pblock2][pairblock]; 244 Add(projpairs,[x,y]); 245 od; 246 nogood:=false; 247 248 for ppair in projpairs 249 do 250 if permlist[ppair[1]] in [ppair[1],ppair[2]] 251 then 252 permlist[ppair[1]]:=ppair[2]; 253 else 254 nogood:=true; 255 fi; 256 od; 257 258 if not nogood 259 then 260 perm:=PermList(permlist); 261 if IsCollineationOfProjectivePlane(perm,plane) 262 then 263 return perm; 264 else 265 Error("Unable to generate elation"); 266 fi; 267 else 268 Error("Unable to generate elation"); 269 fi; 270end); 271 272 273############################################################################# 274## 275#O ElationByPair( <centre>,<axis>,<pair>,<plane>) calculate elations of projective planes. 276## This is the "small" implementation. It does not use .jpoint 277## 278InstallMethod(ElationByPair, 279 "for projective planes", 280 [IsInt,IsVector,IsVector,IsRecord], 281 function(centre,axis,pair,plane) 282 local blockslist, axispos, init_cblocks, axispoints, 283 permlist, cblocks, projpairs, pairblock, point, 284 pblock1, pblock2, cblock, x, y, cblockpair, nogood, 285 ppair, perm; 286 287 if not IsProjectivePlane(plane) 288 then 289 Error("this is not a projective plane"); 290 fi; 291 if IsBound(plane.jpoint) 292 then 293 TryNextMethod(); 294 fi; 295 296 if not IsSubset([1..plane.v],pair) 297 then 298 Error("<pair> must be a pair of points"); 299 fi; 300 301 # die Punkte muessen integers sein! 302 if not axis in plane.blocks 303 then 304 Error("The axis must be a block"); 305 fi; 306 if not centre in axis 307 then 308 Error("The centre must lie on the axis"); 309 fi; 310 blockslist:=[1..plane.v]; 311 axispos:=PositionSet(plane.blocks,axis); 312 313 init_cblocks:=Set(Filtered(plane.blocks,b->centre in b)); 314 RemoveSet(init_cblocks,axis); 315 316 axispoints:=Difference(axis,[centre]); 317 318 if pair[1]=pair[2] 319 then 320 Error("There can only be one axis. <pair> must contain two different points."); 321 fi; 322 if Intersection(pair,axis)<>[] 323 then 324 Error("The axis must be fixed pointwise"); 325 fi; 326 permlist:=[1..plane.v]; 327 cblocks:=ShallowCopy(init_cblocks); 328 projpairs:=[]; 329 pairblock:=plane.blocks[plane.jblock[pair[1]][pair[2]]]; 330 331 if not centre in pairblock 332 then 333 Error("The centre must be fixed blockwise"); 334 fi; 335 RemoveSet(cblocks,pairblock); 336 337 for point in axispoints 338 do 339 pblock1:=plane.blocks[plane.jblock[point][pair[1]]]; 340 pblock2:=plane.blocks[plane.jblock[point][pair[2]]]; 341 for cblock in cblocks 342 do 343# x:=First(cblock,i->i in pblock1); 344# y:=First(cblock,i->i in pblock2); 345 x:=Intersection2(cblock,pblock1)[1]; 346 y:=Intersection2(cblock,pblock2)[1]; 347 Add(projpairs,[x,y]); 348 od; 349 od; 350 cblockpair:=Representative(projpairs); 351 cblock:=plane.blocks[plane.jblock[cblockpair[1]][cblockpair[2]]]; 352 for point in axispoints 353 do 354 pblock1:=plane.blocks[plane.jblock[point][cblockpair[1]]]; 355 pblock2:=plane.blocks[plane.jblock[point][cblockpair[2]]]; 356# x:=First(pblock1,i->i in pairblock); 357# y:=First(pblock2,i->i in pairblock); 358 x:=Intersection2(pblock1,pairblock)[1]; 359 y:=Intersection2(pblock2,pairblock)[1]; 360 Add(projpairs,[x,y]); 361 od; 362 nogood:=false; 363 364 for ppair in projpairs 365 do 366 if permlist[ppair[1]] in [ppair[1],ppair[2]] 367 then 368 permlist[ppair[1]]:=ppair[2]; 369 else 370 nogood:=true; 371 fi; 372 od; 373 374 if not nogood 375 then 376 perm:=PermList(permlist); 377 if IsCollineationOfProjectivePlane(perm,plane) 378 then 379 return perm; 380 else 381 Error("Unable to generate elation"); 382 fi; 383 else 384 Error("Unable to generate elation"); 385 fi; 386end); 387 388 389############################################################################# 390## 391#O AllElationsCentAx( <centre>,<axis>,<plane>) calculate group of elations 392#O AllElationsCentAx( <centre>,<axis>,<plane>,"generators") calculate all elations 393## 394InstallMethod(AllElationsCentAx, 395 "for projective planes", 396 [IsInt,IsVector,IsRecord], 397 function(centre,axis,plane) 398 return Group(AllElationsCentAx(centre,axis,plane,"generators")); 399end); 400 401InstallMethod(AllElationsCentAx, 402 "for projective planes", 403 [IsInt,IsVector,IsRecord,IsString], 404 function(centre,axis,plane,genstring) 405 local blocks, ellist, pairs, block, pointset, point, 406 genset, pointsetsize, newelation; 407 408 if not genstring="generators" 409 then 410 Error("please pass >generators< as an option"); 411 fi; 412 if not IsProjectivePlane(plane) 413 then 414 Error("<plane> must be a projective plane"); 415 fi; 416 417 blocks:=plane.blocks; 418 ellist:=[]; 419 pairs:=[]; 420 421 block:=First(blocks,b->centre in b and not b=axis); 422 pointset:=Difference(block,[centre]); 423 point:=Representative(pointset); 424 RemoveSet(pointset,point); 425 426 genset:=[]; 427 while pointset<>[] 428 do 429 pointsetsize:=Size(pointset); 430 newelation:=ElationByPair(centre,axis,[point,pointset[pointsetsize]],plane); 431 Unbind(pointset[pointsetsize]); 432 Add(genset,newelation); 433 SubtractSet(pointset,Orbit(Group(genset),point)); 434 od; 435 return genset; 436end); 437 438 439############################################################################# 440## 441#O AllElationsAx(<axis>,<plane>) calcualte group of elations with given axis. 442#O AllElationsAx(<axis>,<plane>,"generators") calcualte generators of the gorup of elations with given axis. 443## 444InstallMethod(AllElationsAx, 445 "for projective planes", 446 [IsDenseList,IsRecord], 447 function(axis,plane) 448 return Group(AllElationsAx(axis,plane,"generators")); 449end); 450 451InstallMethod(AllElationsAx, 452 "for projective planes", 453 [IsDenseList,IsRecord,IsString], 454 function(axis,plane,genstring) 455 local points, ellist, centre; 456 457 if not genstring="generators" 458 then 459 Error("please pass >generators< as an option"); 460 fi; 461 if not IsProjectivePlane(plane) 462 then 463 Error("this is not a projective plane"); 464 fi; 465 466 points:=Difference([1..plane.v],axis); 467 ellist:=[]; 468 for centre in axis 469 do 470 if ellist<>[] and IsTransitive(Group(ellist),points) 471 then 472 return Set(ellist); 473 else 474 Append(ellist,AllElationsCentAx(centre,axis,plane,"generators")); 475 fi; 476 od; 477 return Set(ellist); 478end); 479 480 481 482############################################################################# 483## 484#O IsTranslationPlane(<infline>,<plane>) 485## 486InstallMethod(IsTranslationPlane, 487 "for projective planes", 488 [IsRecord], 489 function(plane) 490 if not IsProjectivePlane(plane) 491 then 492 return false; 493 fi; 494 return ForAny(plane.blocks,b->IsTranslationPlane(b,plane)); 495end); 496 497 498############################################################################# 499## 500#O IsTranslationPlane(<infline>,<plane>) 501## 502InstallMethod(IsTranslationPlane, 503 "for projective planes", 504 [IsDenseList,IsRecord], 505 function(infline,plane) 506 local cent1, t1gens, cent2, t2gens; 507 cent1:=Random(infline); 508 t1gens:=AllElationsCentAx(cent1,infline,plane,"generators"); 509 if t1gens=[] or Size(Group(t1gens))<>Size(infline)-1 510 then 511 return false; 512 else 513 cent2:=Random(Difference(infline,[cent1])); 514 t2gens:=AllElationsCentAx(cent2,infline,plane,"generators"); 515 fi; 516 if Size(Group(Concatenation(t2gens,t1gens)))=plane.v-Size(infline) 517 then 518 return true; 519 else 520 return false; 521 fi; 522end); 523 524############################################################################# 525## 526#O GroupOfHomologies(<cetre>,<axis>,<plane>) 527## 528InstallMethod(GroupOfHomologies, 529 "for projective planes", 530 [IsInt,IsDenseList,IsRecord], 531 function(centre,axis,plane) 532 local line, pointset, point, genlist, 533 pointsetsize, newhomology; 534 535 if not IsProjectivePlane(plane) 536 then 537 Error("this is not a projective plane"); 538 fi; 539 line:=plane.blocks[plane.jblock[centre][axis[1]]]; 540 pointset:=Difference(line,[centre,axis[1]]); 541 point:=pointset[1]; 542 RemoveSet(pointset,point); 543 genlist:=[]; 544 while pointset<>[] 545 do 546 pointsetsize:=Size(pointset); 547 newhomology:=HomologyByPair(centre,axis,[point,pointset[pointsetsize]],plane); 548 Unbind(pointset[pointsetsize]); 549 if not newhomology=fail 550 then 551 Add(genlist,newhomology); 552 SubtractSet(pointset,Set(Orbit(Group(genlist),point))); 553 fi; 554 od; 555 if genlist=[] 556 then 557 return Group(()); 558 else 559 return Group(genlist); 560 fi; 561end); 562 563############################################################################# 564## 565#O HomologyByPair(<centre>,<axis>,<pair>,<plane>); 566## 567 568InstallMethod(HomologyByPair, 569 "for projective planes", 570 [IsInt,IsDenseList,IsDenseList,IsRecord], 571 function(centre,axis,pair,plane) 572 local points, blocks, jblock, blockslist, axispos, cblocks, 573 returnlist, permlist, projpairs, pairblock, axpoint, 574 plineSource, plineDest, line, ppoint, point, perm; 575 576 if not IsProjectivePlane(plane) 577 then 578 Error("this is not a projective plane"); 579 fi; 580 points:=[1..plane.v]; 581 blocks:=plane.blocks; 582 jblock:=plane.jblock; 583 if not axis in blocks 584 then 585 Error("The axis must be a block"); 586 return fail; 587 fi; 588 blockslist:=[1..Size(blocks)]; 589 axispos:=PositionSet(blocks,axis); 590 cblocks:=Set(Filtered(blocks,b->centre in b)); 591 if axis in cblocks 592 then 593 Error("The axis must not contain the centre"); 594 return fail; 595 fi; 596 returnlist:=[]; 597 if Intersection(pair,axis)<>[] 598 then 599 Error("The axis must be fixed pointwise"); 600 return fail; 601 fi; 602 permlist:=[1..Maximum(points)]; 603 permlist[pair[1]]:=pair[2]; 604 projpairs:=[]; 605 pairblock:=blocks[jblock[pair[1]][pair[2]]]; 606 if not centre in pairblock 607 then 608 Error("The centre must be fixed blockwise"); 609 return fail; 610 fi; 611 RemoveSet(cblocks,pairblock); 612 613 for axpoint in Difference(axis,pairblock) 614 do 615 plineSource:=blocks[jblock[pair[1]][axpoint]]; 616 plineDest:=blocks[jblock[pair[2]][axpoint]]; 617 for line in cblocks 618 do 619 if not axpoint in line 620 then 621 permlist[Intersection2(plineSource,line)[1]]:=Intersection2(plineDest,line)[1]; 622 fi; 623 od; 624 od; 625 #and now the line <pair> lives on. 626 line:=cblocks[1]; 627 ppoint:=First(axis,p->not (p in line or p in pairblock)); 628 for point in Difference(pairblock,Union(axis,[pair[1]],[centre])) 629 do 630 plineSource:=blocks[jblock[point][ppoint]]; 631 plineDest:=blocks[jblock[ppoint][permlist[Intersection(plineSource,line)[1]]]]; 632 permlist[point]:=Intersection(plineDest,pairblock)[1]; 633 od; 634 perm:=PermList(permlist); 635 if IsCollineationOfProjectivePlane(perm,plane) 636 then 637 return perm; 638 else 639 return fail; 640 fi; 641end); 642 643############################################################################# 644## 645#O InducedCollineation(<baerplane>,<baercoll>,<point>,<image>,<plane>,<embedding>) 646## 647InstallMethod(InducedCollineation, 648 "for projective planes", 649 [IsRecord,IsPerm,IsInt,IsInt,IsRecord,IsPerm], 650 function(baerplane,baercoll,point,image,plane,liftingperm) 651 local blocks, jblock, jpoint, baerindices, 652 liftedcollineation, pointtangents, pointsecant, 653 pointsecantnr, imagesecant, fixpoint, imagetangents, 654 shortimagesecant, shortpointsecant, baerblocks, 655 permlist, tpoint, tangent, tangentimage, secant, p, 656 shortsecant, secantimage, ppoint, ppointimage, 657 linepoint, pline, pointinbetween, plineimage, perm; 658 659 if not IsProjectivePlane(plane) 660 then 661 Error("this is not a projective plane"); 662 fi; 663 664 if not IsProjectivePlane(baerplane) 665 then 666 Error("the Baer plane is not a projective plane"); 667 fi; 668 669 if not IsBound(plane.jpoint) 670 then 671 PointJoiningLinesProjectivePlane(plane);; 672 fi; 673 blocks:=plane.blocks; 674 jblock:=plane.jblock; 675 jpoint:=plane.jpoint; 676 baerindices:=OnSets([1..baerplane.v],liftingperm); 677 liftedcollineation:=RestrictedPerm(baercoll^liftingperm,baerindices); 678 if (point in baerindices) or (image in baerindices) 679 then 680 Error("point and image must not lie in the Baer subplane"); 681 return fail; 682 fi; 683 pointtangents:=Set(blocks{Set(jblock[point]{baerindices})}); 684 pointsecant:=First(pointtangents,b->Size(Intersection(b,baerindices))>1); 685 pointsecantnr:=PositionSet(blocks,pointsecant); 686 687 if image in pointsecant 688 then 689 imagesecant:=pointsecant; 690 if point=image 691 then 692 fixpoint:=true; 693 else 694 fixpoint:=false; 695 fi; 696 else 697 fixpoint:=false; 698 imagetangents:=Set(blocks{Set(jblock[image]{baerindices})}); 699 imagesecant:=First(imagetangents,b->Size(Intersection(b,baerindices))>1); 700 shortimagesecant:=Set(Intersection(imagesecant,baerindices)); 701 shortpointsecant:=Set(Intersection(pointsecant,baerindices)); 702 if OnSets(shortimagesecant,liftedcollineation)=shortimagesecant 703 then 704 Info(DebugRDS,1,"Wrong:point and image define different secants and image secant is fixed"); 705 return fail; 706 fi; 707 if 1 in OrbitLengths(Group(liftedcollineation),shortimagesecant) 708 then 709 #here a tangent would be mapped to a secant. 710 #This is impossible. 711 Info(DebugRDS,1,"Wrong:image secant contains a fixed point"); 712 return fail; 713 fi; 714 fi; 715 shortimagesecant:=Set(Intersection(imagesecant,baerindices)); 716 shortpointsecant:=Set(Intersection(pointsecant,baerindices)); 717 if not OnSets(shortpointsecant,liftedcollineation)=shortimagesecant 718 then 719 Info(DebugRDS,1,"point secant is not mapped to image secant"); 720 return fail; 721 fi; 722 baerblocks:=List(baerplane.blocks,b->OnSets(b,liftingperm)); 723 baerblocks:=Set(baerblocks,b->blocks[jblock[b[1]][b[2]]]); 724 RemoveSet(baerblocks,pointsecant); 725 permlist:=List(OnTuples([1..plane.v],liftedcollineation)); 726 permlist[point]:=image; 727 for tpoint in Difference(baerindices,pointsecant) 728 do 729 tangent:=blocks[jblock[tpoint][point]]; 730 tangentimage:=jblock[permlist[tpoint]][image]; 731 for secant in baerblocks 732 do 733 p:=Intersection(secant,tangent)[1]; 734 shortsecant:=Intersection(secant,baerindices); 735 secantimage:=jblock[permlist[shortsecant[1]]][permlist[shortsecant[2]]]; 736 permlist[p]:=jpoint[secantimage][tangentimage]; 737 od; 738 od; 739 ppoint:=Representative(Difference([1..plane.v],Concatenation(baerindices,pointsecant))); 740 ppointimage:=permlist[ppoint]; 741 for linepoint in Difference(pointsecant,Concatenation(baerindices,[point])) 742 do 743 pline:=blocks[jblock[linepoint][ppoint]]; 744 pointinbetween:=First(pline,i->not i in [ppoint,linepoint]); 745 plineimage:=jblock[permlist[pointinbetween]][ppointimage]; 746 permlist[linepoint]:=jpoint[pointsecantnr][plineimage]; 747 od; 748 perm:=PermList(permlist); 749 if perm=fail and not IsSubset(pointsecant,Set(Filtered(Collected(permlist),i->i[2]>1),j->j[1])) 750 then 751 Error("da gibt's noch ein Problem..."); 752 elif perm=fail 753 then 754 return fail; 755 elif IsCollineationOfProjectivePlane(perm,plane) 756 then 757 return perm; 758 else 759 return fail; 760 fi; 761end); 762 763############################################################################# 764## 765#O NrFanoPlanesAtPoints(<points>,<plane>) invariant for projective planes 766## 767InstallMethod(NrFanoPlanesAtPoints, 768 "for projective planes", 769 [IsDenseList,IsRecord], 770 function(pointlist,plane) 771 local returnlist, points, jblock, jpoint, blocks, x, 772 nrfanos, localblocks, localblockssize, points1size, 773 block1number, block1, points1, block2number, block2, 774 points2, block3number, block3, point2number, point2, 775 point3, point4, b24, p24, b34, p34, b324, b234; 776 if not IsProjectivePlane(plane) 777 then 778 Error("<plane> is not a projective plane"); 779 fi; 780 if not IsBound(plane.jpoint) 781 then 782 TryNextMethod(); 783 fi; 784 785 returnlist:=[]; 786 points:=[1..plane.v]; 787 jblock:=plane.jblock; 788 jpoint:=plane.jpoint; 789 blocks:=plane.blocks; 790 for x in pointlist 791 do 792 nrfanos:=0; 793 localblocks:=Difference(Set(jblock[x]),[0]); 794 localblockssize:=Size(localblocks); 795 points1size:=localblockssize-1; 796 for block1number in [1..localblockssize-2] 797 do 798 block1:=localblocks[block1number]; 799 points1:=Difference(blocks[block1],[x]); 800 for block2number in [block1number+1..localblockssize-1] 801 do 802 block2:=localblocks[block2number]; 803 points2:=Difference(blocks[block2],[x]); 804 for block3number in [block2number+1..localblockssize] 805 do 806 block3:=localblocks[block3number]; 807 for point2number in [1..points1size-1] 808 do 809 point2:=points1[point2number]; 810 for point3 in points1{[point2number+1..points1size]} 811 do 812 for point4 in points2 813 do 814 b24:=jblock[point2][point4]; 815 p24:=jpoint[block3][b24]; 816 817 b34:=jblock[point3][point4]; 818 p34:=jpoint[block3][b34]; 819 820 b324:=jblock[point3][p24]; 821 b234:=jblock[point2][p34]; 822 823 if jpoint[block2][b234]=jpoint[block2][b324] 824 then 825 nrfanos:=nrfanos+1; 826 fi; 827 od; 828 od; 829 od; 830 od; 831 od; 832 od; 833 Add(returnlist,[x,nrfanos]); 834 od; 835 return returnlist; 836end); 837 838 839############################################################################# 840## 841#O NrFanoPlanesAtPoints(<pointlist>,<plane>) invariant for projective planes 842## 843## This is the "small" version 844## 845InstallMethod(NrFanoPlanesAtPoints, 846 "for projective planes", 847 [IsDenseList,IsRecord], 848 function(pointlist,plane) 849 local returnlist, points, jblock, blocks, x, nrfanos, 850 localblocks, localblockssize, points1size, 851 block1number, block1, points1, block2number, block2, 852 points2, block3number, block3, points3, point2number, 853 point2, point3, point4, b24, p24, b34, p34, b324, 854 b234; 855 if not IsProjectivePlane(plane) 856 then 857 Error("<plane> is not a projective plane"); 858 fi; 859 860 if IsBound(plane.jpoint) 861 then 862 TryNextMethod(); 863 fi; 864 865 returnlist:=[]; 866 points:=[1..plane.v]; 867 jblock:=plane.jblock; 868 blocks:=plane.blocks; 869 870 for x in pointlist 871 do 872 nrfanos:=0; 873 localblocks:=Difference(Set(jblock[x]),[0]); 874 localblockssize:=Size(localblocks); 875 points1size:=localblockssize-1; 876 for block1number in [1..localblockssize-2] 877 do 878 block1:=localblocks[block1number]; 879 points1:=AsSet(Difference(blocks[block1],[x])); 880 for block2number in [block1number+1..localblockssize-1] 881 do 882 block2:=localblocks[block2number]; 883 points2:=AsSet(Difference(blocks[block2],[x])); 884 for block3number in [block2number+1..localblockssize] 885 do 886 block3:=localblocks[block3number]; 887 points3:=AsSet(blocks[block3]); 888 for point2number in [1..points1size-1] 889 do 890 point2:=points1[point2number]; 891 for point3 in points1{[point2number+1..points1size]} 892 do 893 for point4 in points2 894 do 895 b24:=jblock[point2][point4]; 896 p24:=Intersection(points3,blocks[b24])[1]; 897 898 b34:=jblock[point3][point4]; 899 p34:=Intersection(points3,blocks[b34])[1]; 900 901 b324:=jblock[point3][p24]; 902 b234:=jblock[point2][p34]; 903 904 if Intersection(points2,blocks[b234])=Intersection(points2,blocks[b324]) 905 then 906 nrfanos:=nrfanos+1; 907 fi; 908 od; 909 od; 910 od; 911 od; 912 od; 913 od; 914 Add(returnlist,[x,nrfanos]); 915 od; 916 return returnlist; 917end); 918 919 920############################################################################# 921## 922#O IncidenceMatrix(<design>) 923## 924InstallMethod(IncidenceMatrix, 925 [IsRecord], 926 function(plane) 927 local blocknumber, mat, blocknr, blocksize; 928 929 if not IsBlockDesign(plane) 930 then 931 Error("This is not a block design"); 932 fi; 933 blocknumber:=Size(plane.blocks); 934 mat:=NullMat(plane.v,blocknumber); 935 for blocknr in [1..blocknumber] 936 do 937 blocksize:=Size(plane.blocks[blocknr]); 938 mat{plane.blocks[blocknr]}[blocknr]:=List([1..blocksize],i->1); 939 od; 940 return mat; 941end); 942 943############################################################################# 944## 945#O pRank(<plane>,<p>) 946## 947InstallMethod(PRank@, 948 "for projective planes", 949 [IsRecord,IsInt], 950 function(plane,p) 951 local pointlist; 952 953 if not IsProjectivePlane(plane) 954 then 955 Error("This is not projective plane"); 956 fi; 957 if not Size(Set(FactorsInt(p)))=1 958 then 959 Error("<p> must be a primepower or 0"); 960 fi; 961 if p=0 962 then 963 return RankMatDestructive(IncidenceMatrix(plane)); 964 else 965 return RankMatDestructive(IncidenceMatrix(plane)*Z(p)); 966 fi; 967end); 968 969############################################################################# 970## 971#O FingerprintAntiFlag(<point>,<linenr>,<plane>) 972## 973InstallMethod(FingerprintAntiFlag, 974 [IsInt,IsInt,IsRecord], 975 function(point,linenr,plane) 976 local infline, lblocks, mat, lpoint, projlines, lblock, 977 permlist, pointnr, lblockpoint; 978 979 if not IsProjectivePlane(plane) 980 then 981 Error("this is not a projective plane"); 982 fi; 983 if point in plane.blocks[linenr] 984 then 985 Error("This is not an anti- flag!"); 986 fi; 987 infline:=plane.blocks[linenr]; 988 lblocks:=Set(plane.jblock[point]); 989 RemoveSet(lblocks,0); 990 Apply(lblocks,i->plane.blocks[i]); 991 992 mat:=NullMat(Size(infline),Size(infline));; 993 for lpoint in infline 994 do 995 projlines:=Set(plane.jblock[lpoint]); 996 RemoveSet(projlines,0); 997 Apply(projlines,i->plane.blocks[i]); 998 for lblock in Filtered(lblocks,b->not lpoint in b) 999 do 1000 permlist:=[1..Size(lblock)]; 1001 for pointnr in [1..Size(lblock)] 1002 do 1003 lblockpoint:=lblock[pointnr]; 1004 permlist[pointnr]:=PositionProperty(projlines,b->lblockpoint in b); 1005 od; 1006 mat[PositionSet(infline,lpoint)][PositionSet(lblocks,lblock)]:= SignPerm(PermList(permlist)); 1007 1008 od; 1009 od; 1010 # return Collected(List(Concatenation(mat*TransposedMat(mat)),AbsoluteValue)); 1011 return Collected(List(Concatenation(MatTimesTransMat(mat)),AbsoluteValue)); 1012end); 1013 1014 1015############################################################################# 1016## 1017#O FingerprintProjPlane(<plane>) 1018## 1019InstallMethod(FingerprintProjPlane, 1020 [IsRecord], 1021 function(plane) 1022 local nrOfBlocks, mat, points, point, lblocks, 1023 lblocksindex, linenr, line, permlist, pointnr; 1024 1025 if not IsProjectivePlane(plane) 1026 then 1027 Error("this is not a projective plane"); 1028 fi; 1029 mat:=NullMat(plane.v,plane.v); 1030 for point in [1..plane.v] 1031 do 1032 lblocks:=Set(Filtered(plane.blocks,b->point in b)); 1033 lblocksindex:=Set(lblocks,b->PositionSet(plane.blocks,b)); 1034 for linenr in Difference([1..plane.v],lblocksindex) 1035 do 1036 line:=plane.blocks[linenr]; 1037 permlist:=[1..Size(line)]; 1038 for pointnr in [1..Size(line)] 1039 do 1040 permlist[pointnr]:=PositionProperty(lblocks,b->line[pointnr] in 1041 b); 1042 od; 1043 mat[point][linenr]:=SignPerm(PermList(permlist)); 1044 od; 1045 od; 1046 return Collected(List(Concatenation(MatTimesTransMat(mat)),AbsoluteValue)); 1047end); 1048 1049############################################################################# 1050## 1051#O IsomorphismProjPlanesByGenerators(<gens1>,<plane1>,<gens2>,<plane2>) 1052## 1053InstallMethod(IsomorphismProjPlanesByGenerators, 1054 "for projective planes", 1055 [IsDenseList,IsRecord,IsDenseList,IsRecord], 1056 function(gens1,plane1,gens2,plane2) 1057 local N, hasfailed; 1058 1059 if Size(gens1)<>Size(gens2) 1060 then 1061 Error("<gens1> and <gens2> must be of the same length!"); 1062 fi; 1063 if not IsProjectivePlane(plane1) and IsProjectivePlane(plane2) 1064 then 1065 Error("plane1 and plane2 must be projective planes"); 1066 fi; 1067 N:=plane1.v; 1068 hasfailed:=false; 1069 if not plane2.v=N 1070 then 1071 Error("The planes must be of the same size"); 1072 hasfailed:=true; 1073 fi; 1074 if ProjectiveClosureOfPointSet(gens1,0,plane1).closure.v<>N 1075 or ProjectiveClosureOfPointSet(gens2,0,plane2).closure.v<>N 1076 then 1077 hasfailed:=true; 1078 fi; 1079 if not hasfailed 1080 then 1081 return IsomorphismProjPlanesByGeneratorsNC(gens1,plane1,gens2,plane2); 1082 else 1083 return fail; 1084 fi; 1085end); 1086 1087############################################################################# 1088## 1089#O IsomorphismProjPlanesByGeneratorsNC(<gens1>,<plane1>,<gens2>,<plane2>) 1090## 1091InstallMethod(IsomorphismProjPlanesByGeneratorsNC, 1092 "for projective planes", 1093 [IsDenseList,IsRecord,IsDenseList,IsRecord], 1094 function(gens1,plane1,gens2,plane2) 1095 local newpoints, oldpoints, newblocks, pointimagelist, 1096 blockimagelist, pair, oldblocks, x, iso; 1097 1098 if Size(gens1)<>Size(gens2) 1099 then 1100 Error("<gens1> and <gens2> must be of the same length!"); 1101 fi; 1102 if not (IsProjectivePlane(plane1) and IsProjectivePlane(plane2)) 1103 then 1104 Error("plane1 and plane2 must be projective planes"); 1105 fi; 1106 1107 newpoints:=[]; 1108 oldpoints:=Set(gens1); 1109 newblocks:=[]; 1110 pointimagelist:=ListWithIdenticalEntries(plane2.v,0); 1111 pointimagelist{gens1}:=gens2; 1112 blockimagelist:=ListWithIdenticalEntries(plane2.v,0); 1113 newblocks:=Set(Combinations(oldpoints,2),i-> 1114 [plane1.jblock[i[1]][i[2]], 1115 plane2.jblock[pointimagelist[i[1]]][pointimagelist[i[2]]]]); 1116 if Size(Set(newblocks,i->i[1]))<>Size(Set(newblocks,i->i[1])) 1117 then 1118 Info(DebugRDS,2,"bad generators"); 1119 return fail; 1120 fi; 1121 for pair in newblocks 1122 do 1123 blockimagelist[pair[1]]:=pair[2]; 1124 od; 1125 newblocks:=Set(newblocks,i->i[1]); 1126 oldblocks:=[]; 1127 repeat 1128 newpoints:=Set(Cartesian(oldblocks,newblocks),i-> 1129 [Intersection(plane1.blocks[i[1]],plane1.blocks[i[2]])[1], 1130 Intersection(plane2.blocks[blockimagelist[i[1]]],plane2.blocks[blockimagelist[i[2]]])[1]]); 1131 UniteSet(newpoints,List(Combinations(newblocks,2),i-> 1132 [Intersection(plane1.blocks[i[1]],plane1.blocks[i[2]])[1], 1133 Intersection(plane2.blocks[blockimagelist[i[1]]],plane2.blocks[blockimagelist[i[2]]])[1]])); 1134 for pair in newpoints 1135 do 1136 x:=pair[1]; 1137 if pointimagelist[x]<>0 and pair[2]<>pointimagelist[x] 1138 then 1139 return fail; 1140 elif pointimagelist[x]=0 1141 then 1142 pointimagelist[x]:=pair[2]; 1143 fi; 1144 od; 1145 1146 if Number(pointimagelist,i->i=0)<>0 1147 then 1148 newpoints:=Difference(Set(newpoints,i->i[1]),oldpoints); 1149 UniteSet(oldblocks,newblocks); 1150 newblocks:=Set(Cartesian(oldpoints,newpoints),i-> 1151 [plane1.jblock[i[1]][i[2]], 1152 plane2.jblock[pointimagelist[i[1]]][pointimagelist[i[2]]]] 1153 ); 1154 UniteSet(newblocks,List(Combinations(newpoints,2),i-> 1155 [plane1.jblock[i[1]][i[2]], 1156 plane2.jblock[pointimagelist[i[1]]][pointimagelist[i[2]]] 1157 ] 1158 )); 1159 for pair in newblocks 1160 do 1161 x:=pair[1]; 1162 if blockimagelist[x]<>0 and pair[2]<>blockimagelist[x] 1163 then 1164 return fail; 1165 elif blockimagelist[x]=0 1166 then 1167 blockimagelist[x]:=pair[2]; 1168 fi; 1169 od; 1170 newblocks:=Difference(Set(newblocks,i->i[1]),oldblocks); 1171 UniteSet(oldpoints,newpoints); 1172 else 1173 newpoints:=[]; 1174 fi; 1175 until newpoints=[]; 1176 iso:=PermListList([1..plane1.v],pointimagelist); 1177 if IsPerm(iso) and IsIsomorphismOfProjectivePlanes(iso,plane1,plane2) 1178 then 1179 return iso; 1180 else 1181 return fail; 1182 fi; 1183end); 1184 1185############################################################################# 1186## 1187#E END 1188## 1189