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############################################################################### ## #F ppowerpolyloc.gi The SymbCompCC package D�rte Feichtenschlager ## ############################################################################### ## ## For a/b where a and b are p-power-polys elements and b is not divisible by ## p, the underlying prime. ## ############################################################################### ## #M PPPL_Check( elm_in ) ## ## Input: p-power-poly-loc element elm_in = [ elm1, elm2 ] where elm1 and ## elm2 are p-power-poly elements ## ## Output: [ elm1, elm2 ], where elm1/elm2 is probably reduced, or an Error ## occurs if the input does not represent a p-power-poly-loc element. ## InstallGlobalFunction( PPPL_Check, function( elm_in ) local elm1, elm2, p, Zero0, One1, test, elm, list, gcd_d, gcd_n, gcd, ec1_num, ec2_num, i; p := elm_in[1][1]; if p <> elm_in[2][1] then Error("Wrong input. The underlying primes are different."); fi; Zero0 := PPP_ZeroNC( elm_in[1] ); One1 := PPP_OneNC( elm_in[1] ); if PPP_PadicValue( elm_in[2] ) <> [ 0, 0 ] then Error("Wrong input. The denominator shall not be divisible by the underlying prime. "); fi; if PPP_Smaller( elm_in[2], Zero0 ) then elm1 := PPP_AdditiveInverse( elm_in[1] ); elm2 := PPP_AdditiveInverse( elm_in[2] ); else elm1 := elm_in[1]; elm2 := elm_in[2]; fi; list := PPP_QuotientRemainder( elm1, elm2 ); if PPP_Equal( list[2], Zero0 ) then elm1 := list[1]; elm2 := One1; fi; ## check if we can cancel if not PPP_Equal( elm1, Zero0 ) then ## take the numerators of the coefficients ec1_num := []; for i in [1..Length( elm1[2] )] do ec1_num[i] := NumeratorRat( elm1[2][i] ); od; ec2_num := []; for i in [1..Length( elm2[2] )] do ec2_num[i] := NumeratorRat( elm2[2][i] ); od; ## check if the gcds are non trivial gcd_n := Gcd( ec1_num ); gcd_d := Gcd( ec2_num ); if gcd_n <> 1 and gcd_d <> 1 then gcd := Gcd( gcd_d, gcd_n ); elm1[2] := elm1[2] / gcd; elm2[2] := elm2[2] / gcd; fi; else elm2 := One1; fi; return [elm1, elm2]; end); ############################################################################### ## #M PPPL_CheckNC( elm_in ) ## ## Input: p-power-poly-loc element elm_in = [ elm1, elm2 ] where elm1 and ## elm2 are p-power-poly elements ## ## Output: [ elm1, elm2 ] or an Error occurs if the input does not represent ## a p-power-poly-loc element. ## InstallGlobalFunction( PPPL_CheckNC, function( elm_in ) local elm1, elm2, p, Zero0, One1, test, elm, list, gcd_d, gcd_n, gcd, ec1_num, ec2_num, i; p := elm_in[1][1]; if p <> elm_in[2][1] then Error("Wrong input. The underlying primes are different."); fi; Zero0 := PPP_ZeroNC( elm_in[1] ); One1 := PPP_OneNC( elm_in[1] ); if PPP_PadicValue( elm_in[2] ) <> [ 0, 0 ] then Error("Wrong input. The denominator shall not be divisible by the underlying prime. "); fi; if PPP_Smaller( elm_in[2], Zero0 ) then elm1 := PPP_AdditiveInverse( elm_in[1] ); elm2 := PPP_AdditiveInverse( elm_in[2] ); else elm1 := elm_in[1]; elm2 := elm_in[2]; fi; ## check if we can cancel if not PPP_Equal( elm1, Zero0 ) then ## take the numerators of the coefficients ec1_num := []; for i in [1..Length( elm1[2] )] do ec1_num[i] := NumeratorRat( elm1[2][i] ); od; ec2_num := []; for i in [1..Length( elm2[2] )] do ec2_num[i] := NumeratorRat( elm2[2][i] ); od; ## check if the gcds are non trivial gcd_n := Gcd( ec1_num ); gcd_d := Gcd( ec2_num ); if gcd_n <> 1 and gcd_d <> 1 then gcd := Gcd( gcd_d, gcd_n ); elm1[2] := elm1[2] / gcd; elm2[2] := elm2[2] / gcd; fi; else elm2 := One1; fi; return [elm1, elm2]; end); ############################################################################### ## #M PPPL_Print( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the function prints elm in an easy to read way. ## InstallGlobalFunction( PPPL_Print, function( elm ) Print( " (" ); PPP_Print( elm[1] ); Print( ") / (" ); PPP_Print( elm[2] ); Print( ") " ); end); ############################################################################### ## #M PPPL_PrintMat( obj ) ## ## Input: a matrix obj with p-power-poly-loc entries. ## ## Output: the function prints obj in an easy to read way. ## InstallGlobalFunction( PPPL_PrintMat, function( obj ) local i, j; Print( "[" ); for i in [1..Length( obj )] do Print( "[ " ); PPPL_Print( obj[i][1] ); for j in [2..Length( obj[i] )] do Print( ", " ); PPPL_Print( obj[i][j] ); od; Print( "] " ); if i <> Length( obj ) then Print( ",\n" ); fi; od; Print( "]\n" ); end); ############################################################################### ## #M PPPL_PrintRow( obj ) ## ## Input: a row of p-power-poly-loc elements. ## ## Output: the function prints obj in an easy to read way. ## InstallGlobalFunction( PPPL_PrintRow, function( obj ) local i, j; Print( "[ " ); if IsInt( obj[1] ) then Print( obj[1] ); else PPPL_Print( obj[1] ); fi; for i in [2..Length( obj )] do Print( ", " ); if IsInt( obj[i] ) then Print( obj[i] ); else PPPL_Print( obj[i] ); fi; od; Print( " ]\n" ); end); ############################################################################# ## #M PPPL_Equal( elm1, elm2 ) ## ## Input: p-power-poly-loc elements elm1 and elm2. ## ## Output: a boolean, indicating whether elm1 is equal to elm2. ## InstallGlobalFunction( PPPL_Equal, function( elm1, elm2 ) local num1, num2, denom1, denom2; num1 := elm1[1]; num2 := elm2[1]; denom1 := elm1[2]; denom2 := elm2[2]; if num1[1] <> num2[1] then return false; fi; return PPP_Equal( PPP_Mult( num1, denom2 ), PPP_Mult( num2, denom1 ) ); end); ############################################################################# ## #M PPPL_Smaller( elm1, elm2 ) ## ## Input: p-power-poly-loc elements ## ## Output: a boolean, indicating whether elm1 is smaller than elm2. ## InstallGlobalFunction( PPPL_Smaller, function( elm1, elm2 ) local num1, num2, denom1, denom2; num1 := elm1[1]; num2 := elm2[1]; denom1 := elm1[2]; denom2 := elm2[2]; if PPPL_Equal( elm1, elm2 ) then return false; fi; if num1[1] < num2[1] then return true; elif num1[1] > num2[1] then return false; fi; return PPP_Smaller( PPP_Mult( num1, denom2 ), PPP_Mult( num2, denom1 ) ); end); ############################################################################# ## #M PPPL_Greater( elm1, elm2 ) ## ## Input: p-power-poly-loc elements ## ## Output: a boolean, indicating whether elm1 is greater than elm2. ## InstallGlobalFunction( PPPL_Greater, function( elm1, elm2 ) local num1, num2, denom1, denom2; num1 := elm1[1]; num2 := elm2[1]; denom1 := elm1[2]; denom2 := elm2[2]; if PPPL_Equal( elm1, elm2 ) then return false; fi; if num1[1] > num2[1] then return true; elif num1[1] < num2[1] then return false; fi; return PPP_Greater( PPP_Mult( num1, denom2 ), PPP_Mult( num2, denom1 ) ); end); ############################################################################# ## #M PPPL_Add( elm1, elm2 ) ## ## Input: p-power-poly-loc elements elm1 and elm2. ## ## Output: the sum of elm1 and elm2. ## InstallGlobalFunction( PPPL_Add, function( elm1, elm2 ) local num1, num2, denom1, denom2, num, Zero0, One1, denom, list, elm, p, Zero0Loc; ## catch trivial case if Length( elm1 ) = 4 and Length( elm2 ) = 4 then return [ PPP_Add( elm1, elm2 ), PPP_OneNC( elm1 ) ]; fi; if IsInt( elm1 ) and IsInt( elm2 ) then Error( "No underlying prime is known." ); fi; ## check input if Length( elm1 ) = 4 then One1 := PPP_OneNC( elm1 ); elm1 := [ elm1, One1 ]; elif IsInt( elm1 ) then if Length( elm2 ) = 4 then p := elm2[1]; One1 := PPP_OneNC( elm2 ); else p := elm2[1][1]; One1 := PPP_OneNC( elm2[1] ); fi; elm1 := [ Int2PPowerPoly( p, elm1 ), One1 ]; fi; if Length( elm2 ) = 4 then One1 := PPP_OneNC( elm2 ); elm2 := [ elm2, One1 ]; elif IsInt( elm2 ) then if Length( elm1 ) = 4 then p := elm1[1]; One1 := PPP_OneNC( elm1 ); else p := elm1[1][1]; One1 := PPP_OneNC( elm1[1] ); fi; elm2 := [ Int2PPowerPoly( p, elm2 ), One1 ]; fi; ## initialize num1 := StructuralCopy( elm1[1] ); num2 := StructuralCopy( elm2[1] ); denom1 := StructuralCopy( elm1[2] ); denom2 := StructuralCopy( elm2[2] ); ## check if num1[1] <> num2[1] then Error( "The underlying primes are different." ); fi; Zero0 := PPP_ZeroNC( num1 ); One1 := PPP_OneNC( denom1 ); Zero0Loc := PPPL_ZeroNC( elm1 ); ## same denominator, so only add numerators if PPP_Equal( denom1, denom2 ) then num := PPP_Add( num1, num2 ); denom := denom1; if PPP_Equal( num, Zero0 ) then return Zero0Loc; else ## check if we can cancel list := PPP_QuotientRemainder( num, denom ); if PPP_Equal( list[2], Zero0 ) then num := list[1]; denom := One1; fi; return PPPL_CheckNC( [ num, denom ] ); fi; else ## fractional arithmetic num := PPP_Add( PPP_Mult( denom2, num1 ), PPP_Mult( denom1, num2 ) ); denom := PPP_Mult( denom1, denom2 ); if PPP_Equal( num, Zero0 ) then return Zero0Loc; else ## check if we can cancel list := PPP_QuotientRemainder( num, denom ); if PPP_Equal( list[2], Zero0 ) then num := list[1]; denom := One1; fi; return PPPL_CheckNC( [ num, denom ] ); fi; fi; end); ############################################################################# ## #M PPPL_Subtract( elm1, elm2 ) ## ## Input: p-power-poly-loc elements elm1 and elm2. ## ## Output: the difference elm1 - elm2. ## InstallGlobalFunction( PPPL_Subtract, function( elm1, elm2 ) return PPPL_Add( elm1, PPPL_AdditiveInverse( elm2 ) ); end); ############################################################################# ## #M PPPL_Mult( elm1, elm2 ) ## ## Input: p-power-poly-loc elements elm1 and elm2. ## ## Output: the product of elm1 and elm2. ## InstallGlobalFunction( PPPL_Mult, function( elm1, elm2 ) local num1, num2, denom1, denom2, num, denom, elm, Zero0, One1, list_1, list_2, p; ## catch trivial case if Length( elm1 ) = 4 and Length( elm2 ) = 4 then return [ PPP_Mult( elm1, elm2 ), PPP_OneNC( elm1 ) ]; fi; if IsInt( elm1 ) and IsInt( elm2 ) then Error( "No underlying prime is known." ); fi; ## check input if Length( elm1 ) = 4 then One1 := PPP_OneNC( elm1 ); elm1 := [ elm1, One1 ]; elif IsInt( elm1 ) then if Length( elm2 ) = 4 then p := elm2[1]; One1 := PPP_OneNC( elm2 ); else p := elm2[1][1]; One1 := PPP_OneNC( elm2[1] ); fi; elm1 := [ Int2PPowerPoly( p, elm1 ), One1 ]; fi; if Length( elm2 ) = 4 then One1 := PPP_OneNC( elm2 ); elm2 := [ elm2, One1 ]; elif IsInt( elm2 ) then if Length( elm1 ) = 4 then p := elm1[1]; One1 := PPP_OneNC( elm1 ); else p := elm1[1][1]; One1 := PPP_OneNC( elm1[1] ); fi; elm2 := [ Int2PPowerPoly( p, elm2 ), One1 ]; fi; ## initialize num1 := StructuralCopy( elm1[1] ); num2 := StructuralCopy( elm2[1] ); denom1 := StructuralCopy( elm1[2] ); denom2 := StructuralCopy( elm2[2] ); ## check if num1[1] <> num2[1] then return fail; fi; Zero0 := PPP_ZeroNC( num1 ); One1 := PPP_OneNC( denom1 ); ## check if we can cancel list_1 := PPP_QuotientRemainder( num1, denom2 ); list_2 := PPP_QuotientRemainder( num2, denom1 ); if PPP_Equal( list_1[2], Zero0 ) then num := list_1[1]; denom := One1; else num := num1; denom := denom2; fi; if PPP_Equal( list_2[2], Zero0 ) then num := PPP_Mult( num, list_2[1] ); else num := PPP_Mult( num, num2 ); denom := PPP_Mult( denom, denom1 ); fi; return PPPL_CheckNC( [ num, denom ] ); end); ############################################################################### ## ## PPPL_OneNC( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the corresponding one p-power-poly-loc element. ## InstallGlobalFunction( PPPL_OneNC, function( elm ) local One1; One1 := PPP_OneNC( elm[1] ); return [ One1, One1 ]; end); ############################################################################### ## ## PPPL_ZeroNC( elm ) ## ## Input: a p-power-poly-loc element. ## ## Output: the corresponding zero p-power-poly-loc element. ## InstallGlobalFunction( PPPL_ZeroNC, function( elm ) local Zero0, One1; Zero0 := PPP_ZeroNC( elm[1] ); One1 := PPP_OneNC( elm[1] ); return [ Zero0, One1 ]; end); ############################################################################# ## #M PPPL_AdditiveInverse( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the additive inverse of elm. ## InstallGlobalFunction( PPPL_AdditiveInverse, function( elm ) local num, denom; num := elm[1]; denom := elm[2]; return [ PPP_AdditiveInverse( num ), denom ]; end); ############################################################################### ## #M PPPL_AbsValue( elm ) ## ## Input: a p-power-poly-loc element. ## ## Output: the absolute value of elm. ## InstallGlobalFunction( PPPL_AbsValue, function( elm ) local num, denom, p, One1, Zero0Quot, coeffs; ## initialize num := elm[1]; ## make sure lead-coefficient of numerator is positive coeffs := num[2]; if coeffs[Length( coeffs) ] < 0 then return PPPL_AdditiveInverse( elm ); else return elm; fi; end); ############################################################################### ## #M PPPL_PadicValue( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the p-adic value of elm, which is the p-adic value of the numerator. ## InstallGlobalFunction( PPPL_PadicValue, function( elm ) if not IsPDivisiblePPP( elm[2] ) then return fail; fi; return PPP_PadicValue( elm[1] ); end); ############################################################################### ## #M PPartPolyLoc( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the p-part of elm as a p-power-poly-loc element. ## InstallGlobalFunction( PPartPolyLoc, function( elm ) local num, One1, ppart_num; if not IsPDivisiblePPP( elm[2] ) then return fail; fi; num := elm[1]; One1 := One( num ); ppart_num := PPartPoly( num ); return [ ppart_num, One1 ]; end); ############################################################################### ## #M PPrimePartPolyLoc( elm ) ## ## Input: a p-power-poly-loc element elm. ## ## Output: the p-prime part of elm as a p-power-poly-loc element. ## InstallGlobalFunction( PPrimePartPolyLoc, function( elm ) local pprimepart_num; if not IsPDivisiblePPP( elm[2] ) then return fail; fi; pprimepart_num := PPrimePartPoly( elm[1] ); return [ pprimepart_num, elm[2] ]; end); ############################################################################### ## ## PPowerPolyMat2PPowerPolyLocMat( M ) ## ## Inpput: a matrix M with p-power-poly entries. ## ## Output: a matrix where the entries are the corresponding p-power-poly-loc ## elements. ## InstallMethod( PPowerPolyMat2PPowerPolyLocMat, [ IsList ], function( M ) local One1, M_Q, i, j; One1 := Int2PPowerPoly( M[1][1][1], 1 ); M_Q := []; for i in [1..Length(M)] do M_Q[i] := []; for j in [1..Length(M[i])] do M_Q[i][j] := [ M[i][j], One1 ]; od; od; return M_Q; end); ############################################################################### ## #M PPPL_MatrixMult( A, B ) ## ## Input: p-power-poly-loc matrices A and B. ## ## Ouput: a matrix which is the product of A and B. ## InstallGlobalFunction( PPPL_MatrixMult, function( A, B ) local C, n_A, m_A, n_B, m_B, i, j, k, Zero0Loc; n_A := Length( A ); m_A := Length( A[1] ); n_B := Length( B ); m_B := Length( B[1] ); if n_B <> m_A then Error( "The dimensions of the matrices do not fit together." ); fi; Zero0Loc := PPPL_ZeroNC( A[1][1] ); C := []; for i in [1..n_A] do C[i] := []; for j in [1..m_B] do C[i][j] := Zero0Loc; for k in [1..n_B] do C[i][j] := PPPL_Add( C[i][j], PPPL_Mult( A[i][k], B[k][j] ) ); od; od; od; return C; end); #E ppowerpolyloc.gi . . . . . . . . . . . . . . . . . . . . . . . . ends here