############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Jens Hollmann. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ## ## This file contains the implementation part of the padic numbers. ##
############################################################################# ## #F PrintPadicExpansion( <ppower>, <int>, <prime>, <precision> ) ## ## PrintPadicsExpansion prints a pure p-adic number x, which is given as ## <ppower> and <int> such that x = <prime>^<ppower>*<int> as the p-adic ## expansion in the pure p-adic numbers with <precision> "digits". <int> ## may be divisible by <prime>. Each "digit" ranges from 0 to <prime>-1. ## If a "digit" has more than one decimal digit it is embraced in single ## quotes. ## ## For Example: ## 153.0(17) is 1*17^(-2) + 5*17^(-1) + 3*17^0 and ## '15'3.0(17) is 15*17^(-1) + 3*17^0 ##
BindGlobal( "PrintPadicExpansion", function( ppower, int, prime, precision )
local pos, flag, z, k, r;
if int = 0then
Print( "0" ); else
# <int> might be divisible by <prime> while int mod prime = 0do
int := int / prime;
ppower := ppower + 1;
od; if ppower > 0then
# leading zeros for pos in [0..ppower-1] do if pos = 1then
Print( "." ); fi;
Print( "0" );
od; fi;
pos := ppower;
flag := false;
# print the <int>
z := int;
k := 1;
r := z mod prime; while (pos < 1) or ((k<=precision) and (z<>0)) do if pos = 1then
Print( "." ); fi; if prime >= 10then if flag then
Print( r, "'" ); else
Print( "'" , r, "'" ); fi;
flag := true; else
Print( r );
flag := false; fi;
z := (z - r) / prime;
r := z mod prime;
k := k + 1;
pos := pos + 1;
od; fi;
Print( "(", prime, ")" ); end );
############################################################################# ## #F PadicExpansionByRat( <a>, <prime>, <precision>) ## ## PadicExpansionByRat takes a rational <a> and returns a list [ppart, erg], ## such that <a> is <prime>^ppart*erg in the pure p-adic numbers over ## <prime> with <precision> "digits". ## ## For Example: ## PadicExpansionByRat(5, 3, 4) -> [0, 5] = 12.00(3) ## PadicExpansionByRat(1/2, 3, 4) -> [0, 41] = 2.111(3) ##
BindGlobal( "PadicExpansionByRat", function( a, prime, precision )
local c, flag, ppart, z, step, erg, ppot, l, digit;
if a = 0then
c := [0,0]; else
# extract the p-part (num and den of rationals are coprime)
flag := false;
ppart := 0; if NumeratorRat(a) mod prime = 0then
z := NumeratorRat(a) / prime;
step := 1;
flag := true; fi; if DenominatorRat(a) mod prime = 0then
z := DenominatorRat(a) / prime;
step := -1;
flag := true; fi; if flag then
# extract the <prime>-part
ppart := step; while z mod prime = 0do
z := z / prime;
ppart := ppart + step;
od; fi;
a := a / prime^ppart;
erg := 0;
ppot := 1;
l := 1; while( l<= precision) and (a <> 0) do
digit := a mod prime;
erg := erg + digit * ppot;
a := (a - digit) / prime;
ppot := ppot * prime;
l := l + 1;
od;
c := [ppart, erg]; fi;
return c; end );
############################################################################# ## #F MultMatrixPadicNumbersByCoefficientsList( <list> ) ## ## MultMatrix...List takes the coeff.-list <list> of a polynomial and ## returns a (n x 2*n-1)-matrix if n is the degree of the polynomial ## i.e. the length of <list> minus 1. If you have an extension L of a field ## K by a given polynomial f (i.e. L = K[X]/(f(X))) with coeff.-list <list>, ## than the i-th row of the returned matrix gives the coeff.-presentation of ## X^(i-1) in the basis {X^0, ..., X^n-1} of L. ## ## For example: ## Mult...List( [-1,5,-2,1] ) -> [1 ] ## so the polynomial is [ 1 ] ## X^3-2X^2+5X-1 [ 1] ## [1 -5 2] ## [2 -9 -1] ## ## So multiplying two elements of L (polynomials in X) is simply multiplying ## the polynomials and then multiplying the resulting coeff.-list with the ## matrix and get the coeff.-presentation of the result in the right basis ## of L. ##
BindGlobal( "MultMatrixPadicNumbersByCoefficientsList", function ( list )
local n, F, zero, one, mat, i, j;
n := Length(list) - 1;
F := FamilyObj(list[1]);
zero := Zero(F);
one := One(F); if n <= 1then
return [[one]]; fi; # prepare a zero-matrix with ones on the main diagonal:
mat := [ ]; for i in [1..2*n-1] do
mat[i] := [ ]; for j in [1..n] do
mat[i][j] := zero;
od;
od; for i in [1..n] do
mat[i][i] := one;
od; # the n+1-th row is simple: for j in [1..n] do
mat[n+1][j] := - list[j];
od; # the rest is a little more complex. Regard the fact, that # x^i is x*x^(i-1) and the coeff.presentation of x^(i-1) is # already known. for i in [n+2..2*n-1] do
mat[i] := ShiftedCoeffs(mat[i-1],1) + mat[i-1][n] * mat[n+1];
od;
return mat; end );
############################################################################# ## #F StructureConstantsPadicNumbers( <e>, <f> ) ## ## An extended p-adic field is given by two polynomials. One for the ## ramified part g with degree <e> and one for the unramified part h with ## degree <f>. The extended p-adic field is then the extension of Q_p i.e. L ## = Q_p[x,y]/(g(y),h(x)). ## ## L has a basis in x^i*y^j. This basis is ordered as follows: ## {1, x, x^2, ..., y, x y, x^2 y, ..., y^2, x y^2, x^2 y^2, ...} ## ## Let B_i be the i-th basiselement. StructureConstantsPadicNumbers takes ## the two degrees <e> and <f> and returns a (n x n)-matrix (n = <e> * <f>). ## In this matrix stands at position (i,j) the index of the row of the ## multiplication-matrix that gives the coeff.-presentation of B_i * B_j The ## mult.-matrix of an extended p-adic field is given as the ## Kronecker-product of the mult.-matrices of the two polynomials returned ## by MultMatrixPadicNumbersByCoefficientsList. (see in ## PadicExtensionNumberFamily) ## ## So I get the structure-constants m_ijk if ## B_i*B_j = SUM(k=1,...,n) m_ijk B_k ## simply by M[ B[i,j], k]. ## ## M is the mult.-matrix and B is the matrix returned by this function. ##
BindGlobal( "StructureConstantsPadicNumbers", function( e, f )
local mat, i, j, a1, a2, b1, b2;
# there are <e>*<f> basis-elements and according to the above ordering # B_i is simply x^((i-1) mod f)*y^((i-1) div f)
mat := []; for i in [1..e*f] do
mat[i] := []; for j in [1..e*f] do
a1 := (i-1) mod f;
a2 := (j-1) mod f;
b1 := QuoInt(i-1, f);
b2 := QuoInt(j-1, f);
mat[i][j] := (a1+a2) + (b1+b2)*(2*f-1) + 1;
od;
od;
return mat; end );
############################################################################# ## #M ShiftedPadicNumber( <padic>, <shift> ) ## ## ShiftedPadicNumber takes a p-adic number <padic> and an integer <shift> ## and returns the p-adic number c, that is <padic> * p^<shift>. The ## <shift> is just added to the p-part. ##
InstallMethod( ShiftedPadicNumber,
true,
[ IsPadicNumber, IsInt ], 0,
function( x, shift )
local fam, c;
fam := FamilyObj(x);
c := Immutable( [ x![1]+shift, x![2] ] );
return Objectify( fam!.defaultType, c ); end );
############################################################################# ## #M PurePadicNumberFamily( <p>, <precision> ) ## ## PurePadicNumberFamily returns the family of pure p-adic numbers over the ## prime <p> with <precision> "digits". For the representation of pure ## p-adic numbers see "PadicNumber" below. ##
BindGlobal("PADICS_FAMILIES", []);
InstallGlobalFunction( PurePadicNumberFamily, function( p, precision )
local str, fam;
if not IsPrimeInt( p ) then
Error( "<p> must be a prime" ); fi; if (not IsInt( precision )) or (precision < 0) then
Error( "<precision> must be a positive integer" ); fi; if not IsBound(PADICS_FAMILIES[p]) then
PADICS_FAMILIES[p] := []; fi; if not IsBound(PADICS_FAMILIES[p][precision]) then
str := "PurePadicNumberFamily(";
Append( str, String(p) );
Append( str, "," );
Append( str, String(precision) );
Append( str, ")" );
fam := NewFamily( str, IsPurePadicNumber );
fam!.prime:= p;
fam!.precision:= precision;
fam!.modulus:= p^precision;
fam!.printPadicSeries:= true;
fam!.defaultType := NewType( fam, IsPurePadicNumber and IsPositionalObjectRep );
PADICS_FAMILIES[p][precision] := fam; fi;
return PADICS_FAMILIES[p][precision]; end );
############################################################################# ## #M PadicNumber( <pure-padic-family>, <list> ) ## ## Make a pure p-adic number out of a list. A pure p-adic number is ## represented as a list of length 2 such that the number is p^list[1] * ## list[2]. It is easily guaranteed that list[2] is never divisible by the ## prime p. By that we have always maximum precision. ##
InstallMethod( PadicNumber, "for a pure p-adic family and a list",
true,
[ IsPurePadicNumberFamily,
IsCyclotomicCollection ], 0,
function( fam, list ) if Length(list) <> 2then
Error( "<list> must have length 2" ); elif not IsInt(list[1]) then
Error( "<list>[1] must be an integer" ); elif not IsInt(list[2]) or list[2] < 0 or list[2] >= fam!.modulus then
Error( "<list>[2] must be an integer in {0..p^precision}" ); fi;
return Objectify( fam!.defaultType, list ); end );
############################################################################# ## #M PadicNumber( <pure-padic-family>, <rat> ) ## ## Make a pure p-adic number out of a rational. ##
InstallMethod( PadicNumber, "for a pure p-adic family and a rational",
true,
[ IsPurePadicNumberFamily,
IsRat ], 0,
function( fam, rat )
local c;
c := Immutable( PadicExpansionByRat( rat, fam!.prime, fam!.precision ) );
return Objectify( fam!.defaultType, c ); end );
fam := FamilyObj(x); # printPadicSeries is just a boolean variable. Handy for checking # what REALLY happens if set to false. if fam!.printPadicSeries then
PrintPadicExpansion( x![1], x![2], fam!.prime, fam!.precision ); else
Print( fam!.prime, "^", x![1], "*", x![2], "(" , fam!.prime , ")" ); fi; end );
############################################################################# ## #M Random( <pure-padic-family> ) ## ## This is just something that actually returns a pure p-adic number. The ## range of the p-part is not totally covered as it is infinity. But you ## may get two pure p-adic numbers that have no "digit" in common, so by ## adding them, one of the two vanishes. ##
InstallOtherMethodWithRandomSource( Random, "for a random source and a pure p-adic family",
true,
[ IsRandomSource, IsPurePadicNumberFamily ], 0,
function ( rg, fam )
local c;
c := [];
c[1] := Random( rg, -fam!.precision, fam!.precision );
c[2] := Random( rg, 0, fam!.modulus-1 ); while c[2] mod fam!.prime = 0do
c[1] := c[1] + 1;
c[2] := c[2] / fam!.prime;
od;
return Objectify( fam!.defaultType, c ); end );
function ( fam )
return PadicNumber( fam, [0,1] ); end );
############################################################################# ## #M Valuation( <pure-padic> ## ## The Valuation is the p-part of the p-adic number. ##
InstallMethod( Valuation,
true,
[ IsPurePadicNumber ], 0,
function( x ) if IsZero(x) then
return infinity; fi;
return x![1]; end );
if IsZero(a) then
Error("division by zero"); fi;
fam:= FamilyObj( a );
c:= [ -a![1] , 1/a![2] mod fam!.modulus ];
return Objectify( fam!.defaultType, c ); end );
# if <a> or <b> is zero, return the other one if IsZero(a) then
return b; fi; if IsZero(b) then
return a; fi;
fam:= FamilyObj( a );
# different valuation: c[2] is NOT divisible by p! if a![1] < b![1] then
c := [ a![1],
(a![2]+fam!.prime^(b![1]-a![1])*b![2]) mod fam!.modulus ];
# equal valuation: c[2] MAY BE divisible by p! So check that. elif a![1] = b![1] then
c := [];
c[1] := a![1];
c[2] := (a![2] + b![2]) mod fam!.modulus;
# c[2] might be divisible by p
r := c[2] mod fam!.prime; while (r=0) and (c[2]>1) do
c[1] := c[1] + 1;
c[2] := c[2] / fam!.prime;
r := c[2] mod fam!.prime;
od;
# different valuation: again c[2] is NOT divisible by p! else
c:= [ b![1],
(fam!.prime^(a![1]-b![1])*a![2]+b![2]) mod fam!.modulus ]; fi;
return Objectify( fam!.defaultType, c ); end );
fam:= FamilyObj( a ); if IsZero(a) then
c:= [0, 0]; elif IsZero(b) then
c:= [0, 0]; else
c:= [ a![1]+b![1] , a![2]*b![2] mod fam!.modulus ]; fi;
return Objectify( fam!.defaultType, c ); end );
if IsZero(b) then
Error("division by zero"); fi;
fam:= FamilyObj( a );
c:= [ a![1]-b![1] , a![2]/b![2] mod fam!.modulus ];
return Objectify( fam!.defaultType, c ); end );
function( a, b )
return (a![1] = b![1]) and (a![2] = b![2]); end );
############################################################################# ## #M <pure-padic> < <pure-padic> ## ## This is just something to keep GAP quiet ##
InstallMethod( \<,
IsIdenticalObj,
[ IsPurePadicNumber, IsPurePadicNumber ], 0,
function( a, b ) if a![1] = b![1] then
return a![2] < b![2]; else
return a![1] < b![1]; fi; end );
############################################################################# ## #M PadicExtensionNumberFamily( <p>, <precision>, <unram>, <ram> ) ## ## An extended p-adic field L is given by two polynomials h and g with ## coeff.-lists <unram> (for the unramified part) and <ram> (for the ## ramified part). Then L is Q_p[x,y]/(h(x),g(y)). This function takes the ## prime number <p> and the two coeff.-lists <unram> and <ram> for the two ## polynomials. It is not checked BUT <unram> should be a cyclotomic ## polynomial and <ram> should be an Eisenstein-polynomial or [1,1]. Every ## number out of L is represented as a coeff.-list for the basis ## {1,x,x^2,...,y,xy,x^2y,...} of L. <precision> is the number of "digits" ## that all the coeff. have. ##
InstallGlobalFunction( PadicExtensionNumberFamily, function( p, precision, unram, ram )
local str, fam, yem1;
if not IsPrimeInt( p ) then
Error( "<p> must be a prime" ); fi; if (not IsInt( precision )) or (precision < 0) then
Error( "<precision> must be a positive integer" ); fi;
str := "PadicExtensionNumberFamily(";
Append( str, String(p) );
Append( str, "," );
Append( str, String(precision) );
Append( str, ",...)" );
fam := NewFamily( str, IsPadicExtensionNumber );
fam!.defaultType := NewType( fam, IsPadicExtensionNumber and IsPositionalObjectRep );
fam!.prime := p;
fam!.precision := precision;
fam!.modulus := p^precision;
fam!.unramified := unram;
fam!.f := Length(unram)-1;
fam!.ramified := ram;
fam!.e := Length(ram)-1;
fam!.n := fam!.e * fam!.f;
fam!.M := KroneckerProduct(
MultMatrixPadicNumbersByCoefficientsList(ram),
MultMatrixPadicNumbersByCoefficientsList(unram) );
fam!.B := StructureConstantsPadicNumbers(fam!.e, fam!.f);
############################################################################# ## ## General comment: In PadicExtensionNumberFamily you give the two ## polynomials, that define the extension of Q_p. You have to care for ## yourself, that these polynomials are really irreducible over Q_p! Try ## PadicExtensionNumberFamily(3, 4, [1,1,1], [1,1]) for example. You think ## this is ok? It is not, because x^2+x+1 is NOT irreducible over Q_p. The ## result being, that you get non-invertible extended p-adic numbers. So, ## if that happens, check your polynomials! ##
############################################################################# ## #M PadicNumber( <extended-padic-family>, <list> ) ## ## Make an extended p-adic number out of a list. An extended p-adic number ## is represented as a list L of length 2. ## ## L[2] is the list of coeff. for the Basis {1,..,x^(f-1)*y^(e-1)} of the ## extended p-adic field. ## ## L[1] is a common p-part of all the coeff. ## ## It is NOT guaranteed that all or at least one of the coeff. is not ## divisible by the prime p. ## ## For example: in PadicExtensionNumberFamily(3, 5, [1,1,1], [1,1]) ## the number (1.2000, 0.1210)(3) may be ## [ 0, [ 1.2000, 0.1210 ] ] or ## [-1, [ 12.000, 1.2100 ] ] here the coeff. have to be multiplied ## by p^(-1) ## ## so there may be a number (1.2, 2.2)(3) and you may ask: "Where are my 5 ## digits? There are only two! Where is the complain department!" But ## the number is intern: [-3, [ 0.0012, 0.0022 ] ] and so has in fact ## maximum precision. ## ## So watch it! ##
InstallMethod( PadicNumber, "for a p-adic extension family and a list",
true,
[ IsPadicExtensionNumberFamily,
IsList ], 0,
function( fam, list )
local range;
range := [ 0 .. fam!.modulus-1 ]; if not IsInt(list[1]) then
Error( "<list>[1] must be an integer" ); elif not IsList(list[2]) or Length(list[2]) <> fam!.n then
Error( "<list>[2] must be a list of length ", fam!.n ); elif not ForAll( list[2], x -> x in range ) then
Error( "<list>[2] must be a list of integers in ", range ); fi;
return Objectify( fam!.defaultType, list ); end );
############################################################################# ## #M PadicNumber( <extended-padic-family>, <rat> ) ## ## Make an extended p-adic number out of a rational. That means take the ## result of PadicExpansionByRat and put it at the first position of the ## coeff.list. ##
InstallMethod( PadicNumber, "for a p-adic extension family and a rational",
true,
[ IsPadicExtensionNumberFamily,
IsRat ], 0,
function( fam, rat )
local c, erg;
c := PadicExpansionByRat( rat, fam!.prime, fam!.precision );
erg := List( [1..fam!.n], i->0 );
erg[1] := c[2];
c := [ c[1], erg ];
return Objectify( fam!.defaultType, c ); end );
fam := FamilyObj(x); if fam!.printPadicSeries then
Print( "padic(" ); for l in [1..fam!.n-1] do
PrintPadicExpansion( x![1], x![2][l], fam!.prime, fam!.precision );
Print( "," );
od;
PrintPadicExpansion( x![1], x![2][fam!.n], fam!.prime, fam!.precision );
Print( ")" ); else
Print( "padic(", fam!.prime, "^", x![1], "*", x![2], ")" ); fi; end );
############################################################################# ## #M Random( <extended-padic-family> ## ## Again this is just something that returns an extended p-adic number. The ## p-part is not totally covered (just ranges from -precision to precision). ##
InstallOtherMethodWithRandomSource( Random, "for a random source and p-adic extension family",
true,
[ IsRandomSource, IsPadicExtensionNumberFamily ], 0,
function ( rg, fam )
local c, l;
c := [];
c[1] := Random( rg, -fam!.precision, fam!.precision );
c[2] := []; for l in [ 1 .. fam!.n ] do
c[2][l] := Random( rg, 0, fam!.modulus-1 );
od; while ForAll( c[2], x-> x mod fam!.prime = 0 ) do
c[1] := c[1] + 1;
c[2] := c[2] / fam!.prime;
od;
return Objectify( fam!.defaultType, c ); end );
c := List( [ 1 .. fam!.n ], i -> 0 );
c[1] := 1;
return Objectify( fam!.defaultType, [0, c] ); end );
############################################################################# ## #M Valuation( <extended-padic> ## ## In an extended p-adic field the prime p has valuation e (the degree of ## the totally ramified part) and y has valuation 1. y^e is p so this makes ## sense. ## ## The valuation of a sum is (in this case) the minimum of the valuations of ## the summands. As an extended p-adic number is ## ## SUM(i=0..(f-1)) SUM(j=0..(e-1)) a_ij x^i y^j ## ## the valuation nu of that number is the minimum over i and j of ## ## nu(a_ij x^i y^j) ## ## The valuation of a product is the sum of the single valuations, so ## ## nu(a_ij x^i y^j) = nu(a_ij) + nu(x^i) + nu(y^j) ## = nu(a_ij) + j ##
InstallMethod( Valuation,
true,
[ IsPadicExtensionNumber ], 0,
function ( x )
local fam, min, j, wert;
fam := FamilyObj(x);
min := Minimum( List([1..fam!.f], i -> Valuation(x![2][i],fam!.prime)) ); if min <> infinity then
min := fam!.e * min; fi; for j in [1..fam!.e-1] do
wert := Minimum( List( [1..fam!.f], i ->
Valuation(x![2][i+j*fam!.f], fam!.prime) ) ); if wert <> infinity then
wert := fam!.e * wert + j; fi; if wert < min then
min := wert; fi;
od; if min <> infinity then
min := min + x![1] * fam!.e; fi;
return min; end );
function(x)
local fam, val, coeffppart, coeffypart, ppart, z, L, k, j,
Lp, E, Beta, ppot, Beta_k, c, addppart;
if IsZero(x) then
Error( "<x> must be non-zero" ); fi;
fam := FamilyObj(x); # need a copy of x later:
z := Objectify( fam!.defaultType, [x![1], ShallowCopy(x![2])] );
# if x = [ppart, [x_1,...,x_n]] then # Valuation(x) = ppart*fam!.e + coeffppart*fam!.e + coeffypart
val := Valuation(x); if fam!.e > 1then
coeffypart := val mod fam!.e; else
coeffypart := 0; fi;
ppart := x![1];
coeffppart := (val - ppart*fam!.e - coeffypart) / fam!.e; # so x = p^(ppart + coeffppart) * y^coeffypart * z # and z is divisible neither by y nor by p, so it has Valuation 0 # and can be inverted. # We don't have y^(-1) but y^(e-1) which is p*y^(-1) # so z = x * y^(e-1)^coeffypart * p^(-ppart-coeffppart-coeffypart). # at least there is the coeffppart in z![2]: if coeffppart > 0then
z![1] := z![1] + coeffppart;
z![2] := z![2] / fam!.prime^coeffppart; fi;
addppart := 0; if coeffypart > 0then
z := z * fam!.yem1^coeffypart; # BUT by multiplying with y^(e-1) one may get additional p-parts # in the coeffs while ForAll( z![2], y -> y mod fam!.prime = 0 ) do
addppart := addppart + 1;
z![1] := z![1] + 1;
z![2] := z![2] / fam!.prime;
od; fi; # z![1] := z![1] - ppart - coeffppart - coeffypart - addppart;
# NOW z![2] has an entry that is not divisible by p and L should be # invertible
L := []; for k in [1..fam!.n] do
L[k] := []; for j in [1..fam!.n] do
L[k][j]:=Sum(List([1..fam!.n],
i -> z![2][i] * fam!.M[ fam!.B[i][j] ][ k ] ));
od;
od;
Lp := InverseMatMod(L, fam!.prime);
# E is the right side (1,0,...,0) and Beta is just (0,...,0)
E := List([1..fam!.n], i->0);
Beta := ShallowCopy(E);
E[1] := 1;
ppot := 1;
# now solve L * Beta = E mod p: for k in [0..fam!.precision-1-coeffppart] do
Beta_k := List( Lp * E, x -> x mod fam!.prime );
Beta := Beta + Beta_k * ppot;
E := (E - L * Beta_k) / fam!.prime;
ppot := ppot * fam!.prime;
od;
c := [];
c[1] := -z![1];
c[2] := Beta;
# as z^(-1) is now calculated, the formula above gives # x^(-1) = z^(-1) * y^(e-1)^m * p^(-ppart-coeffppart-coeffypart)
c[1] := c[1] - coeffppart - addppart;
c[2] := c[2] * fam!.prime^(coeffppart + addppart);
c[2] := List( c[2], x -> x mod fam!.modulus );
Objectify( fam!.defaultType, c );
return ( c * fam!.yem1^coeffypart ); end );
if IsZero(y) then
return x; elif IsZero(x) then
return y; fi;
fam:= FamilyObj( x );
ppot := Minimum( x![1], y![1] );
c := [];
c[1] := ppot;
c[2] := fam!.prime^(x![1]-ppot)*x![2] + fam!.prime^(y![1]-ppot)*y![2];
c[2] := List( c[2], x -> x mod fam!.modulus );
return Objectify( fam!.defaultType, c ); end );
if IsZero(y) then
return x; elif IsZero(x) then
return y; fi;
fam:= FamilyObj( x );
ppot := Minimum( x![1], y![1] );
c := [];
c[1] := ppot;
c[2] := fam!.prime^(x![1]-ppot)*x![2] - fam!.prime^(y![1]-ppot)*y![2];
c[2] := List( c[2], x -> x mod fam!.modulus );
return Objectify( fam!.defaultType, c ); end );
function (a, b)
local fam, vec, addvec, bj, bi, aj, ai, c;
fam := FamilyObj( a );
## zwei Nullvektoren der Laenge (2f-1)(2e-1):
vec := List( [1..(2*fam!.f-1)*(2*fam!.e-1)], i->0 );
addvec := List( [1..(2*fam!.f-1)*(2*fam!.e-1)], i->0 );
## Koeff. von b eintragen for bj in [1..fam!.e] do for bi in [1..fam!.f] do
vec[ (bj-1)*(2*fam!.f-1) + bi ] := b![2][ (bj-1)*fam!.f + bi ];
od;
od;
## Das eigentliche Multiplizieren: for aj in [1..fam!.e] do for ai in [1..fam!.f] do
addvec := addvec + vec * a![2][ (aj-1)*fam!.f + ai ];
vec := ShiftedCoeffs( vec, 1 );
od;
vec := ShiftedCoeffs( vec, fam!.f-1 );
od;
c := [ a![1] + b![1], List(addvec * fam!.M, x -> x mod fam!.modulus) ];
return Objectify( fam!.defaultType, c ); end );
if IsZero(a) then
return IsZero(b); elif IsZero(b) then
return false; fi; # A little work is needed, because p^1 * 10 is equal to one
fam := FamilyObj(a);
a := [ a![1], ShallowCopy(a![2]) ];
b := [ b![1], ShallowCopy(b![2]) ]; while ForAll( a[2], z -> z mod fam!.prime = 0 ) do
a[2] := a[2] / fam!.prime;
a[1] := a[1] + 1;
od; while ForAll( b[2], z -> z mod fam!.prime = 0 ) do
b[2] := b[2] / fam!.prime;
b[1] := b[1] + 1;
od;
return (a[1] = b[1]) and (a[2] = b[2]); end );
############################################################################# ## #M <extended-padic> < <extended-padic> ## ## Again just something to have it. ##
InstallMethod( \<,
IsIdenticalObj,
[ IsPadicExtensionNumber,
IsPadicExtensionNumber ], 0,
function( a, b )
local fam;
if IsZero(a) then
return not IsZero(b); elif IsZero(b) then
return false; fi;
fam := FamilyObj(a);
a := [ a![1], ShallowCopy(a![2]) ];
b := [ b![1], ShallowCopy(b![2]) ]; while ForAll( a[2], z -> z mod fam!.prime = 0 ) do
a[2] := a[2] / fam!.prime;
a[1] := a[1] + 1;
od; while ForAll( b[2], z -> z mod fam!.prime = 0 ) do
b[2] := b[2] / fam!.prime;
b[1] := b[1] + 1;
od; if a[1] = b[1] then
return a[2] < b[2]; else
return a[1] < b[1]; fi; end );
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.30Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-13)
¤
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.