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: 418346/****************************************************************************1**2*W finfield.h GAP source Werner Nickel3** & Martin Schönert4**5**6*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany7*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland8*Y Copyright (C) 2002 The GAP Group9**10** This file declares the functions to compute with elements from small11** finite fields.12**13** Finite fields are an important domain in computational group theory14** because the classical matrix groups are defined over those finite fields.15** In GAP we support small finite fields with up to 65536 elements,16** larger fields can be realized as polynomial domains over smaller fields.17**18** Elements in small finite fields are represented as immediate objects.19**20** +----------------+-------------+---+21** | <value> | <field> |010|22** +----------------+-------------+---+23**24** The least significant 3 bits of such an immediate object are always 010,25** flagging the object as an object of a small finite field.26**27** The next 13 bits represent the small finite field where the element lies.28** They are simply an index into a global table of small finite fields.29**30** The most significant 16 bits represent the value of the element.31**32** If the value is 0, then the element is the zero from the finite field.33** Otherwise the integer is the logarithm of this element with respect to a34** fixed generator of the multiplicative group of the finite field plus one.35** In the following descriptions we denote this generator always with $z$, it36** is an element of order $o-1$, where $o$ is the order of the finite field.37** Thus 1 corresponds to $z^{1-1} = z^0 = 1$, i.e., the one from the field.38** Likewise 2 corresponds to $z^{2-1} = z^1 = z$, i.e., the root itself.39**40** This representation makes multiplication very easy, we only have to add41** the values and subtract 1 , because $z^{a-1} * z^{b-1} = z^{(a+b-1)-1}$.42** Addition is reduced to * by the formula $z^a + z^b = z^b * (z^{a-b}+1)$.43** This makes it necessary to know the successor $z^a + 1$ of every value.44**45** The finite field bag contains the successor for every nonzero value,46** i.e., 'SUCC_FF(<ff>)[<a>]' is the successor of the element <a>, i.e, it47** is the logarithm of $z^{a-1} + 1$. This list is usually called the48** Zech-Logarithm table. The zeroth entry in the finite field bag is the49** order of the finite field minus one.50*/5152#ifndef GAP_FINFIELD_H53#define GAP_FINFIELD_H545556/****************************************************************************57**58*T FF . . . . . . . . . . . . . . . . . . . . . type of small finite fields59**60** 'FF' is the type used to represent small finite fields.61**62** Small finite fields are represented by an index into a global table.63**64** Since there are only 6542 (prime) + 93 (nonprime) small finite fields,65** the index fits into a 'UInt2' (actually into 13 bits).66*/67typedef UInt2 FF;686970/****************************************************************************71**72*F CHAR_FF(<ff>) . . . . . . . . . . . characteristic of small finite field73**74** 'CHAR_FF' returns the characteristic of the small finite field <ff>.75**76** Note that 'CHAR_FF' is a macro, so do not call it with arguments that77** have side effects.78*/79#define CHAR_FF(ff) INT_INTOBJ( ELM_PLIST( CharFF, ff ) )8081extern Obj CharFF;828384/****************************************************************************85**86*F DEGR_FF(<ff>) . . . . . . . . . . . . . . . degree of small finite field87**88** 'DEGR_FF' returns the degree of the small finite field <ff>.89**90** Note that 'DEGR_FF' is a macro, so do not call it with arguments that91** have side effects.92*/93#define DEGR_FF(ff) INT_INTOBJ( ELM_PLIST( DegrFF, ff ) )9495extern Obj DegrFF;969798/****************************************************************************99**100*F SIZE_FF(<ff>) . . . . . . . . . . . . . . . . size of small finite field101**102** 'SIZE_FF' returns the size of the small finite field <ff>.103**104** Note that 'SIZE_FF' is a macro, so do not call it with arguments that105** have side effects.106*/107#define SIZE_FF(ff) (*SUCC_FF(ff)+1)108109110/****************************************************************************111**112*F SUCC_FF(<ff>) . . . . . . . . . . . successor table of small finite field113**114** 'SUCC_FF' returns a pointer to the successor table of the small finite115** field <ff>.116**117** Note that 'SUCC_FF' is a macro, so do not call it with arguments that118** side effects.119*/120#define SUCC_FF(ff) ((FFV*)ADDR_OBJ( ELM_PLIST( SuccFF, ff ) ))121122extern Obj SuccFF;123124125/****************************************************************************126**127*F TYPE_FF(<ff>) . . . . . . . . . . . . . . . type of a small finite field128**129** 'TYPE_FF' returns the type of elements of the small finite field <ff>.130** 'TYPE_FF0' returns the type of the zero of <ff>131**132** Note that 'TYPE_FF' is a macro, so do not call it with arguments that133** have side effects.134*/135#define TYPE_FF(ff) (ELM_PLIST( TypeFF, ff ))136#define TYPE_FF0(ff) (ELM_PLIST( TypeFF0, ff ))137138extern Obj TypeFF;139extern Obj TypeFF0;140141extern Obj TYPE_FFE;142extern Obj TYPE_FFE0;143144145/****************************************************************************146**147*T FFV . . . . . . . . type of the values of elements of small finite fields148**149** 'FFV' is the type used to represent the values of elements of small150** finite fields.151**152** Values of elements of small finite fields are represented by the153** logarithm of the element with respect to the root plus one.154**155** Since small finite fields contain at most 65536 elements, the value fits156** into a 'UInt2'.157**158** It may be possible to change this to 'UInt4' to allow small finite fields159** with more than than 65536 elements. The macros and have been coded in160** such a way that they work without problems. The exception is 'POW_FFV'161** which will only work if the product of integers of type 'FFV' does not162** cause an overflow. And of course the successor table stored for a finite163** field will become quite large for fields with more than 65536 elements.164*/165typedef UInt2 FFV;166167168/****************************************************************************169**170*F SUM_FFV(<a>,<b>,<f>) . . . . . . . . . . . . sum of finite field values171**172** 'SUM_FFV' returns the sum of the two finite field values <a> and <b> from173** the finite field pointed to by the pointer <f>.174**175** Note that 'SUM_FFV' may only be used if the operands are represented in176** the same finite field. If you want to add two elements where one lies in177** a subfield of the other use 'SumFFEFFE'.178**179** Use 'SUM_FFV' only with arguments that are variables or array elements,180** because it is a macro and arguments with side effects will behave strange,181** and because it is a complex macro so most C compilers will be upset by182** complex arguments. Especially do not use 'SUM_FFV(a,NEG_FFV(b,f),f)'.183**184** If either operand is 0, the sum is just the other operand.185** If $a <= b$ we have186** $a + b ~ z^{a-1}+z^{b-1} = z^{a-1} * (z^{(b-1)-(a-1)}+1) ~ a * f[b-a+1]$,187** otherwise we have188** $a + b ~ z^{b-1}+z^{a-1} = z^{b-1} * (z^{(a-1)-(b-1)}+1) ~ b * f[a-b+1]$.189*/190#define SUM2_FFV(a,b,f) PROD_FFV( a, (f)[(b)-(a)+1], f )191#define SUM1_FFV(a,b,f) ( (a)<=(b) ? SUM2_FFV(a,b,f) : SUM2_FFV(b,a,f) )192#define SUM_FFV(a,b,f) ( (a)==0 || (b)==0 ? (a)+(b) : SUM1_FFV(a,b,f) )193194195/****************************************************************************196**197*F NEG_FFV(<a>,<f>) . . . . . . . . . . . . negative of finite field value198**199** 'NEG_FFV' returns the negative of the finite field value <a> from the200** finite field pointed to by the pointer <f>.201**202** Use 'NEG_FFV' only with arguments that are variables or array elements,203** because it is a macro and arguments with side effects will behave strange,204** and because it is a complex macro so most C compilers will be upset by205** complex arguments. Especially do not use 'NEG_FFV(PROD_FFV(a,b,f),f)'.206**207** If the characteristic is 2, every element is its own additive inverse.208** Otherwise note that $z^{o-1} = 1 = -1^2$ so $z^{(o-1)/2} = 1^{1/2} = -1$.209** If $a <= (o-1)/2$ we have210** $-a ~ -1 * z^{a-1} = z^{(o-1)/2} * z^{a-1} = z^{a+(o-1)/2-1} ~ a+(o-1)/2$211** otherwise we have212** $-a ~ -1 * z^{a-1} = z^{a+(o-1)/2-1} = z^{a+(o-1)/2-1-(o-1)} ~ a-(o-1)/2$213*/214#define NEG2_FFV(a,f) ( (a)<=*(f)/2 ? (a)+*(f)/2 : (a)-*(f)/2 )215#define NEG1_FFV(a,f) ( *(f)%2==1 ? (a) : NEG2_FFV(a,f) )216#define NEG_FFV(a,f) ( (a)==0 ? 0 : NEG1_FFV(a,f) )217218219/****************************************************************************220**221*F PROD_FFV(<a>,<b>,<f>) . . . . . . . . . . . product of finite field value222**223** 'PROD_FFV' returns the product of the two finite field values <a> and <b>224** from the finite field pointed to by the pointer <f>.225**226** Note that 'PROD_FFV' may only be used if the operands are represented in227** the same finite field. If you want to multiply two elements where one228** lies in a subfield of the other use 'ProdFFEFFE'.229**230** Use 'PROD_FFV' only with arguments that are variables or array elements,231** because it is a macro and arguments with side effects will behave strange,232** and because it is a complex macro so most C compilers will be upset by233** complex arguments. Especially do not use 'NEG_FFV(PROD_FFV(a,b,f),f)'.234**235** If one of the values is 0 the product is 0.236** If $a+b <= o$ we have $a * b ~ z^{a-1} * z^{b-1} = z^{(a+b-1)-1} ~ a+b-1$237** otherwise we have $a * b ~ z^{(a+b-2)-(o-1)} = z^{(a+b-o)-1} ~ a+b-o$238*/239#define PROD1_FFV(a,b,f) ( (a)-1<=*(f)-(b) ? (a)-1+(b) : (a)-1-(*(f)-(b)) )240#define PROD_FFV(a,b,f) ( (a)==0 || (b)==0 ? 0 : PROD1_FFV(a,b,f) )241242243/****************************************************************************244**245*F QUO_FFV(<a>,<b>,<f>) . . . . . . . . . . quotient of finite field values246**247** 'QUO_FFV' returns the quotient of the two finite field values <a> and <b>248** from the finite field pointed to by the pointer <f>.249**250** Note that 'QUO_FFV' may only be used if the operands are represented in251** the same finite field. If you want to divide two elements where one lies252** in a subfield of the other use 'QuoFFEFFE'.253**254** Use 'QUO_FFV' only with arguments that are variables or array elements,255** because it is a macro and arguments with side effects will behave strange,256** and because it is a complex macro so most C compilers will be upset by257** complex arguments. Especially do not use 'NEG_FFV(PROD_FFV(a,b,f),f)'.258**259** A division by 0 is an error, and dividing 0 by a nonzero value gives 0.260** If $0 <= a-b$ we have $a / b ~ z^{a-1} / z^{b-1} = z^{a-b+1-1} ~ a-b+1$,261** otherwise we have $a / b ~ z^{a-b+1-1} = z^{a-b+(o-1)} ~ a-b+o$.262*/263#define QUO1_FFV(a,b,f) ( (b)<=(a) ? (a)-(b)+1 : *(f)-(b)+1+(a) )264#define QUO_FFV(a,b,f) ( (a)==0 ? 0 : QUO1_FFV(a,b,f) )265266267/****************************************************************************268**269*F POW_FFV(<a>,<n>,<f>) . . . . . . . . . . . power of a finite field value270**271** 'POW_FFV' returns the <n>th power of the finite field value <a> from the272** the finite field pointed to by the pointer <f>.273**274** Note that 'POW_FFV' may only be used if the right operand is an integer275** in the range $0..order(f)-1$.276**277** Finally 'POW_FFV' may only be used if the product of two integers of the278** size of 'FFV' does not cause an overflow, i.e. only if 'FFV' is279** 'unsigned short'.280**281** Note that 'POW_FFV' is a macro, so do not call it with arguments that282** have side effects. For optimal performance put the operands in registers283** before calling 'POW_FFV'.284**285** If the finite field element is 0 the power is also 0, otherwise we have286** $a^n ~ (z^{a-1})^n = z^{(a-1)*n} = z^{(a-1)*n % (o-1)} ~ (a-1)*n % (o-1)$287**288** In the first macro one needs to be careful to convert a and n to UInt4.289** Before performing the multiplication, ANSI-C will only convert to Int290** since UInt2 fits into Int.291*/292#define POW1_FFV(a,n,f) ( (((UInt4)(a)-1) * (UInt4)(n)) % (UInt4)*(f) + 1 )293#define POW_FFV(a,n,f) ( (n)==0 ? 1 : ( (a)==0 ? 0 : POW1_FFV(a,n,f) ) )294295296/****************************************************************************297**298*F FLD_FFE(<ffe>) . . . . . . . field of an element of a small finite field299**300** 'FLD_FFE' returns the small finite field over which the element <ffe> is301** represented.302**303** Note that 'FLD_FFE' is a macro, so do not call it with arguments that304** have side effects.305*/306#define FLD_FFE(ffe) ((FF)((((UInt)(ffe)) & 0xFFFF) >> 3))307308309/****************************************************************************310**311*F VAL_FFE(<ffe>) . . . . . . . value of an element of a small finite field312**313** 'VAL_FFE' returns the value of the element <ffe> of a small finite field.314** Thus, if <ffe> is $0_F$, it returns 0; if <ffe> is $1_F$, it returns 1;315** and otherwise if <ffe> is $z^i$, it returns $i+1$.316**317** Note that 'VAL_FFE' is a macro, so do not call it with arguments that318** have side effects.319*/320#define VAL_FFE(ffe) ((FFV)(((UInt)(ffe)) >> 16))321322323/****************************************************************************324**325*F NEW_FFE(<fld>,<val>) . . . . make a new element of a small finite field326**327** 'NEW_FFE' returns a new element <ffe> of the small finite field <fld>328** with the value <val>.329**330** Note that 'NEW_FFE' is a macro, so do not call it with arguments that331** have side effects.332*/333#define NEW_FFE(fld,val) ((Obj)(((UInt)(val) << 16) + \334((UInt)(fld) << 3) + (UInt)0x02))335336337/****************************************************************************338**339*F FiniteField(<p>,<d>) . . . make the small finite field with <q> elements340**341** 'FiniteField' returns the small finite field with <p>^<d> elements.342*/343extern FF FiniteField (344UInt p,345UInt d );346347348/****************************************************************************349**350*F CommonFF(<f1>,<d1>,<f2>,<d2>) . . . . . . . . . . . . find a common field351**352** 'CommonFF' returns a small finite field that can represent elements of353** degree <d1> from the small finite field <f1> and elements of degree <d2>354** from the small finite field <f2>. Note that this is not guaranteed to be355** the smallest such field. If <f1> and <f2> have different characteristic356** or the smallest common field, is too large, 'CommonFF' returns 0.357*/358extern FF CommonFF (359FF f1,360UInt d1,361FF f2,362UInt d2 );363364365/****************************************************************************366**367*F CharFFE(<ffe>) . . . . . . . . . characteristic of a small finite field368**369** 'CharFFE' returns the characteristic of the small finite field in which370** the element <ffe> lies.371*/372extern UInt CharFFE (373Obj ffe );374375376/****************************************************************************377**378*F DegreeFFE(<ffe>) . . . . . . . . . . . . degree of a small finite field379**380** 'DegreeFFE' returns the degree of the smallest finite field in which the381** element <ffe> lies.382*/383extern UInt DegreeFFE (384Obj ffe );385386387/****************************************************************************388**389*F TypeFFE(<ffe>) . . . . . . . . . . type of element of small finite field390**391** 'TypeFFE' returns the type of the element <ffe> of a small finite field.392**393** 'TypeFFE' is the function in 'TypeObjFuncs' for elements in small finite394** fields.395*/396extern Obj TypeFFE (397Obj ffe );398399400/****************************************************************************401**402403*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *404*/405406407/****************************************************************************408**409410*F InitInfoFinfield() . . . . . . . . . . . . . . . table of init functions411*/412StructInitInfo * InitInfoFinfield ( void );413414415#endif // GAP_FINFIELD_H416417/****************************************************************************418**419420*E finfield.h . . . . . . . . . . . . . . . . . . . . . . . . . . ends here421*/422423424