############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Martin Schönert. ## ## 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 methods for rationals. ##
InstallMethod( Coefficients, "method for canonical basis of Rationals",
IsCollsElms,
[ IsBasis and IsCanonicalBasis and IsCanonicalBasisRationals, IsVector ], function( B, v ) if IsRat( v ) then
return [ v ]; else
return fail; fi; end );
############################################################################ ## #M Iterator( Rationals ) ## ## Let $A_n = \{ \frac{p}{q} ; p,q \in\{ 1, \ldots, n \} \}$ ## $B_n = A_n \setminus \bigcup_{i<n} A_i$, ## $B_0 = \{ 0 \}$, and ## $B_{-n} = \{ -x; x\in B_n \}$ for $n \in\N$. ## Then $\Q = \bigcup_{n\in\Z} B_n$ as a disjoint union. ## ## $\|B_n\| = 2 ( n - 1 ) - 2 ( \tau(n) - 2 ) = 2 ( n - \tau(n) + 1 )$ ## where $\tau(n)$ denotes the number of divisors of $n$. ## Now define the ordering on $\Q$ by the ordering of the sets $B_n$ ## as defined in 'IntegersOps.Iterator', by the natural ordering of ## elements in each $B_n$ for positive $n$, and the reverse of this ## ordering for negative $n$. ##
BindGlobal( "NextIterator_Rationals", function( iter )
local value;
if iter!.actualn = 1then
# Catch the special case that numerator and denominator are # allowed to be equal.
value:= iter!.sign; if iter!.sign = -1then
iter!.actualn := 2;
iter!.len := 1;
iter!.pos := 1;
iter!.coprime := [ 1 ]; fi;
iter!.sign:= - iter!.sign;
elif iter!.up then
# We are in the first half (proper fractions).
value:= iter!.sign * iter!.coprime[ iter!.pos ] / iter!.actualn;
# Check whether we reached the last element of the first half. if iter!.pos = iter!.len then
iter!.up:= false; else
iter!.pos:= iter!.pos + 1; fi;
else
# We are in the second half.
value:= iter!.sign * iter!.actualn / iter!.coprime[ iter!.pos ];
# Check whether we reached the last element of the second half. if iter!.pos = 1then if iter!.sign = -1then
iter!.actualn := iter!.actualn + 1;
iter!.coprime := PrimeResidues( iter!.actualn );
iter!.len := Length( iter!.coprime ); fi;
iter!.sign := - iter!.sign;
iter!.up := true; else
iter!.pos:= iter!.pos - 1; fi;
fi;
return value; end );
BindGlobal( "ShallowCopy_Rationals",
iter -> rec(
actualn := iter!.actualn,
up := iter!.up,
sign := iter!.sign,
pos := iter!.pos,
coprime := ShallowCopy( iter!.coprime ),
len := Length( iter!.coprime ) ) );
############################################################################# ## #M Enumerator( Rationals ) ##
BindGlobal( "NumberElement_Rationals", function( enum, elm )
local num,
den,
max,
number,
residues;
if not IsRat( elm ) then
return fail; fi;
num:= NumeratorRat( elm);
den:= DenominatorRat( elm );
max:= AbsInt( num ); if max < den then
max:= den; fi;
if elm = 0then
number:= 1; elif elm = 1then
number:= 2; elif elm = -1then
number:= 3; else
# Take the sum over all inner squares. # For $i > 1$, the positive half of the $i$-th square has # $n_i = 2 \varphi(i)$ elements, $n_1 = 1$, so the sum is # \[ 1 + \sum_{j=1}^{max-1} 2 n_j = # 4 \sum_{j=1}^{max-1} \varphi(j) - 1 . \]
number:= 4 * Sum( [ 1 .. max-1 ], Phi ) - 1;
# Add the part in the actual square.
residues:= PrimeResidues( max ); if num < 0then # Add $n_{max}$.
number:= number + 2 * Length( residues );
num:= - num; fi; if num > den then
number:= number + 2 * Length( residues )
- Position( residues, den ) + 1; else
number:= number + Position( residues, num ); fi;
fi;
# Return the result.
return number; end );
BindGlobal( "ElementNumber_Rationals", function( enum, number )
local elm,
max, 4phi,
sign;
if number <= 3then
if number = 1then
elm:= 0; elif number = 2then
elm:= 1; else
elm:= -1; fi;
else
# Compute the maximum of numerator and denominator, # and subtract the number of inner squares from 'number'.
number:= number - 3;
max:= 2; 4phi:= 4 * Phi( max ); while number > 4phi do
number := number - 4phi;
max := max + 1; 4phi := 4 * Phi( max );
od; if number > 4phi / 2then
sign:= -1;
number:= number - 4phi / 2; else
sign:= 1; fi; if number > 4phi / 4then
elm:= sign * max / PrimeResidues( max )[ 4phi / 2 - number + 1 ]; else
elm:= sign * PrimeResidues( max )[ number ] / max; fi;
if not IsPrimeInt(p) then TryNextMethod(); fi; if rat = 0then return infinity; fi;
a := NumeratorRat(rat)/p;
i := 0; while IsInt(a) do
i := i+1;
a := a/p;
od; if i > 0 or IsInt(rat) then
return i; fi;
a := DenominatorRat(rat)/p;
i := 0; while IsInt(a) do
i := i+1;
a := a/p;
od;
return -i; end );
# If someone tries to convert a rational into # a rational, just return the number.
InstallMethod( Rat, [ IsRat ], IdFunc );
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.