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 QuotientRemainder.gi The SymbCompCC package D�rte Feichtenschlager ## ############################################################################### ## #M PPP_QuotientRemainder( x, y( , ReturnPos ) ) ## ## Input: p-power-poly elements x and y as the first two input parameters ## and optional a boolean ReturnPos which indicates whether a positive ## remainder shall be returned. ## ## Output: a list [q, r] of p-power-poly elements such that x = y * q + r. ## InstallGlobalFunction( PPP_QuotientRemainder, function( arg ) local p, Zero0, One1, test, q, c_y, l_y, c_test, l_test, r, px_part, p_part, coeff, help, list, c_r, l_r, l, c, i, help1, help2, x, y, ReturnPos; x := arg[1]; y := arg[2]; if Length( arg ) < 3 then ReturnPos := true; else ReturnPos := arg[3]; fi; ## checking if y[2] = [] then Error( "Wrong input, second element cannot be zero." ); fi; ## initialize p := x[1]; Zero0 := PPP_ZeroNC( x ); One1 := PPP_OneNC( x ); test := StructuralCopy( x ); c_test := test[2]; ## x = zero? if c_test = [] then return [ Zero0, Zero0 ]; fi; l_test := Length( c_test ); c_y := y[2]; l_y := Length( c_y ); ## catch trivial cases if PPP_Equal( y, One1 ) then return [x, Zero0]; elif PPP_Equal( y, PPP_AdditiveInverse( One1 ) ) then return [ PPP_AdditiveInverse( x ), Zero0 ]; fi; q := Zero0; ## get trivial case if PPP_Equal( test, Zero0 ) then return [q, Zero0]; elif PPP_Equal( test, y ) then r := Zero0; q := PPP_Add( q, One1 ); return [q,r]; elif PPP_Equal( test, PPP_AdditiveInverse( y ) ) then r := Zero0; q := PPP_Subtract( q, One1 ); return [q,r]; elif l_test < l_y then r := test; elif l_test = l_y and AbsoluteValue( c_test[l_test] ) < AbsoluteValue( c_y[l_y] ) then r := test; fi; while not IsBound( r ) do if l_test > l_y and IsPDivRat( c_test[l_test]/c_y[l_y], p ) then l := l_test - l_y; c := []; c[l+1] := c_test[l_test] / c_y[l_y]; for i in [l,l-1..1] do c[i] := 0; od; help := [ p, c, true, ]; q := PPP_Add( q, help ); test := PPP_Subtract( test, PPP_Mult( help, y ) ); elif l_test = l_y and IsInt( c_test[l_test] / c_y[l_y] ) then coeff := c_test[l_test] / c_y[l_y]; help := Int2PPowerPoly( p, coeff ); q := PPP_Add( q, help ); test := PPP_Subtract( test, PPP_Mult( help, y ) ); elif l_test = l_y and AbsoluteValue( c_test[l_test] ) >= AbsoluteValue( c_y[l_y] ) then help1 := NumeratorRat(c_test[l_test])*DenominatorRat(c_y[l_y]); help2 := NumeratorRat(c_y[l_y])*DenominatorRat(c_test[l_test]); list := QuotientRemainder( help1, help2 ); coeff := list[1]; help := Int2PPowerPoly( p, coeff ); q := PPP_Add( q, help ); test := PPP_Subtract( test, PPP_Mult( help, y ) ); else ## cannot divide r := test; fi; if PPP_Equal( test, Zero0 ) then return [q, Zero0]; fi; c_test := test[2]; l_test := Length( c_test ); ## chck if we are done... if not IsBound( r ) then if PPP_Equal( test, y ) then r := Zero0; q := PPP_Add( q, One1 ); elif PPP_Equal( test, PPP_AdditiveInverse( y ) ) then r := Zero0; q := PPP_Subtract( q, One1 ); elif l_test < l_y then r := test; elif l_test = l_y and AbsoluteValue( c_test[l_test] ) < AbsoluteValue( c_y[l_y] ) then r := test; fi; fi; od; c_r := r[2]; if PPP_Smaller( r, Zero0 ) or PPP_Greater( r, Zero0 ) then l_r := Length( c_r ); else l_r := 0; fi; if ReturnPos then if PPP_Smaller( r, Zero0 ) and PPP_Greater( y, Zero0 ) and l_r <= l_y then while PPP_Smaller( r, Zero0 ) do r := PPP_Add( r, y ); q := PPP_Subtract( q, One1 ); od; fi; fi; return [q,r]; end); #E QuotientRemainder.gi . . . . . . . . . . . . . . . . . . . . . . ends here