Changeset 7fa60f in git
- Timestamp:
- Apr 14, 2005, 5:39:22 PM (18 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'f875bbaccd0831e36aaed09ff6adeb3eb45aeb94')
- Children:
- 3373f841d24f042ddb78a4121c62d12b4ebb2f3a
- Parents:
- 54ff35fb086438cda61fdfdc9ab33efa8472e4eb
- Location:
- Singular/LIB
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/LIB/hnoether.lib
r54ff35 r7fa60f 1 version="$Id: hnoether.lib,v 1.4 3 2005-01-13 09:42:03Singular Exp $";1 version="$Id: hnoether.lib,v 1.44 2005-04-14 15:39:20 Singular Exp $"; 2 2 category="Singularities"; 3 3 info=" 4 4 LIBRARY: hnoether.lib Hamburger-Noether (Puiseux) Development 5 AUTHOR: Martin Lamm, lamm@mathematik.uni-kl.de 5 AUTHORS: Martin Lamm, lamm@mathematik.uni-kl.de 6 Christoph Lossen, lossen@mathematik.uni-kl.de 6 7 7 8 OVERVIEW: 8 A library for computing the Hamburger-Noether, resp. Puiseux, development 9 of a plane curve singularity following [Campillo, A.: Algebroid curves 10 in positive characteristic, Springer LNM 813 (1980)]. @* 9 A library for computing the Hamburger-Noether expansion (analogue of 10 Puiseux expansion over fields of arbitrary characteristic) of a reduced 11 plane curve singularity following [Campillo, A.: Algebroid curves in 12 positive characteristic, Springer LNM 813 (1980)]. @* 11 13 The library contains also procedures for computing the (topological) 12 14 numerical invariants of plane curve singularities. 13 15 14 16 MAIN PROCEDURES: 15 hnexpansion(f); Hamburger-Noether (H-N) development of f 16 sethnering(hn); changes to the hnering created by hnexpansion 17 develop(f [,n]); H-N development of irreducible curves 17 hnexpansion(f [,\"ess\"]); Hamburger-Noether (HN) expansion of f 18 develop(f [,n]); HN expansion of irreducible plane curve germs 18 19 extdevelop(hne,n); extension of the H-N development hne of f 19 param etrisation(f [,x]); a parametrization of f20 displayHNE(hne); display H -N development as an ideal21 invariants( f);invariants of f, e.g. the characteristic exponents22 displayInvariants( f);display invariants of f23 multsequence( f);sequence of multiplicities24 displayMultsequence( f);display sequence of multiplicities20 param(L [,s]); parametrization of branches described by HN data 21 displayHNE(hne); display HN development as an ideal 22 invariants(hne); invariants of f, e.g. the characteristic exponents 23 displayInvariants(hne); display invariants of f 24 multsequence(hne); sequence of multiplicities 25 displayMultsequence(hne); display sequence of multiplicities 25 26 intersection(hne1,hne2); intersection multiplicity of two curves 26 stripHNE(hne); reduce amount of memory consumed by hne 27 is_irred(f); test if f is irreducible 27 is_irred(f); test if f is irreducible as power series 28 28 delta(f); delta invariant of f 29 29 newtonpoly(f); (local) Newton polygon of f … … 32 32 33 33 AUXILIARY PROCEDURES: 34 stripHNE(hne); reduce amount of memory consumed by hne 34 35 puiseux2generators(m,n); convert Puiseux pairs to generators of semigroup 35 36 separateHNE(hne1,hne2); number of quadratic transf. needed for separation … … 41 42 "; 42 43 43 // HNdevelop(f); Hamburger-Noether (H-N) development of f 44 // reddevelop(f); H-N development of reducible curves 45 // essdevelop(f); H-N development of essential branches 44 // essdevelop(f); HN expansion of essential branches 46 45 // multiplicities(hne); multiplicities of blowed up curves 47 48 46 49 47 /////////////////////////////////////////////////////////////////////////////// … … 85 83 // static procedures not useful for interactive use: 86 84 // polytest(f); tests coefficients and exponents of poly f 87 // extractHNEs(H,t); extracts output H of HN to output of reddevelop88 // HN(f,grenze); recursive subroutine for reddevelop85 // extractHNEs(H,t); extracts output H of HN to output of hnexpansion 86 // HN(f,grenze); recursive subroutine for hnexpansion 89 87 // constructHNEs(...); subroutine for HN 90 88 } … … 182 180 /////////////////////////////////////////////////////////////////////////////// 183 181 184 proc T2_Transform (poly f , number d, int M, int N, poly refpoly)182 proc T2_Transform (poly f_neu, number d, int M, int N, poly refpoly) 185 183 "USAGE: T2_Transform(f,d,M,N,ref); f poly, d number; M,N int; ref poly 186 184 RETURN: list: poly T2(f,d',M,N), number d' in \{ d, 1/d \} … … 219 217 } 220 218 //------------------- Durchfuehrung der Transformation T2 -------------------- 221 f =Tstar(f);219 f_neu=Tstar(f_neu); 222 220 refpoly=Tstar(refpoly); 223 //--- dividiere f so lange durch x & y, wie die Div. aufgeht, benutze ein --- 224 //--- Referenzpolynom mit gleichem Newtonpolynom wie f zur Beschleunigung: --- 221 //--- dividiere f_neu so lange durch x & y, wie die Division aufgeht, 222 // benutze ein Referenzpolynom mit gleichem Newtonpolynom wie f_neu zur 223 // Beschleunigung: --- 225 224 for (hilf=refpoly/xp; hilf*xp==refpoly; hilf=refpoly/xp) {refpoly=hilf; s++;} 226 225 for (hilf=refpoly/yp; hilf*yp==refpoly; hilf=refpoly/yp) {refpoly=hilf; t++;} 227 f =f/(xp^s*yp^t);228 return(list(T1(f ),d));226 f_neu=f_neu/(xp^s*yp^t); 227 return(list(T1(f_neu),d)); 229 228 } 230 229 example … … 807 806 if (Abbruch == 0) { 808 807 f = T1_Transform(f,delt,M/ e); 809 dbprint(printlevel-voice+2,"a("+string(zeile)+","+string(Q)+") = "+string(delt)); 808 dbprint(printlevel-voice+2,"a("+string(zeile)+","+string(Q)+") = " 809 +string(delt)); 810 810 a(zeile)[Q]=delt; 811 811 if (defined(HNDebugOn)) {"transformed polynomial: ",f;}} … … 902 902 // (the missing x in the last line indicates that it is not complete.) 903 903 hne[2]; 904 param etrisation(hne);904 param(hne); 905 905 // parametrization: x(t)= -t^14+O(t^21), y(t)= -3t^98+O(t^105) 906 906 // (the term -t^109 in y may have a wrong coefficient) … … 912 912 /////////////////////////////////////////////////////////////////////////////// 913 913 914 proc parametrisation 915 "USAGE: parametrisation(INPUT [,x]); INPUT list or poly, x int (optional) 916 ASSUME: INPUT is either a bivariate polynomial f defining a plane curve 917 singularity, or it is the output of @code{hnexpansion(f[,\"ess\"])}, 918 or of @code{develop(f)}, or of @code{extdevelop(develop(f),n)}, 919 or the list @{hne} in the ring created by @code{hnexpansion(f)} 920 respectively one entry thereof. 921 RETURN: a list L containing a parametrization L[i] for each branch f[i] of f 922 in the following format: @* 923 - if only the list INPUT is given, L[i] is an ideal of two polynomials 924 p[1],p[2]: if the HNE of was finite then f[i](p[1],p[2])=0; if not, 925 the \"real\" parametrization will be two power series and p[1],p[2] are 926 truncations of these series.@* 927 - if the optional parameter x is given, L[i] is itself a list: 928 L[i][1] is the parametrization ideal as above and L[i][2] is an intvec 929 with two entries indicating the highest degree up to which the 930 coefficients of the monomials in L[i][1] are exact (entry -1 means that 931 the corresponding parametrization is exact). 932 NOTE: If the basering has only 2 variables, the first variable is chosen 933 as indefinite. Otherwise, the 3rd variable is chosen. @* 934 In case the Hamburger-Noether expansion of the curve f is needed 935 for other purposes as well it is better to calculate this first 936 with the aid of @code{hnexpansion} and use it as input instead of 937 the polynomial itself. 938 SEE ALSO: develop, extdevelop 939 KEYWORDS: parametrization 940 EXAMPLE: example parametrisation; shows an example 941 example develop; shows another example 942 " 943 { 944 //////////////////////////////////////////////////////////////////////// 945 // Decide on the type of input 946 //////////////////////////////////////////////////////////////////////// 947 // Do the case where the input is a polynomial 948 if (typeof(#[1])=="poly") 949 { 950 list HNEXPANSION=hnexpansion(#[1]); 951 if (size(#)==1) 952 { 953 return(parametrisation(HNEXPANSION)); 954 } 955 else 956 { 957 return(parametrisation(HNEXPANSION,1)); 958 } 959 } 960 // Do the case where the input is not a polynomial. 961 int zusatz; 962 if (typeof(#[1])=="list") 963 { 964 if (typeof(#[1][1])=="ring") 965 { // Input is a HNEring and extra input x exists. 966 zusatz=1; 967 def HNE_RING=#[1][1]; 968 } 969 else 970 { 971 if (typeof(#[1][1])=="list") 972 { // Input is a reducible HN-expansion and extra input x exists. 973 zusatz=1; 974 list hne=#[1]; 975 } 976 else 977 { 978 if (typeof(#[size(#)])=="list") 979 { // Input is a reducible HN-expansion and no extra input exists. 980 list hne=#; 981 } 982 else 983 { // Input is an irreducible HN-expansion and extra input x exists 984 list hne; 985 hne[1]=#[1]; 986 zusatz=1; 987 } 988 } 989 } 990 } 991 if (typeof(#[1])=="matrix") 992 { 993 list hne; 994 hne[1]=#; 995 } 996 if (typeof(#[1])=="ring") 997 { // Input is a HNEring and no extra input exists. 998 def HNE_RING=#[1]; 999 } 1000 //////////////////////////////////////////////////////////////////////////// 1001 // Calculate the parametrization. 1002 if (defined(HNE_RING)) 1003 { 1004 def rettering=basering; 1005 setring HNE_RING; 1006 } 1007 int r=size(hne); 1008 list ErGeBnIs; 1009 // Calculate the parametrization for each branch with the aid of param. 1010 for (int lauf=1;lauf<=r;lauf++) 1011 { 1012 if (zusatz==1) 1013 { 1014 ErGeBnIs[lauf]=param(hne[lauf],1); 1015 } 1016 else 1017 { 1018 ErGeBnIs[lauf]=param(hne[lauf]); 1019 } 1020 } 1021 // Map the parametrization to the basering, if necessary, and return it. 1022 if (defined(HNE_RING)) 1023 { 1024 setring rettering; 1025 list erg=fetch(HNE_RING,ErGeBnIs); 1026 kill HNE_RING; 1027 // If the basering has 3 variables, choose the third variable for the parametrization. 1028 if (nvars(rettering)>=3) 1029 { 1030 for (lauf=1;lauf<=r;lauf++) 1031 { 1032 if (zusatz==1) 1033 { 1034 erg[lauf][1]=subst(erg[lauf][1],var(1),var(3)); 1035 } 1036 else 1037 { 1038 erg[lauf]=subst(erg[lauf],var(1),var(3)); 1039 } 1040 } 1041 } 1042 return(erg); 1043 } 1044 else 1045 { 1046 return(ErGeBnIs); 1047 } 1048 } 1049 example 1050 { "EXAMPLE:"; echo = 2; 1051 ring exring=0,(x,y,t),ds; 1052 // 1st Example: input is a polynomial 1053 poly g=(x2-y3)*(x3-y5); 1054 parametrisation(g); 1055 // 2nd Example: input is the ring of a Hamburger-Noether expansion 1056 poly h=x2-y2-y3; 1057 list hn=hnexpansion(h); 1058 parametrisation(h,1); 1059 // 3rd Example: input is a Hamburger-Noether expansion 1060 poly f=x3+2xy2+y2; 1061 list hne=develop(f); 1062 list hne_extended=extdevelop(hne,10); 1063 // compare the matrices ... 1064 print(hne[1]); 1065 print(hne_extended[1]); 1066 // ... and the resulting parametrizations: 1067 parametrisation(hne); 1068 parametrisation(hne_extended); 1069 parametrisation(hne_extended,0); 1070 } 1071 1072 1073 proc param 1074 "USAGE: param(L [,x]); L list, x any type (optional) 914 proc param (list L, list #) 915 "USAGE: param(L [,s]); L list, s any type (optional) 1075 916 ASSUME: L is the output of @code{develop(f)}, or of 1076 @code{extdevelop(develop(f),n)}, or one entry in the list @code{hne}1077 in the ringcreated by @code{hnexpansion(f[,\"ess\"])}.917 @code{extdevelop(develop(f),n)}, or (one entry in) the list of HN 918 data created by @code{hnexpansion(f[,\"ess\"])}. 1078 919 RETURN: a parametrization for f in the following format: @* 1079 920 - if only the list L is given, the result is an ideal of two 1080 921 polynomials p[1],p[2]: if the HNE was finite then f(p[1],p[2])=0}; 1081 if not, the \"real\" parametrization will be two power series and1082 p[1],p[2] are truncations of these series.@*922 if not, the true parametrization will be given by two power series, 923 and p[1],p[2] are truncations of these series.@* 1083 924 - if the optional parameter x is given, the result is a list l: 1084 925 l[1]=param(L) (ideal) and l[2]=intvec with two entries indicating … … 1088 929 NOTE: If the basering has only 2 variables, the first variable is chosen 1089 930 as indefinite. Otherwise, the 3rd variable is chosen. 1090 SEE ALSO: parametrization,develop, extdevelop931 SEE ALSO: develop, extdevelop 1091 932 KEYWORDS: parametrization 1092 933 EXAMPLE: example param; shows an example … … 1095 936 { 1096 937 //-------------------------- Initialisierungen ------------------------------- 1097 if (typeof(#[1])=="list") { 1098 list Li=#[1]; 1099 matrix m=Li[1]; 1100 intvec v=Li[2]; 1101 int switch=Li[3]; 1102 int return_list=1; 938 int return_list; 939 if (size(#)>0) { return_list=1; } 940 941 if (typeof(L[1])=="list") { // output of hnexpansion (> 1 branch) 942 list Ergebnis; 943 for (int i=1; i<=size(L); i++) { 944 dbprint(printlevel-voice+4,"// Parametrization of branch number " 945 +string(i)+" computed."); 946 printlevel=printlevel+1; 947 if (return_list==1) { Ergebnis[i]=param(L[i],1); } 948 else { Ergebnis[i]=param(L[i]); } 949 printlevel=printlevel-1; 950 } 951 return(Ergebnis); 1103 952 } 1104 953 else { 1105 matrix m=#[1]; 1106 intvec v=#[2]; 1107 int switch=#[3]; 1108 int return_list=0; 954 matrix m=L[1]; 955 intvec v=L[2]; 956 int switch=L[3]; 1109 957 } 1110 958 if (switch==-1) { … … 1123 971 for (i=1; i<=v[zeile]; i++) { 1124 972 z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i; 1125 }} 973 } 974 } 1126 975 else { 1127 976 untervor=1; // = Untergrad der vorhergehenden Zeile … … 1132 981 if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;} 1133 982 // = Untergrad der aktuellen Zeile 1134 }} 983 } 984 } 1135 985 else { 1136 986 fehler= -v[zeile]; … … 1138 988 z(zeile)=z(zeile)+m[zeile,i]*z(zeile+1)^i; 1139 989 if ((untergrad==0) and (m[zeile,i]!=0)) {untergrad=i;} 1140 }} 990 } 991 } 1141 992 } 1142 993 //------------- Parametrisierung der restlichen Zeilen der HNE --------------- … … 1155 1006 hilf=untergrad; 1156 1007 untergrad=untergrad*v[zeile]+untervor; 1157 untervor=hilf;}} // untervor = altes untergrad 1008 untervor=hilf;} // untervor = altes untergrad 1009 } 1158 1010 else { 1159 1011 fehlervor=fehler; … … 1161 1013 untervor=untergrad; 1162 1014 untergrad=untergrad*beginn; 1163 }} 1015 } 1016 } 1164 1017 //--------------------- Ausgabe der Fehlerabschaetzung ----------------------- 1165 1018 if (switch==0) { 1166 1019 if (fehler>0) { 1167 1020 if (fehlervor>0) { 1168 if ((voice==2) && (printlevel > -1)) { 1169 "// ** Warning: result is exact up to order",fehlervor-1,"in", 1170 maxideal(1)[1],"and",fehler-1,"in",maxideal(1)[2],"!"; 1171 }} 1021 dbprint(printlevel-voice+4,""+ 1022 "// ** Warning: result is exact up to order "+string(fehlervor-1)+ 1023 " in "+ string(var(1))+" and "+string(fehler-1)+" in " + 1024 string(var(2))+" !"); 1025 } 1172 1026 else { 1173 if ((voice==2) && (printlevel > -1)) {1174 "// ** Warning: result is exact up to order ",fehler-1,"in",1175 maxideal(1)[2],"!";1176 } }1027 dbprint(printlevel-voice+4,""+ 1028 "// ** Warning: result is exact up to order "+ string(fehler-1)+ 1029 " in "+string(var(2))+" !"); 1030 } 1177 1031 } 1178 1032 if (return_list==0) { return(ideal(z(2),z(1))); } … … 1182 1036 if (fehler>0) { 1183 1037 if (fehlervor>0) { 1184 if ((voice==2) && (printlevel > -1)) { 1185 "// ** Warning: result is exact up to order",fehler-1,"in", 1186 maxideal(1)[1],"and",fehlervor-1,"in",maxideal(1)[2],"!"; 1187 }} 1038 dbprint(printlevel-voice+4,""+ 1039 "// ** Warning: result is exact up to order "+string(fehler-1)+ 1040 " in "+ string(var(1))+" and "+string(fehlervor-1)+" in " + 1041 string(var(2))+" !"); 1042 } 1188 1043 else { 1189 if ((voice==2) && (printlevel > -1)) {1190 "// ** Warning: result is exact up to order ",fehler-1,"in",1191 maxideal(1)[1],"!";1192 } }1044 dbprint(printlevel-voice+4,""+ 1045 "// ** Warning: result is exact up to order "+ string(fehler-1)+ 1046 " in "+string(var(1))+" !"); 1047 } 1193 1048 } 1194 1049 if (return_list==0) { return(ideal(z(1),z(2))); } … … 1202 1057 list hne=develop(f); 1203 1058 list hne_extended=extdevelop(hne,10); 1204 // compare the matrices ...1059 // compare the HNE matrices ... 1205 1060 print(hne[1]); 1206 1061 print(hne_extended[1]); … … 1209 1064 param(hne_extended); 1210 1065 param(hne_extended,0); 1211 } 1066 1067 // An example with more than one branch: 1068 list L=hnexpansion(f*(x2+y4)); 1069 def HNring = L[1]; setring HNring; 1070 param(hne); 1071 } 1072 1212 1073 /////////////////////////////////////////////////////////////////////////////// 1213 1074 1214 1075 proc invariants 1215 1076 "USAGE: invariants(INPUT); INPUT list or poly 1216 ASSUME: INPUTis the output of @code{develop(f)}, or of1217 @code{extdevelop(develop(f),n)}, or one entry in the list @code{hne}1218 of the HNEring created by @code{hnexpansion}.1219 RETURN: list , if INPUT contains a valid HNE:1077 ASSUME: @code{INPUT} is the output of @code{develop(f)}, or of 1078 @code{extdevelop(develop(f),n)}, or one entry of the list of HN data 1079 computed by @code{hnexpansion(f[,\"ess\"])}. 1080 RETURN: list @code{INV} of the following format: 1220 1081 @format 1221 invariants(INPUT)[1]: intvec (characteristic exponents)1222 invariants(INPUT)[2]: intvec (generators of the semigroup)1223 invariants(INPUT)[3]: intvec (Puiseux pairs, 1st components)1224 invariants(INPUT)[4]: intvec (Puiseux pairs, 2nd components)1225 invariants(INPUT)[5]: int (degree of the conductor)1226 invariants(INPUT)[6]: intvec (sequence of multiplicities)1082 INV[1]: intvec (characteristic exponents) 1083 INV[2]: intvec (generators of the semigroup) 1084 INV[3]: intvec (Puiseux pairs, 1st components) 1085 INV[4]: intvec (Puiseux pairs, 2nd components) 1086 INV[5]: int (degree of the conductor) 1087 INV[6]: intvec (sequence of multiplicities) 1227 1088 @end format 1228 an empty list, if INPUT contains no valid HNE. 1229 ASSUME: INPUT is bivariate polynomial f or the output of @code{hnexpansion(f[,\"ess\"])}, 1230 or the list @code{hne} in the HNEring created by @code{hnexpansion}. 1231 RETURN: list INV, such that INV[i] is the output of @code{invariants(develop(f[i]))} 1232 as above, where f[i] is the ith branch of the curve f, and the last 1233 entry contains further invariants of f in the format: 1089 If @code{INPUT} contains no valid HN expansion, the empty list is 1090 returned. 1091 ASSUME: @code{INPUT} is a bivariate polynomial f, or the output of 1092 @code{hnexpansion(f)}, or the list of HN data computed by 1093 @code{hnexpansion(f [,\"ess\"])}. 1094 RETURN: list @code{INV}, such that @code{INV[i]} coincides with the output of 1095 @code{invariants(develop(f[i]))}, where f[i] is the i-th branch of 1096 f, and the last entry of @code{INV} contains further invariants of 1097 f in the format: 1234 1098 @format 1235 INV[i][1] : intvec (characteristic exponents)1236 INV[i][2] : intvec (generators of the semigroup)1237 INV[i][3] : intvec (Puiseux pairs, 1st components)1238 INV[i][4] : intvec (Puiseux pairs, 2nd components)1239 INV[i][5] : int (degree of the conductor)1240 INV[i][6] : intvec (sequence of multiplicities)1241 1099 INV[last][1] : intmat (contact matrix of the branches) 1242 1100 INV[last][2] : intmat (intersection multiplicities of the branches) … … 1247 1105 with the aid of @code{hnexpansion} and use it as input instead of 1248 1106 the polynomial itself. 1249 SEE ALSO: develop, displayInvariants, multsequence, intersection1107 SEE ALSO: hnexpansion, develop, displayInvariants, multsequence, intersection 1250 1108 KEYWORDS: characteristic exponents; semigroup of values; Puiseux pairs; 1251 1109 conductor, degree; multiplicities, sequence of … … 1253 1111 " 1254 1112 { 1255 //---- INPUT = poly, or HNEring, or hne of reducible curve -------------------- 1256 if (typeof(#[1])!="matrix") 1257 { 1258 if (typeof(#[1])=="poly") 1259 { 1260 list HNEXPANSION=hnexpansion(#[1]); 1261 return(invariants(HNEXPANSION)); 1262 } 1263 if (typeof(#[1])=="ring") 1264 { 1265 def H_N_E_R_I_N_G=#[1]; 1266 def rette_ring=basering; 1267 setring H_N_E_R_I_N_G; 1268 } 1269 if (typeof(#[1])=="list") 1270 { 1271 list hne=#; 1272 } 1273 list ErGeBnIs; 1274 for (int lauf=1;lauf<=size(hne);lauf++) 1275 { 1276 ErGeBnIs[lauf]=invariants(hne[lauf]); 1277 } 1278 // Calculate the intersection matrix and the intersection multiplicities. 1279 intmat contact[size(hne)][size(hne)]; 1280 intmat intersectionmatrix[size(hne)][size(hne)]; 1281 int Lauf; 1282 for (lauf=1;lauf<=size(hne);lauf++) 1283 { 1284 for (Lauf=lauf+1;Lauf<=size(hne);Lauf++) 1285 { 1286 contact[lauf,Lauf]=separateHNE(hne[lauf],hne[Lauf]); 1287 contact[Lauf,lauf]=contact[lauf,Lauf]; 1288 intersectionmatrix[lauf,Lauf]=intersection(hne[lauf],hne[Lauf]); 1289 intersectionmatrix[Lauf,lauf]=intersectionmatrix[lauf,Lauf]; 1113 //---- INPUT = poly, or HNEring, or hne of reducible curve ----------------- 1114 if (typeof(#[1])!="matrix") { 1115 if (typeof(#[1])=="poly") { 1116 list L=hnexpansion(#[1]); 1117 if (typeof(L[1])=="ring") { 1118 def altring = basering; 1119 def HNring = L[1]; setring HNring; 1120 list Ergebnis = invariants(hne); 1121 setring altring; 1122 kill HNring; 1123 return(Ergebnis); 1290 1124 } 1291 } 1292 // Calculate the delta invariant. 1293 int inters; 1294 int del=ErGeBnIs[size(hne)][5]/2; 1295 for(lauf=1;lauf<=size(hne)-1;lauf++) 1296 { 1297 del=del+ErGeBnIs[lauf][5]/2; 1298 for(Lauf=lauf+1;Lauf<=size(hne);Lauf++) 1299 { 1125 else { 1126 return(invariants(L)); 1127 } 1128 } 1129 if (typeof(#[1])=="ring") { 1130 def altring = basering; 1131 def HNring = #[1]; setring HNring; 1132 list Ergebnis = invariants(hne); 1133 setring altring; 1134 kill HNring; 1135 return(Ergebnis); 1136 } 1137 if (typeof(#[1])=="list") { 1138 list hne=#; 1139 list Ergebnis; 1140 for (int lauf=1;lauf<=size(hne);lauf++) { 1141 Ergebnis[lauf]=invariants(hne[lauf]); 1142 } 1143 // Calculate the intersection matrix and the intersection multiplicities. 1144 intmat contact[size(hne)][size(hne)]; 1145 intmat intersectionmatrix[size(hne)][size(hne)]; 1146 int Lauf; 1147 for (lauf=1;lauf<=size(hne);lauf++) { 1148 for (Lauf=lauf+1;Lauf<=size(hne);Lauf++) { 1149 contact[lauf,Lauf]=separateHNE(hne[lauf],hne[Lauf]); 1150 contact[Lauf,lauf]=contact[lauf,Lauf]; 1151 intersectionmatrix[lauf,Lauf]=intersection(hne[lauf],hne[Lauf]); 1152 intersectionmatrix[Lauf,lauf]=intersectionmatrix[lauf,Lauf]; 1153 } 1154 } 1155 // Calculate the delta invariant. 1156 int inters; 1157 int del=Ergebnis[size(hne)][5]/2; 1158 for(lauf=1;lauf<=size(hne)-1;lauf++) { 1159 del=del+Ergebnis[lauf][5]/2; 1160 for(Lauf=lauf+1;Lauf<=size(hne);Lauf++) { 1300 1161 inters=inters+intersectionmatrix[lauf,Lauf]; 1301 } 1302 } 1303 del=del+inters; 1304 list LAST=contact,intersectionmatrix,del; 1305 ErGeBnIs[size(hne)+1]=LAST; 1306 if (defined(H_N_E_R_I_N_G)) 1307 { 1308 setring rette_ring; 1309 kill H_N_E_R_I_N_G; 1310 } 1311 return(ErGeBnIs); 1312 } 1162 } 1163 } 1164 del=del+inters; 1165 list LAST=contact,intersectionmatrix,del; 1166 Ergebnis[size(hne)+1]=LAST; 1167 return(Ergebnis); 1168 } 1169 } 1313 1170 //-------------------------- Initialisierungen ------------------------------- 1314 1171 matrix m=#[1]; … … 1418 1275 proc displayInvariants 1419 1276 "USAGE: displayInvariants(INPUT); INPUT list or poly 1420 ASSUME: INPUT is a bivariate polynomial, or the output of @code{develop(f)}, or of 1421 @code{extdevelop(develop(f),n)}, or (one entry of) the list @code{hne} 1422 in the ring created by @code{hnexpansion(f[,\"ess\"])}. 1277 ASSUME: @code{INPUT} is a bivariate polynomial, or the output of 1278 @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one 1279 entry of) the list of HN data computed by 1280 @code{hnexpansion(f[,\"ess\"])}. 1423 1281 RETURN: none 1424 1282 DISPLAY: invariants of the corresponding branch, resp. of all branches, 1425 1283 in a better readable form. 1426 NOTE: I n casethe Hamburger-Noether expansion of the curve f is needed1284 NOTE: If the Hamburger-Noether expansion of the curve f is needed 1427 1285 for other purposes as well it is better to calculate this first 1428 1286 with the aid of @code{hnexpansion} and use it as input instead of … … 1432 1290 " 1433 1291 { 1434 // INPUT = poly or ring 1435 if (typeof(#[1])=="poly") 1436 { 1437 list HNEXPANSION=hnexpansion(#[1]); 1438 displayInvariants(HNEXPANSION); 1439 return(); 1440 } 1441 if (typeof(#[1])=="ring") 1442 { 1443 def H_N_E_RING=#[1]; 1444 def rettering=basering; 1445 setring H_N_E_RING; 1446 displayInvariants(hne); 1447 setring rettering; 1448 kill H_N_E_RING; 1449 return(); 1450 } 1451 // INPUT = hne of a plane curve 1292 // INPUT = poly or ring 1293 if (typeof(#[1])=="poly") { 1294 list L=hnexpansion(#[1]); 1295 if (typeof(L[1])=="ring") { 1296 def HNring = L[1]; setring HNring; 1297 displayInvariants(hne); 1298 return(); 1299 } 1300 else { 1301 displayInvariants(L); 1302 return(); 1303 } 1304 } 1305 if (typeof(#[1])=="ring") 1306 { 1307 def HNring = #[1]; setring HNring; 1308 displayInvariants(hne); 1309 return(); 1310 } 1311 // INPUT = hne of a plane curve 1452 1312 int i,j,k,mul; 1453 1313 string Ausgabe; … … 1739 1599 example 1740 1600 { 1741 // ------ the example starts here -------1742 1601 "EXAMPLE:"; echo = 2; 1743 1602 ring r=0,(x,y),dp; 1744 list hn=hnexpansion((x2-y3)*(x2+y3)); 1745 def HNEring=hn[1]; 1746 setring HNEring; 1603 list hne=hnexpansion((x2-y3)*(x2+y3)); 1747 1604 intersection(hne[1],hne[2]); 1748 1605 } … … 1751 1608 proc multsequence 1752 1609 "USAGE: multsequence(INPUT); INPUT list or poly 1753 ASSUME: INPUT is the output of @code{develop(f)}, or of @code{extdevelop(develop(f),n)}, 1754 or one entry in the list @code{hne} of the ring created by @code{hnexpansion(f)}. 1755 RETURN: intvec corresponding to the multiplicity sequence of (a branch) 1756 of the curve (the same as @code{invariants(INPUT)[6]}). 1757 1758 ASSUME: INPUT is a bivariate polynomial, or the output of @code{hnexpansion(f)}, 1759 or the list @code{hne} in the ring created by @code{hnexpansion(f)}. 1610 ASSUME: @code{INPUT} is the output of @code{develop(f)}, or of 1611 @code{extdevelop(develop(f),n)}, or one entry of the list of HN data 1612 computed by @code{hnexpansion(f[,\"ess\"])}. 1613 RETURN: intvec corresponding to the multiplicity sequence of the irreducible 1614 plane curve singularity described by the HN data (return value 1615 coincides with @code{invariants(INPUT)[6]}). 1616 1617 ASSUME: @code{INPUT} is a bivariate polynomial f, or the output of 1618 @code{hnexpansion(f)}, or the list of HN data computed by 1619 @code{hnexpansion(f [,\"ess\"])}. 1760 1620 RETURN: list of two integer matrices: 1761 1621 @texinfo … … 1772 1632 @end table 1773 1633 @end texinfo 1774 NOTE: The order of elements of the list @code{hne} obtained from @code{hnexpansion(f[,\"ess\")} 1775 must not be changed (because then the coincident infinitely near points 1776 couldn't be grouped together, cf. meaning of 2nd intmat in example). 1777 Hence, it is not wise to compute the HNE of several polynomials 1778 separately, put them into a list INPUT and call @code{multsequence(INPUT)}. @* 1634 NOTE: The order of the elements of the list of HN data obtained from 1635 @code{hnexpansion(f [,\"ess\"])} must not be changed (because otherwise 1636 the coincident infinitely near points couldn't be grouped together, 1637 see the meaning of the 2nd intmat in the example). 1638 Hence, it is not wise to compute the HN expansion of polynomial factors 1639 separately, put them into a list INPUT and call 1640 @code{multsequence(INPUT)}. @* 1779 1641 Use @code{displayMultsequence} to produce a better readable output for 1780 1642 reducible curves on the screen. @* … … 1789 1651 { 1790 1652 //---- INPUT = poly, or HNEring -------------------- 1791 if (typeof(#[1])=="poly") 1792 { 1793 list HNEXPANSION=hnexpansion(#[1]); 1794 return(multsequence(HNEXPANSION)); 1795 } 1796 if (typeof(#[1])=="ring") 1797 { 1798 def H_N_ER_I_N_G=#[1]; 1799 def ret_te_ring=basering; 1800 setring H_N_ER_I_N_G; 1801 list ErGeBnIs=multsequence(hne); 1802 setring ret_te_ring; 1803 kill H_N_ER_I_N_G; 1804 return(ErGeBnIs); 1805 } 1653 if (typeof(#[1])=="poly") { 1654 list L=hnexpansion(#[1]); 1655 if (typeof(L[1])=="ring") { 1656 def altring = basering; 1657 def HNring = L[1]; setring HNring; 1658 list Ergebnis = multsequence(hne); 1659 setring altring; 1660 kill HNring; 1661 return(Ergebnis); 1662 } 1663 else { 1664 return(multsequence(L)); 1665 } 1666 } 1667 if (typeof(#[1])=="ring") { 1668 def altring = basering; 1669 def HNring = #[1]; setring HNring; 1670 list Ergebnis = multsequence(hne); 1671 setring altring; 1672 kill HNring; 1673 return(Ergebnis); 1674 } 1806 1675 //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: -- 1807 1676 #=stripHNE(#); … … 1886 1755 example 1887 1756 { 1888 // -------- prepare for example ---------1889 if (nameof(basering)=="HNEring") {1890 def rettering=HNEring;1891 kill HNEring;1892 }1893 // ------ the example starts here -------1894 1757 "EXAMPLE:"; echo = 2; 1895 1758 ring r=0,(x,y),dp; 1896 list hn=hnexpansion((x6-y10)*(x+y2-y3)*(x+y2+y3)); // 4 branches 1897 def HNEring=hn[1]; 1898 setring HNEring; 1759 list hne=hnexpansion((x6-y10)*(x+y2-y3)*(x+y2+y3)); 1899 1760 multsequence(hne[1])," | ",multsequence(hne[2])," | ", 1900 1761 multsequence(hne[3])," | ",multsequence(hne[4]); … … 1902 1763 // The meaning of the entries of the 2nd matrix is as follows: 1903 1764 displayMultsequence(hne); 1904 echo = 0;1905 // --- restore HNEring if previously defined ---1906 kill HNEring,r;1907 if (defined(rettering)) {1908 setring rettering;1909 def HNEring=rettering;1910 export HNEring;1911 }1912 1765 } 1913 1766 /////////////////////////////////////////////////////////////////////////////// … … 1915 1768 proc displayMultsequence 1916 1769 "USAGE: displayMultsequence(INPUT); INPUT list or poly 1917 ASSUME: INPUT is a bivariate polynomial, or the output of @code{develop(f)}, 1918 or of @code{extdevelop(develop(f),n)}, or of of @code{hnexpansion(f[,\"ess\"])}, 1919 or (one entry in) the list @code{hne} of the ring created by @code{hnexpansion(f[,\"ess \"])}. 1770 ASSUME: @code{INPUT} is a bivariate polynomial, or the output of 1771 @code{develop(f)}, resp. of @code{extdevelop(develop(f),n)}, or (one 1772 entry of) the list of HN data computed by @code{hnexpansion(f[,\"ess\"])}, 1773 or the output of @code{hnexpansion(f)}. 1920 1774 RETURN: nothing 1921 1775 DISPLAY: the sequence of multiplicities: … … 1923 1777 - if @code{INPUT=develop(f)} or @code{INPUT=extdevelop(develop(f),n)} or @code{INPUT=hne[i]}: 1924 1778 @code{a , b , c , ....... , 1} 1925 - if @code{INPUT=f} or @code{INPUT=hnexpansion(f [,\"ess\"])} or @code{INPUT=hne}:1779 - if @code{INPUT=f} or @code{INPUT=hnexpansion(f)} or @code{INPUT=hne}: 1926 1780 @code{[(a_1, .... , b_1 , .... , c_1)],} 1927 1781 @code{[(a_2, ... ), ... , (... , c_2)],} … … 1933 1787 @code{(...)} indicating branches meeting in an infinitely near point. 1934 1788 @end format 1935 NOTE: The same restrictions for INPUT as in @code{multsequence} apply.@*1789 NOTE: The Same restrictions as in @code{multsequence} apply for the input.@* 1936 1790 In case the Hamburger-Noether expansion of the curve f is needed 1937 1791 for other purposes as well it is better to calculate this first … … 1943 1797 { 1944 1798 //---- INPUT = poly, or HNEring -------------------- 1945 if (typeof(#[1])=="poly") 1946 { 1947 list HNEXPANSION=hnexpansion(#[1]); 1948 displayMultsequence(HNEXPANSION); 1949 return(); 1950 } 1951 if (typeof(#[1])=="ring") 1952 { 1953 def H_N_ER_I_N_G=#[1]; 1954 def ret_te_ring=basering; 1955 setring H_N_ER_I_N_G; 1956 displayMultsequence(hne); 1957 setring ret_te_ring; 1958 kill H_N_ER_I_N_G; 1959 return(); 1960 } 1799 if (typeof(#[1])=="poly") { 1800 list L=hnexpansion(#[1]); 1801 if (typeof(L[1])=="ring") { 1802 def HNring = L[1]; setring HNring; 1803 displayMultsequence(hne); 1804 return(); 1805 } 1806 else { 1807 displayMultsequence(L); 1808 return(); 1809 } 1810 } 1811 if (typeof(#[1])=="ring") { 1812 def HNring = #[1]; setring HNring; 1813 displayMultsequence(hne); 1814 return(); 1815 } 1816 1961 1817 //-- entferne ueberfluessige Daten zur Erhoehung der Rechengeschwindigkeit: -- 1962 1818 #=stripHNE(#); … … 1992 1848 } 1993 1849 } 1994 } // example multsequence; geht wegen echo nicht (muesste auf 3 gesetzt werden)1850 } 1995 1851 example 1996 1852 { 1997 // ------ the example starts here -------1998 1853 "EXAMPLE:"; echo = 2; 1999 1854 ring r=0,(x,y),dp; 2000 // //Example 1: Input = output of develop1855 // Example 1: Input = output of develop 2001 1856 displayMultsequence(develop(x3-y5)); 2002 //// Example 2: Input = bivariate polynomial 1857 1858 // Example 2: Input = bivariate polynomial 2003 1859 displayMultsequence((x6-y10)*(x+y2-y3)*(x+y2+y3)); 2004 1860 } 1861 2005 1862 /////////////////////////////////////////////////////////////////////////////// 2006 1863 … … 2556 2413 @code{develop(f,N)}.@* 2557 2414 If the matrix M of L has n columns then, compared with 2558 @code{parametri sation(L)}, @code{paramametrize(extdevelop(L,N))} will increase the2415 @code{parametrization(L)}, @code{paramametrize(extdevelop(L,N))} will increase the 2559 2416 exactness by at least (N-n) more significant monomials. 2560 SEE ALSO: develop, hnexpansion, parametri sation2417 SEE ALSO: develop, hnexpansion, parametrization 2561 2418 EXAMPLE: example extdevelop; shows an example 2562 2419 " … … 2683 2540 example 2684 2541 { 2685 if (defined(HNEring))2686 {2687 def save_r_i_n_g=HNEring;2688 kill HNEring;2689 }2690 // ------ the example starts here -------2691 2542 "EXAMPLE:"; echo = 2; 2692 2543 ring exring=0,(x,y),dp; 2693 list hn =hnexpansion(x14-3y2x11-y3x10-y2x9+3y4x8+y5x7+3y4x6+x5*(-y6+y5)2544 list hne=hnexpansion(x14-3y2x11-y3x10-y2x9+3y4x8+y5x7+3y4x6+x5*(-y6+y5) 2694 2545 -3y6x3-y7x2+y8); 2695 def HNEring=hn[1]; 2696 setring HNEring; echo=0; 2697 export(HNEring); echo=2; 2698 print(hne[1][1]); // HNE of 1st branch is finite 2546 displayHNE(hne); // HNE of 1st,3rd branch is finite 2699 2547 print(extdevelop(hne[1],5)[1]); 2700 print(hne[2][1]); // HNE of 2nd branch can be extended2701 2548 list ehne=extdevelop(hne[2],5); 2702 print(ehne[1]); // new HN-matrix has 5 columns 2703 parametrisation(hne[2]); 2704 parametrisation(ehne); 2705 echo=0; 2706 if (defined(save_r_i_n_g)) 2707 { 2708 kill HNEring; 2709 def HNEring=save_r_i_n_g; 2710 } 2549 displayHNE(ehne); 2550 param(hne[2]); 2551 param(ehne); 2552 2711 2553 } 2712 2554 /////////////////////////////////////////////////////////////////////////////// … … 2786 2628 proc factorfirst(poly f, int M, int N) 2787 2629 "USAGE : factorfirst(f,M,N); f poly, M,N int 2788 RETURN: number d : f=c*(y^(N/e) - d*x^(M/e))^e with e=gcd(M,N), number c fitting2789 0 if d does not exist2630 RETURN: number d such that f=const*(y^(N/e) - d*x^(M/e))^e, where e=gcd(M,N), 2631 0 if such a d does not exist 2790 2632 EXAMPLE: example factorfirst; shows an example 2791 2633 " … … 2832 2674 } 2833 2675 2834 /////////////////////////////////////////////////////////////////////////////// 2835 // 2836 // the command HNdevelop is obsolete --> here is the former help string: 2837 // 2838 /////////////////////////////////////////////////////////////////////////////// 2839 // 2840 //ASSUME: f is a bivariate polynomial (in the first 2 ring variables) 2841 //CREATE: ring with name @code{HNEring}, variables @code{x,y} and ordering 2842 // @code{ls} over a field extension of the current basering's ground 2843 // field. @* 2844 // Since the Hamburger-Noether development usually does not exist 2845 // in the originally given basering, @code{HNdevelop} always defines 2846 // @code{HNEring} and CHANGES to it. The field extension is chosen 2847 // minimally. 2848 //RETURN: list @code{L} of lists @code{L[i]} (corresponding to the output of 2849 // @code{develop(f[i])}, f[i] a branch of f, but the last entry being 2850 // omitted). 2851 //@texinfo 2852 //@table @asis 2853 //@item @code{L[i][1]}; matrix: 2854 // Each row contains the coefficients of the corresponding line of the 2855 // Hamburger-Noether expansion (HNE) for f[i]. The end of the line is 2856 // marked in the matrix by the first ring variable (usually x). 2857 //@item @code{L[i][2]}; intvec: 2858 // indicating the length of lines of the HNE 2859 //@item @code{L[i][3]}; int: 2860 // 0 if the 1st ring variable was transversal (with respect to f[i]), @* 2861 // 1 if the variables were changed at the beginning of the 2862 // computation, @* 2863 // -1 if an error has occurred. 2864 //@item @code{L[i][4]}; poly: 2865 // the transformed polynomial of f[i] to make it possible to extend the 2866 // Hamburger-Noether development a posteriori without having to do 2867 // all the previous calculation once again (0 if not needed) 2868 //@end table 2869 //@end texinfo 2870 //NOTE: @code{HNdevelop} decides which procedure (@code{develop} or 2871 // @code{reddevelop}) applies best to the given problem and calls it. @* 2872 // If f is known to be irreducible as a power series, @code{develop(f)} 2873 // should be chosen instead to avoid the change of basering. @* 2874 // If @code{printlevel>=2} comments are displayed (default is 2875 // @code{printlevel=0}). 2876 // 2877 //EXAMPLE: example HNdevelop; shows an example 2878 // 2879 proc HNdevelop (poly f) 2880 "USAGE: HNdevelop(f); f poly 2881 NOTE: command is obsolete, use hnexpansion(f) instead. 2882 SEE ALSO: hnexpansion, develop, extdevelop, param, displayHNE 2676 /////////////////////////////////////////////////////////////////////////// 2677 2678 proc hnexpansion(poly f,list #) 2679 "USAGE: hnexpansion(f[,\"ess\"]); f poly 2680 ASSUME: f is a bivariate polynomial (in the first 2 ring variables) 2681 RETURN: list @code{L}, containing Hamburger-Noether data of @code{f}: 2682 If the computation of the HNE required no field extension, @code{L} 2683 is a list of lists @code{L[i]} (corresponding to the output of 2684 @code{develop}, applied to a branch of @code{f}, but the last entry 2685 being omitted): 2686 @texinfo 2687 @table @asis 2688 @item @code{L[i][1]}; matrix: 2689 Each row contains the coefficients of the corresponding line of the 2690 Hamburger-Noether expansion (HNE) for the i-th branch. The end of 2691 the line is marked in the matrix by the first ring variable 2692 (usually x). 2693 @item @code{L[i][2]}; intvec: 2694 indicating the length of lines of the HNE 2695 @item @code{L[i][3]}; int: 2696 0 if the 1st ring variable was transversal (with respect to the 2697 i-th branch), @* 2698 1 if the variables were changed at the beginning of the 2699 computation, @* 2700 -1 if an error has occurred. 2701 @item @code{L[i][4]}; poly: 2702 the transformed equation of the i-th branch to make it possible 2703 to extend the Hamburger-Noether data a posteriori without having 2704 to do all the previous calculation once again (0 if not needed). 2705 @end table 2706 @end texinfo 2707 If the computation of the HNE required a field extension, the first 2708 entry @code{L[1]} of the list is a ring, in which a list @code{hne} 2709 of lists (the HN data, as above) and a poly @code{f} (image of 2710 @code{f} over the new field) are stored. 2711 @* 2712 If called with an additional input parameter, @code{hnexpansion} 2713 computes only one representative for each class of conjugate 2714 branches (over the ground field active when calling the procedure). 2715 In this case, the returned list @code{L} always has only two 2716 entries: @code{L[1]} is either a list of lists (the HN data) or a 2717 ring (as above), and @code{L[2]} is an integer vector (the number 2718 of branches in the respective conjugacy classes). 2719 2720 NOTE: If f is known to be irreducible as a power series, @code{develop(f)} 2721 could be chosen instead to avoid a change of basering during the 2722 computations. @* 2723 Increasing @code{printlevel} leads to more and more comments. @* 2724 Having defined a variable @code{HNDebugOn} leads to a maximum 2725 number of comments. 2726 2727 SEE ALSO: develop, extdevelop, parametrization, displayHNE 2728 EXAMPLE: example hnexpansion; shows an example 2883 2729 " 2884 2730 { 2885 int irred=0; 2731 int essential; 2732 if (size(#)==1) { essential=1; } 2733 int field_ext; 2734 def altring=basering; 2735 2886 2736 //--------- Falls Ring (p^k,a),...: Wechsel in (p,a),... + minpoly ----------- 2887 if ((find(charstr(basering),string(char(basering)))!=1) && 2888 (charstr(basering)<>"real")) { 2737 if ( (find(charstr(basering),string(char(basering)))!=1) && 2738 (charstr(basering)<>"real")&& 2739 (charstr(basering)<>"complex") ) { 2889 2740 string strmip=string(minpoly); 2890 2741 string strf=string(f); … … 2893 2744 execute("minpoly="+strmip+";"); 2894 2745 execute("poly f="+strf+";"); 2895 list hne=reddevelop(f); 2746 field_ext=1; 2747 def L=pre_HN(f,essential); 2748 if (size(L)==0) { return(list()); } 2749 def HNEring=L[1]; 2750 setring HNEring; 2751 if ((typeof(hne[1])=="ideal")) { return(list()); } 2896 2752 if ((voice==2) && (printlevel > -1)) { 2897 "// Attention: The parameter",par(1),"has changed its meaning!"; 2898 "// It need no longer be a generator of the cyclic group of unities!"; 2899 } 2753 "// Attention: The parameter",par(1),"may have changed its meaning!"; 2754 "// It needs no longer be a generator of the cyclic group of unities!"; 2755 } 2756 dbprint(printlevel-voice+2, 2757 "// result: "+string(size(hne))+" branch(es) successfully computed."); 2900 2758 } 2901 2759 else { 2902 //--- Falls Ring (0,a),... + minpoly : solange factorize nicht in Singular --- 2903 //------- implementiert ist, develop aufrufen (kann spaeter entfallen) ------- 2904 // 2905 // **** lossen: gestrichen 08/05 **** 2906 // if ((char(basering)==0) && (npars(basering)==1)) { 2907 // if (string(minpoly)<>"0") { irred=1; } 2908 // } 2909 // 2910 //------------------ Aufruf der geeigneten Prozedur -------------------------- 2911 if (irred==0) { 2912 list hne=pre_HN(f,0); // = reddevelop(f); 2913 dbprint(printlevel-voice+2, 2914 "// result: "+string(size(hne))+" branch(es) successfully computed,", 2915 "// basering has changed to HNEring"); 2760 def L=pre_HN(f,essential); 2761 if (size(L)==0) { return(list()); } 2762 if (L[2]==1) { field_ext=1; } 2763 intvec hne_conj=L[3]; 2764 def HNEring=L[1]; 2765 setring HNEring; 2766 if ((typeof(hne[1])=="ideal")) { return(list()); } 2767 dbprint(printlevel-voice+2, 2768 "// result: "+string(size(hne))+" branch(es) successfully computed."); 2769 } 2770 if (field_ext==1) { 2771 dbprint(printlevel-voice+3," 2772 // 'hnexpansion' created a list of one ring. 2773 // To see the ring and the data stored in the ring, type (if you assigned 2774 // the name L to the list): 2775 show(L); 2776 // To display the computed HN expansion, type 2777 def HNring = L[1]; setring HNring; displayHNE(hne); "); 2778 if (essential==1) { 2779 dbprint(printlevel-voice+3,""+ 2780 "// As second entry of the returned list L, you obtain an integer vector, 2781 // indicating the number of conjugates for each of the computed branches."); 2782 return(list(HNEring,hne_conj)); 2783 } 2784 return(list(HNEring)); 2785 } 2786 else { // no change of basering necessary --> map data to original ring 2787 setring altring; 2788 if ((npars(altring)==1) and (minpoly!=0)) { 2789 ring HNhelpring=char(altring),(a,x,y),ls; 2790 list hne=imap(HNEring,hne); 2791 setring altring; 2792 map m=HNhelpring,par(1),var(1),var(2); 2793 list hne=m(hne); 2794 kill m,HNhelpring; 2795 } 2796 else { 2797 list hne=fetch(HNEring,hne); 2798 } 2799 kill HNEring; 2800 if (essential==1) { 2801 dbprint(printlevel-voice+3," 2802 // No change of ring necessary, return value is a list: 2803 // first entry = list : HN expansion of essential branches. 2804 // second entry = intvec: numbers of conjugated branches 2805 "); 2806 return(list(hne,hne_conj)); 2916 2807 } 2917 2808 else { 2918 def altring=basering; 2919 string strmip=string(minpoly); 2920 ring HNEring=(char(altring),`parstr(altring)`),(x,y),ls; 2921 execute("minpoly="+strmip+";"); 2922 export HNEring; 2923 poly f=fetch(altring,f); 2924 list hn=develop(f,-1); 2925 list hne; 2926 if (hn[3] <> -1) { 2927 hne[1]=list(hn[1],hn[2],hn[3],hn[4]); 2928 if (hn[5] <> 1) { 2929 " ** WARNING : The curve is reducible, but only one branch could be found!"; 2930 } 2931 } 2932 else { " ** Sorry -- could not find a HNE."; } 2933 dbprint(printlevel-voice+2,"// note: basering has changed to HNEring"); 2934 } 2935 } 2936 export hne; 2937 keepring basering; 2938 return(hne); 2809 dbprint(printlevel-voice+3," 2810 // No change of ring necessary, return value is HN expansion. 2811 "); 2812 return(hne); 2813 } 2814 } 2939 2815 } 2940 2816 example 2941 2817 { 2942 // -------- prepare for example ---------2943 if (nameof(basering)=="HNEring") {2944 def rettering=HNEring;2945 kill HNEring;2946 }2947 // ------ the example starts here -------2948 2818 "EXAMPLE:"; echo = 2; 2949 2819 ring r=0,(x,y),dp; 2950 list hne=HNdevelop(x4-y6);2951 nameof(basering);2820 // First, an example which requires no field extension: 2821 list hne=hnexpansion(x4-y6); 2952 2822 size(hne); // number of branches 2953 print(hne[1][1]); // HN-matrix of 1st branch2823 displayHNE(hne); // HN expansion of branches 2954 2824 param(hne[1]); // parametrization of 1st branch 2955 2825 param(hne[2]); // parametrization of 2nd branch 2956 kill HNEring,r; 2957 echo = 0; 2958 // --- restore HNEring if previously defined --- 2959 if (defined(rettering)) { 2960 setring rettering; 2961 def HNEring=rettering; 2962 export HNEring; 2963 } 2964 } 2965 2966 /////////////////////////////////////////////////////////////////////////////// 2967 // 2968 // the command reddevelop is obsolete --> here is the former help string: 2969 // 2970 /////////////////////////////////////////////////////////////////////////////// 2971 //ASSUME: f is a bivariate polynomial (in the first 2 ring variables) 2972 //CREATE: ring with name @code{HNEring}, variables @code{x,y} and ordering 2973 // @code{ls} over a field extension of the current basering's ground 2974 // field. @* 2975 // Since the Hamburger-Noether development of a reducible curve 2976 // singularity usually does not exist in the originally given basering, 2977 // @code{reddevelop} always defines @code{HNEring} and CHANGES to it. 2978 // The field extension is chosen minimally. 2979 //RETURN: list @code{L} of lists @code{L[i]} (corresponding to the output of 2980 // @code{develop(f[i])}, f[i] a branch of f, but the last entry being 2981 // omitted). 2982 //@texinfo 2983 //@table @asis 2984 //@item @code{L[i][1]}; matrix: 2985 // Each row contains the coefficients of the corresponding line of the 2986 // Hamburger-Noether expansion (HNE) for f[i]. The end of the line is 2987 // marked in the matrix by the first ring variable (usually x). 2988 //@item @code{L[i][2]}; intvec: 2989 // indicating the length of lines of the HNE 2990 //@item @code{L[i][3]}; int: 2991 // 0 if the 1st ring variable was transversal (with respect to f[i]), @* 2992 // 1 if the variables were changed at the beginning of the 2993 // computation, @* 2994 // -1 if an error has occurred. 2995 //@item @code{L[i][4]}; poly: 2996 // the transformed polynomial of f[i] to make it possible to extend the 2997 // Hamburger-Noether development a posteriori without having to do 2998 // all the previous calculation once again (0 if not needed) 2999 //@end table 3000 //@end texinfo 3001 //NOTE: If @code{printlevel>=0} comments are displayed (default is 3002 // @code{printlevel=0}). 3003 // 3004 //EXAMPLE: example reddevelop; shows an example 3005 // 3006 proc reddevelop (poly f) 3007 "USAGE: reddevelop(f); f poly 3008 NOTE: command is obsolete, use hnexpansion(f) instead. 3009 SEE ALSO: hnexpansion, develop, extdevelop, param, displayHNE 3010 " 3011 { 3012 list Ergebnis=pre_HN(f,0); 3013 if (size(Ergebnis)>0) { // otherwise an error may have occurred 3014 dbprint(printlevel-voice+2, 3015 "// result: "+string(size(Ergebnis))+" branch(es) successfully computed,", 3016 "// basering has changed to HNEring"); 3017 } 3018 3019 // ----- Lossen 10/02 : the branches have to be resorted to be able to 3020 // ----- display the multsequence in a nice way 3021 if (size(Ergebnis)>2) 3022 { 3023 int i,j,k,m; 3024 list dummy; 3025 int nbsave; 3026 int no_br = size(Ergebnis); 3027 intmat nbhd[no_br][no_br]; 3028 for (i=1;i<no_br;i++) 3029 { 3030 for (j=i+1;j<=no_br;j++) 3031 { 3032 nbhd[i,j]=separateHNE(Ergebnis[i],Ergebnis[j]); 3033 k=i+1; 3034 while ( (nbhd[i,k] >= nbhd[i,j]) and (k<j) ) 3035 { 3036 k++; 3037 } 3038 if (k<j) // branches have to be resorted 3039 { 3040 dummy=Ergebnis[j]; 3041 nbsave=nbhd[i,j]; 3042 for (m=k; m<j; m++) 3043 { 3044 Ergebnis[m+1]=Ergebnis[m]; 3045 nbhd[i,m+1]=nbhd[i,m]; 3046 } 3047 Ergebnis[k]=dummy; 3048 nbhd[i,k]=nbsave; 3049 } 3050 } 3051 } 3052 } 3053 // ----- 3054 3055 export Ergebnis; 3056 keepring basering; 3057 return(Ergebnis); 3058 } 3059 example 3060 { 3061 // -------- prepare for example --------- 3062 if (nameof(basering)=="HNEring") 3063 { 3064 def rettering=HNEring; 3065 kill HNEring; 3066 } 3067 // ------ the example starts here ------- 3068 "EXAMPLE:"; echo = 2; 3069 ring r = 32003,(x,y),dp; 3070 poly f = x25+x24-4x23-1x22y+4x22+8x21y-2x21-12x20y-4x19y2+4x20+10x19y 3071 +12x18y2-24x18y-20x17y2-4x16y3+x18+60x16y2+20x15y3-9x16y 3072 -80x14y3-10x13y4+36x14y2+60x12y4+2x11y5-84x12y3-24x10y5 3073 +126x10y4+4x8y6-126x8y5+84x6y6-36x4y7+9x2y8-1y9; 3074 list hne=reddevelop(f); 3075 size(hne); // number of branches 3076 print(hne[1][1]); // HN-matrix of 1st branch 3077 print(hne[4][1]); // HN-matrix of 4th branch 3078 // a ring change was necessary, a is a parameter 3079 HNEring; 3080 kill HNEring,r; 3081 echo = 0; 3082 // --- restore HNEring if previously defined --- 3083 if (defined(rettering)) { 3084 setring rettering; 3085 def HNEring=rettering; 3086 export HNEring; 3087 } 3088 } 2826 2827 // An example which requires a field extension: 2828 list L=hnexpansion((x4-y6)*(y2+x4)); 2829 def R=L[1]; setring R; displayHNE(hne); 2830 basering; 2831 setring r; kill R; 2832 2833 // Computing only one representative per conjugacy class: 2834 L=hnexpansion((x4-y6)*(y2+x4),"ess"); 2835 def R=L[1]; setring R; displayHNE(hne); 2836 L[2]; // number of branches in respective conjugacy classes 2837 } 2838 3089 2839 /////////////////////////////////////////////////////////////////////////////// 3090 2840 3091 2841 static proc pre_HN (poly f, int essential) 3092 2842 "NOTE: This procedure is only for internal use, it is called via 3093 reddevelop or essdevelop" 2843 hnexpansion 2844 RETURN: list: first entry = HNEring (containing list hne, poly f) 2845 second entry = 0 if no change of base ring necessary 2846 1 if change of base ring necessary 2847 third entry = numbers of conjugates ( if essential = 1 ) 2848 if some error has occured, the empty list is returned 2849 " 3094 2850 { 3095 2851 def altring = basering; 3096 int p = char(basering); // Ringcharakteristik 2852 int p = char(basering); 2853 int field_ext; 2854 intvec hne_conj; 3097 2855 3098 2856 //-------------------- Tests auf Zulaessigkeit von basering ------------------ … … 3119 2877 //----------------- Definition eines neuen Ringes: HNEring ------------------- 3120 2878 string namex=varstr(1); string namey=varstr(2); 3121 if (string(char(altring))==charstr(altring)) { // kein Parameter2879 if (string(char(altring))==charstr(altring)) { // kein Parameter, nicht 'real' 3122 2880 ring HNEring = char(altring),(x,y),ls; 3123 2881 map m=altring,x,y; 3124 2882 poly f=m(f); 2883 export f; 3125 2884 kill m; 3126 2885 } … … 3128 2887 string mipl=string(minpoly); 3129 2888 if (mipl=="0") { 3130 " ** WARNING: No algebraic extension of this ground field ispossible!";3131 " ** We try to develop this polynomial, but if the need for an extension";3132 " ** occurs during the calculation, we cannot proceed with the";3133 " ** corresponding branches ...";2889 "// ** WARNING: Algebraic extension of given ground field not possible!"; 2890 "// ** We try to develop this polynomial, but if the need for a field"; 2891 "// ** extension occurs during the calculation, we cannot proceed with"; 2892 "// ** the corresponding branches."; 3134 2893 execute("ring HNEring=("+charstr(basering)+"),(x,y),ls;"); 3135 //--- ring ...=(char(.),`parstr()`),... geht nicht, wenn mehr als 1 Param. ---3136 2894 } 3137 2895 else { … … 3142 2900 map getminpol=HNhelpring,a; 3143 2901 mipl=string(getminpol(mipo)); // String umgewandelt mit 'a' als Param. 3144 execute("minpoly="+mipl+";"); 2902 execute("minpoly="+mipl+";"); // "minpoly=poly is not supported" 3145 2903 kill HNhelpring, getminpol; 3146 2904 } 3147 if (nvars(altring)==2) { poly f=fetch(altring,f); } 2905 if (nvars(altring)==2) { 2906 poly f=fetch(altring,f); 2907 export f; 2908 } 3148 2909 else { 3149 map m=altring,x,y; 3150 poly f=m(f); 2910 if (defined(pa)) { // Parameter hatte vorher anderen Namen als 'a' 2911 ring HNhelpring=p,(`pa`,x,y),ls; 2912 poly f=imap(altring,f); 2913 setring HNEring; 2914 map m=HNhelpring,a,x,y; 2915 poly f=m(f); 2916 kill HNhelpring; 2917 } 2918 else { 2919 map m=altring,x,y; 2920 poly f=m(f); 2921 } 2922 export f; 3151 2923 kill m; 3152 2924 } 3153 2925 } 3154 export HNEring; 3155 2926 3156 2927 if (defined(HNDebugOn)) 3157 2928 {"received polynomial: ",f,", with x =",namex,", y =",namey;} … … 3160 2931 int Abbruch,i,NullHNEx,NullHNEy; 3161 2932 string str; 3162 list Newton,Ergebnis,hilflist; 2933 list Newton,hne; 2934 2935 // --- changed for SINGULAR 3: --- 2936 hne=ideal(0); 2937 export hne; 3163 2938 3164 2939 //====================== Tests auf Zulaessigkeit des Polynoms ================ … … 3168 2943 dbprint(printlevel+1, 3169 2944 "The given polynomial is a unit in the power series ring!"); 3170 keepringHNEring;2945 setring altring; kill HNEring; 3171 2946 return(list()); // there are no HNEs 3172 2947 } 3173 2948 if (f==0) { 3174 2949 dbprint(printlevel+1,"The given polynomial is zero!"); 3175 keepringHNEring;2950 setring altring; kill HNEring; 3176 2951 return(list()); // there are no HNEs 3177 2952 } … … 3228 3003 if (str<>"c") { 3229 3004 setring altring; 3230 if(system("with","Namespaces")) { kill Top::HNEring; }3231 3005 kill HNEring;kill zweitring; 3232 3006 return(list());} … … 3263 3037 " (c) continue with a squarefree divisor (but factors of the form g^" 3264 3038 +string(p); 3265 " are lost; this is recommended, takes no moretime)";3039 " are lost; this is recommended, takes no extra time)"; 3266 3040 " (f) continue with the full radical (using a factorization of the"; 3267 " pure power part; this could take muchtime)";3041 " pure power part; this could take some time)"; 3268 3042 " (q) quit the algorithm"; 3269 3043 "";"Please enter the letter of your choice:"; … … 3281 3055 " printlevel=1;"; 3282 3056 "// before calling me with a non-squarefree f."; 3283 "// If printlevel > 0, I will present to you some possibilities how to", 3284 "proceed."; 3057 "// If printlevel > 0, I present some possibilities how to proceed."; 3285 3058 str="q"; 3286 3059 } 3287 3060 if (str=="q") { 3288 if(system("with","Namespaces")) { kill Top::HNEring; }3289 3061 setring altring;kill HNEring; 3290 3062 return(list()); … … 3298 3070 //====================== Ende Test auf Quadratfreiheit ======================= 3299 3071 if (subst(subst(f,x,0),y,0)!=0) { 3300 " Sorry. The remaining polynomial is a unit in the power series ring...";3301 keepringHNEring;3072 "The polynomial is a unit in the power series ring. No HNE computed."; 3073 setring altring;kill HNEring; 3302 3074 return(list()); 3303 3075 } … … 3327 3099 // Binde die Listen (azeilen,...) an den Ring (um sie nicht zu ueberschreiben 3328 3100 // bei Def. in einem anderen Ring). 3329 // Exportiere Objekte, damit sie auch in der proc HN noch da sind3330 3101 //---------------------------------------------------------------------------- 3331 3102 ring HNE_noparam = char(altring),(a,x,y),ls; 3332 export HNE_noparam;3333 3103 poly f; 3334 3104 list azeilen=ideal(0); … … 3336 3106 list aneu=ideal(0); 3337 3107 list faktoren=ideal(0); 3108 3338 3109 ideal deltais; 3339 poly delt; // nicht number, weil delta von a abhaengen kann3340 export f,azeilen,HNEs,aneu,faktoren,deltais,delt; 3110 poly delt; 3111 3341 3112 //----- hier steht die Anzahl bisher benoetigter Ringerweiterungen drin: ----- 3342 int EXTHNEnumber=0; export EXTHNEnumber; 3113 int EXTHNEnumber=0; 3114 3115 list EXTHNEring; 3116 list HNE_RingDATA; 3117 int number_of_letztring; 3343 3118 setring HNEring; 3119 number_of_letztring=0; 3344 3120 3345 3121 // ================= Die eigentliche Berechnung der HNE: ===================== … … 3349 3125 {"1st step: Treat Newton polygon until height",grenze1;} 3350 3126 if (grenze1>0) { 3351 hilflist=HN(f,grenze1,1,essential); 3352 if (typeof(hilflist[1][1])=="ideal") { hilflist[1]=list(); } 3353 //- fuer den Fall, dass keine Zweige in transz. Erw. berechnet werden konnten- 3354 Ergebnis=extractHNEs(hilflist[1],0); 3355 if (hilflist[2]!=-1) { 3356 if (defined(HNDebugOn)) {" ring change in HN(",1,") detected";} 3357 poly transfproc=hilflist[2]; 3358 map hole=HNE_noparam,transfproc,x,y; 3359 setring HNE_noparam; 3360 f=imap(HNEring,f); 3361 setring EXTHNEring(EXTHNEnumber); 3362 poly f=hole(f); 3363 } 3364 } 3127 if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); } 3128 HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring, 3129 number_of_letztring); 3130 3131 list hilflist=HN(HNE_RingDATA,f,grenze1,1,essential,0,hne_conj,1); 3132 kill HNEring, HNE_noparam; 3133 if (EXTHNEnumber>0) { kill EXTHNEring(1..EXTHNEnumber);} 3134 def HNEring = hilflist[1][1]; 3135 def HNE_noparam = hilflist[1][2]; 3136 EXTHNEnumber = hilflist[1][3]; 3137 for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; } 3138 if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; } 3139 else { setring EXTHNEring(hilflist[2]);} 3140 if (hilflist[3]==1){field_ext=1;} 3141 hne_conj=hilflist[5]; 3142 3143 if (number_of_letztring != hilflist[2]) 3144 { // Ringwechsel in Prozedur HN 3145 map hole=HNE_noparam,transfproc,x,y; 3146 setring HNE_noparam; 3147 if (not(defined(f))) {poly f;} 3148 f=imap(HNEring,f); 3149 setring EXTHNEring(EXTHNEnumber); 3150 if (not(defined(f))) {poly f; f=hole(f); export f;} 3151 else {f=hole(f);} 3152 } 3153 number_of_letztring = hilflist[2]; 3154 kill hilflist; 3155 } 3156 3365 3157 if (NullHNEy==1) { 3366 Ergebnis=Ergebnis+list(list(matrix(ideal(0,x)),intvec(1),int(0),poly(0))); 3158 if ((typeof(hne[1])=="ideal")) { hne=list(); } 3159 hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(0),poly(0))); 3160 if (hne_conj==0) { hne_conj=1; } 3161 else { hne_conj = hne_conj, 1; } 3367 3162 } 3368 3163 // --------------- Berechne HNE von allen verbliebenen Zweigen: -------------- … … 3370 3165 {"2nd step: Treat Newton polygon until height",grenze2;} 3371 3166 if (grenze2>0) { 3167 3168 if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); } 3169 3170 if (essential==1) { number_of_letztring=0; } 3171 if (number_of_letztring==0) { setring HNEring; } 3172 else { setring EXTHNEring(number_of_letztring); } 3372 3173 map xytausch=basering,y,x; 3174 3175 HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring, 3176 number_of_letztring); 3177 list hilflist=HN(HNE_RingDATA,xytausch(f),grenze2,1,essential,1,hne_conj,1); 3178 kill HNEring, HNE_noparam; 3179 if (EXTHNEnumber>0){ kill EXTHNEring(1..EXTHNEnumber); } 3180 def HNEring = hilflist[1][1]; 3181 def HNE_noparam = hilflist[1][2]; 3182 EXTHNEnumber = hilflist[1][3]; 3183 for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=hilflist[1][4][i]; } 3184 if (hilflist[2]==0) { setring HNEring; number_of_letztring=0; } 3185 else { setring EXTHNEring(hilflist[2]); 3186 number_of_letztring=hilflist[2]; } 3187 if (hilflist[3]==1){field_ext=1;} 3188 hne_conj=hilflist[5]; 3373 3189 kill hilflist; 3374 def letztring=basering;3375 if (EXTHNEnumber==0) { setring HNEring; }3376 else { setring EXTHNEring(EXTHNEnumber); }3377 list hilflist=HN(xytausch(f),grenze2,1,essential);3378 if (typeof(hilflist[1][1])=="ideal") { hilflist[1]=list(); }3379 if (not defined(Ergebnis)) {3380 //-- HN wurde schon mal ausgefuehrt; Ringwechsel beim zweiten Aufruf von HN --3381 if (defined(HNDebugOn)) {" ring change in HN(",1,") detected";}3382 poly transfproc=hilflist[2];3383 map hole=HNE_noparam,transfproc,x,y;3384 setring HNE_noparam;3385 list Ergebnis=imap(letztring,Ergebnis);3386 setring EXTHNEring(EXTHNEnumber);3387 list Ergebnis=hole(Ergebnis);3388 }3389 Ergebnis=Ergebnis+extractHNEs(hilflist[1],1);3390 3190 } 3391 3191 if (NullHNEx==1) { 3392 Ergebnis=Ergebnis+list(list(matrix(ideal(0,x)),intvec(1),int(1),poly(0))); 3393 } 3394 //------------------- Loesche globale, nicht mehr benoetigte Objekte: -------- 3395 if (EXTHNEnumber>0) { 3396 if(system("with","Namespaces")) { kill Top::HNEring; } 3397 if (defined(HNEring)) { kill HNEring; } 3398 def HNEring=EXTHNEring(EXTHNEnumber); 3399 setring HNEring; 3400 export HNEring; 3401 kill EXTHNEring(1..EXTHNEnumber); 3402 } 3403 kill HNE_noparam; 3404 kill EXTHNEnumber; 3405 export Ergebnis; 3406 keepring basering; 3407 3408 return(Ergebnis); 3409 } 3410 3411 /////////////////////////////////////////////////////////////////////////////// 3412 // 3413 // the command essdevelop is obsolete --> here is the former help string: 3414 // 3415 /////////////////////////////////////////////////////////////////////////////// 3416 //ASSUME: f is a bivariate polynomial (in the first 2 ring variables) 3417 //CREATE: ring with name @code{HNEring}, variables @code{x,y} and ordering 3418 // @code{ls} over a field extension of the current basering's ground 3419 // field. @* 3420 // Since the Hamburger-Noether development of a reducible curve 3421 // singularity usually does not exist in the originally given basering, 3422 // @code{essdevelop} always defines @code{HNEring} and CHANGES to it. 3423 // The field extension is chosen minimally. 3424 //RETURN: list @code{L} of lists @code{L[i]} (corresponding to the output of 3425 // @code{develop(f[i])}, f[i] an \"essential\" branch of f, but the 3426 // last entry being omitted).@* 3427 // For more details type @code{help reddevelop;}. 3428 //NOTE: If the HNE needs a field extension, some of the branches will be 3429 // conjugate. In this case @code{essdevelop} reduces the computation to 3430 // one representative for each group of conjugate branches.@* 3431 // Note that the degree of each branch is in general less than the 3432 // degree of the field extension in which all HNEs can be put.@* 3433 // Use @code{reddevelop} or @code{HNdevelop} to compute a complete HNE, 3434 // i.e., a HNE for all branches.@* 3435 // If @code{printlevel>=0} comments are displayed (default is 3436 // @code{printlevel=0}). 3437 //SEE ALSO: hnexpansion, develop, reddevelop, HNdevelop, extdevelop 3438 //EXAMPLE: example essdevelop; shows an example 3192 if ((typeof(hne[1])=="ideal")) { hne=list(); } 3193 hne=hne+list(list(matrix(ideal(0,x)),intvec(1),int(1),poly(0))); 3194 if (hne_conj==0) { hne_conj=1; } 3195 else { hne_conj = hne_conj, 1; } 3196 } 3197 3198 3199 // --- aufraeumen --- 3200 if (defined(HNEakut)){ 3201 kill HNEakut,faktoren,deltais,transformiert,teiler,leitf; 3202 } 3203 if (defined(hilflist)) {kill hilflist;} 3204 if (defined(erg)) {kill erg;} 3205 if (defined(delt)) {kill delt;} 3206 if (defined(azeilen)) { kill azeilen;} 3207 if (defined(aneu)) { kill aneu;} 3208 if (defined(transfproc)) { kill transfproc;} 3209 if (defined(transf)) { kill transf;} 3210 if (not(defined(f))) { poly f = imap(HNEring,f); export f; } 3211 3212 return(list(basering,field_ext,hne_conj)); 3213 } 3214 3215 ////////////////////////////////////////////////////////////////////////////// 3439 3216 proc essdevelop (poly f) 3440 3217 "USAGE: essdevelop(f); f poly … … 3443 3220 " 3444 3221 { 3445 list Ergebnis=pre_HN(f,1); 3446 dbprint(printlevel-voice+2, 3447 "// result: "+string(size(Ergebnis))+" branch(es) successfully computed;"); 3448 if (string(minpoly) <> "0") { 3449 dbprint(printlevel-voice+2, 3450 "// note that conjugate branches are omitted and that the number", 3451 "// of branches represented by each remaining one may vary!"); 3452 } 3453 dbprint(printlevel-voice+2, 3454 "// basering has changed to HNEring"); 3455 export Ergebnis; 3456 keepring basering; 3222 printlevel=printlevel+1; 3223 list Ergebnis=hnexpansion(f,1); 3224 printlevel=printlevel-1; 3457 3225 return(Ergebnis); 3458 3226 } 3459 example 3460 { 3461 // -------- prepare for example --------- 3462 if (nameof(basering)=="HNEring") { 3463 def rettering=HNEring; 3464 kill HNEring; 3465 } 3466 // ------ the example starts here ------- 3467 "EXAMPLE:"; echo = 2; 3468 ring r=2,(x,y),dp; 3469 poly f=(x4+x2y+y2)*(x3+xy2+y3); 3470 // --------- compute all branches: --------- 3471 list hne=reddevelop(f); 3472 displayHNE(hne[1]); // HN-matrix of 1st branch 3473 displayHNE(hne[4]); // HN-matrix of 4th branch 3474 setring r; 3475 kill HNEring; 3476 // --- compute only one of conjugate branches: --- 3477 list hne=essdevelop(f); 3478 displayHNE(hne); 3479 // no. 1 of essdevelop represents no. 1 - 3 of reddevelop and 3480 // no. 2 of essdevelop represents no. 4 + 5 of reddevelop 3481 kill HNEring,r; 3482 echo = 0; 3483 // --- restore HNEring if previously defined --- 3484 if (defined(rettering)) { 3485 setring rettering; 3486 def HNEring=rettering; 3487 export HNEring; 3488 } 3489 } 3490 3491 /////////////////////////////////////////////////////////////////////////////// 3492 static proc HN (poly f,int grenze, int Aufruf_Ebene, int essential) 3493 "NOTE: This procedure is only for internal use, it is called via pre_HN" 3227 3228 /////////////////////////////////////////////////////////////////////////////// 3229 static proc HN (list HNE_RingDATA,poly fneu,int grenze,Aufruf_Ebene, 3230 essential,getauscht,intvec hne_conj,int conj_factor) 3231 "NOTE: This procedure is only for internal use, it is called via pre_HN 3232 RETURN: list: first entry = list of HNErings, 3233 second entry = number of new base ring (0 for HNEring, 3234 -1 for HNE_noparam, 3235 i for EXTHNEring(i)) 3236 third entry = 0 if no field extension necessary 3237 1 if field extension necessary 3238 forth entry = HNEs (only if no change of basering) 3239 " 3494 3240 { 3495 3241 //---------- Variablendefinitionen fuer den unverzweigten Teil: -------------- 3496 3242 if (defined(HNDebugOn)) {"procedure HN",Aufruf_Ebene;} 3497 int Abbruch,ende,i,j, e,M,N,Q,R,zeiger,zeile,zeilevorher;3243 int Abbruch,ende,i,j,k,e,M,N,Q,R,zeiger,zeile,zeilevorher,dd; 3498 3244 intvec hqs; 3245 int field_ext; 3246 int ring_changed, hneshift; 3247 intvec conjugates,conj2,conj1; 3248 3249 list EXTHNEring; 3250 def HNEring = HNE_RingDATA[1]; 3251 def HNE_noparam = HNE_RingDATA[2]; 3252 int EXTHNEnumber = HNE_RingDATA[3]; 3253 for (i=1; i<=EXTHNEnumber; i++) { def EXTHNEring(i)=HNE_RingDATA[4][i]; } 3254 int number_of_letztring = HNE_RingDATA[5]; 3255 if (defined(basering)) 3256 { 3257 if (number_of_letztring==0) { kill HNEring; def HNEring=basering; } 3258 else { kill EXTHNEring(number_of_letztring); 3259 def EXTHNEring(number_of_letztring)=basering; } 3260 } 3261 else 3262 { 3263 if ( number_of_letztring==0) { setring HNEring; } 3264 else { setring EXTHNEring(number_of_letztring); } 3265 } 3266 if (not(defined(hne))) {list hne;} 3499 3267 poly fvorher; 3500 3268 list erg=ideal(0); list HNEs=ideal(0); // um die Listen an den Ring zu binden … … 3511 3279 int p = char(basering); // Ringcharakteristik 3512 3280 list azeilen=ideal(0); 3513 ideal hilfid; list hilflist=ideal(0); intvec hilfvec; 3281 3282 ideal hilfid; intvec hilfvec; 3514 3283 3515 3284 // ======================= der unverzweigte Teil: ============================ 3516 3285 while (Abbruch==0) { 3517 Newton=newtonpoly(f ,1);3286 Newton=newtonpoly(fneu,1); 3518 3287 zeiger=find_in_list(Newton,grenze); 3519 3288 if (Newton[zeiger][2] != grenze) … … 3526 3295 Q = M / N; 3527 3296 3528 //-------- 1. Versuch: ist der quasihomogene Leitterm reine Potenz ? ---------3529 // (dann geht alles wie im irreduziblen Fall)3530 //----------------------------------------------------------------------------3297 //-------- 1. Versuch: ist der quasihomogene Leitterm reine Potenz ? ------ 3298 // (dann geht alles wie im irreduziblen Fall) 3299 //------------------------------------------------------------------------- 3531 3300 e = gcd(M,N); 3532 delt=factorfirst(redleit(f ,Newton[zeiger],Newton[zeiger+1])3301 delt=factorfirst(redleit(fneu,Newton[zeiger],Newton[zeiger+1]) 3533 3302 /x^Newton[zeiger][1],M,N); 3534 3303 if (delt==0) { … … 3537 3306 } 3538 3307 if (Abbruch==0) { 3539 //-------------- f,zeile retten fuer den Spezialfall (###): ------------------3540 fvorher=f ;zeilevorher=zeile;3308 //----------- fneu,zeile retten fuer den Spezialfall (###): ------------- 3309 fvorher=fneu;zeilevorher=zeile; 3541 3310 if (R==0) { 3542 //------------- transformiere f mit T1, wenn kein Abbruch nachher: -----------3543 if (N>1) { f = T1_Transform(f,delt,M/ e); }3311 //-------- transformiere fneu mit T1, wenn kein Abbruch nachher: ------ 3312 if (N>1) { fneu = T1_Transform(fneu,delt,M/ e); } 3544 3313 else { ende=1; } 3545 3314 if (defined(HNDebugOn)) {"a("+string(zeile)+","+string(Q)+") =",delt;} … … 3547 3316 } 3548 3317 else { 3549 //------------- R > 0 : transformiere f mit T2 -------------------------------3550 erg=T2_Transform(f ,delt,M,N,referencepoly(Newton));3551 f =erg[1];delt=erg[2];3552 //------- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ---------3318 //------------- R > 0 : transformiere fneu mit T2 --------------------- 3319 erg=T2_Transform(fneu,delt,M,N,referencepoly(Newton)); 3320 fneu=erg[1];delt=erg[2]; 3321 //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ---- 3553 3322 while (R!=0) { 3554 3323 if (defined(HNDebugOn)) { "h("+string(zeile)+") =",Q; } 3555 3324 hqs[zeile+1]=Q; // denn zeile beginnt mit dem Wert 0 3556 //------------------ markiere das Zeilenende der HNE: ------------------------3325 //--------------- markiere das Zeilenende der HNE: ------------------- 3557 3326 azeilen[zeile+1][Q+1]=x; 3558 3327 zeile=zeile+1; 3559 //----------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ---------3328 //-------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ---- 3560 3329 azeilen[zeile+1]=ideal(0); 3561 3330 M=N; N=R; R=M%N; Q=M / N; … … 3564 3333 azeilen[zeile+1][Q]=delt; 3565 3334 } 3566 if (defined(HNDebugOn)) {"transformed polynomial: ",f ;}3335 if (defined(HNDebugOn)) {"transformed polynomial: ",fneu;} 3567 3336 grenze=e; 3568 //----------------------- teste Abbruchbedingungen: --------------------------3569 if (subst(f ,y,0)==0) { // <==> y|f3337 //----------------------- teste Abbruchbedingungen: --------------------- 3338 if (subst(fneu,y,0)==0) { // <==> y|fneu 3570 3339 dbprint(printlevel-voice+3,"finite HNE of one branch found"); 3571 3340 // voice abzufragen macht bei rekursiven procs keinen Sinn 3572 3341 azeilen[zeile+1][Q+1]=x; 3573 //- Q wird nur in hqs eingetragen, wenn der Spezialfall nicht eintritt (s.u.)- 3342 //----- Q wird nur in hqs eingetragen, wenn der Spezialfall nicht 3343 // eintritt (siehe unten) ----- 3574 3344 Abbruch=2; 3575 3345 if (grenze>1) { 3576 if (jet(f,1,intvec(0,1))==0) { 3577 //------ jet(...)=alle Monome von f, die nicht durch y2 teilbar sind --------- 3578 "THE TEST FOR SQUAREFREENESS WAS BAD!! The polynomial was NOT squarefree!!!";} 3346 if (jet(fneu,1,intvec(0,1))==0) { 3347 //- jet(...)=alle Monome von fneu, die nicht durch y2 teilbar sind - 3348 "THE TEST FOR SQUAREFREENESS WAS BAD!!"; 3349 " The polynomial was NOT squarefree!!!";} 3579 3350 else { 3580 //-------------------------- Spezialfall (###): ------------------------------ 3581 // Wir haben das Problem, dass die HNE eines Zweiges hier abbricht, aber ein 3582 // anderer Zweig bis hierher genau die gleiche HNE hat, die noch weiter geht 3583 // Loesung: mache Transform. rueckgaengig und behandle f im Verzweigungsteil 3584 //---------------------------------------------------------------------------- 3351 //----------------------- Spezialfall (###): ----------------------- 3352 // Wir haben das Problem, dass die HNE eines Zweiges hier abbricht, 3353 // aber ein anderer Zweig bis hierher genau die gleiche HNE hat, die 3354 // noch weiter geht 3355 // Loesung: mache Transform. rueckgaengig und behandle fneu im 3356 // Verzweigungsteil 3357 //------------------------------------------------------------------ 3585 3358 Abbruch=1; 3586 f =fvorher;zeile=zeilevorher;grenze=Newton[zeiger][2];3359 fneu=fvorher;zeile=zeilevorher;grenze=Newton[zeiger][2]; 3587 3360 }} 3588 else {f =0;} // fnicht mehr gebraucht - spare Speicher3361 else {fneu=0;} // fneu nicht mehr gebraucht - spare Speicher 3589 3362 if (Abbruch==2) { hqs[zeile+1]=Q; } 3590 3363 } // Spezialfall nicht eingetreten … … 3600 3373 3601 3374 // ===================== der Teil bei Verzweigung: =========================== 3602 3603 3375 if (Abbruch==1) { 3604 //---------- Variablendefinitionen fuer den verzweigten Teil: ----------------3376 //---------- Variablendefinitionen fuer den verzweigten Teil: --------------- 3605 3377 poly leitf,teiler,transformiert; 3606 3378 list aneu=ideal(0); 3607 3379 list faktoren; 3608 list HNEakut=ideal(0);3609 3380 ideal deltais; 3381 list HNEakut=ideal(0); 3610 3382 intvec eis; 3611 3383 int zaehler,hnezaehler,zl,zl1,M1,N1,R1,Q1,needext; … … 3620 3392 azeilen=list(hqs)+azeilen; // hat jetzt Struktur von HNEs: hqs in der 1.Zeile 3621 3393 3622 //======= Schleife fuer jede zu betrachtende Seite des Newtonpolygons: =======3394 //======= Schleife fuer jede zu betrachtende Seite des Newtonpolygons: ====== 3623 3395 for(i=zeiger; i<size(Newton); i++) { 3396 if ((essential==1) and (EXTHNEnumber>number_of_letztring)) { 3397 // ----- setze ring zurueck fuer neue Kante ----- 3398 // ---- (damit konjugierte Zweige erkennbar) ----- 3399 hneshift=hneshift+hnezaehler; 3400 hnezaehler=0; 3401 ring_changed=0; 3402 def SaveRing = EXTHNEring(EXTHNEnumber); 3403 setring SaveRing; 3404 if (not(defined(HNEs))) { // HN wurde zum 2.Mal von pre_HN aufgerufen 3405 list HNEs=ideal(0); 3406 } 3407 for (k=number_of_letztring+1; k<=EXTHNEnumber; k++) { kill EXTHNEring(k);} 3408 EXTHNEnumber=number_of_letztring; 3409 if (EXTHNEnumber==0) { setring HNEring; } 3410 else { setring EXTHNEring(EXTHNEnumber); } 3411 if (not(defined(HNEs))) { list HNEs; } 3412 HNEs=ideal(0); 3413 deltais=0; 3414 delt=0; 3415 if (defined(zerlege)) { kill zerlege; } 3416 "Hier durch gelaufen"; 3417 } 3418 3624 3419 if (defined(HNDebugOn)) { "we consider side",Newton[i],Newton[i+1]; } 3625 3420 M=Newton[i+1][1]-Newton[i][1]; … … 3631 3426 letztringname=nameof(basering); 3632 3427 lastRingnumber=EXTHNEnumber; 3633 faktoren=list(ideal(charPoly(redleit(f ,Newton[i],Newton[i+1])3428 faktoren=list(ideal(charPoly(redleit(fneu,Newton[i],Newton[i+1]) 3634 3429 /(x^Newton[i][1]*y^Newton[i+1][2]),M,N) ), 3635 3430 intvec(1)); // = (zu faktoriserendes Poly, 1) 3636 3637 //-- wechsle so lange in Ringerw., bis Leitform vollst. in Linearfakt. zerf.:- 3431 conjugates=1; 3432 3433 //-- wechsle so lange in Ringerweiterungen, bis Leitform vollstaendig 3434 // in Linearfaktoren zerfaellt ----- 3638 3435 for (numberofRingchanges=1; needext==1; numberofRingchanges++) { 3639 leitf=redleit(f,Newton[i],Newton[i+1])/(x^Newton[i][1]*y^Newton[i+1][2]); 3436 leitf=redleit(fneu,Newton[i],Newton[i+1])/ 3437 (x^Newton[i][1]*y^Newton[i+1][2]); 3640 3438 delt=factorfirst(leitf,M,N); 3641 3439 needext=0; 3642 3440 if (delt==0) { 3643 3644 //---------- Sonderbehandlung: faktorisiere einige Polynome ueber Q(a): -------3645 if (charstr(basering)=="0,a") {3646 //*CL old: faktoren=factorize(charPoly(leitf,M,N),2); // damit funktion. Bsp. Baladi 5 3647 faktoren=factorize(charPoly(leitf,M,N));3441 //---------- Sonderbehandlung: faktorisiere einige Polynome ueber Q(a): -- 3442 if ((charstr(basering)=="0,a") and (essential==0)) { 3443 faktoren=factorize(charPoly(leitf,M,N)); 3444 conjugates=1; 3445 for (k=2;k<=size(faktoren[2]);k++) {conjugates=conjugates,1;} 3648 3446 } 3649 3447 else { 3650 //------------------ faktorisiere das charakt. Polynom: ----------------------3448 //------------------ faktorisiere das charakt. Polynom: ---------------- 3651 3449 if ((numberofRingchanges==1) or (essential==0)) { 3652 faktoren=factorlist(faktoren); 3450 def L_help=factorlist(faktoren,conjugates); 3451 faktoren=L_help[1]; 3452 conjugates=L_help[2]*conj_factor; 3453 kill L_help; 3653 3454 } 3654 3455 else { // eliminiere alle konjugierten Nullstellen bis auf eine: 3655 3456 ideal hilf_id; 3656 3457 for (zaehler=1; zaehler<=size(faktoren[1]); zaehler++) { 3657 hilf_id=factorize(faktoren[1][zaehler])[1]; 3658 if (size(hilf_id)>1) { faktoren[1][zaehler]=hilf_id[2]; } 3659 else { faktoren[1][zaehler]=hilf_id[1]; } 3458 hilf_id=factorize(faktoren[1][zaehler],1); // war vorher ...)[1]; 3459 if (size(hilf_id)>1) { 3460 poly fac=hilf_id[1]; 3461 dd=deg(fac); 3462 // Zur Sicherheit: 3463 if (deg(fac)==0) { fac=hilf_id[2]; } 3464 for (k=2;k<=size(hilf_id);k++) { 3465 dd=dd+deg(hilf_id[k]); 3466 if (deg(hilf_id[k])<deg(fac)) { fac=hilf_id[k]; } 3467 } 3468 faktoren[1][zaehler]=fac; 3469 kill fac; 3470 conjugates[zaehler]=conj_factor*dd; 3471 } 3472 else { 3473 faktoren[1][zaehler]=hilf_id[1]; 3474 conjugates[zaehler]=conj_factor; 3475 } 3660 3476 } 3661 3477 } … … 3665 3481 for (j=1; j<=size(faktoren[2]); j++) { 3666 3482 teiler=faktoren[1][j]; 3667 if (teiler/y != 0) { // sonst war's eine Einheit--> wegwerfen!3483 if (teiler/y != 0) { // sonst war's eine Konstante --> wegwerfen! 3668 3484 if (defined(HNDebugOn)) {"factor of leading form found:",teiler;} 3669 3485 if (teiler/y2 == 0) { // --> Faktor hat die Form cy+d 3670 3486 deltais[zaehler]=-subst(teiler,y,0)/koeff(teiler,0,1); //=-d/c 3671 3487 eis[zaehler]=faktoren[2][j]; 3488 conj2[zaehler]=conjugates[j]; 3672 3489 zaehler++; 3673 3490 } … … 3675 3492 dbprint(printlevel-voice+2, 3676 3493 " Change of basering (field extension) necessary!"); 3677 if (defined(HNDebugOn)) { teiler,"is not properly factored!"; }3494 if (defined(HNDebugOn)) { teiler,"is not yet properly factorized!"; } 3678 3495 if (needext==0) { poly zerlege=teiler; } 3679 3496 needext=1; 3497 field_ext=1; 3680 3498 } 3681 3499 } 3682 } 3500 } // end(for j) 3683 3501 } 3684 else { deltais=ideal(delt); eis=e; }3502 else { deltais=ideal(delt); eis=e; conj2=conj_factor; } 3685 3503 if (defined(HNDebugOn)) {"roots of char. poly:";deltais; 3686 3504 "with multiplicities:",eis;} 3687 3505 if (needext==1) { 3688 //--------------------- fuehre den Ringwechsel aus: --------------------------3506 //--------------------- fuehre den Ringwechsel aus: --------------------- 3689 3507 ringischanged=1; 3690 3508 if ((size(parstr(basering))>0) && string(minpoly)=="0") { 3691 " ** We've had bad luck! The HNE cannot completely be calculated!";3692 // HNE in transzendenter Erw.fehlgeschlagen3509 " ** We've had bad luck! The HNE cannot be calculated completely!"; 3510 // HNE in transzendenter Erweiterung fehlgeschlagen 3693 3511 kill zerlege; 3694 3512 ringischanged=0; break; // weiter mit gefundenen Faktoren 3695 3513 } 3696 3514 if (parstr(basering)=="") { 3697 EXTHNEnumber++; 3698 splitring(zerlege,"EXTHNEring("+string(EXTHNEnumber)+")"); 3515 EXTHNEnumber++; 3516 def EXTHNEring(EXTHNEnumber) = splitring(zerlege); 3517 setring EXTHNEring(EXTHNEnumber); 3518 3699 3519 poly transf=0; 3700 3520 poly transfproc=0; 3521 ring_changed=1; 3522 export transfproc; 3701 3523 } 3702 3524 else { 3703 if (defined(translist)) { kill translist; } // Vermeidung einer Warnung3704 3525 if (numberofRingchanges>1) { // ein Ringwechsel hat nicht gereicht 3705 list translist=splitring(zerlege,"",list(transf,transfproc,faktoren)); 3706 poly transf=translist[1]; 3707 poly transfproc=translist[2]; 3708 list faktoren=translist[3]; 3526 def helpring = splitring(zerlege,list(transf,transfproc,faktoren)); 3527 kill EXTHNEring(EXTHNEnumber); 3528 def EXTHNEring(EXTHNEnumber)=helpring; 3529 setring EXTHNEring(EXTHNEnumber); 3530 kill helpring; 3531 3532 poly transf=erg[1]; 3533 poly transfproc=erg[2]; 3534 ring_changed=1; 3535 list faktoren=erg[3]; 3536 export transfproc; 3537 kill erg; 3709 3538 } 3710 3539 else { 3711 if ( defined(transfproc)) { // in dieser proc geschah schon Ringwechsel3540 if (ring_changed==1) { // in dieser proc geschah schon Ringwechsel 3712 3541 EXTHNEnumber++; 3713 list translist=splitring(zerlege,"EXTHNEring(" 3714 +string(EXTHNEnumber)+")",list(a,transfproc)); 3715 poly transf=translist[1]; 3716 poly transfproc=translist[2]; 3542 def EXTHNEring(EXTHNEnumber) = splitring(zerlege,list(a,transfproc)); 3543 setring EXTHNEring(EXTHNEnumber); 3544 poly transf=erg[1]; 3545 poly transfproc=erg[2]; 3546 export transfproc; 3547 kill erg; 3717 3548 } 3718 else { 3549 else { // parameter war vorher da 3719 3550 EXTHNEnumber++; 3720 list translist=splitring(zerlege,"EXTHNEring("3721 +string(EXTHNEnumber)+")",a);3722 poly transf= translist[1];3551 def EXTHNEring(EXTHNEnumber) = splitring(zerlege,a); 3552 setring EXTHNEring(EXTHNEnumber); 3553 poly transf=erg[1]; 3723 3554 poly transfproc=transf; 3555 ring_changed=1; 3556 export transfproc; 3557 kill erg; 3724 3558 }} 3725 3559 } 3726 //---------------------------------------------------------------------------- 3727 // transf enthaelt jetzt den alten Parameter des Ringes, der aktiv war vor 3728 // Beginn der Schleife (evtl. also ueber mehrere Ringwechsel weitergereicht), 3729 // transfproc enthaelt den alten Parm. des R., der aktiv war zu Beginn der 3730 // Prozedur, und der an die aufrufende Prozedur zurueckgegeben werden muss 3731 // transf ist Null, falls der alte Ring keinen Parameter hatte, 3732 // das gleiche gilt fuer transfproc 3733 //---------------------------------------------------------------------------- 3734 3735 //------ Neudef. von Variablen, Uebertragung bisher errechneter Daten: ------- 3560 //----------------------------------------------------------------------- 3561 // transf enthaelt jetzt den alten Parameter des Ringes, der aktiv war 3562 // vor Beginn der Schleife (evtl. also ueber mehrere Ringwechsel 3563 // weitergereicht), 3564 // transfproc enthaelt den alten Parameter des Ringes, der aktiv war zu 3565 // Beginn der Prozedur, und der an die aufrufende Prozedur zurueckgegeben 3566 // werden muss 3567 // transf ist Null, falls der alte Ring keinen Parameter hatte, 3568 // das gleiche gilt fuer transfproc 3569 //----------------------------------------------------------------------- 3570 3571 //---- Neudef. von Variablen, Uebertragung bisher errechneter Daten: ---- 3736 3572 poly leitf,teiler,transformiert; 3737 3573 list aneu=ideal(0); … … 3740 3576 setring HNE_noparam; 3741 3577 if (defined(letztring)) { kill letztring; } 3742 if (lastRingnumber>0) { def letztring=EXTHNEring(lastRingnumber); } 3743 else { def letztring=HNEring; } 3578 if (EXTHNEnumber>1) { def letztring=EXTHNEring(EXTHNEnumber-1); } 3579 else { def letztring=HNEring; } 3580 if (not defined(fneu)) {poly fneu;} 3581 fneu=imap(letztring,fneu); 3582 if (not defined(f)) {poly f;} 3744 3583 f=imap(letztring,f); 3584 if (not defined(hne)) {list hne;} 3585 hne=imap(letztring,hne); 3586 3587 if (not defined(faktoren)) {list faktoren; } 3745 3588 faktoren=imap(letztring,faktoren); 3589 3590 if (not(defined(azeilen))){list azeilen,HNEs;} 3591 azeilen=imap(letztring,azeilen); 3592 HNEs=imap(letztring,HNEs); 3593 3746 3594 setring EXTHNEring(EXTHNEnumber); 3747 map hole=HNE_noparam,transf,x,y; 3748 poly f=hole(f); 3749 if (not defined(faktoren)) { 3750 list faktoren=hole(faktoren); 3595 if (not(defined(hole))) { map hole; } 3596 hole=HNE_noparam,transf,x,y; 3597 poly fneu=hole(fneu); 3598 if (not defined(faktoren)) {list faktoren;} 3599 faktoren=hole(faktoren); 3600 3601 if (not(defined(f))) 3602 { 3603 poly f=hole(f); 3604 list hne=hole(hne); 3605 export f,hne; 3751 3606 } 3752 3607 } … … 3755 3610 if (eis==0) { i++; continue; } 3756 3611 if (ringischanged==1) { 3757 list erg,hilflist,HNEakut; // dienen nur zum Sp. von Zwi.erg. 3612 list erg,HNEakut; // dienen nur zum Sp. von Zwi.erg. 3613 3758 3614 ideal hilfid; 3759 erg=ideal(0); hilflist=erg;HNEakut=erg;3615 erg=ideal(0); HNEakut=erg; 3760 3616 3761 3617 hole=HNE_noparam,transf,x,y; 3762 3618 setring HNE_noparam; 3619 if (not(defined(azeilen))){list azeilen,HNEs;} 3763 3620 azeilen=imap(letztring,azeilen); 3764 3621 HNEs=imap(letztring,HNEs); … … 3771 3628 } 3772 3629 3773 //============ Schleife fuer jeden gefundenen Faktor der Leitform: ===========3630 //============ Schleife fuer jeden gefundenen Faktor der Leitform: ========= 3774 3631 for (j=1; j<=size(eis); j++) { 3775 //-- Mache Transf. T1 oder T2, trage Daten in HNEs ein, falls HNE abbricht: -- 3776 3777 //------------------------ Fall R==0: ---------------------------------------- 3632 //---- Mache Transformation T1 oder T2, trage Daten in HNEs ein, 3633 // falls HNE abbricht: ---- 3634 3635 //------------------------ Fall R==0: ------------------------------------- 3778 3636 if (R==0) { 3779 transformiert = T1_Transform(f ,number(deltais[j]),M/ e);3637 transformiert = T1_Transform(fneu,number(deltais[j]),M/ e); 3780 3638 if (defined(HNDebugOn)) { 3781 3639 "a("+string(zeile)+","+string(Q)+") =",deltais[j]; … … 3785 3643 dbprint(printlevel-voice+3,"finite HNE found"); 3786 3644 hnezaehler++; 3787 //------------ trage deltais[j],x ein in letzte Zeile, fertig: ---------------3645 //-------- trage deltais[j],x ein in letzte Zeile, fertig: ------------- 3788 3646 HNEakut=azeilen+list(poly(0)); // =HNEs[hnezaehler]; 3789 3647 hilfid=HNEakut[zeile+2]; hilfid[Q]=deltais[j]; hilfid[Q+1]=x; … … 3791 3649 HNEakut[1][zeile+1]=Q; // aktualisiere Vektor mit den hqs 3792 3650 HNEs[hnezaehler]=HNEakut; 3651 conj1[hneshift+hnezaehler]=conj2[j]; 3793 3652 if (eis[j]>1) { 3794 3653 transformiert=transformiert/y; 3795 if (subst(transformiert,y,0)==0) {3796 "THE TEST FOR SQUAREFREENESS WAS BAD!! The polynomial was NOT squarefree!!!";}3654 if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!" 3655 +"! The polynomial was NOT squarefree!!!";} 3797 3656 else { 3798 //------ Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden --------3657 //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden -- 3799 3658 eis[j]=eis[j]-1; 3800 3659 } … … 3803 3662 } 3804 3663 else { 3805 //------------------------ Fall R <> 0: --------------------------------------3806 erg=T2_Transform(f ,number(deltais[j]),M,N,referencepoly(Newton));3664 //------------------------ Fall R <> 0: --------------------------------- 3665 erg=T2_Transform(fneu,number(deltais[j]),M,N,referencepoly(Newton)); 3807 3666 transformiert=erg[1];delt=erg[2]; 3808 3667 if (defined(HNDebugOn)) {"transformed polynomial: ",transformiert;} … … 3810 3669 dbprint(printlevel-voice+3,"finite HNE found"); 3811 3670 hnezaehler++; 3812 //---------------- trage endliche HNE in HNEs ein: ---------------------------3671 //---------------- trage endliche HNE in HNEs ein: --------------------- 3813 3672 HNEakut=azeilen; // dupliziere den gemeins. Anfang der HNE's 3814 3673 zl=2; // (kommt schliesslich nach HNEs[hnezaehler]) 3815 //---------------------------------------------------------------------------- 3816 // Werte von: zeile: aktuelle Zeilennummer der HNE (gemeinsamer Teil) 3817 // zl : die HNE spaltet auf; zeile+zl ist der Index fuer die 3818 // Zeile des aktuellen Zweigs; (zeile+zl-2) ist die tatsaechl. Zeilennr. 3819 // (bei 0 angefangen) der HNE ([1] <- intvec(hqs), [2] <- 0. Zeile usw.) 3820 //---------------------------------------------------------------------------- 3821 3822 //---------- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ------ 3674 //---------------------------------------------------------------------- 3675 // Werte von: zeile: aktuelle Zeilennummer der HNE (gemeinsamer Teil) 3676 // zl : die HNE spaltet auf; zeile+zl ist der Index fuer die 3677 // Zeile des aktuellen Zweigs; (zeile+zl-2) ist die 3678 // tatsaechl. Zeilennr. (bei 0 angefangen) der HNE 3679 // ([1] <- intvec(hqs), [2] <- 0. Zeile usw.) 3680 //---------------------------------------------------------------------- 3681 3682 //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ----- 3823 3683 M1=M;N1=N;R1=R;Q1=M1/ N1; 3824 3684 while (R1!=0) { … … 3828 3688 // markiere das Zeilenende der HNE 3829 3689 zl=zl+1; 3830 //-------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ------------3690 //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: -------- 3831 3691 HNEakut[zeile+zl]=ideal(0); 3832 3692 … … 3841 3701 HNEakut[zeile+zl+1]=poly(0); 3842 3702 HNEs[hnezaehler]=HNEakut; 3843 //-------------------- Ende der Eintragungen in HNEs ------------------------- 3703 conj1[hneshift+hnezaehler]=conj2[j]; 3704 3705 //-------------------- Ende der Eintragungen in HNEs ------------------- 3844 3706 3845 3707 if (eis[j]>1) { 3846 3708 transformiert=transformiert/y; 3847 if (subst(transformiert,y,0)==0) {3848 "THE TEST FOR SQUAREFREENESS WAS BAD!!The polynomial was NOT squarefree!!!";}3709 if (subst(transformiert,y,0)==0){"THE TEST FOR SQUAREFREENESS WAS BAD!" 3710 +" The polynomial was NOT squarefree!!!";} 3849 3711 else { 3850 //--------- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden -----3712 //--- Spezialfall (###) eingetreten: Noch weitere Zweige vorhanden -- 3851 3713 eis[j]=eis[j]-1; 3852 3714 }} … … 3854 3716 } // endelse (R<>0) 3855 3717 3856 //========== Falls HNE nicht abbricht: Rekursiver Aufruf von HN: =============3857 //------------------- Berechne HNE von transformiert -------------------------3718 //========== Falls HNE nicht abbricht: Rekursiver Aufruf von HN: ========== 3719 //------------------- Berechne HNE von transformiert ---------------------- 3858 3720 if (subst(transformiert,y,0)!=0) { 3859 3721 lastRingnumber=EXTHNEnumber; 3860 list HNerg=HN(transformiert,eis[j],Aufruf_Ebene+1,essential); 3861 if (HNerg[2]==-1) { // kein Ringwechsel in HN aufgetreten 3862 aneu=HNerg[1]; } 3863 else { 3722 3723 if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); } 3724 HNE_RingDATA = list( HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring, 3725 lastRingnumber); 3726 if (defined(HNerg)) {kill HNerg;} 3727 list HNerg=HN(HNE_RingDATA,transformiert,eis[j],Aufruf_Ebene+1, 3728 essential,getauscht,hne_conj,conj2[j]); 3729 HNE_RingDATA = HNerg[1]; 3730 if (conj1==0) { conj1=HNerg[5]; } 3731 else { conj1 = conj1,HNerg[5]; } 3732 3733 if (HNerg[3]==1) { field_ext=1; } 3734 if (HNerg[2]==lastRingnumber) { // kein Ringwechsel in HN aufgetreten 3735 if (not(defined(aneu))) { list aneu; } 3736 aneu = HNerg[4]; 3737 } 3738 else { // Ringwechsel aufgetreten 3864 3739 if (defined(HNDebugOn)) 3865 3740 {" ring change in HN(",Aufruf_Ebene+1,") detected";} 3866 list aneu=HNerg[1]; 3867 poly transfproc=HNerg[2]; 3868 3869 //- stelle lokale Var. im neuen Ring wieder her und rette ggf. ihren Inhalt: - 3870 list erg,hilflist,faktoren,HNEakut; 3871 ideal hilfid; 3872 erg=ideal(0); hilflist=erg; faktoren=erg; HNEakut=erg; 3741 EXTHNEnumber = HNerg[1][3]; 3742 for (i=lastRingnumber+1; i<=EXTHNEnumber; i++) { 3743 def EXTHNEring(i)=HNerg[1][4][i]; 3744 } 3745 if (HNerg[2]==0) { setring HNEring; } 3746 else { setring EXTHNEring(HNerg[2]); } 3747 def tempRing=HNerg[4]; 3748 def aneu=imap(tempRing,HNEs); 3749 kill tempRing; 3750 3751 //--- stelle lokale Variablen im neuen Ring wieder her, und rette 3752 // gegebenenfalls ihren Inhalt: ---- 3753 list erg,faktoren,HNEakut; 3754 ideal hilfid; 3755 erg=ideal(0); faktoren=erg; HNEakut=erg; 3873 3756 poly leitf,teiler,transformiert; 3874 3875 3757 map hole=HNE_noparam,transfproc,x,y; 3876 3758 setring HNE_noparam; … … 3878 3760 else { def letztring=HNEring; } 3879 3761 HNEs=imap(letztring,HNEs); 3762 if (not defined(azeilen)) {list azeilen;} 3880 3763 azeilen=imap(letztring,azeilen); 3764 if (not defined(deltais)) {ideal deltais;} 3881 3765 deltais=imap(letztring,deltais); 3766 if (not defined(delt)) {poly delt;} 3882 3767 delt=imap(letztring,delt); 3768 if (not defined(fneu)) {poly fneu;} 3769 fneu=imap(letztring,fneu); 3770 if (not defined(f)) {poly f;} 3883 3771 f=imap(letztring,f); 3772 if (not defined(hne)) {list hne;} 3773 hne=imap(letztring,hne); 3884 3774 3885 3775 setring EXTHNEring(EXTHNEnumber); … … 3888 3778 ideal deltais=hole(deltais); 3889 3779 number delt=number(hole(delt)); 3890 poly f=hole(f); 3780 poly fneu=hole(fneu); 3781 if (not(defined(f))) 3782 { 3783 poly f=hole(f); 3784 list hne=hole(hne); 3785 export f,hne; 3786 } 3891 3787 } 3892 kill HNerg; 3893 //---------------------------------------------------------------------------- 3894 // HNerg muss jedesmal mit "list" neu definiert werden, weil vorher noch nicht 3895 // ------- klar ist, ob der Ring nach Aufruf von HN noch derselbe ist -------- 3896 3897 //============= Verknuepfe bisherige HNE mit von HN gelieferten HNEs: ======== 3788 3789 //========== Verknuepfe bisherige HNE mit von HN gelieferten HNEs: ====== 3898 3790 if (R==0) { 3899 3791 HNEs,hnezaehler=constructHNEs(HNEs,hnezaehler,aneu,azeilen,zeile, 3900 3792 deltais,Q,j); 3793 kill aneu; 3901 3794 } 3902 3795 else { … … 3905 3798 HNEakut=azeilen; // dupliziere den gemeinsamen Anfang der HNE's 3906 3799 zl=2; // (kommt schliesslich nach HNEs[hnezaehler]) 3907 //---------------- Trage Beitrag dieser Transformation T2 ein: ---------------3908 //--------- Zur Bedeutung von zeile, zl: siehe Kommentar weiter oben ---------3909 3910 //--------- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: -------3800 //------------ Trage Beitrag dieser Transformation T2 ein: ------------- 3801 //------ Zur Bedeutung von zeile, zl: siehe Kommentar weiter oben ------ 3802 3803 //----- vollziehe Euklid.Alg. nach, um die HN-Matrix zu berechnen: ----- 3911 3804 M1=M;N1=N;R1=R;Q1=M1/ N1; 3912 3805 while (R1!=0) { … … 3915 3808 HNEakut[zeile+zl][Q1+1]=x; // Markierung des Zeilenendes der HNE 3916 3809 zl=zl+1; 3917 //-------- Bereitstellung von Speicherplatz fuer eine neue Zeile: ------------3810 //----- Bereitstellung von Speicherplatz fuer eine neue Zeile: -------- 3918 3811 HNEakut[zeile+zl]=ideal(0); 3919 3812 M1=N1; N1=R1; R1=M1%N1; Q1=M1 / N1; … … 3924 3817 HNEakut[zeile+zl][Q1]=delt; 3925 3818 3926 //--- Daten aus T2_Transform sind eingetragen; haenge Daten von HN an: -------3819 //-- Daten aus T2_Transform sind eingetragen; haenge Daten von HN an: -- 3927 3820 hilfid=HNEakut[zeile+zl]; 3928 3821 for (zl1=Q1+1; zl1<=ncols(aneu[zaehler][2]); zl1++) { … … 3930 3823 } 3931 3824 HNEakut[zeile+zl]=hilfid; 3932 //--- vorher HNEs[.][zeile+zl]<-aneu[.][2], jetzt [zeile+zl+1] <- [3] usw.: -- 3825 // ------ vorher HNEs[.][zeile+zl]<-aneu[.][2], 3826 // jetzt [zeile+zl+1] <- [3] usw.: -------- 3933 3827 for (zl1=3; zl1<=size(aneu[zaehler]); zl1++) { 3934 3828 HNEakut[zeile+zl+zl1-2]=aneu[zaehler][zl1]; 3935 3829 } 3936 //--- setze die hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] ----3830 //--- setze hqs zusammen: HNEs[hnezaehler][1]=HNEs[..][1],aneu[..][1] -- 3937 3831 hilfvec=HNEakut[1],aneu[zaehler][1]; 3938 3832 HNEakut[1]=hilfvec; 3939 //----------- weil nicht geht: liste[1]=liste[1],aneu[zaehler][1] ------------3833 //-------- weil nicht geht: liste[1]=liste[1],aneu[zaehler][1] --------- 3940 3834 HNEs[hnezaehler]=HNEakut; 3941 3835 } // end(for zaehler) 3836 kill aneu; 3942 3837 } // endelse (R<>0) 3943 3838 } // endif (subst()!=0) (weiteres Aufblasen mit HN) … … 3945 3840 } // end(for j) (Behandlung der einzelnen delta_i) 3946 3841 3947 } 3948 export HNEs; 3949 keepring basering; 3950 if (defined(transfproc)) { export transfproc;return(list(HNEs,transfproc)); } 3951 else { return(list(HNEs,poly(-1))); } 3952 // -1 als 2. Rueckgabewert zeigt an, dass kein Ringwechsel stattgefunden hat - 3842 3843 // ------------------------- new for essdevelop ---------------------------- 3844 if ((essential==1) and (defined(SaveRing))) { 3845 // ----- uebertrage Daten in gemeinsame Koerpererweiterung --------------- 3846 if (EXTHNEnumber>number_of_letztring) { 3847 // ----- fuer aktuelle Kante war Koerpererweiterung erforderlich ------- 3848 EXTHNEnumber++; 3849 if (not(defined(minPol))) { poly miniPol; } 3850 miniPol=minpoly; 3851 setring SaveRing; 3852 if (not(defined(miniPol))) { poly miniPol; } 3853 miniPol=minpoly; 3854 setring HNE_noparam; 3855 if (not(defined(a_x))){ map a_x,a_y; poly mp_save, mp_new; } 3856 mp_save=imap(SaveRing,miniPol); 3857 mp_new=imap(EXTHNEring(EXTHNEnumber-1),miniPol); 3858 if (mp_save==mp_new) { // Sonderfall: wieder gleicher Ring 3859 def EXTHNEring(EXTHNEnumber)=SaveRing; 3860 setring EXTHNEring(EXTHNEnumber); 3861 if (not(defined(f))) {poly f; f=hole(f); export f;} 3862 list dummyL=imap(EXTHNEring(EXTHNEnumber-1),HNEs); 3863 if (not(defined(HNEs))) { def HNEs=list(); } 3864 HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)]; 3865 kill dummyL,SaveRing; 3866 } 3867 else { // verschiedene Ringe 3868 a_x=HNE_noparam,x,0,0; 3869 a_y=HNE_noparam,y,0,0; 3870 mp_save=a_x(mp_save); // minpoly aus SaveRing mit a --> x 3871 mp_new=a_y(mp_new); // minpoly aus SaveRing mit a --> y 3872 setring SaveRing; 3873 poly mp_new=imap(HNE_noparam,mp_new); 3874 list Lfac=factorize(mp_new,1); 3875 poly fac=Lfac[1][1]; 3876 for (k=2;k<=size(Lfac[1]);k++) { 3877 if (deg(Lfac[1][k])<deg(fac)) { fac=Lfac[1][k]; } 3878 } 3879 3880 if (deg(fac)==1) { // keine Erweiterung noetig 3881 def EXTHNEring(EXTHNEnumber)=SaveRing; 3882 setring HNE_noparam; 3883 HNEs=imap(EXTHNEring(EXTHNEnumber-1),HNEs); 3884 setring EXTHNEring(EXTHNEnumber); 3885 if (not(defined(f))) {poly f; f=hole(f); export f;} 3886 map phi=HNE_noparam,-subst(fac,y,0)/koeff(fac,0,1),x,y; 3887 list dummyL=phi(HNEs); 3888 if (not(defined(HNEs))) { def HNEs=list(); } 3889 if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();} 3890 HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)]; 3891 kill dummyL,phi,SaveRing; 3892 } 3893 else { // Koerpererweiterung noetig 3894 def EXTHNEring(EXTHNEnumber) = splitring(fac,list(a,transfproc)); 3895 setring EXTHNEring(EXTHNEnumber); 3896 poly transf=erg[1]; // image of parameter from SaveRing 3897 poly transfproc=erg[2]; 3898 poly transb=erg[3]; // image of parameter from EXTHNEring(..) 3899 export transfproc; 3900 kill erg; 3901 setring HNE_noparam; 3902 if (not(defined(HNEs1))) { list HNEs1=ideal(0); } 3903 HNEs1=imap(EXTHNEring(EXTHNEnumber-1),HNEs); 3904 if (not(defined(hne))) { list hne=ideal(0); } 3905 hne=imap(SaveRing,hne); 3906 HNEs=imap(SaveRing,HNEs); 3907 setring EXTHNEring(EXTHNEnumber); 3908 map hole=HNE_noparam,transf,x,y; 3909 poly fneu=hole(fneu); 3910 poly f=hole(f); 3911 map phi=HNE_noparam,transb,x,y; 3912 list HNEs=hole(HNEs); 3913 list hne=hole(hne); 3914 export f,hne; 3915 if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();} 3916 list dummyL=phi(HNEs1); 3917 HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)]; 3918 kill dummyL,phi,SaveRing; 3919 } 3920 } 3921 } 3922 else { // nur bei letzter Kante muss was getan werden 3923 if (i==size(Newton)-1) { 3924 EXTHNEnumber++; 3925 if (number_of_letztring==0) { def letztring=HNEring; } 3926 else { def letztring=EXTHNEring(EXTHNEnumber); } 3927 if (minpoly==0) { 3928 def EXTHNEring(EXTHNEnumber)=SaveRing; 3929 setring EXTHNEring(EXTHNEnumber); 3930 if (not(defined(f))) {poly f; f=hole(f); export f;} 3931 if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();} 3932 list dummyL=imap(letztring,HNEs); 3933 HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)]; 3934 kill dummyL,letztring,SaveRing; 3935 } 3936 else { // muessen Daten nach SaveRing uebertragen; 3937 setring HNE_noparam; 3938 if (not(defined(HNEs))) { list HNEs; } 3939 HNEs=imap(letztring,HNEs); 3940 def EXTHNEring(EXTHNEnumber)=SaveRing; 3941 setring EXTHNEring(EXTHNEnumber); 3942 if (not(defined(hole))) { map hole; } 3943 hole=HNE_noparam,transfproc,x,y; 3944 list dummyL=hole(HNEs); 3945 if (not(defined(HNEs))) { def HNEs=list(); } 3946 if ((size(HNEs)==1) and (typeof(HNEs[1])=="ideal")) {HNEs=list();} 3947 HNEs[size(HNEs)+1..size(HNEs)+size(dummyL)]=dummyL[1..size(dummyL)]; 3948 kill dummyL, letztring,SaveRing; 3949 } 3950 } 3951 } 3952 } 3953 // -----------------end of new part (loop for essential=1) ---------------- 3954 } // end (Loop uber Kanten) 3955 if (defined(SaveRing)) { kill SaveRing; } 3953 3956 } 3954 3957 else { 3955 HNEs[1]=list(hqs)+azeilen+list(f); // f ist das transform. Poly oder Null 3956 export HNEs; 3957 keepring basering; 3958 return(list(HNEs,poly(-1))); 3959 //-- in dieser proc trat keine Verzweigung auf, also auch kein Ringwechsel --- 3960 } 3961 } 3958 HNEs[1]=list(hqs)+azeilen+list(fneu); // fneu ist transform. Poly oder Null 3959 conj1[1]=conj_factor; 3960 } 3961 3962 if (Aufruf_Ebene == 1) 3963 { 3964 if ((number_of_letztring!=EXTHNEnumber) and (not(defined(hne)))) 3965 { 3966 //----- falls Zweige in transz. Erw. berechnet werden konnten --------- 3967 if (defined(transfproc)) 3968 { // --- Ringwechsel hat stattgefunden --- 3969 if (defined(HNDebugOn)) {" ring change in HN(",1,") detected";} 3970 if (not(defined(hole))) { map hole; } 3971 hole=HNE_noparam,transfproc,x,y; 3972 setring HNE_noparam; 3973 f=imap(HNEring,f); 3974 if (number_of_letztring==0) { def letztring=HNEring; } 3975 else { def letztring=EXTHNEring(EXTHNEnumber); } 3976 if (not(defined(hne))) { list hne; } 3977 hne=imap(letztring,hne); 3978 setring EXTHNEring(EXTHNEnumber); 3979 if (not(defined(f))) { poly f=hole(f); export f; } 3980 list hne=hole(hne); 3981 export hne; 3982 } 3983 } 3984 if (size(HNEs)>0) { 3985 if ((size(HNEs)>1) or (typeof(HNEs[1])!="ideal") or (size(HNEs[1])>0)) { 3986 if ((typeof(hne[1])=="ideal")) { hne=list(); } 3987 hne=hne+extractHNEs(HNEs,getauscht); 3988 if (hne_conj==0) { hne_conj=conj1; } 3989 else { hne_conj = hne_conj, conj1; } 3990 } 3991 } 3992 } 3993 else 3994 { // HN wurde rekursiv aufgerufen 3995 if (number_of_letztring!=EXTHNEnumber) 3996 { // Ringwechsel hatte stattgefunden 3997 string mipl_alt = string(minpoly); 3998 execute("ring tempRing = ("+charstr(basering)+"),("+varstr(basering)+ 3999 "),("+ordstr(basering)+");"); 4000 execute("minpoly="+ mipl_alt +";"); 4001 list HNEs=imap(EXTHNEring(EXTHNEnumber),HNEs); 4002 export HNEs; 4003 if (defined(HNDebugOn)) {" ! tempRing defined ! ";} 4004 } 4005 if (conj1!=0) { hne_conj=conj1; } 4006 else { hne_conj=conj_factor; } 4007 } 4008 if (EXTHNEnumber>0){ EXTHNEring = EXTHNEring(1..EXTHNEnumber); } 4009 HNE_RingDATA = list(HNEring, HNE_noparam, EXTHNEnumber, EXTHNEring); 4010 if (number_of_letztring==EXTHNEnumber) { 4011 return(list(HNE_RingDATA,EXTHNEnumber,field_ext,HNEs,hne_conj)); 4012 } 4013 else { 4014 if (defined(tempRing)) { 4015 return(list(HNE_RingDATA,EXTHNEnumber,field_ext,tempRing,hne_conj)); 4016 } 4017 return(list(HNE_RingDATA,EXTHNEnumber,field_ext,0,hne_conj)); 4018 } 4019 } 4020 3962 4021 /////////////////////////////////////////////////////////////////////////////// 3963 4022 … … 4015 4074 /////////////////////////////////////////////////////////////////////////////// 4016 4075 4017 proc factorlist (list L )4076 proc factorlist (list L, list #) 4018 4077 "USAGE: factorlist(L); L a list in the format of `factorize' 4019 4078 RETURN: the nonconstant irreducible factors of … … 4024 4083 " 4025 4084 { 4085 int k; 4086 if ((size(#)>=1) and ((typeof(#[1])=="intvec") or (typeof(#[1])=="int"))) { 4087 int with_conj = 1; intvec C = #[1]; 4088 } 4089 else { 4090 int with_conj = 0; intvec C = L[2]; 4091 } 4026 4092 // eine Sortierung der Faktoren eruebrigt sich, weil keine zwei versch. 4027 4093 // red.Fakt. einen gleichen irred. Fakt. haben koennen (I.3.27 Diplarb.) 4028 4094 int i,gross; 4029 4095 list faktoren,hilf; 4096 intvec conjugates; 4030 4097 ideal hil1,hil2; 4031 intvec v,w ;4098 intvec v,w,hilf_conj; 4032 4099 for (i=1; (L[1][i] == jet(L[1][i],0)) && (i<size(L[1])); i++) {;} 4033 4100 if (L[1][i] != jet(L[1][i],0)) { … … 4037 4104 // der Monomordnung!!! Im Beispiel unten verschwindet der Faktor x+y+1, wenn 4038 4105 // man ds statt dp als Ordnung nimmt! 4106 hilf_conj=C[i]; 4107 for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; } 4039 4108 hilf[2]=hilf[2]*L[2][i]; 4040 4109 hil1=hilf[1]; 4041 4110 gross=size(hil1); 4042 4111 if (gross>1) { 4043 // faktoren=list(hilf[1][2..gross],hilf[2][2..gross]);4044 // --> `? indexed object must have a name'4045 4112 v=hilf[2]; 4046 4113 faktoren=list(ideal(hil1[2..gross]),intvec(v[2..gross])); 4047 } 4048 else { faktoren=hilf; } 4114 conjugates=intvec(hilf_conj[2..gross]); 4115 } 4116 else { faktoren=hilf; conjugates=hilf_conj; } 4049 4117 } 4050 4118 else { 4051 4119 faktoren=L; 4120 conjugates=C; 4052 4121 } 4053 4122 … … 4060 4129 faktoren[1]=hil1; 4061 4130 v=faktoren[2],L[2][i]; 4131 conjugates=conjugates,C[i]; 4062 4132 faktoren[2]=v; 4063 4133 } … … 4066 4136 else { 4067 4137 hilf=factorize(L[1][i]); 4138 hilf_conj=C[i]; 4139 for (k=2;k<=size(hilf[2]);k++){ hilf_conj=hilf_conj,C[i]; } 4068 4140 hilf[2]=hilf[2]*L[2][i]; 4069 4141 hil1=faktoren[1]; … … 4077 4149 w=hilf[2]; 4078 4150 v=faktoren[2],w[2..gross]; 4151 conjugates=conjugates,hilf_conj[2..gross]; 4079 4152 faktoren[2]=v; 4080 4153 } 4081 4154 } 4082 return(faktoren); 4155 if (with_conj==0) { return(faktoren); } 4156 else { return(list(faktoren,conjugates)); } // for essential development 4083 4157 } 4084 4158 example 4085 4159 { "EXAMPLE:"; echo = 2; 4086 4160 ring exring=0,(x,y),ds; 4087 list L= ideal(x,(x-y)^2*(x+y+1),x+y),intvec(2,2,1);4161 list L=list(ideal(x,(x-y)^2*(x+y+1),x+y),intvec(2,2,1)); 4088 4162 L; 4089 4163 factorlist(L); … … 4172 4246 4173 4247 /////////////////////////////////////////////////////////////////////////////// 4174 4175 4176 proc hnexpansion(poly f,list #)4177 "USAGE: hnexpansion(f); or hnexpansion(f,\"ess\"); f poly4178 4179 USAGE: hnexpansion(f); f poly4180 ASSUME: f is a bivariate polynomial (in the first 2 ring variables)4181 CREATE: ring with variables @code{x,y} and ordering @code{ls} over a4182 field extension of the current basering's ground field,4183 since the Hamburger-Noether development usually does not exist4184 in the originally given basering. The field extension is chosen4185 minimally.@*4186 Moreover, in the ring a list @code{hne} of lists @code{hne[i]} is4187 created (corresponding to the output of @code{develop(f[i])},4188 f[i] a branch of f, but the last entry being omitted).4189 @texinfo4190 @table @asis4191 @item @code{hne[i][1]}; matrix:4192 Each row contains the coefficients of the corresponding line of the4193 Hamburger-Noether expansion (HNE) for f[i]. The end of the line is4194 marked in the matrix by the first ring variable (usually x).4195 @item @code{hne[i][2]}; intvec:4196 indicating the length of lines of the HNE4197 @item @code{hne[i][3]}; int:4198 0 if the 1st ring variable was transversal (with respect to f[i]), @*4199 1 if the variables were changed at the beginning of the4200 computation, @*4201 -1 if an error has occurred.4202 @item @code{hne[i][4]}; poly:4203 the transformed polynomial of f[i] to make it possible to extend the4204 Hamburger-Noether development a posteriori without having to do4205 all the previous calculation once again (0 if not needed)4206 @end table4207 @end texinfo4208 RETURN: a list, say @code{hn}, containing the created ring4209 NOTE: to use the ring type: @code{def HNEring=hn[i]; setring HNEring;}.4210 @*4211 If f is known to be irreducible as a power series, @code{develop(f)}4212 could be chosen instead to avoid the change of basering. @*4213 Increasing @code{printlevel} leads to more and more comments.4214 4215 USAGE: hnexpansion(f,\"ess\"); f poly4216 ASSUME: f is a bivariate polynomial (in the first 2 ring variables)4217 CREATE: ring with variables @code{x,y} and ordering @code{ls} over a4218 field extension of the current basering's ground field,4219 since the Hamburger-Noether development usually does not exist4220 in the originally given basering. The field extension is chosen4221 minimally.4222 @*4223 Moreover, in the ring a list @code{hne} of lists @code{hne[i]} is4224 created (corresponding to the output of @code{develop(f[i])}, f[i] an4225 \"essential\" branch of f, but the last entry being omitted). See4226 @code{hnexpansion} above for more details.4227 RETURN: a list, say @code{hn}, containing the created ring4228 NOTE: to use the ring type: @code{def hnering=hn[i]; setring hnering;}.4229 @*4230 Alternatively you may use the procedure sethnering and type:4231 @code{sethnering(hn);}4232 @*4233 If the HNE needs a field extension, some of the branches will be4234 conjugate. In this case @code{hnexpansion(f,\"ess\")} reduces the4235 computation to one representative for each group of conjugate4236 branches.@*4237 Note that the degree of each branch is in general less than the degree4238 of the field extension in which all HNEs can be put.@*4239 Use @code{hnexpansion(f)} to compute a complete HNE, i.e., a HNE for4240 all branches.@*4241 Increasing @code{printlevel} leads to more and more comments.4242 SEE ALSO: develop, extdevelop, parametrisation, displayHNE4243 EXAMPLE: example hnexpansion; shows an example4244 "4245 {4246 def rettering=basering;4247 if (defined(HNEring))4248 {4249 def @HNEring = HNEring;4250 kill HNEring;4251 }4252 if (size(#)==1)4253 {4254 list hne=essdevelop(f);4255 }4256 else4257 {4258 list hne=HNdevelop(f);4259 }4260 export hne;4261 list hnereturn=HNEring;4262 setring rettering;4263 kill HNEring;4264 if (defined(@HNEring))4265 {4266 def HNEring=@HNEring;4267 export(HNEring);4268 }4269 dbprint(printlevel-voice+2,"4270 // 'hnexpansion' created a list containing a ring, which4271 // contains the Hamburger-Noether expansion as a list hne.4272 // To see the ring, type (if the name of your list is hn):4273 show(hn);4274 // To access the ring and list, type:4275 def hnering = hn[1];4276 setring hnering;4277 hne;4278 ////////////////////////////////////////////////");4279 4280 return(hnereturn);4281 }4282 example4283 {4284 "EXAMPLE:"; echo = 2;4285 ring r=0,(x,y),ls;4286 list hn=hnexpansion(x4-y6);4287 show(hn);4288 4289 def hnering=hn[1];4290 setring hnering;4291 size(hne); // number of branches4292 print(hne[1][1]); // HN-matrix of 1st branch4293 parametrisation(hne); // parametrization of the two branches4294 /////////////////////////////////////////////////////////4295 ring s=2,(x,y),ls;4296 poly f=(x4+x2y+y2)*(x3+xy2+y3);4297 // --------- compute all branches: ---------4298 hn=hnexpansion(f);4299 hnering=hn[1];4300 setring hnering;4301 displayHNE(hne[1]); // HN-matrix of 1st branch4302 displayHNE(hne[4]); // HN-matrix of 4th branch4303 setring s;4304 // --- compute only one of conjugate branches: ---4305 hn=hnexpansion(f,"ess");4306 hnering=hn[1];4307 setring hnering;4308 displayHNE(hne);4309 // no. 1 of hnexpansion(f,"ess") represents no. 1 - 3 of hnexpansion(f) and4310 // no. 2 of hnexpansion(f,"ess") represents no. 4 + 5 of hnexpansion(f)4311 }4312 ///////////////////////////////////////////////////////////////////////////////4313 4314 proc sethnering (list L,list #)4315 "USAGE: sethnering(L[,s]); L list, s string (optional)4316 ASSUME: L is a list containing a ring (e.g. the output of @code{hnexpansion}).4317 CREATE: The procedure creates a ring with name given by the optional parameter4318 s resp. with name hnering, if no optional parameter is given, and4319 changes your ring to this ring. The new ring will be the ring given4320 as the first entry in the list L.4321 RETURN: nothing.4322 SEE ALSO: hnexpansion4323 EXAMPLE: example sethnering; shows some examples.4324 "4325 4326 {4327 if (typeof(L[1])=="ring")4328 {4329 if (size(#)>0)4330 {4331 if (typeof(#[1])=="string")4332 {4333 execute("def "+#[1]+"=L[1];");4334 execute("export "+#[1]+";");4335 execute("setring "+#[1]+";");4336 execute("keepring "+#[1]+";");4337 }4338 else4339 {4340 ERROR("Optional Input was no string.");4341 return();4342 }4343 }4344 else4345 {4346 def hnering=L[1];4347 export hnering;4348 setring hnering;4349 keepring hnering;4350 }4351 return();4352 }4353 else4354 {4355 ERROR("Input was no hnering.");4356 return();4357 }4358 }4359 example4360 {4361 // -------- prepare for example ---------4362 if (defined(hnering))4363 {4364 def rette@ring=hnering;4365 if (nameof(basering)=="hnering")4366 {4367 int wechsel=1;4368 }4369 else4370 {4371 int wechsel;4372 }4373 kill hnering;4374 }4375 // ------ the example starts here -------4376 "EXAMPLE:"; echo = 2;4377 ring r=0,(x,y),ls;4378 nameof(basering);4379 sethnering(hnexpansion(x4-y6)); // Creates hnering and changes to it!4380 nameof(basering);4381 echo = 0;4382 // --- restore HNEring if previously defined ---4383 kill hnering;4384 if (defined(rette@ring)) {4385 def hnering=rette@ring;4386 export hnering;4387 if (wechsel==1)4388 {4389 setring hnering;4390 }4391 }4392 } -
Singular/LIB/primitiv.lib
r54ff35 r7fa60f 3 3 // This library is for Singular 1.2 or newer 4 4 5 version="$Id: primitiv.lib,v 1.1 6 2001-08-27 14:47:59Singular Exp $";5 version="$Id: primitiv.lib,v 1.17 2005-04-14 15:39:22 Singular Exp $"; 6 6 category="Commutative Algebra"; 7 7 info=" … … 253 253 /////////////////////////////////////////////////////////////////////////////// 254 254 255 proc splitring 256 "USAGE: splitring(f ,R[,L]); f poly, R string, L list of polys and/or ideals255 proc splitring(poly f,list #) 256 "USAGE: splitring(f[,L]); f poly, L list of polys and/or ideals 257 257 (optional) 258 ASSUME: f is univariate and irreducible over the active basering. @*258 ASSUME: f is univariate and irreducible over the active ring. @* 259 259 The active ring must allow an algebraic extension (e.g., it cannot 260 260 be a transcendent ring extension of Q or Z/p). 261 CREATE: a ring with name R, in which f is reducible, and CHANGE to it. 262 RETURN: list L mapped into the new ring R, if L is given; else nothing 261 RETURN: ring; @ 262 if called with a nonempty second parameter L, then in the output 263 ring there is defined a list erg ( =L mapped to the new ring). 263 264 NOTE: If the old ring has no parameter, the name @code{a} is chosen for the 264 265 parameter of R (if @code{a} is no ring variable; if it is, @code{b} is 265 266 chosen, etc.; if @code{a,b,c,o} are ring variables, 266 @code{splitring(f ,R[,L])} produces an error message), otherwise the267 @code{splitring(f[,L])} produces an error message), otherwise the 267 268 name of the parameter is kept and only the minimal polynomial is 268 269 changed. @* 269 270 The names of the ring variables and the orderings are not affected. @* 270 It is also allowed to call @code{splitring} with R=\"\".271 Then the old basering will be REPLACED by the new ring (with the272 same name as the old ring).273 271 KEYWORDS: algebraic field extension; extension of rings 274 272 EXAMPLE: example splitring; shows an example … … 276 274 { 277 275 //----------------- split ist bereits eine proc in 'inout.lib' ! ------------- 278 poly f=#[1]; string @R=#[2]; 279 if (size(#)>2) { 280 list L=#[3]; 276 if (size(#)>=1) { 277 list L=#; 281 278 int L_groesse=size(L); 282 279 } … … 284 281 //-------------- ermittle das Minimalpolynom des aktuellen Rings: ------------ 285 282 string minp=string(minpoly); 286 287 if (@R=="") {288 string altrname=nameof(basering);289 @R="splt_temp";290 }291 283 292 284 def altring=basering; … … 297 289 int anzvar=size(maxideal(1)); 298 290 //--------------- Fall 1: Bisheriger Ring hatte kein Minimalpolynom ---------- 299 if (minp=="0") { 291 if (minp=="0") { // only possible without parameters (by assumption) 300 292 if (find(varnames,"a")==0) { algname="a";} 301 293 else { if (find(varnames,"b")==0) { algname="b";} … … 311 303 } 312 304 } 313 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: --305 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: - 314 306 execute("ring splt1="+charakt+","+algname+",dp;"); 315 307 ideal abbnach=var(1); … … 318 310 execute("poly mipol="+string(nach_splt1(f))+";"); 319 311 string Rminp=string(mipol); 320 //--------------------- definiere den neuen Ring: ---------------------------- 321 execute("ring "+@R+" = ("+charakt+","+algname+"),("+varnames+"),(" 312 313 //--------------------- definiere den neuen Ring: --------------------------- 314 execute("ring neuring = ("+charakt+","+algname+"),("+varnames+"),(" 322 315 +ordstr(altring)+");"); 323 316 execute("minpoly="+Rminp+";"); 324 execute("export "+@R+";"); 325 def neuring=basering; 326 //---------------------- Berechne die zurueckzugebende Liste: ---------------- 327 list erg; 317 318 //---------------------- Berechne die zurueckzugebende Liste: --------------- 328 319 if (L_groesse>0) { 329 // L ist ja nicht in 'neuring' def., daher merke man sich die Groesse als int320 list erg; 330 321 map take=altring,maxideal(1); 331 322 erg=take(L); 332 } // take(empty list) gibt nicht empty list, sondern Fehlermeldung323 } 333 324 } 334 325 else { 335 //------------- Fall 2: Bisheriger Ring hatte ein Minimalpolynom: ------------ 326 327 //------------- Fall 2: Bisheriger Ring hatte ein Minimalpolynom: ----------- 336 328 algname=parstr(altring); // Name des algebraischen Elements 337 if (size(algname)>1) {"only one Parameter is allowed!!"; return();} 338 //---------------- Minimalpolynom in ein Polynom umwandeln: ------------------ 329 if (npars(altring)>1) {"only one Parameter is allowed!!"; return(altring);} 330 331 //---------------- Minimalpolynom in ein Polynom umwandeln: ----------------- 339 332 execute("ring splt2="+charakt+","+algname+",dp;"); 340 333 execute("poly mipol="+minp+";"); 341 // f ist Polynom in algname und einer weiteren Variablen --> mache f bivariat:334 // f ist Polynom in algname und einer weiteren Variablen -> mache f bivariat: 342 335 execute("ring splt3="+charakt+",("+algname+","+varnames+"),dp;"); 343 336 poly f=imap(altring,f); 344 //-------------- Vorbereitung des Aufrufes von primitive: -------------------- 337 338 //-------------- Vorbereitung des Aufrufes von primitive: ------------------- 345 339 execute("ring splt1="+charakt+",(x,y),dp;"); 346 340 ideal abbnach=x; … … 353 347 primit=primitive_extra(maxid); 354 348 } 355 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: --349 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: - 356 350 setring splt2; 357 351 map nach_splt2=splt1,0,var(1); // x->0, y->a 358 352 minp=string(nach_splt2(primit)[1]); 359 353 if (printlevel > -1) { "// new minimal polynomial:",minp; } 360 //--------------------- definiere den neuen Ring: ----------------------------361 execute("ring "+@R+"= ("+charakt+","+algname+"),("+varnames+"),("354 //--------------------- definiere den neuen Ring: --------------------------- 355 execute("ring neuring = ("+charakt+","+algname+"),("+varnames+"),(" 362 356 +ordstr(altring)+");"); 363 357 execute("minpoly="+minp+";"); 364 execute("export "+@R+";"); 365 def neuring=basering; 366 367 //--------------- Uebersicht: wenn altring=(p,a),(x,y),dp; dann: ------------- 368 //------------ splt1=p,(x,y),dp; splt2=p,a,dp; splt3=p,(a,x,y),dp; --------- 369 370 list erg; 358 371 359 if (L_groesse>0) { 372 //---------------------- Berechne die zurueckzugebende Liste: ---------------- 360 //---------------------- Berechne die zurueckzugebende Liste: ------------- 361 list erg; 373 362 setring splt3; 374 363 list zwi=imap(altring,L); 375 364 map nach_splt3_1=splt1,0,var(1); // x->0, y->a 376 //----- rechne das primitive Element von altring in das von neuring um: ------365 //----- rechne das primitive Element von altring in das von neuring um: --- 377 366 ideal convid=maxideal(1); 378 367 convid[1]=nach_splt3_1(primit)[2]; 368 poly new_b=nach_splt3_1(primit)[3]; 379 369 map convert=splt3,convid; 380 370 zwi=convert(zwi); 381 371 setring neuring; 382 erg=imap(splt3,zwi); 372 erg=imap(splt3,zwi); 373 erg[size(erg)+1]=imap(splt3,new_b); 383 374 } 384 375 } 385 if (defined(altrname)) { 386 if(system("with","Namespaces")) 387 { kill Top::`altrname`; kill Top::splt_temp; } 388 execute("kill "+altrname+";"); 389 execute("def "+altrname+" = splt_temp;"); 390 @R=altrname; 391 execute("export "+altrname+";"); 392 kill splt_temp; 393 } 394 395 execute("keepring "+@R+";"); 396 if (L_groesse >= 0) { return(erg); } 376 if (defined(erg)){export erg;} 377 return(neuring); 397 378 } 398 379 example
Note: See TracChangeset
for help on using the changeset viewer.