## Implementation stuff for the external computer algebra system MAGMA.
#################################### # # global variables: # ####################################
BindGlobal( "HOMALG_IO_MAGMA",
rec(
cas := "magma", ## normalized name on which the user should have no control
name := "MAGMA",
executable := [ "magma" ], ## this list is processed from left to right
options := [ ],
BUFSIZE := 1024,
READY := "!$%&/(",
CUT_POS_BEGIN := 1, ## these are the most
CUT_POS_END := 2, ## delicate values!
eoc_verbose := ";",
eoc_quiet := ";",
remove_enter := true, ## a MAGMA specific
error_stdout := " error", ## a MAGMA specific
setring := _MAGMA_SetRing, ## a MAGMA specific define := ":=", delete := function( var, stream ) homalgSendBlocking( [ "delete ", var ], "need_command", stream, "delete" ); end,
multiple_delete := _MAGMA_multiple_delete,
prompt := "\033[01mmagma>\033[0m ",
output_prompt := "\033[1;31;47m<magma\033[0m ",
display_color := "\033[0;30;47m",
InitializeCASMacros := InitializeMAGMAMacros,
time := function( stream, t ) return Int( homalgSendBlocking( [ "Floor( Cputime() * 1000 )" ], "need_output", stream, "time" ) ) - t; end,
)
);
#################################### # # families and types: # ####################################
# a new type:
BindGlobal( "TheTypeHomalgExternalRingObjectInMAGMA",
NewType( TheFamilyOfHomalgRings,
IsHomalgExternalRingObjectInMAGMARep ) );
# a new type:
BindGlobal( "TheTypeHomalgExternalRingInMAGMA",
NewType( TheFamilyOfHomalgRings,
IsHomalgExternalRingInMAGMARep ) );
#################################### # # global functions: # ####################################
##
InstallGlobalFunction( _MAGMA_SetRing, function( R )
local stream, param, indets;
stream := homalgStream( R );
## since _MAGMA_SetRing might be called from homalgSendBlocking, ## we first set the new active ring to avoid infinite loops:
stream.active_ring := R;
if HasRationalParameters( R ) then
param := RationalParameters( R );
param := List( param, String );
param := JoinStringsWithSeparator( param ); if HasIsFreePolynomialRing( R ) and HasCoefficientsRing( R ) then
homalgSendBlocking( [ "_<", param, "> := BaseRing(", R, ")" ], "need_command", "break_lists", "initialize" ); else
homalgSendBlocking( [ "_<", param, "> := ", R ], "need_command", "break_lists", "initialize" ); fi; fi;
if HasCoefficientsRing( R ) and not IsIdenticalObj( R, CoefficientsRing( R ) ) then
indets := Indeterminates( R );
indets := List( indets, String );
indets := JoinStringsWithSeparator( indets );
homalgSendBlocking( [ "_<", indets, "> := ", R ], "need_command", "break_lists", "initialize"); fi;
if IsBound( HOMALG_IO_MAGMA.setring_post ) then
homalgSendBlocking( HOMALG_IO_MAGMA.setring_post, "need_command", stream, "initialize" ); fi;
end );
##
InstallGlobalFunction( _MAGMA_multiple_delete, function( var_list, stream )
local num, l, i, str;
num := 100;
l := Length( var_list );
i := 1;
if l - i < num then
str := [ "delete ", var_list ]; else while true do
str := [ "delete ", var_list{[ i .. i + num - 1 ]} ];
homalgSendBlocking( str, "need_command", stream, "break_lists", "multiple_delete" );
i := i + num; if l - i < num then
break; fi;
od;
str := [ "delete ", var_list{[ i .. l ]} ]; fi;
IsDiagonalMatrix := "\n\
IsDiagonalMatrix := function(M)\n\ for i:= 1 to Min(Nrows(M),Ncols(M)) do M[i,i]:= 0; endfor;\n\
return IsZero(M);\n\ endfunction;\n\n",
ZeroRows := "\n\
ZeroRows := function(M)\n\
return [i: i in [ 1 .. Nrows(M) ] | IsZero(M[i]) ];\n\ endfunction;\n\n",
ZeroColumns := "\n\
ZeroColumns := function(M)\n\
return [i: i in [ 1 .. Ncols(M) ] | IsZero(ColumnSubmatrixRange(M,i,i)) ];\n\ endfunction;\n\n",
GetColumnIndependentUnitPositions := "\n\
GetColumnIndependentUnitPositions:= function(M, pos_list)\n\
rest := [ 1..Ncols(M) ];\n\
pos := [ ];\n\ for i in [ 1 .. Nrows(M) ] do\n\ for r in Reverse(rest) do\n\ if [ i, r ] notin pos_list and IsUnit(M[i, r]) then\n\
Append( ~pos, [ i, r ] );\n\
rest:= [ x: x in rest | IsZero(M[i, x]) ];\n\
break;\n\ endif;\n\ endfor;\n\ endfor;\n\
return pos;\n\ endfunction;\n\n",
GetRowIndependentUnitPositions := "\n\
GetRowIndependentUnitPositions:= function(M, pos_list)\n\
rest := [ 1..Nrows(M) ];\n\
pos := [ ];\n\ for j in [ 1 .. Ncols(M) ] do\n\ for r in Reverse(rest) do\n\ if [ j, r ] notin pos_list and IsUnit(M[r, j]) then\n\
Append( ~pos, [ j, r ] );\n\
rest:= [ x: x in rest | IsZero(M[x, j]) ];\n\
break;\n\ endif;\n\ endfor;\n\ endfor;\n\
return pos;\n\ endfunction;\n\n",
GetUnitPosition := "\n\
GetUnitPosition:= function(M, pos_list)\n\
collist:= [ x : x in [1 .. Ncols(M)] | x notin pos_list ];\n\
ok:= exists(l){ [i, j]: i in [1 .. Nrows(M) ], j in collist | IsUnit( M[i, j] ) };\n\
return ok select l else \"fail\";\n\ endfunction;\n\n",
PositionOfFirstNonZeroEntryPerRow := "\n\
PositionOfFirstNonZeroEntryPerRow := function(M)\n\
X:= [];\n\ for i in [1..Nrows(M)] do\n\
Append(~X, Depth(M[i]));\n\ endfor;\n\ if exists{ x : x in X | x ne X[1] } then\n\
return X;\n\ else\n\
return X[1];\n\ endif;\n\ endfunction;\n\n",
PositionOfFirstNonZeroEntryPerColumn := "\n\
PositionOfFirstNonZeroEntryPerColumn := function(M)\n\
X:= [];\n\
m:= Nrows(M);\n\ for j in [1..Ncols(M)] do\n\ if exists(i){ i: i in [1..m] | not IsZero(M[i,j]) } then\n\
Append(~X, i);\n\ else\n\
Append(~X, 0);\n\ endif;\n\ endfor;\n\ if exists{ x : x in X | x ne X[1] } then\n\
return X;\n\ else\n\
return X[1];\n\ endif;\n\ endfunction;\n\n",
DivideRowByUnit := "\n\
DivideRowByUnit:= procedure( ~M, i, u, j )\n\
R := BaseRing(M);\n\
M[i] *:= 1/(R ! u);\n\
// to be sure:\n\ if j gt 0then\n\
M[i, j]:= R ! 1;\n\ endif;\n\ end procedure;\n\n",
DivideColumnByUnit := "\n\
DivideColumnByUnit:= procedure( ~M, j, u, i )\n\
R := BaseRing(M);\n\
uinv:= 1/(R ! u);\n\ for a in [ 1 .. Nrows(M) ] do\n\
M[a, j] *:= uinv;\n\ endfor;\n\
// to be sure:\n\ if i gt 0then\n\
M[i, j]:= R ! 1;\n\ endif;\n\ end procedure;\n\n",
CopyRowToIdentityMatrix := "\n\
CopyRowToIdentityMatrix := procedure( M, i, ~I, j, e)\n\
I[j]:= M[i];\n\ if e eq -1then I[j] *:= -1; endif;\n\
I[j,j]:= 1;\n\ end procedure;\n\n",
CopyRowToIdentityMatrix2 := "\n\
CopyRowToIdentityMatrix2 := procedure( M, i, ~I1, ~I2, j)\n\
I1[j]:= -M[i];\n\
I1[j,j]:= 1;\n\
I2[j]:= M[i];\n\
I2[j,j]:= 1;\n\ end procedure;\n\n",
CopyColumnToIdentityMatrix := "\n\
CopyColumnToIdentityMatrix := procedure( M, j, ~I, i , e)\n\
rowlist:= [ 1..i-1 ] cat [ i+1 .. Nrows(M)];\n\ if e eq 1then\n\ for k in rowlist do\n\
I[k,i] := M[k,j];\n\ endfor;\n\ else\n\ for k in rowlist do\n\
I[k,i] := -M[k,j];\n\ endfor;\n\ endif;\n\ end procedure;\n\n",
CopyColumnToIdentityMatrix2 := "\n\
CopyColumnToIdentityMatrix2 := procedure( M, j, ~I1, ~I2, i )\n\
rowlist:= [ 1..i-1 ] cat [ i+1 .. Nrows(M)];\n\ for k in rowlist do\n\
x:= M[k,j];\n\
I1[k,i] := -x;\n\
I2[k,i] := x;\n\ endfor;\n\ end procedure;\n\n",
SetColumnToZero := "\n\
SetColumnToZero:= procedure( ~M, i, j )\n\
rowlist:= [ 1..i-1 ] cat [ i+1 .. Nrows(M)];\n\ for k in rowlist do\n\
M[k,j]:= 0;\n\ endfor;\n\ end procedure;\n\n",
ConvertRowToMatrix := "\n\
ConvertRowToMatrix:= function( M, r, c, R )\n\
return Matrix(R,r,c,[ M[1][i] : i in [ 1 .. r * c ] ]);\n\ endfunction;\n\n",
GetCleanRowsPositions := "\n\
GetCleanRowsPositions:= function( M, clean_columns )\n\
clean_rows := [ ];\n\
m := Nrows( M );\n\ for j in clean_columns do\n\ for i in [ 1 .. m ] do\n\ if IsOne(M[i, j]) then\n\
Append( ~clean_rows, i );\n\
break;\n\ endif;\n\ endfor;\n\ endfor;\n\
return clean_rows;\n\ endfunction;\n\n",
DecideZeroRowsEffectively := "\n\
DecideZeroRowsEffectively:= function(A, B)\n\
S := MyRowspace(B);\n\
F := Generic(S);\n\
M := Matrix( [Eltseq(NormalForm(F ! A[i], S)): i in [1..Nrows(A)]] );\n\
return M, Solution( B, M-A );\n\ endfunction;\n\n",
DecideZeroColumnsEffectively := "\n\
DecideZeroColumnsEffectively:= function(A, B)\n\
M, T := DecideZeroRowsEffectively(Transpose(A),Transpose(B));\n\
return Transpose(M), Transpose(T);\n\ endfunction;\n\n",
SyzygiesGeneratorsOfRows := "\n\
SyzygiesGeneratorsOfRows:= function(M)\n\
S := MyRowspace(M);\n\
SM := SyzygyModule(S);\n\
return Matrix( BaseRing(M), Degree(SM), &cat [Eltseq(x) : x in Basis(SM)] );\n\ endfunction;\n\n",
imap := "\n\ function imap(M, R)\n\
S:= BaseRing(Parent(M));\n\ if {Type(S), Type(R)} subset {RngMPol, RngUPol, FldFunRat} then\n\
N:= []; V:= []; B:= R;\n\ while Type(B) in {RngMPol, RngUPol, FldFunRat} do\n\
N cat:= Names(B);\n\
V cat:= [ R | B.i: i in [1..NumberOfNames(B)] ];\n\
B:= BaseRing(B);\n\ endwhile;\n\
error if#Set(N) ne #N, \"variable name used twice!\";\n\
Images:= [ i eq 0 select R ! 0else V[i] where i:= Index(N, n) : n in Names(S)];\n\
h:= hom< S -> R | Images >;\n\
return ChangeRing(M, h);\n\ endif;\n\
return ChangeRing(M, R);\n\ endfunction;\n\n",
DegreeOfRingElement := "\n\
// a work around of a bug noticed by Markus L.-H. in the 64bit Magma V2.17-2\n\ if Degree(PolynomialRing(Rationals(),2)!0) eq 0then\n\
Deg:= function(r,R)\n\
a := R!r;\n\ if a eq 0then return -1; endif; return Degree(a);\n\ endfunction;\n\
Deg2:= function(r,R,v)\n\
a := R!r;\n\ if a eq 0then return -1; endif; return Degree(a,v);\n\ endfunction;\n\ else\n\
Deg:= function(r,R)\n\
return Degree(R!r);\n\ endfunction;\n\
Deg2:= function(r,R,v)\n\
return Degree(R!r,v);\n\ endfunction;\n\ endif;\n\n",
MonomialsUnivariate := "\n\
MonomialsUnivariate :=\n\
func<f,x| [x^(i-1): i in [1..#C] | C[i] ne 0] where C:=Coefficients(f,x)>;\n\n",
("!Diff") := "\n\
// liefert f nach g. Reihenfolge ist der Parameter in Magma-Konvention (alles andere ist sehr komisch)\n\ function mydiff(f,g)\n\
P:= Parent(f);\n\
assert not IsZero(g) and Parent(g) eq P;\n\
C, M:= CoefficientsAndMonomials(g);\n\
return &+ [ C[j] * &* [ P | Derivative(f, e[i], i) : i in [1..#e] | e[i] ne 0 ] where e:= Exponents(M[j]) : j in [1..#C] ];\n\ endfunction;\n\n",
Diff := "\n\
// Frei nach dem GAP-Handbuch:\n\
// If D is a f × p-matrix and N is a g × q-matrix then H=Diff(D,N) is an fg × pq-matrix whose entry H[g*(i-1)+j,q*(k-1)+l] is the\n\
// result of differentiating N[j,l] by the differential operator corresponding to D[i,k]. (Here we follow the Macaulay2 convention.)\n\ function Diff(D, N)\n\
return Matrix( Ncols(D) * Ncols(N), [ mydiff(N[j,l], D[i,k]) : l in [1..Ncols(N)], k in [1..Ncols(D)] , j in [1..Nrows(N)], i in [1..Nrows(D)] ] );\n\ endfunction;\n\n",
if nargs > 0 and IsInt( arg[1] ) and arg[1] <> 0then
l := 2; ## characteristic:
c := AbsInt( arg[1] ); if IsPrime( c ) then if nargs > 1 and IsPosInt( arg[2] ) then
d := arg[2];
l := 3; else
d := 1; fi;
R := [ [ "GaloisField(", c, d, ")" ], [ ], [ "<Z", c, "_", d, ">" ] ]; else
R := [ [ "IntegerRing(", c, ")" ] ]; fi; else if nargs > 0 and arg[1] = 0then
l := 2; else
l := 1; fi; ## characteristic:
c := 0;
R := [ [ "IntegerRing()" ] ]; fi;
if not ( IsZero( c ) or IsPrime( c ) ) then
Error( "the ring Z/", c, "Z (", c, " non-prime) is not yet supported for MAGMA!\nYou can use the generic residue class ring constructor '/' provided by homalg after defining the ambient ring (over the integers)\nfor help type: ?homalg: constructor for residue class rings\n" ); fi;
R := Concatenation( R, [ IsPrincipalIdealRing ], arg{[ l .. nargs ]} );
R := CallFuncList( RingForHomalgInMAGMA, R );
if IsBound( d ) and d > 1then
R!.NameOfPrimitiveElement := Concatenation( "Z", String( c ), "_", String( d ) );
SetIsFieldForHomalg( R, true );
SetRingProperties( R, c, d );
SetName( R, Concatenation( "GF(", String( c ), "^", String( d ), ")" ) ); else
SetIsResidueClassRingOfTheIntegers( R, true );
SetRingProperties( R, c ); fi;
return R;
end );
##
InstallMethod( HomalgRingOfIntegersInUnderlyingCAS, "for an integer and homalg ring in MAGMA",
[ IsInt, IsHomalgExternalRingInMAGMARep ],
HomalgRingOfIntegersInMAGMA );
##
InstallGlobalFunction( HomalgFieldOfRationalsInMAGMA, function( arg )
local nargs, param, minimal_polynomial, Q, R;
function( R, indets )
local ar, r, var, nr_var, properties, ext_obj, S, l;
ar := _PrepareInputForPolynomialRing( R, indets );
r := ar[1];
var := ar[2]; ## all indeterminates, relative and base
nr_var := ar[3]; ## the number of relative indeterminates
properties := ar[4];
## create the new ring if Length( var ) = 1 and HasIsFieldForHomalg( r ) and IsFieldForHomalg( r ) then
ext_obj := homalgSendBlocking( [ "PolynomialRing(", r, ")" ], [ ], [ "<", var, ">" ], TheTypeHomalgExternalRingObjectInMAGMA, properties, "break_lists", "CreateHomalgRing" ); else
ext_obj := homalgSendBlocking( [ "PolynomialRing(", r, Length( var ), ",\"grevlex\")" ], [ ], [ "<", var, ">" ], TheTypeHomalgExternalRingObjectInMAGMA, properties, "break_lists", "CreateHomalgRing" ); fi;
S := CreateHomalgExternalRing( ext_obj, TheTypeHomalgExternalRingInMAGMA );
var := List( var, a -> HomalgExternalRingElement( a, S ) );
Perform( var, Name );
SetIsFreePolynomialRing( S, true );
if HasIndeterminatesOfPolynomialRing( R ) and IndeterminatesOfPolynomialRing( R ) <> [ ] then
SetBaseRing( S, R );
l := Length( var );
SetRelativeIndeterminatesOfPolynomialRing( S, var{[ l - nr_var + 1 .. l ]} ); fi;
¤ 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.0.42Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-12)
¤
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.