Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 4183461[1X2 [33X[0;0YImplementing circle objects[133X[101X23[33X[0;0YIn this chapter we explain how the [5XGAP[105X system may be extended with new4objects using the circle multiplication as an example. We follow the5guidelines given in the [5XGAP[105X Reference Manual (see [14X'Reference: Creating New6Objects'[114X and subsequent chapters), to which we refer for more details.[133X789[1X2.1 [33X[0;0YFirst attempts[133X[101X1011[33X[0;0YOf course, having two ring elements, you can straightforwardly compute their12circle product defined as [22Xr ⋅ s = r + s + rs[122X. You can do this in a command13line, and it is a trivial task to write a simplest function of two arguments14that will do this:[133X1516[4X[32X Example [32X[104X17[4X[28X[128X[104X18[4X[25Xgap>[125X [27XCircleMultiplication := function(a,b)[127X[104X19[4X[25X>[125X [27X return a+b+a*b;[127X[104X20[4X[25X>[125X [27X end;[127X[104X21[4X[28Xfunction( a, b ) ... end[128X[104X22[4X[25Xgap>[125X [27XCircleMultiplication(2,3); [127X[104X23[4X[28X11[128X[104X24[4X[25Xgap>[125X [27XCircleMultiplication( ZmodnZObj(2,8), ZmodnZObj(5,8) ); [127X[104X25[4X[28XZmodnZObj( 1, 8 )[128X[104X26[4X[28X[128X[104X27[4X[32X[104X2829[33X[0;0YHowever, there is no check whether both arguments belong to the same ring30and whether they are ring elements at all, so it is easy to obtain some31meaningless results:[133X3233[4X[32X Example [32X[104X34[4X[28X[128X[104X35[4X[25Xgap>[125X [27XCircleMultiplication( 3, ZmodnZObj(3,8) );[127X[104X36[4X[28XZmodnZObj( 7, 8 )[128X[104X37[4X[25Xgap>[125X [27XCircleMultiplication( [1], [2,3] );[127X[104X38[4X[28X[ 5, 5 ][128X[104X39[4X[28X[128X[104X40[4X[32X[104X4142[33X[0;0YYou can include some tests for arguments, and maybe the best way of doing43this would be declaring a new operation for two ring elements, and44installing the previous function as a method for this operation. This will45check automatically if the arguments are ring elements from the common ring:[133X4647[4X[32X Example [32X[104X48[4X[28X[128X[104X49[4X[25Xgap>[125X [27XDeclareOperation( "BetterCircleMultiplication", [127X[104X50[4X[25X>[125X [27X [IsRingElement,IsRingElement] );[127X[104X51[4X[25Xgap>[125X [27XInstallMethod( BetterCircleMultiplication,[127X[104X52[4X[25X>[125X [27X IsIdenticalObj,[127X[104X53[4X[25X>[125X [27X [IsRingElement,IsRingElement], [127X[104X54[4X[25X>[125X [27X CircleMultiplication );[127X[104X55[4X[25Xgap>[125X [27XBetterCircleMultiplication(2,3);[127X[104X56[4X[28X11[128X[104X57[4X[25Xgap>[125X [27XBetterCircleMultiplication( ZmodnZObj(2,8), ZmodnZObj(5,8) );[127X[104X58[4X[28XZmodnZObj( 1, 8 )[128X[104X59[4X[28X[128X[104X60[4X[32X[104X6162[33X[0;0YNevertheless, the functionality gained from such operation would be rather63limited. You will not be able to compute circle product via the infix64operator [10X*[110X, and, moreover, you will not be able to create higher level65objects such as semigroups and groups with respect to the circle66multiplication.[133X6768[33X[0;0YIn order to "integrate" the circle multiplication into the [5XGAP[105X library69properly, instead of defining [13Xnew[113X operations for existing objects, we should70define [13Xnew[113X objects for which the infix operator [10X*[110X will perform the circle71multiplication. This approach is explained in the next two sections.[133X727374[1X2.2 [33X[0;0YDefining circle objects[133X[101X7576[33X[0;0YThus, we are going to implement [13Xcircle objects[113X, for which we can envisage77the following functionality:[133X7879[4X[32X Example [32X[104X80[4X[28X[128X[104X81[4X[25Xgap>[125X [27XCircleObject( 2 ) * CircleObject( 3 ); [127X[104X82[4X[28XCircleObject( 11 )[128X[104X83[4X[28X[128X[104X84[4X[32X[104X8586[33X[0;0YFirst we need to distinguish these new objects from other [5XGAP[105X objects. This87is done via the [13Xtype[113X of the objects, that is mainly determined by their88[13Xcategory[113X, [13Xrepresentation[113X and [13Xfamily[113X.[133X8990[33X[0;0YWe start with declaring the category [10XIsCircleObject[110X as a subcategory of91[10XIsAssociativeElement>[110X and [10XIsMultiplicativeElementWithInverse[110X. Thus, each92circle object will "know" that it is [10XIsAssociativeElement[110X and93[10XIsMultiplicativeElementWithInverse[110X, and this will make it possible to apply94to circle objects such operations as [10XOne[110X and [10XInverse[110X (the latter is allowed95to return [9Xfail[109X for a given circle object), and construct semigroups96generated by circle objects.[133X9798[4X[32X Example [32X[104X99[4X[28X[128X[104X100[4X[25Xgap>[125X [27XDeclareCategory( "IsMyCircleObject", [127X[104X101[4X[25X>[125X [27XIsAssociativeElement and IsMultiplicativeElementWithInverse );[127X[104X102[4X[28X[128X[104X103[4X[32X[104X104105[33X[0;0YFurther we would like to create semigroups and groups generated by circle106objects. Such structures will be [13Xcollections[113X of circle objects, so they will107be in the category [10XCategoryCollections( IsCircleObject )[110X. This is why108immediately after we declare the underlying category of circle objects, we109need also to declare the category of their collections:[133X110111[4X[32X Example [32X[104X112[4X[28X[128X[104X113[4X[25Xgap>[125X [27XDeclareCategoryCollections( "IsMyCircleObject" );[127X[104X114[4X[28X[128X[104X115[4X[32X[104X116117[33X[0;0YOn the next step we should think about the internal representation of circle118objects. A natural way would be to store the underlying ring element in a119list-like structure at its first position. We do not foresee any other data120that we need to store internally in the circle object. This is quite common121situation, so we may define first [10XIsPositionalObjectOneSlotRep[110X that is the122list-like representation with only one position in the list, and then123declare a synonym [10XIsDefaultCircleObject[110X that means that we are dealing with124a circle object in one-slot representation:[133X125126[4X[32X Example [32X[104X127[4X[28X[128X[104X128[4X[25Xgap>[125X [27XDeclareRepresentation( "IsMyPositionalObjectOneSlotRep",[127X[104X129[4X[25X>[125X [27X IsPositionalObjectRep, [ 1 ] );[127X[104X130[4X[25Xgap>[125X [27XDeclareSynonym( "IsMyDefaultCircleObject",[127X[104X131[4X[25X>[125X [27X IsMyCircleObject and IsMyPositionalObjectOneSlotRep );[127X[104X132[4X[28X[128X[104X133[4X[32X[104X134135[33X[0;0YUntil now we are still unable to create circle objects, because we did not136specify to which family they will belong. Naturally, having a ring, we want137to have all circle objects for elements of this ring in the same family to138be able to multiply them, and we expect circle objects for elements of139different rings to be placed in different families. Thus, it would be nice140to establish one-to-one correspondence between the family of ring elements141and a family of circle elements for this ring. We can store the142corresponding circle family as an attribute of the ring elements family. To143do this first we declare an attribute [10XCircleFamily[110X for families:[133X144145[4X[32X Example [32X[104X146[4X[28X[128X[104X147[4X[25Xgap>[125X [27XDeclareAttribute( "MyCircleFamily", IsFamily );[127X[104X148[4X[28X[128X[104X149[4X[32X[104X150151[33X[0;0YNow we install the method that stores the corresponding circle family in152this attribute:[133X153154[4X[32X Example [32X[104X155[4X[28X[128X[104X156[4X[25Xgap>[125X [27XInstallMethod( MyCircleFamily,[127X[104X157[4X[25X>[125X [27X "for a family",[127X[104X158[4X[25X>[125X [27X [ IsFamily ],[127X[104X159[4X[25X>[125X [27X function( Fam )[127X[104X160[4X[25X>[125X [27X local F;[127X[104X161[4X[25X>[125X [27X # create the family of circle elements[127X[104X162[4X[25X>[125X [27X F:= NewFamily( "MyCircleFamily(...)", IsMyCircleObject );[127X[104X163[4X[25X>[125X [27X if HasCharacteristic( Fam ) then[127X[104X164[4X[25X>[125X [27X SetCharacteristic( F, Characteristic( Fam ) );[127X[104X165[4X[25X>[125X [27X fi;[127X[104X166[4X[25X>[125X [27X # store the type of objects in the output[127X[104X167[4X[25X>[125X [27X F!.MyCircleType:= NewType( F, IsMyDefaultCircleObject );[127X[104X168[4X[25X>[125X [27X # Return the circle family[127X[104X169[4X[25X>[125X [27X return F;[127X[104X170[4X[25X>[125X [27Xend );[127X[104X171[4X[28X[128X[104X172[4X[32X[104X173174[33X[0;0YSimilarly, we want one-to-one correspondence between circle elements and175underlying ring elements. We declare an attribute [10XCircleObject[110X for a ring176element, and then install the method to create new circle object from the177ring element. This method takes the family of the ring element, finds178corresponding circle family, extracts from it the type of circle objects and179finally creates the new circle object of that type:[133X180181[4X[32X Example [32X[104X182[4X[28X[128X[104X183[4X[25Xgap>[125X [27XDeclareAttribute( "MyCircleObject", IsRingElement );[127X[104X184[4X[25Xgap>[125X [27XInstallMethod( MyCircleObject,[127X[104X185[4X[25X>[125X [27X "for a ring element",[127X[104X186[4X[25X>[125X [27X [ IsRingElement ],[127X[104X187[4X[25X>[125X [27X obj -> Objectify( MyCircleFamily( FamilyObj( obj ) )!.MyCircleType,[127X[104X188[4X[25X>[125X [27X [ Immutable( obj ) ] ) );[127X[104X189[4X[28X[128X[104X190[4X[32X[104X191192[33X[0;0YOnly after entering all code above we are able to create some circle object.193However, it is displayed just as [10X<object>[110X, though we can get the underlying194ring element using the "!" operator:[133X195196[4X[32X Example [32X[104X197[4X[28X[128X[104X198[4X[25Xgap>[125X [27Xa:=MyCircleObject(2);[127X[104X199[4X[28X<object>[128X[104X200[4X[25Xgap>[125X [27Xa![1];[127X[104X201[4X[28X2[128X[104X202[4X[28X[128X[104X203[4X[32X[104X204205[33X[0;0YWe can check that the intended relation between families holds:[133X206207[4X[32X Example [32X[104X208[4X[28X[128X[104X209[4X[25Xgap>[125X [27XFamilyObj( MyCircleObject ( 2 ) ) = MyCircleFamily( FamilyObj( 2 ) );[127X[104X210[4X[28Xtrue[128X[104X211[4X[28X[128X[104X212[4X[32X[104X213214[33X[0;0YWe can not multiply circle objects yet. But before implementing this, first215let us improve the output by installing the method for [10XPrintObj[110X:[133X216217[4X[32X Example [32X[104X218[4X[28X[128X[104X219[4X[25Xgap>[125X [27XInstallMethod( PrintObj,[127X[104X220[4X[25X>[125X [27X "for object in `IsMyCircleObject'",[127X[104X221[4X[25X>[125X [27X [ IsMyDefaultCircleObject ],[127X[104X222[4X[25X>[125X [27X function( obj )[127X[104X223[4X[25X>[125X [27X Print( "MyCircleObject( ", obj![1], " )" );[127X[104X224[4X[25X>[125X [27X end );[127X[104X225[4X[28X[128X[104X226[4X[32X[104X227228[33X[0;0YThis method will be used by [10XPrint[110X function, and also by [10XView[110X, since we did229not install special method for [10XViewObj[110X for circle objects. As a result of230this installation, the output became more meaningful:[133X231232[4X[32X Example [32X[104X233[4X[28X[128X[104X234[4X[25Xgap>[125X [27Xa;[127X[104X235[4X[28XMyCircleObject( 2 )[128X[104X236[4X[28X[128X[104X237[4X[32X[104X238239[33X[0;0YWe need to avoid the usage of "!" operator, which, in general, is not240recommended to the user (for example, if [5XGAP[105X developers will change the241internal representation of some object, all [5XGAP[105X functions that deal with it242must be adjusted appropriately, while if the user's code had direct access243to that representation via "!", an error may occur). To do this, we wrap244getting the first component of a circle object in the following operation:[133X245246[4X[32X Example [32X[104X247[4X[28X[128X[104X248[4X[25Xgap>[125X [27XDeclareAttribute("UnderlyingRingElement", IsMyCircleObject );[127X[104X249[4X[25Xgap>[125X [27XInstallMethod( UnderlyingRingElement,[127X[104X250[4X[25X>[125X [27X "for a circle object", [127X[104X251[4X[25X>[125X [27X [ IsMyCircleObject],[127X[104X252[4X[25X>[125X [27X obj -> obj![1] );[127X[104X253[4X[25Xgap>[125X [27XUnderlyingRingElement(a);[127X[104X254[4X[28X2[128X[104X255[4X[28X[128X[104X256[4X[32X[104X257258259[1X2.3 [33X[0;0YInstalling operations for circle objects[133X[101X260261[33X[0;0YNow we are finally able to install circle multiplication as a default method262for the multiplication of circle objects, and perform the computation that263we envisaged in the beginning:[133X264265[4X[32X Example [32X[104X266[4X[28X[128X[104X267[4X[25Xgap>[125X [27XInstallMethod( \*,[127X[104X268[4X[25X>[125X [27X "for two objects in `IsMyCircleObject'",[127X[104X269[4X[25X>[125X [27X IsIdenticalObj,[127X[104X270[4X[25X>[125X [27X [ IsMyDefaultCircleObject, IsMyDefaultCircleObject ],[127X[104X271[4X[25X>[125X [27X function( a, b )[127X[104X272[4X[25X>[125X [27X return MyCircleObject( a![1] + b![1] + a![1]*b![1] );[127X[104X273[4X[25X>[125X [27X end );[127X[104X274[4X[25Xgap>[125X [27XMyCircleObject(2)*MyCircleObject(3);[127X[104X275[4X[28XMyCircleObject( 11 )[128X[104X276[4X[28X[128X[104X277[4X[32X[104X278279[33X[0;0YHowever, this functionality is not enough to form semigroups or groups280generated by circle elements. We need to be able to check whether two circle281objects are equal, and we need to define ordering for them (for example, to282be able to form sets of circle elements). Since we already have both283operations for underlying ring elements, this can be implemented in a284straightforward way:[133X285286[4X[32X Example [32X[104X287[4X[28X[128X[104X288[4X[25Xgap>[125X [27XInstallMethod( \=,[127X[104X289[4X[25X>[125X [27X "for two objects in `IsMyCircleObject'",[127X[104X290[4X[25X>[125X [27X IsIdenticalObj,[127X[104X291[4X[25X>[125X [27X [ IsMyDefaultCircleObject, IsMyDefaultCircleObject ],[127X[104X292[4X[25X>[125X [27X function( a, b )[127X[104X293[4X[25X>[125X [27X return a![1] = b![1];[127X[104X294[4X[25X>[125X [27X end );[127X[104X295[4X[25Xgap>[125X [27XInstallMethod( \<,[127X[104X296[4X[25X>[125X [27X "for two objects in `IsMyCircleObject'",[127X[104X297[4X[25X>[125X [27X IsIdenticalObj,[127X[104X298[4X[25X>[125X [27X [ IsMyDefaultCircleObject, IsMyDefaultCircleObject ],[127X[104X299[4X[25X>[125X [27X function( a, b )[127X[104X300[4X[25X>[125X [27X return a![1] < b![1];[127X[104X301[4X[25X>[125X [27X end );[127X[104X302[4X[28X[128X[104X303[4X[32X[104X304305[33X[0;0YFurther, zero element of the ring plays a role of the neutral element for306the circle multiplication, and we add this knowledge to our code in a form307of a method for [10XOneOp[110X that returns circle object for the corresponding zero308object:[133X309310[4X[32X Example [32X[104X311[4X[28X[128X[104X312[4X[25Xgap>[125X [27XInstallMethod( OneOp,[127X[104X313[4X[25X>[125X [27X "for an object in `IsMyCircleObject'",[127X[104X314[4X[25X>[125X [27X [ IsMyDefaultCircleObject ],[127X[104X315[4X[25X>[125X [27X a -> MyCircleObject( Zero( a![1] ) ) );[127X[104X316[4X[25Xgap>[125X [27XOne(a);[127X[104X317[4X[28XMyCircleObject( 0 )[128X[104X318[4X[28X[128X[104X319[4X[32X[104X320321[33X[0;0YNow we are already able to create monoids generated by circle objects:[133X322323[4X[32X Example [32X[104X324[4X[28X[128X[104X325[4X[25Xgap>[125X [27XS:=Monoid(a);[127X[104X326[4X[28X<commutative monoid with 1 generator>[128X[104X327[4X[25Xgap>[125X [27XOne(S);[127X[104X328[4X[28XMyCircleObject( 0 )[128X[104X329[4X[25Xgap>[125X [27XS:=Monoid( MyCircleObject( ZmodnZObj( 2,8) ) );[127X[104X330[4X[28X<commutative monoid with 1 generator>[128X[104X331[4X[25Xgap>[125X [27XSize(S);[127X[104X332[4X[28X2[128X[104X333[4X[25Xgap>[125X [27XAsList(S);[127X[104X334[4X[28X[ MyCircleObject( ZmodnZObj( 0, 8 ) ), MyCircleObject( ZmodnZObj( 2, 8 ) ) ][128X[104X335[4X[28X[128X[104X336[4X[32X[104X337338[33X[0;0YFinally, to generate groups using circle objects, we need to add a method339for the [10XInverseOp[110X. In our implementation we will assume that the underlying340ring is a subring of the ring with one, thus, if the circle inverse for an341element [22Xx[122X exists, than it can be computed as [22X-x(1+x)^-1[122X:[133X342343[4X[32X Example [32X[104X344[4X[28X[128X[104X345[4X[25Xgap>[125X [27XInstallMethod( InverseOp,[127X[104X346[4X[25X>[125X [27X "for an object in `IsMyCircleObject'",[127X[104X347[4X[25X>[125X [27X [ IsMyDefaultCircleObject ],[127X[104X348[4X[25X>[125X [27X function( a )[127X[104X349[4X[25X>[125X [27X local x;[127X[104X350[4X[25X>[125X [27X x := Inverse( One( a![1] ) + a![1] );[127X[104X351[4X[25X>[125X [27X if x = fail then[127X[104X352[4X[25X>[125X [27X return fail;[127X[104X353[4X[25X>[125X [27X else[127X[104X354[4X[25X>[125X [27X return MyCircleObject( -a![1] * x );[127X[104X355[4X[25X>[125X [27X fi;[127X[104X356[4X[25X>[125X [27X end );[127X[104X357[4X[25Xgap>[125X [27XMyCircleObject(-2)^-1; [127X[104X358[4X[28XMyCircleObject( -2 )[128X[104X359[4X[25Xgap>[125X [27XMyCircleObject(2)^-1; [127X[104X360[4X[28XMyCircleObject( -2/3 )[128X[104X361[4X[28X[128X[104X362[4X[32X[104X363364[33X[0;0YThe last method already makes it possible to create groups generated by365circle objects (the warning may be ignored):[133X366367[4X[32X Example [32X[104X368[4X[28X[128X[104X369[4X[25Xgap>[125X [27XGroup( MyCircleObject(2) ); [127X[104X370[4X[28X#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for[128X[104X371[4X[28X[ MyCircleObject( 2 ) ][128X[104X372[4X[28X<group with 1 generators>[128X[104X373[4X[25Xgap>[125X [27XG:=Group( [MyCircleObject( ZmodnZObj( 2,8 ) ) ]);[127X[104X374[4X[28X#I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for[128X[104X375[4X[28X[ MyCircleObject( ZmodnZObj( 2, 8 ) ) ][128X[104X376[4X[28X<group with 1 generators>[128X[104X377[4X[25Xgap>[125X [27XSize(G);[127X[104X378[4X[28X2[128X[104X379[4X[25Xgap>[125X [27XAsList(G);[127X[104X380[4X[28X[ MyCircleObject( ZmodnZObj( 0, 8 ) ), MyCircleObject( ZmodnZObj( 2, 8 ) ) ][128X[104X381[4X[28X[128X[104X382[4X[32X[104X383384[33X[0;0YThe [5XGAP[105X code used in this Chapter, is contained in the files385[11Xcircle/lib/circle.gd[111X and [11Xcircle/lib/circle.gi[111X (without [10XMy[110X in identifiers).386For more examples of implementing new [5XGAP[105X objects and further details see387[14X'Reference: Creating New Objects'[114X and subsequent chapters in the [5XGAP[105X388Reference Manual.[133X389390391392