Changeset d96d51 in git for Singular/LIB
- Timestamp:
- May 21, 2010, 7:01:36 PM (14 years ago)
- Branches:
- (u'fieker-DuVal', '117eb8c30fc9e991c4decca4832b1d19036c4c65')(u'spielwiese', '38dfc5131670d387a89455159ed1e071997eec94')
- Children:
- 9d32ecfbdafd318114c653ba4b319fe24cde03ae
- Parents:
- 96b106ffe8f65be0a6179966e3d9e24e18c6e416
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/LIB/tropical.lib
r96b106 rd96d51 8 8 @* Thomas Markwig, email: keilen@mathematik.uni-kl.de 9 9 10 WARNING: 10 WARNING: 11 11 - tropicalLifting will only work with LINUX and if in addition gfan is installed. 12 @*- drawTropicalCurve and drawTropicalNewtonSubdivision will only display the 13 @* tropical curve with LINUX and if in addition latex and kghostview 12 @*- drawTropicalCurve and drawTropicalNewtonSubdivision will only display the 13 @* tropical curve with LINUX and if in addition latex and kghostview 14 14 @* are installed. 15 @*- For tropicalLifting in the definition of the basering the parameter t 15 @*- For tropicalLifting in the definition of the basering the parameter t 16 16 @* from the Puiseux series field C{{t}} must be defined as a variable, 17 17 @* while for all other procedures it must be defined as a parameter. 18 18 19 19 THEORY: 20 Fix some base field K and a bunch of lattice points v0,...,vm in the integer 21 lattice Z^n, then this defines a toric variety as the closure of (K*)^n in 22 the projective space P^m, where the torus is embedded via the map sending a 20 Fix some base field K and a bunch of lattice points v0,...,vm in the integer 21 lattice Z^n, then this defines a toric variety as the closure of (K*)^n in 22 the projective space P^m, where the torus is embedded via the map sending a 23 23 point x in (K*)^n to the point (x^v0,...,x^vm). 24 The generic hyperplane sections are just the images of the hypersurfaces 24 The generic hyperplane sections are just the images of the hypersurfaces 25 25 in (K*)^n defined by the polynomials f=a0*x^v0+...+am*x^vm=0. Some properties 26 of these hypersurfaces can be studied via tropicalisation. 27 28 For this we suppose that K=C{{t}} is the field of Puiseux series over the 26 of these hypersurfaces can be studied via tropicalisation. 27 28 For this we suppose that K=C{{t}} is the field of Puiseux series over the 29 29 field of complex numbers (or any other field with a valuation into the real 30 numbers). One associates to the hypersurface given by f=a0*x^v0+...+am*x^vm 30 numbers). One associates to the hypersurface given by f=a0*x^v0+...+am*x^vm 31 31 the tropical hypersurface defined by the tropicalisation 32 trop(f)=min{val(a0)+<v0,x>,...,val(am)+<vm,x>}. 32 trop(f)=min{val(a0)+<v0,x>,...,val(am)+<vm,x>}. 33 33 Here, <v,x> denotes the standard scalar product of the integer vector v in Z^n 34 34 with the vector x=(x1,...,xn) of variables, so that trop(f) is a piecewise 35 linear function on R^n. The corner locus of this function (i.e. the points 36 at which the minimum is attained a least twice) is the tropical hypersurface 37 defined by trop(f). 38 The theorem of Newton-Kapranov states that this tropical hypersurface is 39 the same as if one computes pointwise the valuation of the hypersurface 40 given by f. The analogue holds true if one replaces one equation f by an 41 ideal I. A constructive proof of the theorem is given by an adapted 42 version of the Newton-Puiseux algorithm. The hard part is to find a point 43 in the variety over C{{t}} which corresponds to a given point in the 35 linear function on R^n. The corner locus of this function (i.e. the points 36 at which the minimum is attained a least twice) is the tropical hypersurface 37 defined by trop(f). 38 The theorem of Newton-Kapranov states that this tropical hypersurface is 39 the same as if one computes pointwise the valuation of the hypersurface 40 given by f. The analogue holds true if one replaces one equation f by an 41 ideal I. A constructive proof of the theorem is given by an adapted 42 version of the Newton-Puiseux algorithm. The hard part is to find a point 43 in the variety over C{{t}} which corresponds to a given point in the 44 44 tropical variety. 45 45 46 It is the purpose of this library to provide basic means to deal with 47 tropical varieties. Of course we cannot represent the field of Puiseux 48 series over C in its full strength, however, in order to compute interesting 49 examples it will be sufficient to replace the complex numbers C by the 50 rational numbers Q and to replace Puiseux series in t by rational functions 51 in t, i.e. we replace C{{t}} by Q(t), or sometimes even by Q[t]. 46 It is the purpose of this library to provide basic means to deal with 47 tropical varieties. Of course we cannot represent the field of Puiseux 48 series over C in its full strength, however, in order to compute interesting 49 examples it will be sufficient to replace the complex numbers C by the 50 rational numbers Q and to replace Puiseux series in t by rational functions 51 in t, i.e. we replace C{{t}} by Q(t), or sometimes even by Q[t]. 52 52 Note, that this in particular forbids rational exponents for the t's. 53 53 54 54 Moreover, in @sc{Singular} no negative exponents of monomials are allowed, so 55 that the integer vectors vi will have to have non-negative entries. 56 Shifting all exponents by a fixed integer vector does not change the 57 tropicalisation nor does it change the toric variety. Thus this does not 55 that the integer vectors vi will have to have non-negative entries. 56 Shifting all exponents by a fixed integer vector does not change the 57 tropicalisation nor does it change the toric variety. Thus this does not 58 58 cause any restriction. 59 If, however, for some reason you prefer to work with general vi, then you 60 have to pass right away to the tropicalisation of the equations, whereever 59 If, however, for some reason you prefer to work with general vi, then you 60 have to pass right away to the tropicalisation of the equations, whereever 61 61 this is allowed -- these are linear polynomials where the constant coefficient 62 corresponds to the valuation of the original coefficient and where 63 the non-constant coefficient correspond to the exponents of the monomials, 64 thus they may be rational numbers respectively negative numbers: 62 corresponds to the valuation of the original coefficient and where 63 the non-constant coefficient correspond to the exponents of the monomials, 64 thus they may be rational numbers respectively negative numbers: 65 65 e.g. if f=t^{1/2}*x^{-2}*y^3+2t*x*y+4 then trop(f)=min{1/2-2x+3y,1+x+y,0}. 66 66 67 67 The main tools provided in this library are as follows: 68 @* - tropicalLifting implements the constructive proof of the Theorem of 69 Newton-Kapranov and constructs a point in the variety 70 over C{{t}} corresponding to a given point in the 71 corresponding tropical variety associated to an 72 ideal I; the generators of I have to be in the 73 polynomial ring Q[t,x1,...,xn] considered as a 74 subring of C{{t}}[x1,...,xn]; a solution will be 75 constructed up to given order; note that several 68 @* - tropicalLifting implements the constructive proof of the Theorem of 69 Newton-Kapranov and constructs a point in the variety 70 over C{{t}} corresponding to a given point in the 71 corresponding tropical variety associated to an 72 ideal I; the generators of I have to be in the 73 polynomial ring Q[t,x1,...,xn] considered as a 74 subring of C{{t}}[x1,...,xn]; a solution will be 75 constructed up to given order; note that several 76 76 field extensions of Q might be necessary throughout 77 77 the intermediate computations; the procedures use 78 78 the external program gfan 79 @* - drawTropicalCurve visualises a tropical plane curve either given by a 80 polynomial in Q(t)[x,y] or by a list of linear 81 polynomials of the form ax+by+c with a,b in Z and c 79 @* - drawTropicalCurve visualises a tropical plane curve either given by a 80 polynomial in Q(t)[x,y] or by a list of linear 81 polynomials of the form ax+by+c with a,b in Z and c 82 82 in Q; latex must be installed on your computer 83 @* - tropicalJInvariant computes the tropical j-invaiant of a tropical 83 @* - tropicalJInvariant computes the tropical j-invaiant of a tropical 84 84 elliptic curve 85 85 @* - jInvariant computes the j-invariant of an elliptic curve 86 @* - weierstrassForm computes the Weierstrass form of an elliptic curve 86 @* - weierstrassForm computes the Weierstrass form of an elliptic curve 87 87 88 88 PROCEDURES FOR TROPICAL LIFTING: 89 tropicalLifting() computes a point in the tropical variety 89 tropicalLifting() computes a point in the tropical variety 90 90 displayTropicalLifting() displays the output of tropicalLifting 91 91 … … 107 107 tInitialIdeal() computes the tInitial ideal of an ideal in Q[t,x_1,...,x_n] 108 108 initialForm() computes the initial form of poly in Q[x_1,...,x_n] 109 initialIdeal() computes the initial ideal of an ideal in Q[x_1,...,x_n] 109 initialIdeal() computes the initial ideal of an ideal in Q[x_1,...,x_n] 110 110 111 111 PROCEDURES FOR LATEX CONVERSION: … … 115 115 texDrawBasic() embeds output of texDrawTropical in a texdraw environment 116 116 texDrawTropical() computes the texdraw commands for a tropical curve 117 texDrawNewtonSubdivision() computes texdraw commands for a Newton subdivision 117 texDrawNewtonSubdivision() computes texdraw commands for a Newton subdivision 118 118 texDrawTriangulation() computes texdraw commands for a triangulation 119 119 … … 121 121 radicalMemberShip() checks radical membership 122 122 tInitialFormPar() computes the t-initial form of poly in Q(t)[x_1,...,x_n] 123 tInitialFormParMax() same as tInitialFormPar, but uses maximum 123 tInitialFormParMax() same as tInitialFormPar, but uses maximum 124 124 solveTInitialFormPar() displays approximated solution of a 0-dim ideal 125 125 detropicalise() computes the detropicalisation of a linear form 126 126 tDetropicalise() computes the detropicalisation of a linear form 127 dualConic() computes the dual of an affine plane conic 127 dualConic() computes the dual of an affine plane conic 128 128 parameterSubstitute() substitutes in the polynomial the parameter t by t^N 129 129 tropicalSubst() makes certain substitutions in a tropical polynomial … … 156 156 /// - eliminatecomponents 157 157 /// - findzerosAndBasictransform 158 /// - ordermaximalideals 158 /// - ordermaximalideals 159 159 /// - verticesTropicalCurve 160 160 /// - bunchOfLines … … 205 205 206 206 /////////////////////////////////////////////////////////////////////////////// 207 /// Procedures concerned with tropical parametrisation 207 /// Procedures concerned with tropical parametrisation 208 208 /////////////////////////////////////////////////////////////////////////////// 209 209 210 210 proc tropicalLifting (ideal i,intvec w,int ordnung,list #) 211 211 "USAGE: tropicalLifting(i,w,ord[,opt]); i ideal, w intvec, ord int, opt string 212 ASSUME: - i is an ideal in Q[t,x_1,...,x_n], w=(w_0,w_1,...,w_n) 213 and (w_1/w_0,...,w_n/w_0) is in the tropical variety of i, 214 and ord is the order up to which a point in V(i) over Q{{t}} 215 lying over (w_1/w_0,...,w_n/w_0) shall be computed; 212 ASSUME: - i is an ideal in Q[t,x_1,...,x_n], w=(w_0,w_1,...,w_n) 213 and (w_1/w_0,...,w_n/w_0) is in the tropical variety of i, 214 and ord is the order up to which a point in V(i) over Q{{t}} 215 lying over (w_1/w_0,...,w_n/w_0) shall be computed; 216 216 w_0 may NOT be ZERO 217 @* - the basering should not have any parameters on its own 218 and it should have a global monomial ordering, 217 @* - the basering should not have any parameters on its own 218 and it should have a global monomial ordering, 219 219 e.g. ring r=0,(t,x(1..n)),dp; 220 @* - the first variable of the basering will be treated as the 220 @* - the first variable of the basering will be treated as the 221 221 parameter t in the Puiseux series field 222 @* - the optional parameter opt should be one or more strings among 222 @* - the optional parameter opt should be one or more strings among 223 223 the following: 224 224 @* 'isZeroDimensional' : the dimension i is zero (not to be checked); 225 @* 'isPrime' : the ideal is prime over Q(t)[x_1,...,x_n] 225 @* 'isPrime' : the ideal is prime over Q(t)[x_1,...,x_n] 226 226 (not to be checked); 227 @* 'isInTrop' : (w_1/w_0,...,w_n/w_0) is in the tropical 227 @* 'isInTrop' : (w_1/w_0,...,w_n/w_0) is in the tropical 228 228 variety (not to be checked); 229 @* 'oldGfan' : uses gfan version 0.2.1 or less 230 @* 'findAll' : find all solutions of a zero-dimensional 229 @* 'oldGfan' : uses gfan version 0.2.1 or less 230 @* 'findAll' : find all solutions of a zero-dimensional 231 231 ideal over (w_1/w_0,...,w_n/w_0) 232 232 @* 'noAbs' : do NOT use absolute primary decomposition … … 234 234 RETURN: IF THE OPTION 'findAll' WAS NOT SET THEN: 235 235 @* list, containing one lifting of the given point (w_1/w_0,...,w_n/w_0) 236 in the tropical variety of i to a point in V(i) over Puiseux 236 in the tropical variety of i to a point in V(i) over Puiseux 237 237 series field up to the first ord terms; more precisely: 238 238 @* IF THE OPTION 'noAbs' WAS NOT SET, THEN: … … 249 249 @* IF THE OPITON 'findAll' WAS SET, THEN: 250 250 @* list, containing ALL liftings of the given point ((w_1/w_0,...,w_n/w_0) 251 in the tropical variety of i to a point in V(i) over Puiseux 252 series field up to the first ord terms, if the ideal is 251 in the tropical variety of i to a point in V(i) over Puiseux 252 series field up to the first ord terms, if the ideal is 253 253 zero-dimensional over Q{{t}}; 254 more precisely, each entry of the list is a list l as computed 254 more precisely, each entry of the list is a list l as computed 255 255 if 'findAll' was NOT set 256 256 @* WE NOW DESCRIBE THE LIST ENTRIES IF 'findAll' WAS NOT SET: 257 @* - the ring l[1] contains an ideal LIFT, which contains 257 @* - the ring l[1] contains an ideal LIFT, which contains 258 258 a point in V(i) lying over w up to the first ord terms; 259 @* - and if the integer l[2] is N then t has to be replaced by t^1/N 259 @* - and if the integer l[2] is N then t has to be replaced by t^1/N 260 260 in the lift, or alternatively replace t by t^N in the defining ideal 261 @* - if the k+1st entry of l[3] is non-zero, then the kth component of 262 LIFT has to be multiplied t^(-l[3][k]/l[3][1]) AFTER substituting t 261 @* - if the k+1st entry of l[3] is non-zero, then the kth component of 262 LIFT has to be multiplied t^(-l[3][k]/l[3][1]) AFTER substituting t 263 263 by t^1/N 264 @* - unless the option 'noResubst' was set, the kth entry of list l[4] 264 @* - unless the option 'noResubst' was set, the kth entry of list l[4] 265 265 is a string which represents the kth generator of 266 the ideal i where the coordinates have been replaced by the result 266 the ideal i where the coordinates have been replaced by the result 267 267 of the lift; 268 the t-order of the kth entry should in principle be larger than the 268 the t-order of the kth entry should in principle be larger than the 269 269 t-degree of LIFT 270 @* - if the option 'noAbs' was set, then the string in l[5] defines 271 a maximal ideal in the field Q[X(1),...,X(k)], where X(1),...,X(k) 270 @* - if the option 'noAbs' was set, then the string in l[5] defines 271 a maximal ideal in the field Q[X(1),...,X(k)], where X(1),...,X(k) 272 272 are the parameters of the ring in l[1]; 273 the basefield of the ring in l[1] should be considered modulo this 273 the basefield of the ring in l[1] should be considered modulo this 274 274 ideal 275 REMARK: - it is best to use the procedure displayTropicalLifting to 275 REMARK: - it is best to use the procedure displayTropicalLifting to 276 276 display the result 277 277 @* - the option 'findAll' cannot be used if 'noAbs' is set 278 278 @* - if the parameter 'findAll' is set AND the ideal i is zero-dimensional 279 in Q{{t}}[x_1,...,x_n] then ALL points in V(i) lying over w are 279 in Q{{t}}[x_1,...,x_n] then ALL points in V(i) lying over w are 280 280 computed up to order ord; if the ideal is not-zero dimenisonal, then 281 281 only the points in the ideal after cutting down to dimension zero 282 282 will be computed 283 283 @* - the procedure requires that the program GFAN is installed on your 284 computer; if you have GFAN version less than 0.3.0 then you must 284 computer; if you have GFAN version less than 0.3.0 then you must 285 285 use the optional parameter 'oldGfan' 286 286 @* - the procedure requires the @sc{Singular} procedure absPrimdecGTZ to be 287 287 present in the package primdec.lib, unless the option 'noAbs' is set; 288 but even if absPrimdecGTZ is present it might be necessary to set 289 the option 'noAbs' in order to avoid the costly absolute primary 290 decomposition; the side effect is that the field extension which is 288 but even if absPrimdecGTZ is present it might be necessary to set 289 the option 'noAbs' in order to avoid the costly absolute primary 290 decomposition; the side effect is that the field extension which is 291 291 computed throughout the recursion might need more than one 292 292 parameter to be described 293 293 @* - since Q is infinite, the procedure finishes with probability one 294 @* - you can call the procedure with Z/pZ as base field instead of Q, 294 @* - you can call the procedure with Z/pZ as base field instead of Q, 295 295 but there are some problems you should be aware of: 296 @* + the Puiseux series field over the algebraic closure of Z/pZ is 297 NOT algebraicall closed, and thus there may not exist a point in 298 V(i) over the Puiseux series field with the desired valuation; 296 @* + the Puiseux series field over the algebraic closure of Z/pZ is 297 NOT algebraicall closed, and thus there may not exist a point in 298 V(i) over the Puiseux series field with the desired valuation; 299 299 so there is no chance that the procedure produced a sensible output 300 - e.g. if i=tx^p-tx-1 301 @* + if the dimension of i over Z/pZ(t) is not zero the process of 302 reduction to zero might not work if the characteristic is small 300 - e.g. if i=tx^p-tx-1 301 @* + if the dimension of i over Z/pZ(t) is not zero the process of 302 reduction to zero might not work if the characteristic is small 303 303 and you are unlucky 304 @* + the option 'noAbs' has to be used since absolute primary 304 @* + the option 'noAbs' has to be used since absolute primary 305 305 decomposition in @sc{Singular} only works in characteristic zero 306 @* - the basefield should either be Q or Z/pZ for some prime p; 307 field extensions will be computed if necessary; if you need 308 parameters or field extensions from the beginning they should 309 rather be simulated as variables possibly adding their relations to 306 @* - the basefield should either be Q or Z/pZ for some prime p; 307 field extensions will be computed if necessary; if you need 308 parameters or field extensions from the beginning they should 309 rather be simulated as variables possibly adding their relations to 310 310 the ideal; the weights for the additional variables should be zero 311 311 EXAMPLE: example tropicalLifting; shows an example" … … 358 358 noabs=1; 359 359 } 360 // this option is not documented -- it prevents the execution of gfan and 361 // just asks for wneu to be inserted -- it can be used to check problems 362 // with the precedure without calling gfan, if wneu is know from previous 360 // this option is not documented -- it prevents the execution of gfan and 361 // just asks for wneu to be inserted -- it can be used to check problems 362 // with the precedure without calling gfan, if wneu is know from previous 363 363 // computations 364 364 if (#[j]=="noGfan") … … 371 371 } 372 372 } 373 // if the basering has characteristic not equal to zero, 373 // if the basering has characteristic not equal to zero, 374 374 // then absolute factorisation 375 375 // is not available, and thus we need the option noAbs … … 385 385 { 386 386 Error("The first coordinate of your input w must be NON-ZERO, since it is a DENOMINATOR!"); 387 } 387 } 388 388 // if w_0<0, then replace w by -w, so that the "denominator" w_0 is positive 389 389 if (w[1]<0) … … 392 392 } 393 393 intvec prew=w; // stores w for later reference 394 // for our computations, w[1] represents the weight of t and this 394 // for our computations, w[1] represents the weight of t and this 395 395 // should be -w_0 !!! 396 396 w[1]=-w[1]; … … 402 402 w[1]=-1; 403 403 } 404 // if some entry of w is positive, we have to make a transformation, 404 // if some entry of w is positive, we have to make a transformation, 405 405 // which moves it to something non-positive 406 406 for (j=2;j<=nvars(basering);j++) … … 428 428 { 429 429 variablen=variablen+var(j); 430 } 430 } 431 431 map GRUNDPHI=BASERING,t,variablen; 432 432 ideal i=GRUNDPHI(i); 433 // compute the initial ideal of i and test if w is in the tropical 434 // variety of i 433 // compute the initial ideal of i and test if w is in the tropical 434 // variety of i 435 435 // - the last entry 1 only means that t is the last variable in the ring 436 436 ideal ini=tInitialIdeal(i,w,1); 437 437 if (isintrop==0) // test if w is in trop(i) only if isInTrop has not been set 438 { 438 { 439 439 poly product=1; 440 440 for (j=1;j<=nvars(basering)-1;j++) … … 454 454 int dd=dim(i); 455 455 setring GRUNDRING; 456 // if the dimension is not zero, we cut the ideal down to dimension zero 456 // if the dimension is not zero, we cut the ideal down to dimension zero 457 457 // and compute the 458 458 // t-initial ideal of the new ideal at the same time 459 459 if(dd!=0) 460 460 { 461 // the procedurce cutdown computes a new ring, in which there lives a 461 // the procedurce cutdown computes a new ring, in which there lives a 462 462 // zero-dimensional 463 // ideal which has been computed by cutting down the input with 463 // ideal which has been computed by cutting down the input with 464 464 // generic linear forms 465 // of the type x_i1-p_1,...,x_id-p_d for some polynomials 466 // p_1,...,p_d not depending 467 // on the variables x_i1,...,x_id; that way we have reduced 465 // of the type x_i1-p_1,...,x_id-p_d for some polynomials 466 // p_1,...,p_d not depending 467 // on the variables x_i1,...,x_id; that way we have reduced 468 468 // the number of variables by dd !!! 469 // the new zero-dimensional ideal is called i, its t-initial 469 // the new zero-dimensional ideal is called i, its t-initial 470 470 // ideal (with respect to 471 // the new w=CUTDOWN[2]) is ini, and finally there is a list 472 // repl in the ring 471 // the new w=CUTDOWN[2]) is ini, and finally there is a list 472 // repl in the ring 473 473 // which contains at the polynomial p_j at position i_j and 474 474 //a zero otherwise; … … 493 493 list liftrings; // will contain the final result 494 494 // if the procedure is called without 'findAll' then it may happen, that no 495 // proper solution is found when dd>0; in that case we have 495 // proper solution is found when dd>0; in that case we have 496 496 // to start all over again; 497 497 // this is controlled by the while-loop … … 509 509 // compute the liftrings by resubstitution 510 510 kk=1; // counts the liftrings 511 int isgood; // test in the non-zerodimensional case 511 int isgood; // test in the non-zerodimensional case 512 512 // if the result has the correct valuation 513 513 for (jj=1;jj<=size(TP);jj++) 514 514 { 515 // the list TP contains as a first entry the ring over which the 516 // tropical parametrisation 515 // the list TP contains as a first entry the ring over which the 516 // tropical parametrisation 517 517 // of the (possibly cutdown ideal) i lives 518 518 def LIFTRING=TP[jj][1]; 519 // if the dimension of i originally was not zero, 519 // if the dimension of i originally was not zero, 520 520 // then we have to fill in the missing 521 521 // parts of the parametrisation 522 522 if (dd!=0) 523 523 { 524 // we need a ring where the parameters X_1,...,X_k 524 // we need a ring where the parameters X_1,...,X_k 525 525 // from LIFTRING are present, 526 526 // and where also the variables of CUTDOWNRING live 527 527 execute("ring REPLACEMENTRING=("+charstr(LIFTRING)+"),("+varstr(CUTDOWNRING)+"),dp;"); 528 list repl=imap(CUTDOWNRING,repl); // get the replacement rules 528 list repl=imap(CUTDOWNRING,repl); // get the replacement rules 529 529 // from CUTDOWNRING 530 ideal PARA=imap(LIFTRING,PARA); // get the zero-dim. parametrisatio 530 ideal PARA=imap(LIFTRING,PARA); // get the zero-dim. parametrisatio 531 531 // from LIFTRING 532 532 // compute the lift of the solution of the original ideal i … … 534 534 k=1; 535 535 // the lift has as many components as GRUNDRING has variables!=t 536 for (j=1;j<=nvars(GRUNDRING)-1;j++) 536 for (j=1;j<=nvars(GRUNDRING)-1;j++) 537 537 { 538 538 // if repl[j]=0, then the corresponding variable was not eliminated 539 if (repl[j]==0) 539 if (repl[j]==0) 540 540 { 541 LIFT[j]=PARA[k]; // thus the lift has been 541 LIFT[j]=PARA[k]; // thus the lift has been 542 542 // computed by tropicalparametrise 543 543 k++; // k checks how many entries of PARA have already been used … … 545 545 else // if repl[j]!=0, repl[j] contains replacement rule for the lift 546 546 { 547 LIFT[j]=repl[j]; // we still have to replace the vars 547 LIFT[j]=repl[j]; // we still have to replace the vars 548 548 // in repl[j] by the corresp. entries of PARA 549 549 // replace all variables!=t (from CUTDOWNRING) 550 for (l=1;l<=nvars(CUTDOWNRING)-1;l++) 550 for (l=1;l<=nvars(CUTDOWNRING)-1;l++) 551 551 { 552 552 // substitute the kth variable by PARA[k] 553 LIFT[j]=subst(LIFT[j],var(l),PARA[l]); 553 LIFT[j]=subst(LIFT[j],var(l),PARA[l]); 554 554 } 555 555 } 556 556 } 557 557 setring LIFTRING; 558 ideal LIFT=imap(REPLACEMENTRING,LIFT); 559 // test now if the LIFT has the correct valuation !!! 560 // note: it may happen, that when resubstituting PARA into 558 ideal LIFT=imap(REPLACEMENTRING,LIFT); 559 // test now if the LIFT has the correct valuation !!! 560 // note: it may happen, that when resubstituting PARA into 561 561 // the replacement rules 562 // there occured some unexpected cancellation; 562 // there occured some unexpected cancellation; 563 563 // we only know that for SOME 564 // solution of the zero-dimensional reduction NO 565 // canellation will occur, 566 // but for others this may very well happen; 564 // solution of the zero-dimensional reduction NO 565 // canellation will occur, 566 // but for others this may very well happen; 567 567 // this in particular means that 568 // we possibly MUST compute all zero-dimensional 568 // we possibly MUST compute all zero-dimensional 569 569 // solutions when cutting down! 570 570 intvec testw=precutdownw[1]; … … 590 590 kill PARA; 591 591 // only if LIFT has the right valuation we have to do something 592 if (isgood==1) 593 { 594 // it remains to reverse the original substitutions, 592 if (isgood==1) 593 { 594 // it remains to reverse the original substitutions, 595 595 // where appropriate !!! 596 // if some entry of the original w was positive, 596 // if some entry of the original w was positive, 597 597 // we replace the corresponding 598 598 // variable x_i by t^-w[i]*x_i, so we must now replace … … 611 611 */ 612 612 // if LIFTRING contains a parameter @a, change it to a 613 if ((noabs==0) and (defined(@a)==-1)) 613 if ((noabs==0) and (defined(@a)==-1)) 614 614 { 615 // pass first to a ring where a and @a 615 // pass first to a ring where a and @a 616 616 // are variables in order to use maps 617 617 poly mp=minpoly; … … 622 622 // replace @a by a in minpoly and in LIFT 623 623 map phi=INTERRING,t,a,a; 624 mp=phi(mp); 624 mp=phi(mp); 625 625 LIFT=phi(LIFT); 626 626 // pass now to a ring whithout @a and with a as parameter … … 629 629 ideal LIFT=imap(INTERRING,LIFT); 630 630 kill INTERRING; 631 } 631 } 632 632 // then export LIFT 633 export(LIFT); 633 export(LIFT); 634 634 // test the result by resubstitution 635 setring GRUNDRING; 635 setring GRUNDRING; 636 636 list resubst; 637 637 if (noresubst==0) … … 642 642 } 643 643 else 644 { 644 { 645 645 resubst=tropicalliftingresubstitute(substitute(i,t,t^(TP[jj][2])),list(LIFTRING),N*TP[jj][2]); 646 646 } 647 647 } 648 648 setring BASERING; 649 // Finally, if t has been replaced by t^N, then we have to change the 649 // Finally, if t has been replaced by t^N, then we have to change the 650 650 // third entry of TP by multiplying by N. 651 651 if (noabs==1) … … 663 663 kill LIFTRING; 664 664 } 665 // if dd!=0 and the procedure was called without the 665 // if dd!=0 and the procedure was called without the 666 666 // option findAll, then it might very well 667 // be the case that no solution is found, since 667 // be the case that no solution is found, since 668 668 // only one solution for the zero-dimensional 669 // reduction was computed and this one might have 669 // reduction was computed and this one might have 670 670 // had cancellations when resubstituting; 671 671 // if so we have to restart the process with the option findAll … … 675 675 "The procedure will be restarted with the option 'findAll'."; 676 676 "Go on by hitting RETURN!"; 677 findall=1; 677 findall=1; 678 678 noabs=0; 679 679 setring CUTDOWNRING; … … 681 681 "i";i; 682 682 "ini";tInitialIdeal(i,w,1); 683 683 684 684 /* 685 685 setring GRUNDRING; … … 699 699 } 700 700 } 701 // if internally the option findall was set, then return 701 // if internally the option findall was set, then return 702 702 // only the first solution 703 703 if (defined(hadproblems)!=0) … … 708 708 if (voice+printlevel>=2) 709 709 { 710 710 711 711 "The procedure has created a list of lists. The jth entry of this list 712 712 contains a ring, an integer and an intvec. 713 713 In this ring lives an ideal representing the wanted lifting, 714 714 if the integer is N then in the parametrisation t has to be replaced by t^1/N, 715 and if the ith component of the intvec is w[i] then the ith component in LIFT 715 and if the ith component of the intvec is w[i] then the ith component in LIFT 716 716 should be multiplied by t^-w[i]/N in order to get the parametrisation. 717 717 718 718 Suppose your list has the name L, then you can access the 1st ring via: 719 719 "; 720 720 if (findall==1) 721 721 { 722 "def LIFTRing=L[1][1]; setring LIFTRing; LIFT; 722 "def LIFTRing=L[1][1]; setring LIFTRing; LIFT; 723 723 "; 724 724 } 725 725 else 726 726 { 727 "def LIFTRing=L[1]; setring LIFTRing; LIFT; 727 "def LIFTRing=L[1]; setring LIFTRing; LIFT; 728 728 "; 729 } 729 } 730 730 } 731 731 if (findall==1) // if all solutions have been computed, return a list of lists … … 752 752 def LIFTRing=LIST[1]; 753 753 setring LIFTRing; 754 // LIFT contains the first 4 terms of a point in the variety of i 754 // LIFT contains the first 4 terms of a point in the variety of i 755 755 // over the Puiseux series field C{{t}} whose order is -w[1]/w[0]=1 756 756 LIFT; … … 780 780 // NOTE: since the last component of v is positive, the lifting 781 781 // must start with a negative power of t, which in Singular 782 // is not allowed for a variable. 782 // is not allowed for a variable. 783 783 def LIFTRing3=LIST[1]; 784 784 setring LIFTRing3; … … 835 835 string Kstring="Z/"+string(char(LIFTRing))+"Z"; 836 836 } 837 // this means that tropicalLifting was called with 837 // this means that tropicalLifting was called with 838 838 // absolute primary decomposition 839 if (size(troplift)==4) 840 { 839 if (size(troplift)==4) 840 { 841 841 setring LIFTRing; 842 842 "The lifting of the point in the tropical variety lives in the ring"; 843 843 if ((size(LIFTpar)==0) and (N==1)) 844 844 { 845 Kstring+"[[t]]"; 845 Kstring+"[[t]]"; 846 846 } 847 847 if ((size(LIFTpar)==0) and (N!=1)) 848 848 { 849 Kstring+"[[t^(1/"+string(N)+")]]"; 849 Kstring+"[[t^(1/"+string(N)+")]]"; 850 850 } 851 851 if ((size(LIFTpar)!=0) and (N!=1)) 852 { 853 Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t^(1/"+string(N)+")]]"; 852 { 853 Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t^(1/"+string(N)+")]]"; 854 854 } 855 855 if ((size(LIFTpar)!=0) and (N==1)) 856 { 857 Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t]]"; 856 { 857 Kstring+"["+LIFTpar+"]/"+string(minpoly)+"[[t]]"; 858 858 } 859 859 } … … 872 872 } 873 873 if ((size(LIFTpar)!=0) and (N!=1)) 874 { 875 Kstring+"["+LIFTpar+"]/M[[t^(1/"+string(N)+")]]"; 874 { 875 Kstring+"["+LIFTpar+"]/M[[t^(1/"+string(N)+")]]"; 876 876 "where M is the maximal ideal"; 877 877 "M=<"+m+">"; 878 878 } 879 879 if ((size(LIFTpar)!=0) and (N==1)) 880 { 881 Kstring+"["+LIFTpar+"]/M[[t]]"; 880 { 881 Kstring+"["+LIFTpar+"]/M[[t]]"; 882 882 "where M is the maximal ideal"; 883 883 "M=<"+m+">"; 884 } 884 } 885 885 } 886 886 ""; … … 909 909 } 910 910 } 911 } 911 } 912 912 } 913 913 example … … 923 923 924 924 /////////////////////////////////////////////////////////////////////////////// 925 /// Procedures concerned with drawing a tropical curve or a Newton subdivision 925 /// Procedures concerned with drawing a tropical curve or a Newton subdivision 926 926 /////////////////////////////////////////////////////////////////////////////// 927 927 928 928 proc tropicalCurve (def tp,list #) 929 929 "USAGE: tropicalCurve(tp[,#]); tp list, # optional list 930 ASSUME: tp is list of linear polynomials of the form ax+by+c 931 with integers a, b and a rational number c representing 930 ASSUME: tp is list of linear polynomials of the form ax+by+c 931 with integers a, b and a rational number c representing 932 932 a tropical Laurent polynomial defining a tropical plane curve; 933 alternatively tp can be a polynomial in Q(t)[x,y] defining a 934 tropical plane curve via the valuation map; 935 the basering must have a global monomial ordering, 933 alternatively tp can be a polynomial in Q(t)[x,y] defining a 934 tropical plane curve via the valuation map; 935 the basering must have a global monomial ordering, 936 936 two variables and up to one parameter! 937 RETURN: list, each entry i=1,...,size(l)-1 corresponds to a vertex 937 RETURN: list, each entry i=1,...,size(l)-1 corresponds to a vertex 938 938 in the tropical plane curve defined by tp 939 939 l[i][1] = x-coordinate of the ith vertex 940 940 l[i][2] = y-coordinate of the ith vertex 941 l[i][3] = intmat, if j is an entry in the first row 941 l[i][3] = intmat, if j is an entry in the first row 942 942 of intmat then the ith vertex of 943 the tropical curve is connected to the 943 the tropical curve is connected to the 944 944 jth vertex with multiplicity given 945 945 by the corresponding entry in the second row 946 l[i][4] = list of lists, the first entry of a list is 947 a primitive integer vector defining the direction 948 of an unbounded edge emerging from the ith vertex 949 of the graph, the corresponding second entry in 946 l[i][4] = list of lists, the first entry of a list is 947 a primitive integer vector defining the direction 948 of an unbounded edge emerging from the ith vertex 949 of the graph, the corresponding second entry in 950 950 the list is the multiplicity of the unbounded edge 951 l[i][5] = a polynomial whose monomials mark the vertices 951 l[i][5] = a polynomial whose monomials mark the vertices 952 952 in the Newton polygon corresponding to the entries 953 in tp which take the common minimum at the ith 954 vertex -- if some coefficient a or b of the 955 linear polynomials in the input was negative, 953 in tp which take the common minimum at the ith 954 vertex -- if some coefficient a or b of the 955 linear polynomials in the input was negative, 956 956 then each monomial has to be shifted by 957 957 the values in l[size(l)][3] 958 l[size(l)][1] = list, the entries describe the boundary 958 l[size(l)][1] = list, the entries describe the boundary 959 959 points of the Newton subdivision 960 l[size(l)][2] = list, the entries are pairs of integer 960 l[size(l)][2] = list, the entries are pairs of integer 961 961 vectors defining an interior 962 962 edge of the Newton subdivision 963 l[size(l)][3] = intvec, the monmials occuring in l[i][5] 964 have to be shifted by this vector 965 in order to represent marked 963 l[size(l)][3] = intvec, the monmials occuring in l[i][5] 964 have to be shifted by this vector 965 in order to represent marked 966 966 vertices in the Newton polygon 967 NOTE: here the tropical polynomial is supposed to be the MINIMUM 968 of the linear forms in tp, unless the optional input #[1] 967 NOTE: here the tropical polynomial is supposed to be the MINIMUM 968 of the linear forms in tp, unless the optional input #[1] 969 969 is the string 'max' 970 970 EXAMPLE: example tropicalCurve; shows an example" … … 979 979 ERROR("The basering should have a global monomial ordering, e.g. ring r=(0,t),(x,y),dp;"); 980 980 } 981 // if you insert a single polynomial instead of an ideal 981 // if you insert a single polynomial instead of an ideal 982 982 // representing a tropicalised polynomial, 983 // then we compute first the tropicalisation of this polynomial 983 // then we compute first the tropicalisation of this polynomial 984 984 // -- this feature is not documented in the above help string 985 985 if (typeof(tp)=="poly") 986 986 { 987 // exclude the case that the basering has not precisely 987 // exclude the case that the basering has not precisely 988 988 // one parameter and two indeterminates 989 989 if ((npars(basering)!=1) or (nvars(basering)!=2)) 990 990 { 991 ERROR("The basering should have precisely one parameter and two indeterminates!"); 991 ERROR("The basering should have precisely one parameter and two indeterminates!"); 992 992 } 993 993 poly f=tp; … … 998 998 if (nvars(basering) != 2) 999 999 { 1000 ERROR("The basering should have precisely two indeterminates!"); 1001 } 1002 // -1) Exclude the pathological case that the defining 1000 ERROR("The basering should have precisely two indeterminates!"); 1001 } 1002 // -1) Exclude the pathological case that the defining 1003 1003 // tropical polynomial has only one term, 1004 1004 // so that the tropical variety is not defined. … … 1008 1008 intmat M[2][1]=0,0; 1009 1009 return(list(list(0,0,M,list(),detropicalise(tp[1])),list(list(leadexp(detropicalise(tp[1]))),list()))); 1010 } 1011 // 0) If the input was a list of linear polynomials, 1010 } 1011 // 0) If the input was a list of linear polynomials, 1012 1012 // then some coefficient of x or y can be negative, 1013 // i.e. the input corresponds to the tropical curve 1013 // i.e. the input corresponds to the tropical curve 1014 1014 // of a Laurent polynomial. In that case we should 1015 // add some ax+by, so that all coefficients are positive. 1015 // add some ax+by, so that all coefficients are positive. 1016 1016 // This does not change the tropical curve. 1017 // however, we have to save (a,b), since the Newton 1017 // however, we have to save (a,b), since the Newton 1018 1018 // polygone has to be shifted by (-a,-b). 1019 1019 poly aa,bb; // koeffizienten … … 1027 1027 { 1028 1028 bb=koeffizienten(tp[i],2); 1029 } 1029 } 1030 1030 } 1031 1031 if ((aa!=0) or (bb!=0)) … … 1036 1036 } 1037 1037 } 1038 // 1) compute the vertices of the tropical curve 1038 // 1) compute the vertices of the tropical curve 1039 1039 // defined by tp and the Newton subdivision 1040 1040 list vtp=verticesTropicalCurve(tp,#); 1041 // if vtp is empty, then the Newton polygone is just 1041 // if vtp is empty, then the Newton polygone is just 1042 1042 // a line segment and constitutes a bunch of lines 1043 1043 // which can be computed by bunchOfLines … … 1046 1046 return(bunchOfLines(tp)); 1047 1047 } 1048 // 2) store all vertices belonging to the ith part of the 1048 // 2) store all vertices belonging to the ith part of the 1049 1049 // Newton subdivision in the list vtp[i] as 4th entry, 1050 1050 // and store those, which are not corners of the ith subdivision polygon 1051 1051 // in vtp[i][6] 1052 poly nwt; 1052 poly nwt; 1053 1053 list boundaryNSD; // stores the boundary of a Newton subdivision 1054 intmat zwsp[2][1]; // used for intermediate storage 1054 intmat zwsp[2][1]; // used for intermediate storage 1055 1055 for (i=1;i<=size(vtp);i++) 1056 1056 { 1057 1057 k=1; 1058 nwt=vtp[i][3]; // the polynomial representing the 1058 nwt=vtp[i][3]; // the polynomial representing the 1059 1059 // ith part of the Newton subdivision 1060 // store the vertices of the ith part of the 1060 // store the vertices of the ith part of the 1061 1061 // Newton subdivision in the list newton 1062 list newton; 1062 list newton; 1063 1063 while (nwt!=0) 1064 1064 { … … 1067 1067 k++; 1068 1068 } 1069 boundaryNSD=findOrientedBoundary(newton);// a list of the vertices 1070 // of the Newton subdivision 1071 // as integer vectors (only those 1072 // on the boundary, and oriented 1069 boundaryNSD=findOrientedBoundary(newton);// a list of the vertices 1070 // of the Newton subdivision 1071 // as integer vectors (only those 1072 // on the boundary, and oriented 1073 1073 // clockwise) 1074 1074 vtp[i][4]=boundaryNSD[1]; 1075 1075 vtp[i][5]=boundaryNSD[2]; 1076 vtp[i][6]=zwsp; // the entries of the first row will denote to which 1077 // vertex the ith one is connected 1078 // and the entries of the second row will denote 1076 vtp[i][6]=zwsp; // the entries of the first row will denote to which 1077 // vertex the ith one is connected 1078 // and the entries of the second row will denote 1079 1079 //with which multiplicity 1080 1080 kill newton; // we kill the superflous list 1081 1081 } 1082 // 3) Next we build for each part of the Newton 1082 // 3) Next we build for each part of the Newton 1083 1083 // subdivision the list of all pairs of vertices on the 1084 1084 // boundary, which are involved, including those which are not corners … … 1097 1097 kill ipairs; 1098 1098 } 1099 // 4) Check for all pairs of verticies in the Newton diagram if they 1099 // 4) Check for all pairs of verticies in the Newton diagram if they 1100 1100 // occur in two different parts of the Newton subdivision 1101 int deleted; // if a pair occurs in two NSD, it can be removed 1101 int deleted; // if a pair occurs in two NSD, it can be removed 1102 1102 // from both - deleted is then set to 1 1103 list inneredges; // contains the list of all pairs contained in two NSD 1103 list inneredges; // contains the list of all pairs contained in two NSD 1104 1104 // - these are inner the edges of NSD 1105 1105 int ggt; 1106 1106 d=1; // counts the inner edges 1107 1107 for (i=1;i<=size(pairs)-1;i++) 1108 { 1108 { 1109 1109 for (j=i+1;j<=size(pairs);j++) 1110 1110 { … … 1113 1113 deleted=0; 1114 1114 for (l=size(pairs[j]);l>=1 and deleted==0;l--) 1115 { 1115 { 1116 1116 if (((pairs[i][k][1]==pairs[j][l][1]) and (pairs[i][k][2]==pairs[j][l][2])) or ((pairs[i][k][1]==pairs[j][l][2]) and (pairs[i][k][2]==pairs[j][l][1]))) 1117 1117 { … … 1119 1119 d++; 1120 1120 ggt=abs(gcd(pairs[i][k][1][1]-pairs[i][k][2][1],pairs[i][k][1][2]-pairs[i][k][2][2])); 1121 zwsp=j,ggt; // and it is recorded that the ith and jth 1121 zwsp=j,ggt; // and it is recorded that the ith and jth 1122 1122 // vertex should be connected with mult ggt 1123 1123 vtp[i][6]=intmatconcat(vtp[i][6],zwsp); 1124 1124 zwsp=i,ggt; 1125 1125 vtp[j][6]=intmatconcat(vtp[j][6],zwsp); 1126 pairs[i]=delete(pairs[i],k); // finally the pair is deleted 1126 pairs[i]=delete(pairs[i],k); // finally the pair is deleted 1127 1127 // from both sets of pairs 1128 1128 pairs[j]=delete(pairs[j],l); … … 1164 1164 } 1165 1165 } 1166 // 6.3) Order the vertices such that passing from one to the next we 1166 // 6.3) Order the vertices such that passing from one to the next we 1167 1167 // travel along the boundary of the Newton polytope clock wise. 1168 1168 boundaryNSD=findOrientedBoundary(vertices); 1169 1169 list orderedvertices=boundaryNSD[1]; 1170 1170 // 7) Find the unbounded edges emerging from a vertex in the tropical curve. 1171 // For this we check the remaining pairs for the ith NSD. 1171 // For this we check the remaining pairs for the ith NSD. 1172 1172 // Each pair is ordered according 1173 // to the order in which the vertices occur in orderedvertices. 1173 // to the order in which the vertices occur in orderedvertices. 1174 1174 // The direction of the 1175 // unbounded edge is then the outward pointing primitive normal 1175 // unbounded edge is then the outward pointing primitive normal 1176 1176 // vector to the vector 1177 1177 // pointing from the first vertex in a pair to the second one. … … 1183 1183 for (i=1;i<=size(pairs);i++) 1184 1184 { 1185 list ubedges; // stores the unbounded edges 1185 list ubedges; // stores the unbounded edges 1186 1186 k=1; // counts the unbounded edges 1187 1187 for (j=1;j<=size(pairs[i]);j++) 1188 1188 { 1189 1189 // computes the position of the vertices in the 1190 pos1=positionInList(orderedvertices,pairs[i][j][1]); 1190 pos1=positionInList(orderedvertices,pairs[i][j][1]); 1191 1191 // pair in the list orderedvertices 1192 pos2=positionInList(orderedvertices,pairs[i][j][2]); 1192 pos2=positionInList(orderedvertices,pairs[i][j][2]); 1193 1193 if (((pos1>pos2) and !((pos1==size(orderedvertices)) and (pos2==1))) or ((pos2==size(orderedvertices)) and (pos1==1))) // reorders them if necessary 1194 1194 { … … 1198 1198 } 1199 1199 // the vector pointing from vertex 1 in the pair to vertex2 1200 normalvector=pairs[i][j][2]-pairs[i][j][1]; 1200 normalvector=pairs[i][j][2]-pairs[i][j][1]; 1201 1201 ggt=gcd(normalvector[1],normalvector[2]); // the gcd of the entries 1202 1202 zw=normalvector[2]; // create the outward pointing normal vector … … 1230 1230 kill ubedges; 1231 1231 } 1232 // 8) Store the computed information for the ith part 1232 // 8) Store the computed information for the ith part 1233 1233 // of the NSD in the list graph[i]. 1234 1234 list graph,gr; … … 1236 1236 { 1237 1237 // the first coordinate of the ith vertex of the tropical curve 1238 gr[1]=vtp[i][1]; 1238 gr[1]=vtp[i][1]; 1239 1239 // the second coordinate of the ith vertex of the tropical curve 1240 gr[2]=vtp[i][2]; 1240 gr[2]=vtp[i][2]; 1241 1241 // to which vertices is the ith vertex of the tropical curve connected 1242 gr[3]=vtp[i][6]; 1243 // the directions unbounded edges emerging from the ith 1242 gr[3]=vtp[i][6]; 1243 // the directions unbounded edges emerging from the ith 1244 1244 // vertex of the trop. curve 1245 gr[4]=vtp[i][7]; 1246 // the vertices of the boundary of the ith part of the NSD 1247 gr[5]=vtp[i][3]; 1245 gr[4]=vtp[i][7]; 1246 // the vertices of the boundary of the ith part of the NSD 1247 gr[5]=vtp[i][3]; 1248 1248 graph[i]=gr; 1249 1249 } … … 1264 1264 } 1265 1265 } 1266 // 10) Finally store the boundary vertices and 1266 // 10) Finally store the boundary vertices and 1267 1267 // the inner edges as last entry in the list graph. 1268 1268 // This represents the NSD. … … 1281 1281 // the coordinates of the first vertex are graph[1][1],graph[1][2]; 1282 1282 graph[1][1],graph[1][2]; 1283 // the first vertex is connected to the vertices 1283 // the first vertex is connected to the vertices 1284 1284 // graph[1][3][1,1..ncols(graph[1][3])] 1285 1285 intmat M=graph[1][3]; 1286 1286 M[1,1..ncols(graph[1][3])]; 1287 // the weights of the edges to these vertices are 1287 // the weights of the edges to these vertices are 1288 1288 // graph[1][3][2,1..ncols(graph[1][3])] 1289 1289 M[2,1..ncols(graph[1][3])]; 1290 1290 // from the first vertex emerge size(graph[1][4]) unbounded edges 1291 1291 size(graph[1][4]); 1292 // the primitive integral direction vector of the first unbounded edge 1292 // the primitive integral direction vector of the first unbounded edge 1293 1293 // of the first vertex 1294 1294 graph[1][4][1][1]; 1295 1295 // the weight of the first unbounded edge of the first vertex 1296 1296 graph[1][4][1][2]; 1297 // the monomials which are part of the Newton subdivision of the first vertex 1297 // the monomials which are part of the Newton subdivision of the first vertex 1298 1298 graph[1][5]; 1299 // connecting the points in graph[size(graph)][1] we get 1299 // connecting the points in graph[size(graph)][1] we get 1300 1300 // the boundary of the Newton polytope 1301 1301 graph[size(graph)][1]; 1302 // an entry in graph[size(graph)][2] is a pair of points 1302 // an entry in graph[size(graph)][2] is a pair of points 1303 1303 // in the Newton polytope bounding an inner edge 1304 1304 graph[size(graph)][2][1]; … … 1309 1309 proc drawTropicalCurve (def f,list #) 1310 1310 "USAGE: drawTropicalCurve(f[,#]); f poly or list, # optional list 1311 ASSUME: f is list of linear polynomials of the form ax+by+c with 1312 integers a, b and a rational number c representing a tropical 1311 ASSUME: f is list of linear polynomials of the form ax+by+c with 1312 integers a, b and a rational number c representing a tropical 1313 1313 Laurent polynomial defining a tropical plane curve; 1314 alternatively f can be a polynomial in Q(t)[x,y] defining 1315 a tropical plane curve via the valuation map; 1316 the basering must have a global monomial ordering, two 1314 alternatively f can be a polynomial in Q(t)[x,y] defining 1315 a tropical plane curve via the valuation map; 1316 the basering must have a global monomial ordering, two 1317 1317 variables and up to one parameter! 1318 1318 RETURN: NONE 1319 NOTE: - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and 1320 /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four 1321 digit integer; 1319 NOTE: - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and 1320 /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four 1321 digit integer; 1322 1322 moreover it displays the tropical curve via kghostview; 1323 if you wish to remove all these files from /tmp, 1323 if you wish to remove all these files from /tmp, 1324 1324 call the procedure cleanTmp 1325 1325 @* - edges with multiplicity greater than one carry this multiplicity 1326 1326 @* - if # is empty, then the tropical curve is computed w.r.t. minimum, 1327 if #[1] is the string 'max', then it is computed w.r.t. maximum 1328 @* - if the last optional argument is 'onlytexfile' then only the 1329 latex file is produced; this option should be used if kghostview 1327 if #[1] is the string 'max', then it is computed w.r.t. maximum 1328 @* - if the last optional argument is 'onlytexfile' then only the 1329 latex file is produced; this option should be used if kghostview 1330 1330 is not installed on your system 1331 @* - note that lattice points in the Newton subdivision which are 1332 black correspond to markings of the marked subdivision, 1331 @* - note that lattice points in the Newton subdivision which are 1332 black correspond to markings of the marked subdivision, 1333 1333 while lattice points in grey are not marked 1334 1334 EXAMPLE: example drawTropicalCurve shows an example" … … 1348 1348 if (typeof(f)=="poly") 1349 1349 { 1350 // exclude the case that the basering has not precisely 1350 // exclude the case that the basering has not precisely 1351 1351 // one parameter and two indeterminates 1352 1352 if ((npars(basering)!=1) or (nvars(basering)!=2)) 1353 1353 { 1354 ERROR("The basering should have precisely one parameter and two indeterminates!"); 1354 ERROR("The basering should have precisely one parameter and two indeterminates!"); 1355 1355 } 1356 1356 // if the characteristic of the base field is not 0 then replace the base field … … 1371 1371 texf="\\mbox{\\tt The defining equation was not handed over!}"; 1372 1372 list graph=f; 1373 } 1373 } 1374 1374 else 1375 1375 { // write the tropical polynomial defined by f 1376 1376 if (size(#)==0) 1377 { 1377 { 1378 1378 texf="\\min\\{"; 1379 1379 } … … 1384 1384 for (j=1;j<=size(f);j++) 1385 1385 { 1386 texf=texf+texPolynomial(f[j]); 1386 texf=texf+texPolynomial(f[j]); 1387 1387 if (j<size(f)) 1388 1388 { … … 1393 1393 texf=texf+"\\}"; 1394 1394 } 1395 } 1395 } 1396 1396 list graph=tropicalCurve(f,#); // the graph of the tropical polynomial f 1397 1397 } … … 1411 1411 \\addtolength{\\topmargin}{-\\headheight} 1412 1412 \\addtolength{\\topmargin}{-\\topskip} 1413 \\setlength{\\textheight}{267mm} 1413 \\setlength{\\textheight}{267mm} 1414 1414 \\addtolength{\\textheight}{\\topskip} 1415 1415 \\addtolength{\\textheight}{-\\footskip} 1416 1416 \\addtolength{\\textheight}{-30pt} 1417 \\setlength{\\oddsidemargin}{-1in} 1417 \\setlength{\\oddsidemargin}{-1in} 1418 1418 \\addtolength{\\oddsidemargin}{20mm} 1419 1419 \\setlength{\\evensidemargin}{\\oddsidemargin} 1420 \\setlength{\\textwidth}{170mm} 1420 \\setlength{\\textwidth}{170mm} 1421 1421 1422 1422 \\begin{document} 1423 1423 \\parindent0cm 1424 1424 \\begin{center} 1425 \\large\\bf The Tropicalisation of 1425 \\large\\bf The Tropicalisation of 1426 1426 1427 1427 \\bigskip … … 1449 1449 1450 1450 \\begin{center} 1451 "+texDrawNewtonSubdivision(graph,#)+" 1451 "+texDrawNewtonSubdivision(graph,#)+" 1452 1452 \\end{center} 1453 1453 \\end{document}"; … … 1456 1456 int rdnum=random(1000,9999); 1457 1457 write(":w /tmp/tropicalcurve"+string(rdnum)+".tex",TEXBILD); 1458 system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log; /bin/rm tropicalcurve"+string(rdnum)+".aux; /bin/rm tropicalcurve"+string(rdnum)+".ps?; /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &"); 1458 system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log; /bin/rm tropicalcurve"+string(rdnum)+".aux; /bin/rm tropicalcurve"+string(rdnum)+".ps?; /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &"); 1459 1459 } 1460 1460 else … … 1483 1483 proc drawNewtonSubdivision (def f,list #) 1484 1484 "USAGE: drawTropicalCurve(f[,#]); f poly, # optional list 1485 ASSUME: f is list of linear polynomials of the form ax+by+c with integers 1486 a, b and a rational number c representing a tropical Laurent 1485 ASSUME: f is list of linear polynomials of the form ax+by+c with integers 1486 a, b and a rational number c representing a tropical Laurent 1487 1487 polynomial defining a tropical plane curve; 1488 alternatively f can be a polynomial in Q(t)[x,y] defining a tropical 1489 plane curve via the valuation map; 1490 the basering must have a global monomial ordering, two variables 1488 alternatively f can be a polynomial in Q(t)[x,y] defining a tropical 1489 plane curve via the valuation map; 1490 the basering must have a global monomial ordering, two variables 1491 1491 and up to one parameter! 1492 1492 RETURN: NONE 1493 NOTE: - the procedure creates the files /tmp/newtonsubdivisionNUMBER.tex, 1494 and /tmp/newtonsubdivisionNUMBER.ps, where NUMBER is a random 1495 four digit integer; 1493 NOTE: - the procedure creates the files /tmp/newtonsubdivisionNUMBER.tex, 1494 and /tmp/newtonsubdivisionNUMBER.ps, where NUMBER is a random 1495 four digit integer; 1496 1496 moreover it desplays the tropical curve defined by f via kghostview; 1497 if you wish to remove all these files from /tmp, call the procedure 1497 if you wish to remove all these files from /tmp, call the procedure 1498 1498 cleanTmp; 1499 @* if # is empty, then the tropical curve is computed w.r.t. minimum, 1500 if #[1] is the string 'max', then it is computed w.r.t. maximum 1501 @* - note that lattice points in the Newton subdivision which are black 1502 correspond to markings of the marked subdivision, while lattice 1499 @* if # is empty, then the tropical curve is computed w.r.t. minimum, 1500 if #[1] is the string 'max', then it is computed w.r.t. maximum 1501 @* - note that lattice points in the Newton subdivision which are black 1502 correspond to markings of the marked subdivision, while lattice 1503 1503 points in grey are not marked 1504 1504 EXAMPLE: example drawNewtonSubdivision; shows an example" … … 1514 1514 { // write the tropical polynomial defined by f 1515 1515 if (size(#)==0) 1516 { 1516 { 1517 1517 texf="\\min\\{"; 1518 1518 } … … 1523 1523 for (j=1;j<=size(f);j++) 1524 1524 { 1525 texf=texf+texPolynomial(f[j]); 1525 texf=texf+texPolynomial(f[j]); 1526 1526 if (j<size(f)) 1527 1527 { … … 1532 1532 texf=texf+"\\}"; 1533 1533 } 1534 } 1534 } 1535 1535 list graph=tropicalCurve(f,#); // the graph of the tropical polynomial f 1536 1536 } … … 1540 1540 \\parindent0cm 1541 1541 \\begin{center} 1542 \\large\\bf The Newtonsubdivison of 1542 \\large\\bf The Newtonsubdivison of 1543 1543 \\begin{displaymath} 1544 1544 f="+texf+" … … 1548 1548 1549 1549 \\begin{center} 1550 "+texDrawNewtonSubdivision(graph)+ 1550 "+texDrawNewtonSubdivision(graph)+ 1551 1551 " \\end{center} 1552 1552 … … 1554 1554 int rdnum=random(1000,9999); 1555 1555 write(":w /tmp/newtonsubdivision"+string(rdnum)+".tex",TEXBILD); 1556 system("sh","cd /tmp; latex /tmp/newtonsubdivision"+string(rdnum)+".tex; dvips /tmp/newtonsubdivision"+string(rdnum)+".dvi -o; /bin/rm newtonsubdivision"+string(rdnum)+".log; /bin/rm newtonsubdivision"+string(rdnum)+".aux; /bin/rm newtonsubdivision"+string(rdnum)+".ps?; /bin/rm newtonsubdivision"+string(rdnum)+".dvi; kghostview newtonsubdivision"+string(rdnum)+".ps &"); 1556 system("sh","cd /tmp; latex /tmp/newtonsubdivision"+string(rdnum)+".tex; dvips /tmp/newtonsubdivision"+string(rdnum)+".dvi -o; /bin/rm newtonsubdivision"+string(rdnum)+".log; /bin/rm newtonsubdivision"+string(rdnum)+".aux; /bin/rm newtonsubdivision"+string(rdnum)+".ps?; /bin/rm newtonsubdivision"+string(rdnum)+".dvi; kghostview newtonsubdivision"+string(rdnum)+".ps &"); 1557 1557 // return(TEXBILD); 1558 1558 } … … 1579 1579 proc tropicalJInvariant (def f,list #) 1580 1580 "USAGE: tropicalJInvariant(f[,#]); f poly or list, # optional list 1581 ASSUME: f is list of linear polynomials of the form ax+by+c with integers 1582 a, b and a rational number c representing a tropical Laurent 1581 ASSUME: f is list of linear polynomials of the form ax+by+c with integers 1582 a, b and a rational number c representing a tropical Laurent 1583 1583 polynomial defining a tropical plane curve; 1584 alternatively f can be a polynomial in Q(t)[x,y] defining a 1585 tropical plane curve via the valuation map; 1586 @* the basering must have a global monomial ordering, two variables 1584 alternatively f can be a polynomial in Q(t)[x,y] defining a 1585 tropical plane curve via the valuation map; 1586 @* the basering must have a global monomial ordering, two variables 1587 1587 and up to one parameter! 1588 RETURN: number, if the graph underlying the tropical curve has precisely 1589 one loop then its weighted lattice length is returned, 1588 RETURN: number, if the graph underlying the tropical curve has precisely 1589 one loop then its weighted lattice length is returned, 1590 1590 otherwise the result will be -1 1591 NOTE: - if the tropical curve is elliptic and its embedded graph has 1592 precisely one loop, then the weigthed lattice length of 1591 NOTE: - if the tropical curve is elliptic and its embedded graph has 1592 precisely one loop, then the weigthed lattice length of 1593 1593 the loop is its tropical j-invariant 1594 @* - the procedure checks if the embedded graph of the tropical 1595 curve has genus one, but it does NOT check if the loop can 1596 be resolved, so that the curve is not a proper tropical 1597 elliptic curve 1598 @* - if the embedded graph of a tropical elliptic curve has more 1599 than one loop, then all but one can be resolved, but this is 1600 not observed by this procedure, so it will not compute 1594 @* - the procedure checks if the embedded graph of the tropical 1595 curve has genus one, but it does NOT check if the loop can 1596 be resolved, so that the curve is not a proper tropical 1597 elliptic curve 1598 @* - if the embedded graph of a tropical elliptic curve has more 1599 than one loop, then all but one can be resolved, but this is 1600 not observed by this procedure, so it will not compute 1601 1601 the j-invariant 1602 1602 @* - if # is empty, then the tropical curve is computed w.r.t. minimum, 1603 if #[1] is the string 'max', then it is computed w.r.t. maximum 1604 @* - the tropicalJInvariant of a plane tropical cubic is the 1605 'cycle length' of the cubic as introduced in the paper: 1606 Eric Katz, Hannah Markwig, Thomas Markwig: The j-invariant 1603 if #[1] is the string 'max', then it is computed w.r.t. maximum 1604 @* - the tropicalJInvariant of a plane tropical cubic is the 1605 'cycle length' of the cubic as introduced in the paper: 1606 Eric Katz, Hannah Markwig, Thomas Markwig: The j-invariant 1607 1607 of a cubic tropical plane curve. 1608 1608 EXAMPLE: example tropicalJInvariant; shows an example" … … 1618 1618 { 1619 1619 if (typeof(f[1])=="list") 1620 { 1620 { 1621 1621 list graph=f; 1622 1622 } … … 1630 1630 { 1631 1631 ERROR("This is no valid input."); 1632 } 1632 } 1633 1633 } 1634 1634 } … … 1647 1647 genus=-genus/2; // we have counted each bounded edge twice 1648 1648 genus=genus+size(graph); // the genus is 1-#bounded_edges+#vertices 1649 // 3) if the embedded graph has not genus one, 1649 // 3) if the embedded graph has not genus one, 1650 1650 // we cannot compute the j-invariant 1651 1651 if(genus!=1) … … 1659 1659 else 1660 1660 { 1661 intmat nullmat[2][1]; // used to set 1662 // 4) find a vertex which has only one bounded edge, 1663 // if none exists zero is returned, 1661 intmat nullmat[2][1]; // used to set 1662 // 4) find a vertex which has only one bounded edge, 1663 // if none exists zero is returned, 1664 1664 // otherwise the number of the vertex in the list graph 1665 int nonloopvertex=findNonLoopVertex(graph); 1665 int nonloopvertex=findNonLoopVertex(graph); 1666 1666 int dv; //checks if vert. has been found to which nonloopvertex is connected 1667 intmat delvert; // takes for a moment graph[i][3] of the vertex 1667 intmat delvert; // takes for a moment graph[i][3] of the vertex 1668 1668 // to which nonloopvertex is connected 1669 // 5) delete successively vertices in the graph which 1669 // 5) delete successively vertices in the graph which 1670 1670 // have only one bounded edge 1671 1671 while (nonloopvertex>0) 1672 1672 { 1673 // find the only vertex to which the nonloopvertex 1673 // find the only vertex to which the nonloopvertex 1674 1674 // is connected, when it is found 1675 1675 // delete the connection in graph[i][3] and set dv=1 … … 1684 1684 { 1685 1685 delvert=graph[i][3]; 1686 delvert=intmatcoldelete(delvert,j); // delete the connection (note 1686 delvert=intmatcoldelete(delvert,j); // delete the connection (note 1687 1687 // there must have been two!) 1688 1688 dv=1; … … 1692 1692 } 1693 1693 } 1694 graph[nonloopvertex][3]=nullmat; // the only connection of nonloopvertex 1694 graph[nonloopvertex][3]=nullmat; // the only connection of nonloopvertex 1695 1695 // is killed 1696 nonloopvertex=findNonLoopVertex(graph); // find the next vertex 1696 nonloopvertex=findNonLoopVertex(graph); // find the next vertex 1697 1697 // which has only one edge 1698 1698 } … … 1700 1700 intvec loop,weights; // encodes the loop and the edges 1701 1701 i=1; 1702 // start by finding some vertex which belongs to the loop 1703 while (loop==0) 1702 // start by finding some vertex which belongs to the loop 1703 while (loop==0) 1704 1704 { 1705 1705 // if graph[i][3] of a vertex in the loop has 2 columns, all others have 1 1706 if (ncols(graph[i][3])==1) 1706 if (ncols(graph[i][3])==1) 1707 1707 { 1708 1708 i++; … … 1710 1710 else 1711 1711 { 1712 loop[1]=i; // a starting vertex is found 1713 loop[2]=graph[i][3][1,1]; // it is connected to vertex with this number 1712 loop[1]=i; // a starting vertex is found 1713 loop[2]=graph[i][3][1,1]; // it is connected to vertex with this number 1714 1714 weights[2]=graph[i][3][2,1]; // and the edge has this weight 1715 1715 } … … 1719 1719 while (j!=i) // the loop ends with the same vertex with which it starts 1720 1720 { 1721 // the first row of graph[j][3] has two entries 1721 // the first row of graph[j][3] has two entries 1722 1722 // corresponding to the two vertices 1723 // to which the active vertex j is connected; 1723 // to which the active vertex j is connected; 1724 1724 // one is loop[k-1], i.e. the one which 1725 1725 // precedes j in the loop; we have to choose the other one 1726 if (graph[j][3][1,1]==loop[k-1]) 1726 if (graph[j][3][1,1]==loop[k-1]) 1727 1727 { 1728 1728 loop[k+1]=graph[j][3][1,2]; … … 1735 1735 } 1736 1736 j=loop[k+1]; // set loop[k+1] the new active vertex 1737 k++; 1738 } 1737 k++; 1738 } 1739 1739 // 7) compute for each edge in the loop the lattice length 1740 poly xcomp,ycomp; // the x- and y-components of the vectors 1740 poly xcomp,ycomp; // the x- and y-components of the vectors 1741 1741 // connecting two vertices of the loop 1742 number nenner; // the product of the denominators of 1742 number nenner; // the product of the denominators of 1743 1743 // the x- and y-components 1744 1744 number jinvariant; // the j-invariant 1745 int eins,zwei,ggt; 1745 int eins,zwei,ggt; 1746 1746 for (i=1;i<=size(loop)-1;i++) // compute the lattice length for each edge 1747 1747 { 1748 xcomp=graph[loop[i]][1]-graph[loop[i+1]][1]; 1749 ycomp=graph[loop[i]][2]-graph[loop[i+1]][2]; 1748 xcomp=graph[loop[i]][1]-graph[loop[i+1]][1]; 1749 ycomp=graph[loop[i]][2]-graph[loop[i+1]][2]; 1750 1750 nenner=denominator(leadcoef(xcomp))*denominator(leadcoef(ycomp)); 1751 execute("eins="+string(numerator(leadcoef(nenner*xcomp)))+";"); 1752 execute("zwei="+string(numerator(leadcoef(nenner*ycomp)))+";"); 1751 execute("eins="+string(numerator(leadcoef(nenner*xcomp)))+";"); 1752 execute("zwei="+string(numerator(leadcoef(nenner*ycomp)))+";"); 1753 1753 ggt=gcd(eins,zwei); // the lattice length is the "gcd" 1754 1754 // of the x-component and the y-component 1755 jinvariant=jinvariant+ggt/(nenner*weights[i+1]); // divided by the 1755 jinvariant=jinvariant+ggt/(nenner*weights[i+1]); // divided by the 1756 1756 // weight of the edge 1757 1757 } 1758 return(jinvariant); 1758 return(jinvariant); 1759 1759 } 1760 1760 } … … 1770 1770 // the curve can have arbitrary degree 1771 1771 tropicalJInvariant(t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2); 1772 // the procedure does not realise, if the embedded graph of the tropical 1772 // the procedure does not realise, if the embedded graph of the tropical 1773 1773 // curve has a loop that can be resolved 1774 1774 tropicalJInvariant(1+x+y+xy+tx2y+txy2); 1775 1775 // but it does realise, if the curve has no loop at all ... 1776 1776 tropicalJInvariant(x+y+1); 1777 // or if the embedded graph has more than one loop - even if only one 1777 // or if the embedded graph has more than one loop - even if only one 1778 1778 // cannot be resolved 1779 1779 tropicalJInvariant(1+x+y+xy+tx2y+txy2+t3x5+t3y5+tx2y2+t2xy4+t2yx4); … … 1784 1784 proc weierstrassForm (poly f,list #) 1785 1785 "USAGE: weierstrassForm(wf[,#]); wf poly, # list 1786 ASSUME: wf is a a polynomial whose Newton polygon has precisely one 1787 interior lattice point, so that it defines an elliptic curve 1786 ASSUME: wf is a a polynomial whose Newton polygon has precisely one 1787 interior lattice point, so that it defines an elliptic curve 1788 1788 on the toric surface corresponding to the Newton polygon 1789 1789 RETURN: poly, the Weierstrass normal form of the polynomial … … 1791 1791 to Fernando Rodriguez Villegas, villegas@math.utexas.edu 1792 1792 @* - the characteristic of the base field should not be 2 or 3 1793 @* - if an additional argument # is given, a simplified Weierstrass 1793 @* - if an additional argument # is given, a simplified Weierstrass 1794 1794 form is computed 1795 1795 EXAMPLE: example weierstrassForm; shows an example" … … 1852 1852 1853 1853 proc jInvariant (poly f,list #) 1854 "USAGE: jInvariant(f[,#]); f poly, # list 1855 ASSUME: - f is a a polynomial whose Newton polygon has precisely one 1856 interior lattice point, so that it defines an elliptic curve 1854 "USAGE: jInvariant(f[,#]); f poly, # list 1855 ASSUME: - f is a a polynomial whose Newton polygon has precisely one 1856 interior lattice point, so that it defines an elliptic curve 1857 1857 on the toric surface corresponding to the Newton polygon 1858 @* - it the optional argument # is present the base field should be 1859 Q(t) and the optional argument should be one of the following 1858 @* - it the optional argument # is present the base field should be 1859 Q(t) and the optional argument should be one of the following 1860 1860 strings: 1861 @* 'ord' : then the return value is of type integer, 1861 @* 'ord' : then the return value is of type integer, 1862 1862 namely the order of the j-invariant 1863 @* 'split' : then the return value is a list of two polynomials, 1863 @* 'split' : then the return value is a list of two polynomials, 1864 1864 such that the quotient of these two is the j-invariant 1865 1865 RETURN: poly, the j-invariant of the elliptic curve defined by poly 1866 NOTE: the characteristic of the base field should not be 2 or 3, 1866 NOTE: the characteristic of the base field should not be 2 or 3, 1867 1867 unless the input is a plane cubic 1868 1868 EXAMPLE: example jInvariant; shows an example" … … 1890 1890 echo=2; 1891 1891 ring r=(0,t),(x,y),dp; 1892 // jInvariant computes the j-invariant of a cubic 1892 // jInvariant computes the j-invariant of a cubic 1893 1893 jInvariant(x+y+x2y+y3+1/t*xy); 1894 // if the ground field has one parameter t, then we can instead 1894 // if the ground field has one parameter t, then we can instead 1895 1895 // compute the order of the j-invariant 1896 1896 jInvariant(x+y+x2y+y3+1/t*xy,"ord"); … … 1900 1900 poly h=x22y11+x19y10+x17y9+x16y9+x12y7+x9y6+x7y5+x2y3+x14y8; 1901 1901 // its j-invariant is 1902 jInvariant(h); 1902 jInvariant(h); 1903 1903 } 1904 1904 … … 1919 1919 @* l[6] = a list containing the vertices of the tropical conic f 1920 1920 @* l[7] = a list containing lists with vertices of the tangents 1921 @* l[8] = a string which contains the latex-code to draw the 1921 @* l[8] = a string which contains the latex-code to draw the 1922 1922 tropical conic and its tropicalised tangents 1923 1923 @* l[9] = if # is non-empty, this is the same data for the dual … … 1943 1943 ring LINRING=(0,t),(x,y,a(1..6)),lp; 1944 1944 list points=imap(BASERING,points); 1945 ideal I; // the ideal will contain the linear equations given by the conic 1945 ideal I; // the ideal will contain the linear equations given by the conic 1946 1946 // and the points 1947 1947 for (i=1;i<=5;i++) … … 1964 1964 ring tRING=0,t,ls; 1965 1965 list pointdenom=imap(BASERING,pointdenom); 1966 list pointnum=imap(BASERING,pointnum); 1966 list pointnum=imap(BASERING,pointnum); 1967 1967 intvec pointcoordinates; 1968 1968 for (i=1;i<=size(pointdenom);i++) … … 2040 2040 We consider the concic through the following five points: 2041 2041 \\begin{displaymath} 2042 "; 2042 "; 2043 2043 string texf=texDrawTropical(graphf,list("",scalefactor)); 2044 2044 for (i=1;i<=size(points);i++) … … 2077 2077 \\end{document}"; 2078 2078 setring BASERING; 2079 // If # non-empty, compute the dual conic and the tangents 2080 // through the dual points 2079 // If # non-empty, compute the dual conic and the tangents 2080 // through the dual points 2081 2081 // corresponding to the tangents of the given conic. 2082 2082 if (size(#)>0) 2083 2083 { 2084 2084 list dualpoints; 2085 for (i=1;i<=size(points);i++) 2085 for (i=1;i<=size(points);i++) 2086 2086 { 2087 2087 dualpoints[i]=list(leadcoef(tangents[i])/substitute(tangents[i],x,0,y,0),leadcoef(tangents[i]-lead(tangents[i]))/substitute(tangents[i],x,0,y,0)); … … 2107 2107 // conic[2] is the equation of the conic f passing through the five points 2108 2108 conic[2]; 2109 // conic[3] is a list containing the equations of the tangents 2109 // conic[3] is a list containing the equations of the tangents 2110 2110 // through the five points 2111 2111 conic[3]; 2112 2112 // conic[4] is an ideal representing the tropicalisation of the conic f 2113 2113 conic[4]; 2114 // conic[5] is a list containing the tropicalisation 2114 // conic[5] is a list containing the tropicalisation 2115 2115 // of the five tangents in conic[3] 2116 2116 conic[5]; 2117 // conic[6] is a list containing the vertices of the tropical conic 2117 // conic[6] is a list containing the vertices of the tropical conic 2118 2118 conic[6]; 2119 2119 // conic[7] is a list containing the vertices of the five tangents 2120 2120 conic[7]; 2121 // conic[8] contains the latex code to draw the tropical conic and 2122 // its tropicalised tangents; it can written in a file, processed and 2123 // displayed via kghostview 2124 write(":w /tmp/conic.tex",conic[8]); 2125 system("sh","cd /tmp; latex /tmp/conic.tex; dvips /tmp/conic.dvi -o; 2121 // conic[8] contains the latex code to draw the tropical conic and 2122 // its tropicalised tangents; it can written in a file, processed and 2123 // displayed via kghostview 2124 write(":w /tmp/conic.tex",conic[8]); 2125 system("sh","cd /tmp; latex /tmp/conic.tex; dvips /tmp/conic.dvi -o; 2126 2126 kghostview conic.ps &"); 2127 // with an optional argument the same information for the dual conic is computed 2127 // with an optional argument the same information for the dual conic is computed 2128 2128 // and saved in conic[9] 2129 2129 conic=conicWithTangents(points,1); 2130 2130 conic[9][2]; // the equation of the dual conic 2131 2131 } 2132 2132 2133 2133 /////////////////////////////////////////////////////////////////////////////// 2134 2134 /// Procedures concerned with tropicalisation … … 2139 2139 ASSUME: f is a polynomial in Q(t)[x_1,...,x_n] 2140 2140 RETURN: list, the linear forms of the tropicalisation of f 2141 NOTE: if # is empty, then the valuation of t will be 1, 2142 @* if # is the string 'max' it will be -1; 2143 @* the latter supposes that we consider the maximum of the 2141 NOTE: if # is empty, then the valuation of t will be 1, 2142 @* if # is the string 'max' it will be -1; 2143 @* the latter supposes that we consider the maximum of the 2144 2144 computed linear forms, the former that we consider their minimum 2145 2145 EXAMPLE: example tropicalise; shows an example" … … 2164 2164 { 2165 2165 tropicalf[i]=tropicalf[i]+exp[j]*var(j); 2166 } 2166 } 2167 2167 f=f-lead(f); 2168 2168 } … … 2204 2204 ///////////////////////////////////////////////////////////////////////// 2205 2205 2206 proc tInitialForm (poly f, intvec w) 2206 proc tInitialForm (poly f, intvec w) 2207 2207 "USAGE: tInitialForm(f,w); f a polynomial, w an integer vector 2208 2208 ASSUME: f is a polynomial in Q[t,x_1,...,x_n] and w=(w_0,w_1,...,w_n) 2209 2209 RETURN: poly, the t-initialform of f(t,x) w.r.t. w evaluated at t=1 2210 NOTE: the t-initialform is the sum of the terms with MAXIMAL 2210 NOTE: the t-initialform is the sum of the terms with MAXIMAL 2211 2211 weighted order w.r.t. w 2212 2212 EXAMPLE: example tInitialForm; shows an example" … … 2218 2218 // do the same for the remaining part of f and compare the results 2219 2219 // keep only the smallest ones 2220 int vglgewicht; 2221 f=f-lead(f); 2220 int vglgewicht; 2221 f=f-lead(f); 2222 2222 while (f!=0) 2223 2223 { … … 2234 2234 initialf=initialf+lead(f); 2235 2235 } 2236 } 2236 } 2237 2237 f=f-lead(f); 2238 2238 } … … 2254 2254 proc tInitialIdeal (ideal i,intvec w,list #) 2255 2255 "USAGE: tInitialIdeal(i,w); i ideal, w intvec 2256 ASSUME: i is an ideal in Q[t,x_1,...,x_n] and w=(w_0,...,w_n) 2256 ASSUME: i is an ideal in Q[t,x_1,...,x_n] and w=(w_0,...,w_n) 2257 2257 RETURN: ideal ini, the t-initial ideal of i with respect to w" 2258 2258 { 2259 2259 // THE PROCEDURE WILL BE CALLED FROM OTHER PROCEDURES INSIDE THIS LIBRARY; 2260 // IN THIS CASE THE VARIABLE t WILL INDEED BE THE LAST VARIABLE INSTEAD OF 2260 // IN THIS CASE THE VARIABLE t WILL INDEED BE THE LAST VARIABLE INSTEAD OF 2261 2261 // THE FIRST, 2262 2262 // AND WE THEREFORE HAVE TO MOVE IT BACK TO THE FRONT! … … 2282 2282 // ... and compute a standard basis with 2283 2283 // respect to the homogenised ordering defined by w. Since the generators 2284 // of i will be homogeneous it we can instead take the ordering wp 2285 // with the weightvector (0,w) replaced by (M,...,M)+(0,w) for some 2286 // large M, so that all entries are positive 2287 int M=-minInIntvec(w)[1]+1; // find M such that w[j]+M is 2284 // of i will be homogeneous it we can instead take the ordering wp 2285 // with the weightvector (0,w) replaced by (M,...,M)+(0,w) for some 2286 // large M, so that all entries are positive 2287 int M=-minInIntvec(w)[1]+1; // find M such that w[j]+M is 2288 2288 // strictly positive for all j 2289 2289 intvec whomog=M; … … 2293 2293 } 2294 2294 execute("ring WEIGHTRING=("+charstr(basering)+"),("+varstr(basering)+"),(wp("+string(whomog)+"));"); 2295 // map i to the new ring and compute a GB of i, then dehomogenise i, 2296 // so that we can be sure, that the 2295 // map i to the new ring and compute a GB of i, then dehomogenise i, 2296 // so that we can be sure, that the 2297 2297 // initial forms of the generators generate the initial ideal 2298 2298 ideal i=subst(groebner(imap(HOMOGRING,i)),@s,1); … … 2548 2548 proc texDrawBasic (list texdraw) 2549 2549 "USAGE: texDrawBasic(texdraw); list texdraw 2550 ASSUME: texdraw is a list of strings representing texdraw commands 2551 (as produced by texDrawTropical) which should be embedded into 2550 ASSUME: texdraw is a list of strings representing texdraw commands 2551 (as produced by texDrawTropical) which should be embedded into 2552 2552 a texdraw environment 2553 2553 RETURN: string, a texdraw environment enclosing the input … … 2569 2569 \\end{texdraw}"; 2570 2570 return(texdrawtp); 2571 } 2571 } 2572 2572 example 2573 2573 { … … 2586 2586 ASSUME: graph is the output of tropicalCurve 2587 2587 RETURN: string, the texdraw code of the tropical plane curve encoded by graph 2588 NOTE: - if the list # is non-empty, the first entry should be a string; 2589 if this string is 'max', then the tropical curve is considered 2588 NOTE: - if the list # is non-empty, the first entry should be a string; 2589 if this string is 'max', then the tropical curve is considered 2590 2590 with respect to the maximum 2591 @* - the procedure computes a scalefactor for the texdraw command which 2592 should help to display the curve in the right way; this may, 2593 however, be a bad idea if several texDrawTropical outputs are 2594 put together to form one image; the scalefactor can be prescribed 2591 @* - the procedure computes a scalefactor for the texdraw command which 2592 should help to display the curve in the right way; this may, 2593 however, be a bad idea if several texDrawTropical outputs are 2594 put together to form one image; the scalefactor can be prescribed 2595 2595 by the further optional entry of type poly 2596 @* - one can add a string as last opional argument to the list #; 2597 it can be used to insert further texdraw commands (e.g. to have 2598 a lighter image as when called from inside conicWithTangents); 2596 @* - one can add a string as last opional argument to the list #; 2597 it can be used to insert further texdraw commands (e.g. to have 2598 a lighter image as when called from inside conicWithTangents); 2599 2599 @* - the list # is optional and may as well be empty 2600 2600 EXAMPLE: example texDrawTropical; shows an example" 2601 2601 { 2602 // there is one possible argument, which is not explained to the user; 2602 // there is one possible argument, which is not explained to the user; 2603 2603 // it is used to draw several tropical curves; there we want to suppress 2604 // the weights sometimes; this is done by handing over the string "noweights" 2605 int i,j; 2604 // the weights sometimes; this is done by handing over the string "noweights" 2605 int i,j; 2606 2606 int noweights; // controls if weights should be drawn or not 2607 2607 for (i=1;i<=size(#);i++) … … 2616 2616 } 2617 2617 } 2618 // deal first with the pathological case that 2618 // deal first with the pathological case that 2619 2619 // the input polynomial was a monomial 2620 // and does therefore not define a tropical curve, 2621 // and check if the Newton polytope is 2620 // and does therefore not define a tropical curve, 2621 // and check if the Newton polytope is 2622 2622 // a line segment so that the curve defines a bunch of lines 2623 2623 int bunchoflines; 2624 2624 // if the boundary of the Newton polytope consists of a single point 2625 if (size(graph[size(graph)][1])==1) 2625 if (size(graph[size(graph)][1])==1) 2626 2626 { 2627 2627 return(string()); … … 2636 2636 } 2637 2637 // then the Newton polytope is a line segment 2638 if ((size(graph[size(graph)][1])-size(syz(M)))==1) 2638 if ((size(graph[size(graph)][1])-size(syz(M)))==1) 2639 2639 { 2640 2640 bunchoflines=1; … … 2667 2667 int nachkomma=2; // number of decimals for the scalefactor 2668 2668 number sf=1; // correction factor for scalefactor 2669 // if no scale factor was handed over to the procedure, use the 2669 // if no scale factor was handed over to the procedure, use the 2670 2670 // one computed by minScaleFactor; 2671 2671 // check first if a scale factor has been handed over … … 2675 2675 { 2676 2676 // if the scalefactor as polynomial was handed over, get it 2677 if (typeof(#[i])=="poly") 2677 if (typeof(#[i])=="poly") 2678 2678 { 2679 2679 poly scalefactor=#[2]; 2680 2680 scfpresent=1; 2681 2681 } 2682 // if the procedure is called for drawing more than one tropical curve 2682 // if the procedure is called for drawing more than one tropical curve 2683 2683 // then scalefactor,sf,nachkomma,minx,miny,maxx,maxy,centerx,centery 2684 2684 // has been handed over to the procedure … … 2697 2697 } 2698 2698 i++; 2699 } 2699 } 2700 2700 // if no scalefactor was handed over we take the one computed in SCF 2701 2701 if (scfpresent==0) … … 2712 2712 { 2713 2713 // if the curve is a bunch of lines no vertex has to be drawn 2714 if (bunchoflines==0) 2714 if (bunchoflines==0) 2715 2715 { 2716 2716 texdrawtp=texdrawtp+" … … 2718 2718 } 2719 2719 // draw the bounded edges emerging from the ith vertex 2720 for (j=1;j<=ncols(graph[i][3]);j++) 2721 { 2722 // don't draw it twice - and if there is only one vertex 2720 for (j=1;j<=ncols(graph[i][3]);j++) 2721 { 2722 // don't draw it twice - and if there is only one vertex 2723 2723 // and graph[i][3][1,1] is thus 0, nothing is done 2724 if (i<graph[i][3][1,j]) 2725 { 2724 if (i<graph[i][3][1,j]) 2725 { 2726 2726 texdrawtp=texdrawtp+" 2727 2727 \\move ("+decimal((graph[i][1]-centerx)/sf)+" "+decimal((graph[i][2]-centery)/sf)+") \\lvec ("+decimal((graph[graph[i][3][1,j]][1]-centerx)/sf)+" "+decimal((graph[graph[i][3][1,j]][2]-centery)/sf)+")"; … … 2736 2736 // draw the unbounded edges emerging from the ith vertex 2737 2737 // they should not be too long 2738 for (j=1;j<=size(graph[i][4]);j++) 2739 { 2738 for (j=1;j<=size(graph[i][4]);j++) 2739 { 2740 2740 relxy=shorten(list(decimal((3*graph[i][4][j][1][1]/scalefactor)*sf),decimal((3*graph[i][4][j][1][2]/scalefactor)*sf),string(5*sf/2))); 2741 2741 texdrawtp=texdrawtp+" … … 2836 2836 // check if scaling is necessary 2837 2837 if (scalefactor<1) 2838 { 2838 { 2839 2839 subdivision=subdivision+" 2840 2840 \\relunitscale"+ decimal(scalefactor); … … 2844 2844 { 2845 2845 subdivision=subdivision+" 2846 \\move ("+string(boundary[i][1])+" "+string(boundary[i][2])+") 2846 \\move ("+string(boundary[i][1])+" "+string(boundary[i][2])+") 2847 2847 \\lvec ("+string(boundary[i+1][1])+" "+string(boundary[i+1][2])+")"; 2848 } 2848 } 2849 2849 subdivision=subdivision+" 2850 \\move ("+string(boundary[size(boundary)][1])+" "+string(boundary[size(boundary)][2])+") 2850 \\move ("+string(boundary[size(boundary)][1])+" "+string(boundary[size(boundary)][2])+") 2851 2851 \\lvec ("+string(boundary[1][1])+" "+string(boundary[1][2])+") 2852 2852 … … 2855 2855 { 2856 2856 subdivision=subdivision+" 2857 \\move ("+string(inneredges[i][1][1])+" "+string(inneredges[i][1][2])+") 2857 \\move ("+string(inneredges[i][1][1])+" "+string(inneredges[i][1][2])+") 2858 2858 \\lvec ("+string(inneredges[i][2][1])+" "+string(inneredges[i][2][2])+")"; 2859 2859 } … … 2866 2866 { 2867 2867 if (scalefactor > 2) 2868 { 2868 { 2869 2869 subdivision=subdivision+" 2870 2870 \\move ("+string(i)+" "+string(j)+") \\fcir f:0.6 r:"+decimal(2/(10*scalefactor),size(string(int(scalefactor)))+1); … … 2876 2876 } 2877 2877 } 2878 } 2878 } 2879 2879 if ((shiftvector[1]!=0) or (shiftvector[2]!=0)) 2880 2880 { … … 2883 2883 } 2884 2884 } 2885 // deal with the pathological cases 2885 // deal with the pathological cases 2886 2886 if (size(boundary)==1) // then the Newton polytope is a point 2887 2887 { … … 2938 2938 { 2939 2939 if (scalefactor > 2) 2940 { 2940 { 2941 2941 subdivision=subdivision+" 2942 \\move ("+string(markings[i][1])+" "+string(markings[i][2])+") 2942 \\move ("+string(markings[i][1])+" "+string(markings[i][2])+") 2943 2943 \\fcir f:0 r:"+decimal(2/(8*scalefactor),size(string(int(scalefactor)))+1); 2944 2944 } … … 2946 2946 { 2947 2947 subdivision=subdivision+" 2948 \\move ("+string(markings[i][1])+" "+string(markings[i][2])+") 2948 \\move ("+string(markings[i][1])+" "+string(markings[i][2])+") 2949 2949 \\fcir f:0 r:"+decimal(2/(16*scalefactor),size(string(int(scalefactor)))+1); 2950 2950 } 2951 2951 } 2952 2952 // enclose subdivision in the texdraw environment 2953 string texsubdivision=" 2953 string texsubdivision=" 2954 2954 \\begin{texdraw} 2955 \\drawdim cm \\relunitscale 1 2955 \\drawdim cm \\relunitscale 1 2956 2956 \\linewd 0.05" 2957 2957 +subdivision+" … … 2967 2967 poly f=x+y+x2y+xy2+1/t*xy; 2968 2968 list graph=tropicalCurve(f); 2969 // compute the texdraw code of the Newton subdivision of the tropical curve 2969 // compute the texdraw code of the Newton subdivision of the tropical curve 2970 2970 texDrawNewtonSubdivision(graph); 2971 2971 } … … 2975 2975 proc texDrawTriangulation (list triang,list polygon) 2976 2976 "USAGE: texDrawTriangulation(triang,polygon); triang,polygon list 2977 ASSUME: polygon is a list of integer vectors describing the 2977 ASSUME: polygon is a list of integer vectors describing the 2978 2978 lattice points of a marked polygon; 2979 triang is a list of integer vectors describing a 2979 triang is a list of integer vectors describing a 2980 2980 triangulation of the marked polygon 2981 in the sense that an integer vector of the form (i,j,k) describes 2981 in the sense that an integer vector of the form (i,j,k) describes 2982 2982 the triangle formed by polygon[i], polygon[j] and polygon[k] 2983 RETURN: string, a texdraw code for the triangulation described 2983 RETURN: string, a texdraw code for the triangulation described 2984 2984 by triang without the texdraw environment 2985 2985 EXAMPLE: example texDrawTriangulation; shows an example" … … 2990 2990 "; 2991 2991 int i,j; // indices 2992 list pairs,markings; // stores edges of the triangulation, respecively 2993 // the marked points for each triangle store the edges and marked 2992 list pairs,markings; // stores edges of the triangulation, respecively 2993 // the marked points for each triangle store the edges and marked 2994 2994 // points of the triangle 2995 2995 for (i=1;i<=size(triang);i++) … … 3000 3000 markings[3*i-2]=triang[i][1]; 3001 3001 markings[3*i-1]=triang[i][2]; 3002 markings[3*i]=triang[i][3]; 3002 markings[3*i]=triang[i][3]; 3003 3003 } 3004 3004 // delete redundant pairs which occur more than once … … 3033 3033 { 3034 3034 latex=latex+" 3035 \\move ("+string(polygon[markings[i]][1])+" "+string(polygon[markings[i]][2])+") 3035 \\move ("+string(polygon[markings[i]][1])+" "+string(polygon[markings[i]][2])+") 3036 3036 \\fcir f:0 r:0.08"; 3037 3037 } … … 3040 3040 { 3041 3041 latex=latex+" 3042 \\move ("+string(polygon[pairs[i][1]][1])+" "+string(polygon[pairs[i][1]][2])+") 3042 \\move ("+string(polygon[pairs[i][1]][1])+" "+string(polygon[pairs[i][1]][2])+") 3043 3043 \\lvec ("+string(polygon[pairs[i][2]][1])+" "+string(polygon[pairs[i][2]][2])+")"; 3044 3044 } … … 3047 3047 { 3048 3048 latex=latex+" 3049 \\move ("+string(polygon[i][1])+" "+string(polygon[i][2])+") 3049 \\move ("+string(polygon[i][1])+" "+string(polygon[i][2])+") 3050 3050 \\fcir f:0.7 r:0.04"; 3051 3051 } … … 3056 3056 "EXAMPLE:"; 3057 3057 echo=2; 3058 // the lattice polygon spanned by the points (0,0), (3,0) and (0,3) 3058 // the lattice polygon spanned by the points (0,0), (3,0) and (0,3) 3059 3059 // with all integer points as markings 3060 3060 list polygon=intvec(1,1),intvec(3,0),intvec(2,0),intvec(1,0),intvec(0,0), 3061 3061 intvec(2,1),intvec(0,1),intvec(1,2),intvec(0,2),intvec(0,3); 3062 // define a triangulation by connecting the only interior point 3062 // define a triangulation by connecting the only interior point 3063 3063 // with the vertices 3064 3064 list triang=intvec(1,2,5),intvec(1,5,10),intvec(1,2,10); … … 3068 3068 3069 3069 /////////////////////////////////////////////////////////////////////////////// 3070 /// Auxilary Procedures 3070 /// Auxilary Procedures 3071 3071 /////////////////////////////////////////////////////////////////////////////// 3072 3072 … … 3074 3074 "USAGE: radicalMemberShip (f,i); f poly, i ideal 3075 3075 RETURN: int, 1 if f is in the radical of i, 0 else 3076 EXAMPLE: example radicalMemberShip; shows an example" 3076 EXAMPLE: example radicalMemberShip; shows an example" 3077 3077 { 3078 3078 def BASERING=basering; … … 3114 3114 { 3115 3115 // compute first the t-order of the leading coefficient of f (leitkoef[1]) and 3116 // the rational constant corresponding to this order in leadkoef(f) 3116 // the rational constant corresponding to this order in leadkoef(f) 3117 3117 // (leitkoef[2]) 3118 3118 list leitkoef=simplifyToOrder(f); … … 3124 3124 // do the same for the remaining part of f and compare the results 3125 3125 // keep only the smallest ones 3126 int vglgewicht; 3127 f=f-lead(f); 3126 int vglgewicht; 3127 f=f-lead(f); 3128 3128 while (f!=0) 3129 3129 { 3130 leitkoef=simplifyToOrder(f); 3130 leitkoef=simplifyToOrder(f); 3131 3131 vglgewicht=leitkoef[1]+scalarproduct(w,leadexp(f)); 3132 3132 if (vglgewicht<gewicht) … … 3143 3143 initialf=initialf+koef*leadmonom(f); 3144 3144 } 3145 } 3145 } 3146 3146 f=f-lead(f); 3147 3147 } … … 3168 3168 { 3169 3169 // compute first the t-order of the leading coefficient of f (leitkoef[1]) and 3170 // the rational constant corresponding to this order in leadkoef(f) 3170 // the rational constant corresponding to this order in leadkoef(f) 3171 3171 // (leitkoef[2]) 3172 list leitkoef=simplifyToOrder(f); 3172 list leitkoef=simplifyToOrder(f); 3173 3173 execute("poly koef="+leitkoef[2]+";"); 3174 3174 // take in lead(f) only the term of lowest t-order and set t=1 … … 3179 3179 // keep only the largest ones 3180 3180 int vglgewicht; 3181 f=f-lead(f); 3181 f=f-lead(f); 3182 3182 while (f!=0) 3183 3183 { … … 3197 3197 initialf=initialf+koef*leadmonom(f); 3198 3198 } 3199 } 3199 } 3200 3200 f=f-lead(f); 3201 3201 } … … 3216 3216 proc solveTInitialFormPar (ideal i) 3217 3217 "USAGE: solveTInitialFormPar(i); i ideal 3218 ASSUME: i is a zero-dimensional ideal in Q(t)[x_1,...,x_n] generated 3219 by the (1,w)-homogeneous elements for some integer vector w 3218 ASSUME: i is a zero-dimensional ideal in Q(t)[x_1,...,x_n] generated 3219 by the (1,w)-homogeneous elements for some integer vector w 3220 3220 - i.e. by the (1,w)-initialforms of polynomials 3221 3221 RETURN: none 3222 NOTE: the procedure just displays complex approximations 3222 NOTE: the procedure just displays complex approximations 3223 3223 of the solution set of i 3224 3224 EXAMPLE: example solveTInitialFormPar; shows an example" … … 3245 3245 ///////////////////////////////////////////////////////////////////////// 3246 3246 3247 proc detropicalise (def p) 3247 proc detropicalise (def p) 3248 3248 "USAGE: detropicalise(f); f poly or f list 3249 ASSUME: if f is of type poly then t is a linear polynomial with 3250 an arbitrary constant term and positive integer coefficients 3249 ASSUME: if f is of type poly then t is a linear polynomial with 3250 an arbitrary constant term and positive integer coefficients 3251 3251 as further coefficients; 3252 3252 @* if f is of type list then f is a list of polynomials of 3253 3253 the type just described in before 3254 3254 RETURN: poly, the detropicalisation of f ignoring the constant parts 3255 NOTE: the output will be a monomial and the constant coefficient 3255 NOTE: the output will be a monomial and the constant coefficient 3256 3256 has been ignored 3257 3257 EXAMPLE: example detropicalise; shows an example" … … 3261 3261 { 3262 3262 if (leadmonom(p)!=1) 3263 { 3263 { 3264 3264 dtp=dtp*leadmonom(p)^int(leadcoef(p)); 3265 3265 } … … 3278 3278 ///////////////////////////////////////////////////////////////////////// 3279 3279 3280 proc tDetropicalise (def p) 3280 proc tDetropicalise (def p) 3281 3281 "USAGE: tDetropicalise(f); f poly or f list 3282 ASSUME: if f is of type poly then f is a linear polynomial with an 3283 integer constant term and positive integer coefficients 3282 ASSUME: if f is of type poly then f is a linear polynomial with an 3283 integer constant term and positive integer coefficients 3284 3284 as further coefficients; 3285 3285 @* if f is of type list then it is a list of polynomials of 3286 the type just described in before 3286 the type just described in before 3287 3287 RETURN: poly, the detropicalisation of f over the field Q(t) 3288 3288 NOTE: the output will be a term where the coeffiecient is a Laurent … … 3293 3293 if (typeof(p)=="list") 3294 3294 { 3295 int i; 3295 int i; 3296 3296 for (i=1;i<=size(p);i++) 3297 3297 { … … 3305 3305 { 3306 3306 if (leadmonom(p)!=1) 3307 { 3307 { 3308 3308 dtp=dtp*leadmonom(p)^int(leadcoef(p)); 3309 3309 } … … 3363 3363 proc parameterSubstitute (poly f,int N) 3364 3364 "USAGE: parameterSubstitute(f,N); f poly, N int 3365 ASSUME: f is a polynomial in Q(t)[x_1,...,x_n] describing 3365 ASSUME: f is a polynomial in Q(t)[x_1,...,x_n] describing 3366 3366 a plane curve over Q(t) 3367 3367 RETURN: poly f with t replaced by t^N … … 3417 3417 poly f=t2x+1/t*y-1; 3418 3418 tropicalSubst(f,2,x,x+t,y,tx+y+t2); 3419 // The procedure can be used to study the effect of a transformation of 3419 // The procedure can be used to study the effect of a transformation of 3420 3420 // the form x -> x+t^b, with b a rational number, on the tropicalisation and 3421 3421 // the j-invariant of a cubic over the Puiseux series. 3422 3422 f=t7*y3+t3*y2+t*(x3+xy2+y+1)+xy; 3423 // - the j-invariant, and hence its valuation, 3423 // - the j-invariant, and hence its valuation, 3424 3424 // does not change under the transformation 3425 3425 jInvariant(f,"ord"); 3426 // - b=3/2, then the cycle length of the tropical cubic equals -val(j-inv) 3427 list g32=tropicalSubst(f,2,x,x+t3,y,y); 3426 // - b=3/2, then the cycle length of the tropical cubic equals -val(j-inv) 3427 list g32=tropicalSubst(f,2,x,x+t3,y,y); 3428 3428 tropicalJInvariant(g32); 3429 3429 // - b=1, then it is still true, but only just ... … … 3438 3438 3439 3439 proc randomPoly (int d,int ug, int og, list #) 3440 "USAGE: randomPoly(d,ug,og[,#]); d, ug, og int, # list 3440 "USAGE: randomPoly(d,ug,og[,#]); d, ug, og int, # list 3441 3441 ASSUME: the basering has a parameter t 3442 RETURN: poly, a polynomial of degree d where the coefficients are 3442 RETURN: poly, a polynomial of degree d where the coefficients are 3443 3443 of the form t^j with j a random integer between ug and og 3444 NOTE: if an optional argument # is given, then the coefficients are 3445 instead either of the form t^j as above or they are zero, 3444 NOTE: if an optional argument # is given, then the coefficients are 3445 instead either of the form t^j as above or they are zero, 3446 3446 and this is chosen randomly 3447 3447 EXAMPLE: example randomPoly; shows an example" … … 3460 3460 { 3461 3461 if (size(#)!=0) 3462 { 3462 { 3463 3463 k=random(0,1); 3464 3464 } 3465 3465 if (k==0) 3466 { 3466 { 3467 3467 j=random(ug,og); 3468 3468 randomPolynomial=randomPolynomial+t^j*m[i]; … … 3494 3494 RETURN: none" 3495 3495 { 3496 system("sh","cd /tmp; /bin/rm -f tropicalcurve*; /bin/rm -f tropicalnewtonsubdivision*"); 3496 system("sh","cd /tmp; /bin/rm -f tropicalcurve*; /bin/rm -f tropicalnewtonsubdivision*"); 3497 3497 } 3498 3498 … … 3551 3551 static proc cutdown (ideal jideal,intvec wvec,int dimension,list #) 3552 3552 "USAGE: cutdown(i,w,d); i ideal, w intvec, d int, # list 3553 ASSUME: i an ideal in Q[t,x_1,...,x_n], (w_1,...,w_n) is in the tropical 3554 variety of jideal and d=dim(i)>0, in Q(t)[x]; the optional 3555 parameter # can contain the string 'isPrime' to indicate that 3556 the input ideal is prime and no minimal associated primes have 3553 ASSUME: i an ideal in Q[t,x_1,...,x_n], (w_1,...,w_n) is in the tropical 3554 variety of jideal and d=dim(i)>0, in Q(t)[x]; the optional 3555 parameter # can contain the string 'isPrime' to indicate that 3556 the input ideal is prime and no minimal associated primes have 3557 3557 to be computed 3558 RETURN: list, the first entry is a ring, namely the basering where some 3559 variables have been eliminated, and the ring contains 3558 RETURN: list, the first entry is a ring, namely the basering where some 3559 variables have been eliminated, and the ring contains 3560 3560 the ideal i (with the same variables eliminated), 3561 the t-initial ideal ini of i (w.r.t. the weight vector 3562 where the entries corresponding to the deleted variables 3563 have been eliminated) and a list repl where for each 3561 the t-initial ideal ini of i (w.r.t. the weight vector 3562 where the entries corresponding to the deleted variables 3563 have been eliminated) and a list repl where for each 3564 3564 eliminated variable there is one entry, namely a polynomial 3565 in the remaining variables and t that explains how 3566 resubstitution of a solution for the new i gives a solution 3565 in the remaining variables and t that explains how 3566 resubstitution of a solution for the new i gives a solution 3567 3567 for the old i; the second entry is the weight vector 3568 wvec with the components corresponding to the eliminated 3568 wvec with the components corresponding to the eliminated 3569 3569 variables removed 3570 NOTE: needs the libraries random.lib and primdec.lib; 3570 NOTE: needs the libraries random.lib and primdec.lib; 3571 3571 is called from tropicalLifting" 3572 { 3573 // IDEA: i is an ideal of dimension d; we want to cut it with d random linear 3572 { 3573 // IDEA: i is an ideal of dimension d; we want to cut it with d random linear 3574 3574 // forms in such a way that the resulting 3575 3575 // ideal is 0-dim and still contains w in the tropical variety 3576 // NOTE: t is the last variable in the basering 3576 // NOTE: t is the last variable in the basering 3577 3577 ideal pideal; //this is the ideal we want to return 3578 3578 ideal cutideal; … … 3592 3592 for (j1=1;j1<=nvars(basering)-1;j1++) 3593 3593 { 3594 variablen=variablen+var(j1); // read the set of variables 3594 variablen=variablen+var(j1); // read the set of variables 3595 3595 // (needed to make the quotring later) 3596 product=product*var(j1); // make product of all variables 3596 product=product*var(j1); // make product of all variables 3597 3597 // (needed for the initial-monomial-check later 3598 } 3598 } 3599 3599 execute("ring QUOTRING=("+charstr(basering)+",t),("+string(variablen)+"),dp;"); 3600 3600 setring BASERING; … … 3603 3603 { 3604 3604 setring QUOTRING; 3605 ideal jideal=imap(BASERING,jideal); 3606 list primp=minAssGTZ(jideal); //compute the primary decomposition 3605 ideal jideal=imap(BASERING,jideal); 3606 list primp=minAssGTZ(jideal); //compute the primary decomposition 3607 3607 for (j1=1;j1<=size(primp);j1++) 3608 { 3608 { 3609 3609 for(j2=1;j2<=size(primp[j1]);j2++) 3610 3610 { 3611 3611 // clear all denominators 3612 3612 primp[j1][j2]=primp[j1][j2]/content(primp[j1][j2]); 3613 } 3613 } 3614 3614 } 3615 3615 setring BASERING; 3616 3616 list primp=imap(QUOTRING,primp); 3617 3617 // if i is not primary itself 3618 // go through the list of min. ass. primes and find the first 3618 // go through the list of min. ass. primes and find the first 3619 3619 // one which has w in its tropical variety 3620 if (size(primp)>1) 3620 if (size(primp)>1) 3621 3621 { 3622 3622 j1=1; … … 3625 3625 //compute the t-initial of the associated prime 3626 3626 // - the last entry 1 only means that t is the last variable in the ring 3627 primini=tInitialIdeal(primp[j1],wvec,1); 3628 // check if it contains a monomial (resp if the product of var 3627 primini=tInitialIdeal(primp[j1],wvec,1); 3628 // check if it contains a monomial (resp if the product of var 3629 3629 // is in the radical) 3630 if (radicalMemberShip(product,primini)==0) 3631 { 3630 if (radicalMemberShip(product,primini)==0) 3631 { 3632 3632 // if w is in the tropical variety of the prime, we take that 3633 3633 jideal=primp[j1]; … … 3636 3636 setring BASERING; 3637 3637 winprim=1; // and stop the checking 3638 } 3638 } 3639 3639 j1=j1+1; //else we look at the next associated prime 3640 3640 } … … 3643 3643 { 3644 3644 jideal=primp[1]; //if i is primary itself we take its prime instead 3645 } 3645 } 3646 3646 } 3647 3647 // now we start as a first try to intersect with a hyperplane parallel to 3648 3648 // coordinate axes, because this would make our further computations 3649 // a lot easier. 3650 // We choose a subset of our n variables of size d=dim(ideal). 3649 // a lot easier. 3650 // We choose a subset of our n variables of size d=dim(ideal). 3651 3651 // For each of these 3652 // variables, we want to fix a value: x_i= a_i*t^-w_i. 3652 // variables, we want to fix a value: x_i= a_i*t^-w_i. 3653 3653 // This will only work if the 3654 // projection of the d-dim variety to the other n-d variables 3654 // projection of the d-dim variety to the other n-d variables 3655 3655 // is the whole n-d plane. 3656 // Then a general choice for a_i will intersect the variety 3656 // Then a general choice for a_i will intersect the variety 3657 3657 // in finitely many points. 3658 // If the projection is not the whole n-d plane, 3658 // If the projection is not the whole n-d plane, 3659 3659 // then a general choice will not work. 3660 // We could determine if we picked a good 3660 // We could determine if we picked a good 3661 3661 // d-subset of variables using elimination 3662 // (NOTE, there EXIST d variables such that 3662 // (NOTE, there EXIST d variables such that 3663 3663 // a random choice of a_i's would work!). 3664 // But since this involves many computations, 3664 // But since this involves many computations, 3665 3665 // we prefer to choose randomly and just 3666 // try in the end if our intersected ideal 3667 // satisfies our requirements. If this does not 3666 // try in the end if our intersected ideal 3667 // satisfies our requirements. If this does not 3668 3668 // work, we give up this try and use our second intersection idea, which 3669 3669 // will work for a Zariksi-open subset (i.e. almost always). 3670 3670 // 3671 // As random subset of d variables we choose 3671 // As random subset of d variables we choose 3672 3672 // those for which the absolute value of the 3673 // wvec-coordinate is smallest, because this will 3673 // wvec-coordinate is smallest, because this will 3674 3674 // give us the smallest powers of t and hence 3675 // less effort in following computations. 3675 // less effort in following computations. 3676 3676 // Note that the smallest absolute value have those 3677 // which are biggest, because wvec is negative. 3677 // which are biggest, because wvec is negative. 3678 3678 //print("first try"); 3679 3679 intvec wminust=intvecdelete(wvec,1); … … 3682 3682 A[1,1..size(wminust)]=-wminust; 3683 3683 A[2,1..size(wminust)]=1..size(wminust); 3684 // sort this matrix in order to get 3684 // sort this matrix in order to get 3685 3685 // the d biggest entries and their position in wvec 3686 A=sortintmat(A); 3687 // we construct a vector which has 1 at entry j if j belongs to the list 3686 A=sortintmat(A); 3687 // we construct a vector which has 1 at entry j if j belongs to the list 3688 3688 // of the d biggest entries of wvec and a 0 else 3689 3689 for (j1=1;j1<=nvars(basering)-1;j1++) //go through the variables … … 3694 3694 { 3695 3695 setvec[j1]=1;//put a 1 3696 } 3697 } 3698 } 3699 // using this 0/1-vector we produce 3700 // a random constant (i.e. coeff in Q times something in t) 3701 // for each of the biggest variables, 3696 } 3697 } 3698 } 3699 // using this 0/1-vector we produce 3700 // a random constant (i.e. coeff in Q times something in t) 3701 // for each of the biggest variables, 3702 3702 // we add the forms x_i-random constant to the ideal 3703 // and we save the constant at the i-th place of 3703 // and we save the constant at the i-th place of 3704 3704 // a list we want to return for later computations 3705 3705 j3=0; … … 3712 3712 { 3713 3713 if(setvec[j1]==1)//if x_i belongs to the biggest variables 3714 { 3714 { 3715 3715 if ((j3==1) and ((char(basering)==0) or (char(basering)>3))) 3716 { 3716 { 3717 3717 randomp1=random(1,3); 3718 randomp=t^(A[1,j2])*randomp1;// make a random constant 3718 randomp=t^(A[1,j2])*randomp1;// make a random constant 3719 3719 // --- first we try small numbers 3720 } 3720 } 3721 3721 if ((j3==2) and ((char(basering)==0) or (char(basering)>100))) 3722 3722 { 3723 3723 randomp1=random(1,100); 3724 randomp=t^(A[1,j2])*randomp1;// make a random constant 3724 randomp=t^(A[1,j2])*randomp1;// make a random constant 3725 3725 // --- next we try bigger numbers 3726 } 3726 } 3727 3727 else 3728 3728 { … … 3736 3736 else 3737 3737 { 3738 ergl[j1]=0; //if the variable is not among the d biggest ones, 3738 ergl[j1]=0; //if the variable is not among the d biggest ones, 3739 3739 //save 0 in the list 3740 3740 erglini[j1]=0; 3741 } 3741 } 3742 3742 } 3743 3743 // print(ergl);print(pideal); 3744 // now we check if we made a good choice of pideal, i.e. if dim=0 and 3744 // now we check if we made a good choice of pideal, i.e. if dim=0 and 3745 3745 // wvec is still in the tropical variety 3746 3746 // change to quotring where we compute dimension … … 3749 3749 { 3750 3750 if(setvec[j1]==1) 3751 { 3752 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 3753 } 3751 { 3752 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 3753 } 3754 3754 } 3755 3755 setring QUOTRING; … … 3763 3763 { 3764 3764 // compute the t-initial of the associated prime 3765 // - the last 1 just means that the variable t is 3765 // - the last 1 just means that the variable t is 3766 3766 // the last variable in the ring 3767 3767 pini=tInitialIdeal(cutideal,wvec ,1); 3768 3768 //print("initial"); 3769 3769 //print(pini); 3770 // and if the initial w.r.t. t contains no monomial 3770 // and if the initial w.r.t. t contains no monomial 3771 3771 // as we want (checked with 3772 3772 // radical-membership of the product of all variables) 3773 if (radicalMemberShip(product,pini)==0) 3774 { 3775 // we made the right choice and now 3776 // we substitute the variables in the ideal 3773 if (radicalMemberShip(product,pini)==0) 3774 { 3775 // we made the right choice and now 3776 // we substitute the variables in the ideal 3777 3777 // to get an ideal in less variables 3778 // also we make a projected vector 3778 // also we make a projected vector 3779 3779 // from wvec only the components of the remaining variables 3780 3780 wvecp=wvec; 3781 variablen=0; 3781 variablen=0; 3782 3782 j2=0; 3783 3783 for(j1=1;j1<=nvars(basering)-1;j1++) … … 3792 3792 else 3793 3793 { 3794 variablen=variablen+var(j1); // read the set of remaining variables 3794 variablen=variablen+var(j1); // read the set of remaining variables 3795 3795 // (needed to make quotring later) 3796 } 3797 } 3796 } 3797 } 3798 3798 // return pideal, the initial and the list ergl which tells us 3799 3799 // which variables we replaced by which form … … 3805 3805 export(ini); 3806 3806 export(repl); 3807 return(list(BASERINGLESS1,wvecp)); 3807 return(list(BASERINGLESS1,wvecp)); 3808 3808 } 3809 3809 } 3810 3810 } 3811 3811 // this is our second try to cut down, which we only use if the first try 3812 // didn't work out. We intersect with d general hyperplanes 3812 // didn't work out. We intersect with d general hyperplanes 3813 3813 // (i.e. we don't choose 3814 3814 // them to be parallel to coordinate hyperplanes anymore. This works out with 3815 3815 // probability 1. 3816 3816 // 3817 // We choose general hyperplanes, i.e. linear forms which involve all x_i. 3818 // Each x_i has to be multiplied bz t^(w_i) in order 3819 // to get the same weight (namely 0) 3817 // We choose general hyperplanes, i.e. linear forms which involve all x_i. 3818 // Each x_i has to be multiplied bz t^(w_i) in order 3819 // to get the same weight (namely 0) 3820 3820 // for each term. As we cannot have negative exponents, we multiply 3821 // the whole form by t^minimumw. Notice that then in the first form, 3821 // the whole form by t^minimumw. Notice that then in the first form, 3822 3822 // there is one term without t- the term of the variable 3823 3823 // x_i such that w_i is minimal. That is, we can solve for this variable. 3824 // In the second form, we can replace that variable, 3825 // and divide by t as much as possible. 3826 // Then there is again one term wihtout t - 3827 // the term of the variable with second least w. 3824 // In the second form, we can replace that variable, 3825 // and divide by t as much as possible. 3826 // Then there is again one term wihtout t - 3827 // the term of the variable with second least w. 3828 3828 // So we can solve for this one again and also replace it in the first form. 3829 // Since all our coefficients are chosen randomly, 3830 // we can also from the beginning on 3831 // choose the set of variables which belong to the d smallest entries of wvec 3832 // (t not counting) and pick random forms g_i(t,x') 3833 // (where x' is the set of remaining variables) 3834 // and set x_i=g_i(t,x'). 3829 // Since all our coefficients are chosen randomly, 3830 // we can also from the beginning on 3831 // choose the set of variables which belong to the d smallest entries of wvec 3832 // (t not counting) and pick random forms g_i(t,x') 3833 // (where x' is the set of remaining variables) 3834 // and set x_i=g_i(t,x'). 3835 3835 // 3836 3836 // make a matrix with first row wvec (without t) and second row 1..n 3837 3837 //print("second try"); 3838 3838 setring BASERING; 3839 A[1,1..size(wminust)]=wminust; 3839 A[1,1..size(wminust)]=wminust; 3840 3840 A[2,1..size(wminust)]=1..size(wminust); 3841 // sort this matrix in otder to get the d smallest entries 3841 // sort this matrix in otder to get the d smallest entries 3842 3842 // (without counting the t-entry) 3843 3843 A=sortintmat(A); … … 3845 3845 setvec=0; 3846 3846 setvec[nvars(basering)-1]=0; 3847 // we construct a vector which has 1 at entry j if j belongs to the list of 3847 // we construct a vector which has 1 at entry j if j belongs to the list of 3848 3848 // the d smallest entries of wvec and a 0 else 3849 3849 for (j1=1;j1<=nvars(basering)-1;j1++) //go through the variables … … 3865 3865 { 3866 3866 j2=j2+1; 3867 wvecp=intvecdelete(wvecp,j1+2-j2);// delete the components 3867 wvecp=intvecdelete(wvecp,j1+2-j2);// delete the components 3868 3868 // we substitute from wvec 3869 3869 } 3870 3870 else 3871 3871 { 3872 variablen=variablen+var(j1); // read the set of remaining variables 3872 variablen=variablen+var(j1); // read the set of remaining variables 3873 3873 // (needed to make the quotring later) 3874 3874 } 3875 } 3875 } 3876 3876 setring BASERING; 3877 3877 execute("ring BASERINGLESS2=("+charstr(BASERING)+"),("+string(variablen)+",t),(dp("+string(ncols(variablen))+"),lp(1));"); 3878 // using the 0/1-vector which tells us which variables belong 3878 // using the 0/1-vector which tells us which variables belong 3879 3879 // to the set of smallest entries of wvec 3880 // we construct a set of d random linear 3881 // polynomials of the form x_i=g_i(t,x'), 3880 // we construct a set of d random linear 3881 // polynomials of the form x_i=g_i(t,x'), 3882 3882 // where the set of all x_i is the set of 3883 // all variables which are in the list of smallest 3883 // all variables which are in the list of smallest 3884 3884 // entries in wvec, and x' are the other variables. 3885 // We add these d random linear polynomials to 3886 // the ideal pideal, i.e. we intersect 3885 // We add these d random linear polynomials to 3886 // the ideal pideal, i.e. we intersect 3887 3887 // with these and hope to get something 3888 // 0-dim which still contains wvec in its 3889 // tropical variety. Also, we produce a list ergl 3888 // 0-dim which still contains wvec in its 3889 // tropical variety. Also, we produce a list ergl 3890 3890 // with g_i at the i-th position. 3891 3891 // This is a list we want to return. … … 3893 3893 setring BASERING; 3894 3894 pideal=jideal; 3895 for(j1=1;j1<=dimension;j1++)//go through the list of variables 3895 for(j1=1;j1<=dimension;j1++)//go through the list of variables 3896 3896 { // corres to the d smallest in wvec 3897 3897 if ((char(basering)==0) or (char(basering)>3)) 3898 { 3898 { 3899 3899 randomp1=random(1,3); 3900 3900 randomp=randomp1*t^(-A[1,j1]); … … 3909 3909 if(setvec[j2]==0)//if x_j belongs to the set x' 3910 3910 { 3911 // add a random term with the suitable power 3911 // add a random term with the suitable power 3912 3912 // of t to the random linear form 3913 3913 if ((char(basering)==0) or (char(basering)>3)) … … 3934 3934 } 3935 3935 //print(ergl); 3936 // Again, we have to test if we made a good choice 3937 // to intersect,i.e. we have to check whether 3936 // Again, we have to test if we made a good choice 3937 // to intersect,i.e. we have to check whether 3938 3938 // pideal is 0-dim and contains wvec in the tropical variety. 3939 3939 cutideal=pideal; … … 3942 3942 if(setvec[j1]==1) 3943 3943 { 3944 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 3945 } 3944 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 3945 } 3946 3946 } 3947 3947 setring QUOTRING; … … 3955 3955 { 3956 3956 // compute the t-initial of the associated prime 3957 // - the last 1 just means that the variable t 3957 // - the last 1 just means that the variable t 3958 3958 // is the last variable in the ring 3959 3959 pini=tInitialIdeal(cutideal,wvec ,1); … … 3962 3962 // and if the initial w.r.t. t contains no monomial as we want (checked with 3963 3963 // radical-membership of the product of all variables) 3964 if (radicalMemberShip(product,pini)==0) 3964 if (radicalMemberShip(product,pini)==0) 3965 3965 { 3966 3966 // we want to replace the variables x_i by the forms -g_i in 3967 // our ideal in order to return an ideal with less variables 3967 // our ideal in order to return an ideal with less variables 3968 3968 // first we substitute the chosen variables 3969 3969 for(j1=1;j1<=nvars(basering)-1;j1++) … … 3982 3982 export(ini); 3983 3983 export(repl); 3984 return(list(BASERINGLESS2,wvecp)); 3984 return(list(BASERINGLESS2,wvecp)); 3985 3985 } 3986 3986 } 3987 3987 // now we try bigger numbers 3988 while (1) //a never-ending loop which will stop with prob. 1 3988 while (1) //a never-ending loop which will stop with prob. 1 3989 3989 { // as we find a suitable ideal with that prob 3990 3990 setring BASERING; 3991 3991 pideal=jideal; 3992 for(j1=1;j1<=dimension;j1++)//go through the list of variables 3992 for(j1=1;j1<=dimension;j1++)//go through the list of variables 3993 3993 { // corres to the d smallest in wvec 3994 3994 randomp1=random(1,100); 3995 3995 randomp=randomp1*t^(-A[1,j1]); 3996 3996 for(j2=1;j2<=nvars(basering)-1;j2++)//go through all variables 3997 { 3997 { 3998 3998 if(setvec[j2]==0)//if x_j belongs to the set x' 3999 3999 { 4000 // add a random term with the suitable power 4000 // add a random term with the suitable power 4001 4001 // of t to the random linear form 4002 4002 if ((char(basering)==0) or (char(basering)>100)) 4003 { 4003 { 4004 4004 randomp2=random(1,100); 4005 4005 randomp1=randomp1+randomp2*var(j2); … … 4022 4022 } 4023 4023 //print(ergl); 4024 // Again, we have to test if we made a good choice to 4025 // intersect,i.e. we have to check whether 4024 // Again, we have to test if we made a good choice to 4025 // intersect,i.e. we have to check whether 4026 4026 // pideal is 0-dim and contains wvec in the tropical variety. 4027 4027 cutideal=pideal; … … 4030 4030 if(setvec[j1]==1) 4031 4031 { 4032 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 4033 } 4032 cutideal=cutideal,var(j1)-ergl[j1];//add all forms to the ideal 4033 } 4034 4034 } 4035 4035 setring QUOTRING; … … 4039 4039 //print(dimp); 4040 4040 kill cutideal; 4041 setring BASERING; 4041 setring BASERING; 4042 4042 if (dimp==0) // if it is 0 as we want 4043 4043 { 4044 4044 // compute the t-initial of the associated prime 4045 // - the last 1 just means that the variable t 4045 // - the last 1 just means that the variable t 4046 4046 // is the last variable in the ring 4047 4047 pini=tInitialIdeal(cutideal,wvec ,1); 4048 4048 //print("initial"); 4049 4049 //print(pini); 4050 // and if the initial w.r.t. t contains no monomial 4050 // and if the initial w.r.t. t contains no monomial 4051 4051 // as we want (checked with 4052 4052 // radical-membership of the product of all variables) 4053 if (radicalMemberShip(product,pini)==0) 4053 if (radicalMemberShip(product,pini)==0) 4054 4054 { 4055 4055 // we want to replace the variables x_i by the forms -g_i in … … 4062 4062 pideal=subst(pideal,var(j1),ergl[j1]);//substitute it 4063 4063 pini=subst(pini,var(j1),erglini[j1]); 4064 } 4065 } 4064 } 4065 } 4066 4066 // return pideal and the list ergl which tells us 4067 4067 // which variables we replaced by which form … … 4073 4073 export(ini); 4074 4074 export(repl); 4075 return(list(BASERINGLESS2,wvecp)); 4075 return(list(BASERINGLESS2,wvecp)); 4076 4076 } 4077 4077 } … … 4084 4084 static proc tropicalparametriseNoabs (ideal i,intvec ww,int ordnung,int gfanold,int nogfan,list #) 4085 4085 "USAGE: tropicalparametriseNoabs(i,tw,ord,gf,ng[,#]); i ideal, tw intvec, ord int, gf,ng int, # opt. list 4086 ASSUME: - i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k], 4087 tw=(w_0,w_1,...,w_n,0,...,0) and (w_0,...,w_n,0,...,0) is in 4088 the tropical variety of i, and ord is the order up to which a point 4089 in V(i) over C((t)) lying over w shall be computed; 4086 ASSUME: - i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k], 4087 tw=(w_0,w_1,...,w_n,0,...,0) and (w_0,...,w_n,0,...,0) is in 4088 the tropical variety of i, and ord is the order up to which a point 4089 in V(i) over C((t)) lying over w shall be computed; 4090 4090 - moreover, k should be zero if the procedure is not called recursively; 4091 - the point in the tropical variety is supposed to lie in the NEGATIVE 4091 - the point in the tropical variety is supposed to lie in the NEGATIVE 4092 4092 orthant; 4093 - the ideal is zero-dimensional when considered 4093 - the ideal is zero-dimensional when considered 4094 4094 in (Q(t)[X_1,...,X_k]/m)[x_1,...,x_n], 4095 where m=#[2] is a maximal ideal in Q(t)[X_1,...,X_k]; 4095 where m=#[2] is a maximal ideal in Q(t)[X_1,...,X_k]; 4096 4096 - gf is 0 if version 2.2 or larger is used and it is 1 else 4097 - ng is 1 if gfan should not be executed 4097 - ng is 1 if gfan should not be executed 4098 4098 RETURN: list, l[1] = ring Q(0,X_1,...,X_r)[[t]] 4099 4099 l[2] = int 4100 4100 l[3] = string 4101 4101 NOTE: - the procedure is also called recursively by itself, and 4102 if it is called in the first recursion, the list # is empty, 4103 otherwise #[1] is an integer, one more than the number 4102 if it is called in the first recursion, the list # is empty, 4103 otherwise #[1] is an integer, one more than the number 4104 4104 of true variables x_1,...,x_n, 4105 4105 and #[2] will contain the maximal ideal m in the variables X_1,...X_k … … 4107 4107 work correctly in K[t,x_1,...,x_n] where K=Q[X_1,...,X_k]/m is a field 4108 4108 extension of Q; 4109 - the ring l[1] contains an ideal PARA, which contains the 4110 parametrisation of a point in V(i) lying over w up to the 4109 - the ring l[1] contains an ideal PARA, which contains the 4110 parametrisation of a point in V(i) lying over w up to the 4111 4111 first ord terms; 4112 - the string m=l[3] contains the code of the maximal ideal m, 4113 by which we have to divide Q[X_1,...,X_r] in order to have 4112 - the string m=l[3] contains the code of the maximal ideal m, 4113 by which we have to divide Q[X_1,...,X_r] in order to have 4114 4114 the appropriate field extension over which the parametrisation lives; 4115 - and if the integer l[2] is N then t has to be replaced by t^1/N in 4116 the parametrisation, or alternatively replace t by t^N in the 4115 - and if the integer l[2] is N then t has to be replaced by t^1/N in 4116 the parametrisation, or alternatively replace t by t^N in the 4117 4117 defining ideal 4118 - the procedure REQUIRES that the program GFAN is installed on 4118 - the procedure REQUIRES that the program GFAN is installed on 4119 4119 your computer" 4120 4120 { … … 4124 4124 if (size(#)==2) // this means the precedure has been called recursively 4125 4125 { 4126 // how many variables are true variables, and how many come 4126 // how many variables are true variables, and how many come 4127 4127 // from the field extension 4128 4128 // only true variables have to be transformed … … 4130 4130 ideal gesamt_m=std(#[2]); // stores all maxideals used for field extensions 4131 4131 // find the zeros of the w-initial ideal and transform the ideal i; 4132 // findzeros and basictransformideal need to know how 4132 // findzeros and basictransformideal need to know how 4133 4133 // many of the variables are true variables 4134 4134 list m_ring=findzeros(i,ww,anzahlvariablen); … … 4137 4137 else // the procedure has been called by tropicalLifting 4138 4138 { 4139 // how many variables are true variables, and how many come from 4139 // how many variables are true variables, and how many come from 4140 4140 // the field extension only true variables have to be transformed 4141 4141 int anzahlvariablen=nvars(basering); … … 4144 4144 ideal ini=#[1]; 4145 4145 // find the zeros of the w-initial ideal and transform the ideal i; 4146 // we should hand the t-initial ideal ine to findzeros, 4146 // we should hand the t-initial ideal ine to findzeros, 4147 4147 // since we know it already 4148 4148 list m_ring=findzeros(i,ww,ini); … … 4166 4166 list a=btr[2]; 4167 4167 ideal m=btr[3]; 4168 gesamt_m=gesamt_m+m; // add the newly found maximal 4168 gesamt_m=gesamt_m+m; // add the newly found maximal 4169 4169 // ideal to the previous ones 4170 4170 } 4171 4171 // check if there is a solution which has the n-th component zero, 4172 // if so, then eliminate the n-th variable from sat(i+x_n,t), 4172 // if so, then eliminate the n-th variable from sat(i+x_n,t), 4173 4173 // otherwise leave i as it is; 4174 // then check if the (remaining) ideal has as solution 4174 // then check if the (remaining) ideal has as solution 4175 4175 // where the n-1st component is zero, 4176 4176 // and procede as before; do the same for the remaining variables; 4177 // this way we make sure that the remaining ideal has 4177 // this way we make sure that the remaining ideal has 4178 4178 // a solution which has no component zero; 4179 4179 intvec deletedvariables; // the jth entry is set 1, if we eliminate x_j 4180 4180 int numberdeletedvariables; // the number of eliminated variables 4181 4181 ideal variablen; // will contain the variables which are not eliminated 4182 intvec tw=ww; // in case some variables are deleted, 4182 intvec tw=ww; // in case some variables are deleted, 4183 4183 // we have to store the old weight vector 4184 4184 deletedvariables[anzahlvariablen]=0; 4185 ideal I,LI; 4185 ideal I,LI; 4186 4186 i=i+m; // if a field extension was necessary, then i has to be extended by m 4187 4187 for (jj=anzahlvariablen-1;jj>=1;jj--) // the variable t is the last one !!! … … 4190 4190 LI=subst(I,var(nvars(basering)),0); 4191 4191 //size(deletedvariables)=anzahlvariablen(before elim.) 4192 for (kk=1;kk<=size(deletedvariables)-1;kk++) 4192 for (kk=1;kk<=size(deletedvariables)-1;kk++) 4193 4193 { 4194 4194 LI=subst(LI,var(kk),0); 4195 4195 } 4196 if (size(LI)==0) // if no power of t is in lead(I) 4196 if (size(LI)==0) // if no power of t is in lead(I) 4197 4197 { // (where the X(i) are considered as field elements) 4198 // get rid of var(jj) 4198 // get rid of var(jj) 4199 4199 i=eliminate(I,var(jj)); 4200 4200 deletedvariables[jj]=1; 4201 anzahlvariablen--; // if a variable is eliminated, 4201 anzahlvariablen--; // if a variable is eliminated, 4202 4202 // then the number of true variables drops 4203 4203 numberdeletedvariables++; … … 4209 4209 } 4210 4210 variablen=invertorder(variablen); 4211 // store also the additional variables and t, 4211 // store also the additional variables and t, 4212 4212 // since they for sure have not been eliminated 4213 4213 for (jj=anzahlvariablen+numberdeletedvariables-1;jj<=nvars(basering);jj++) … … 4215 4215 variablen=variablen+var(jj); 4216 4216 } 4217 // if some variables have been eliminated, 4217 // if some variables have been eliminated, 4218 4218 // then pass to a new ring which has less variables, 4219 4219 // but if no variables are left, then we are done 4220 4220 def BASERING=basering; 4221 if ((numberdeletedvariables>0) and (anzahlvariablen>1)) // if only t remains, 4221 if ((numberdeletedvariables>0) and (anzahlvariablen>1)) // if only t remains, 4222 4222 { // all true variables are gone 4223 4223 execute("ring NEURING=("+charstr(basering)+"),("+string(variablen)+"),(dp("+string(size(variablen)-1)+"),lp(1));"); 4224 4224 ideal i=imap(BASERING,i); 4225 ideal gesamt_m=imap(BASERING,gesamt_m); 4226 } 4227 // now we have to compute a point ww on the tropical variety 4225 ideal gesamt_m=imap(BASERING,gesamt_m); 4226 } 4227 // now we have to compute a point ww on the tropical variety 4228 4228 // of the transformed ideal i; 4229 // of course, we only have to do so, if we have not yet 4229 // of course, we only have to do so, if we have not yet 4230 4230 // reached the order up to which we 4231 4231 // were supposed to do our computations 4232 if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains, 4232 if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains, 4233 4233 { // all true variables are gone 4234 4234 def PREGFANRING=basering; 4235 4235 if (nogfan!=1) 4236 { 4236 { 4237 4237 // pass to a ring which has variables which are suitable for gfan 4238 4238 execute("ring GFANRING=("+charstr(basering)+"),(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z),dp;"); 4239 ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; 4239 ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; 4240 4240 phiideal[nvars(PREGFANRING)]=a; // map t to a 4241 map phi=PREGFANRING,phiideal; 4241 map phi=PREGFANRING,phiideal; 4242 4242 ideal i=phi(i); 4243 // homogenise the ideal i with the first not yet 4244 // used variable in our ring, since gfan 4245 // only handles homogenous ideals; in principle 4243 // homogenise the ideal i with the first not yet 4244 // used variable in our ring, since gfan 4245 // only handles homogenous ideals; in principle 4246 4246 // for this one has first to compute a 4247 // standard basis of i and homogenise that, 4248 // but for the tropical variety (says Anders) 4247 // standard basis of i and homogenise that, 4248 // but for the tropical variety (says Anders) 4249 4249 // it suffices to homogenise an arbitrary system of generators 4250 // i=groebner(i); 4250 // i=groebner(i); 4251 4251 i=homog(i,maxideal(1)[nvars(PREGFANRING)+1]); 4252 4252 // if gfan version >= 0.3.0 is used and the characteristic … … 4260 4260 write(":a /tmp/gfaninput","{"+string(i)+"}"); 4261 4261 } 4262 else 4262 else 4263 4263 { 4264 4264 // write the ideal to a file which gfan takes as input and call gfan … … 4281 4281 string trop=read("/tmp/gfanoutput"); 4282 4282 setring PREGFANRING; 4283 intvec wneu=-1; // this integer vector will store 4283 intvec wneu=-1; // this integer vector will store 4284 4284 // the point on the tropical variety 4285 4285 wneu[nvars(basering)]=0; … … 4294 4294 "IF YOU WANT wneu TO BE TESTED, THEN SET goon=0;"; 4295 4295 ~ 4296 // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY THE 4296 // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY THE 4297 4297 // TROPICAL PREVARIETY 4298 // test, if wneu really is in the tropical variety 4298 // test, if wneu really is in the tropical variety 4299 4299 while (goon==0) 4300 4300 { … … 4313 4313 { 4314 4314 system("sh","gfan_tropicallifting -n "+string(anzahlvariablen)+" --noMult -c < /tmp/gfaninput > /tmp/gfanoutput"); 4315 // read the result from gfan and store it to a string, 4315 // read the result from gfan and store it to a string, 4316 4316 // which in a later version 4317 4317 // should be interpreded by Singular … … 4326 4326 } 4327 4327 } 4328 // if we have not yet computed our parametrisation 4328 // if we have not yet computed our parametrisation 4329 4329 // up to the required order and 4330 // zero is not yet a solution, then we have 4330 // zero is not yet a solution, then we have 4331 4331 // to go on by calling the procedure recursively; 4332 4332 // if all variables were deleted, then i=0 and thus anzahlvariablen==0 4333 4333 if ((ordnung>1) and (anzahlvariablen>1)) 4334 { 4335 // we call the procedure with the transformed ideal i, 4334 { 4335 // we call the procedure with the transformed ideal i, 4336 4336 // the new weight vector, with the 4337 // required order lowered by one, and with 4337 // required order lowered by one, and with 4338 4338 // additional parameters, namely the number of 4339 // true variables and the maximal ideal that 4339 // true variables and the maximal ideal that 4340 4340 // was computed so far to describe the field extension 4341 4341 list PARALIST=tropicalparametriseNoabs(i,wneu,ordnung-1,gfanold,nogfan,anzahlvariablen,gesamt_m); 4342 // the output will be a ring, in which the 4342 // the output will be a ring, in which the 4343 4343 // parametrisation lives, and a string, which contains 4344 4344 // the maximal ideal that describes the necessary field extension … … 4347 4347 string PARAm=PARALIST[3]; 4348 4348 setring PARARing; 4349 // if some variables have been eliminated in before, 4350 // then we have to insert zeros 4349 // if some variables have been eliminated in before, 4350 // then we have to insert zeros 4351 4351 // into the parametrisation for those variables 4352 4352 if (numberdeletedvariables>0) … … 4354 4354 ideal PARAneu=PARA; 4355 4355 int k; 4356 for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++) // t admits 4356 for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++) // t admits 4357 4357 { // no parametrisation 4358 4358 if (deletedvariables[jj]!=1) … … 4368 4368 } 4369 4369 } 4370 // otherwise we are done and we can start to compute 4370 // otherwise we are done and we can start to compute 4371 4371 // the last step of the parametrisation 4372 4372 else … … 4374 4374 // we store the information on m in a string 4375 4375 string PARAm=string(gesamt_m); 4376 // we define the weight of t, i.e. in the parametrisation t 4376 // we define the weight of t, i.e. in the parametrisation t 4377 4377 // has to be replaced by t^1/tweight 4378 4378 int tweight=-tw[1]; 4379 // if additional variables were necessary, 4379 // if additional variables were necessary, 4380 4380 // we introduce them now as parameters; 4381 // in any case the parametrisation ring will 4382 // have only one variable, namely t, 4383 // and its order will be local, so that it 4381 // in any case the parametrisation ring will 4382 // have only one variable, namely t, 4383 // and its order will be local, so that it 4384 4384 // displays the lowest term in t first 4385 4385 if (anzahlvariablen+numberdeletedvariables<nvars(basering)) … … 4392 4392 } 4393 4393 ideal PARA; // will contain the parametrisation 4394 // we start by initialising the entries to be zero; 4394 // we start by initialising the entries to be zero; 4395 4395 // one entry for each true variable 4396 // here we also have to consider the variables 4396 // here we also have to consider the variables 4397 4397 // that we have eliminated in before 4398 4398 for (jj=1;jj<=anzahlvariablen+numberdeletedvariables-1;jj++) … … 4401 4401 } 4402 4402 } 4403 // we now have to change the parametrisation by 4403 // we now have to change the parametrisation by 4404 4404 // reverting the transformations that we have done 4405 4405 list a=imap(BASERING,a); 4406 if (defined(wneu)==0) // when tropicalparametriseNoabs is called for the 4407 { // last time, it does not enter the part, where wneu is defined and the 4406 if (defined(wneu)==0) // when tropicalparametriseNoabs is called for the 4407 { // last time, it does not enter the part, where wneu is defined and the 4408 4408 intvec wneu=-1; // variable t should have weight -1 4409 4409 } … … 4412 4412 PARA[jj]=(PARA[jj]+a[jj+1])*t^(tw[jj+1]*tweight/ww[1]); 4413 4413 } 4414 // if we have reached the stop-level, i.e. either 4414 // if we have reached the stop-level, i.e. either 4415 4415 // we had only to compute up to order 1 4416 // or zero was a solution of the ideal, then we have 4416 // or zero was a solution of the ideal, then we have 4417 4417 // to export the computed parametrisation 4418 4418 // otherwise it has already been exported before 4419 4419 // note, if all variables were deleted, then i==0 and thus testaufnull==0 4420 4420 if ((ordnung==1) or (anzahlvariablen==1)) 4421 { 4421 { 4422 4422 export(PARA); 4423 4423 } 4424 4424 // kill the gfan files in /tmp 4425 system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput"); 4426 // we return a list which contains the 4425 system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput"); 4426 // we return a list which contains the 4427 4427 // parametrisation ring (with the parametrisation ideal) 4428 // and the string representing the maximal ideal 4428 // and the string representing the maximal ideal 4429 4429 // describing the necessary field extension 4430 4430 return(list(PARARing,tweight,PARAm)); … … 4435 4435 static proc findzeros (ideal i,intvec w,list #) 4436 4436 "USAGE: findzeros(i,w[,#]); i ideal, w intvec, # an optional list 4437 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_n+1,...,X_m] and 4437 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_n+1,...,X_m] and 4438 4438 w=(w_0,...,w_n,0,...,0) is in the tropical variety of i 4439 RETURN: list, l[1] = is polynomial ring containing an associated maximal 4440 ideal m of the w-initial ideal of i which does not 4439 RETURN: list, l[1] = is polynomial ring containing an associated maximal 4440 ideal m of the w-initial ideal of i which does not 4441 4441 contain any monomial and where the variables 4442 which do not lead to a field extension have already 4443 been eliminated, and containing a list a such that 4444 the non-zero entries of a correspond to the values 4442 which do not lead to a field extension have already 4443 been eliminated, and containing a list a such that 4444 the non-zero entries of a correspond to the values 4445 4445 of the zero of the associated maximal ideal for the 4446 4446 eliminated variables 4447 4447 l[2] = number of variables which have not been eliminated 4448 l[3] = intvec, if the entry is one then the corresponding 4448 l[3] = intvec, if the entry is one then the corresponding 4449 4449 variable has not been eliminated 4450 NOTE: the procedure is called from inside the recursive procedure 4450 NOTE: the procedure is called from inside the recursive procedure 4451 4451 tropicalparametriseNoabs; 4452 if it is called in the first recursion, the list #[1] contains 4453 the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer, 4452 if it is called in the first recursion, the list #[1] contains 4453 the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer, 4454 4454 one more than the number of true variables x_1,...,x_n" 4455 4455 { 4456 def BASERING=basering; 4456 def BASERING=basering; 4457 4457 // set anzahlvariablen to the number of true variables 4458 4458 if (typeof(#[1])=="int") … … 4460 4460 int anzahlvariablen=#[1]; 4461 4461 // compute the initial ideal of i 4462 // - the last 1 just means that the variable t is the last 4462 // - the last 1 just means that the variable t is the last 4463 4463 // variable in the ring 4464 4464 ideal ini=tInitialIdeal(i,w,1); … … 4467 4467 { 4468 4468 int anzahlvariablen=nvars(basering); 4469 ideal ini=#[1]; // the t-initial ideal has been computed 4469 ideal ini=#[1]; // the t-initial ideal has been computed 4470 4470 // in before and was handed over 4471 4471 } 4472 // move to a polynomial ring with global monomial ordering 4472 // move to a polynomial ring with global monomial ordering 4473 4473 // - the variable t is superflous 4474 4474 ideal variablen; 4475 4475 for (int j=1;j<=nvars(basering)-1;j++) 4476 { 4476 { 4477 4477 variablen=variablen+var(j); 4478 4478 } … … 4480 4480 ideal ini=imap(BASERING,ini); 4481 4481 // compute the associated primes of the initialideal 4482 // ordering the maximal ideals shall help to avoid 4482 // ordering the maximal ideals shall help to avoid 4483 4483 // unneccessary field extensions 4484 4484 list maximalideals=ordermaximalidealsNoabs(minAssGTZ(std(ini)),anzahlvariablen); 4485 4485 ideal m=maximalideals[1][1]; // the first associated maximal ideal 4486 4486 int neuvar=maximalideals[1][2]; // the number of new variables needed 4487 intvec neuevariablen=maximalideals[1][3]; // the information which variable 4487 intvec neuevariablen=maximalideals[1][3]; // the information which variable 4488 4488 // leads to a new one 4489 list a=maximalideals[1][4]; // a_k is the kth component of a 4489 list a=maximalideals[1][4]; // a_k is the kth component of a 4490 4490 // zero of m, if it is not zero 4491 // eliminate from m the superflous variables, that is those ones, 4491 // eliminate from m the superflous variables, that is those ones, 4492 4492 // which do not lead to a new variable 4493 4493 poly elimvars=1; … … 4499 4499 } 4500 4500 } 4501 m=eliminate(m,elimvars); 4502 export(a); 4501 m=eliminate(m,elimvars); 4502 export(a); 4503 4503 export(m); 4504 4504 list m_ring=INITIALRING,neuvar,neuevariablen; … … 4512 4512 static proc basictransformideal (ideal i,intvec w,list m_ring,list #) 4513 4513 "USAGE: basictransformideal(i,w,m_ring[,#]); i ideal, w intvec, m_ring list, # an optional list 4514 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k], 4515 w=(w_0,...,w_n,0,...,0) is in the tropical variety of i, and 4514 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k], 4515 w=(w_0,...,w_n,0,...,0) is in the tropical variety of i, and 4516 4516 m_ring contains a ring containing a maximal ideal m needed 4517 to describe the field extension over which a corresponding 4518 associated maximal ideal of the initialideal of i, considered 4519 in (Q[X_1,...,X_k]/m_alt)(t)[x_1,...,x_n], has a zero, and 4517 to describe the field extension over which a corresponding 4518 associated maximal ideal of the initialideal of i, considered 4519 in (Q[X_1,...,X_k]/m_alt)(t)[x_1,...,x_n], has a zero, and 4520 4520 containing a list a describing the zero of m, and m_ring contains 4521 4521 the information how many new variables are needed for m … … 4524 4524 l[3] = ideal, the maximal ideal m 4525 4525 or l[1] = ring which contains the ideals i and m, and the list a 4526 NOTE: the procedure is called from inside the recursive procedure 4526 NOTE: the procedure is called from inside the recursive procedure 4527 4527 tropicalparametriseNoabs; 4528 if it is called in the first recursion, the list # is empty, 4528 if it is called in the first recursion, the list # is empty, 4529 4529 otherwise #[1] is an integer, the number of true variables x_1,...,x_n; 4530 during the procedure we check if a field extension is necessary 4531 to express a zero (a_1,...,a_n) of m; if so, we have to introduce 4532 new variables and a list containing a ring is returned, otherwise 4533 the list containing i, a and m is returned; 4534 the ideal m will be changed during the procedure since all variables 4530 during the procedure we check if a field extension is necessary 4531 to express a zero (a_1,...,a_n) of m; if so, we have to introduce 4532 new variables and a list containing a ring is returned, otherwise 4533 the list containing i, a and m is returned; 4534 the ideal m will be changed during the procedure since all variables 4535 4535 which reduce to a polynomial in X_1,...,X_k modulo m will be eliminated, 4536 4536 while the others are replaced by new variables X_k+1,...,X_k'" … … 4544 4544 wdegs[j]=deg(i[j],intvec(w[2..size(w)],w[1])); 4545 4545 } 4546 // how many variables are true variables, 4546 // how many variables are true variables, 4547 4547 // and how many come from the field extension 4548 4548 // only real variables have to be transformed … … 4559 4559 // get the information if any new variables are needed from m_ring 4560 4560 int neuvar=m_ring[2]; // number of variables which have to be added 4561 intvec neuevariablen=m_ring[3]; // [i]=1, if for the ith comp. 4561 intvec neuevariablen=m_ring[3]; // [i]=1, if for the ith comp. 4562 4562 // of a zero of m a new variable is needed 4563 4563 def MRING=m_ring[1]; // MRING contains a and m 4564 list a=imap(MRING,a); // (a_1,...,a_n)=(a[2],...,a[n+1]) will be 4564 list a=imap(MRING,a); // (a_1,...,a_n)=(a[2],...,a[n+1]) will be 4565 4565 // a common zero of the ideal m 4566 ideal m=std(imap(MRING,m)); // m is zero, if neuvar==0, 4566 ideal m=std(imap(MRING,m)); // m is zero, if neuvar==0, 4567 4567 // otherwise we change the ring anyway 4568 // if a field extension is needed, then extend the polynomial 4568 // if a field extension is needed, then extend the polynomial 4569 4569 // ring by new variables X_k+1,...,X_k'; 4570 4570 if (neuvar>0) 4571 4571 { 4572 // change to a ring where for each variable needed 4572 // change to a ring where for each variable needed 4573 4573 // in m a new variable has been introduced 4574 4574 ideal variablen; … … 4581 4581 // map i into the new ring 4582 4582 ideal i=imap(BASERING,i); 4583 // define a map phi which maps the true variables, which are not 4583 // define a map phi which maps the true variables, which are not 4584 4584 // reduced to polynomials in the additional variables modulo m, to 4585 // the corresponding newly introduced variables, and which maps 4585 // the corresponding newly introduced variables, and which maps 4586 4586 // the old additional variables to themselves 4587 4587 ideal phiideal; 4588 4588 k=1; 4589 for (j=2;j<=size(neuevariablen);j++) // starting with 2, since the 4589 for (j=2;j<=size(neuevariablen);j++) // starting with 2, since the 4590 4590 { // first entry corresponds to t 4591 4591 if(neuevariablen[j]==1) … … 4596 4596 else 4597 4597 { 4598 phiideal[j-1]=0; 4598 phiideal[j-1]=0; 4599 4599 } 4600 4600 } … … 4603 4603 phiideal=phiideal,X(1..nvars(BASERING)-anzahlvariablen); 4604 4604 } 4605 map phi=MRING,phiideal; 4606 // map m and a to the new ring via phi, so that the true variables 4605 map phi=MRING,phiideal; 4606 // map m and a to the new ring via phi, so that the true variables 4607 4607 // in m and a are replaced by 4608 4608 // the corresponding newly introduced variables … … 4610 4610 list a=phi(a); 4611 4611 } 4612 // replace now the zeros among the a_j by the corresponding 4612 // replace now the zeros among the a_j by the corresponding 4613 4613 // newly introduced variables; 4614 // note that no component of a can be zero 4614 // note that no component of a can be zero 4615 4615 // since the maximal ideal m contains no variable! 4616 // moreover, substitute right away in the ideal i 4616 // moreover, substitute right away in the ideal i 4617 4617 // the true variable x_j by (a_j+x_j)*t^w_j 4618 4618 zaehler=nvars(BASERING)-anzahlvariablen+1; 4619 for (j=1;j<=anzahlvariablen;j++) 4619 for (j=1;j<=anzahlvariablen;j++) 4620 4620 { 4621 4621 if ((a[j]==0) and (j!=1)) // a[1]=0, since t->t^w_0 4622 { 4622 { 4623 4623 a[j]=X(zaehler); 4624 4624 zaehler++; … … 4627 4627 { 4628 4628 if (j!=1) // corresponds to x_(j-1) -- note t is the last variable 4629 { 4629 { 4630 4630 i[k]=substitute(i[k],var(j-1),(a[j]+var(j-1))*t^(-w[j])); 4631 4631 } … … 4639 4639 for (j=1;j<=ncols(i);j++) 4640 4640 { 4641 if (wdegs[j]<0) // if wdegs[j]==0 there is no need to divide, and 4641 if (wdegs[j]<0) // if wdegs[j]==0 there is no need to divide, and 4642 4642 { // we made sure that it is no positive 4643 4643 i[j]=i[j]/t^(-wdegs[j]); 4644 4644 } 4645 4645 } 4646 // since we want to consider i now in the ring 4646 // since we want to consider i now in the ring 4647 4647 // (Q[X_1,...,X_k']/m)[t,x_1,...,x_n] 4648 // we can reduce i modulo m, so that "constant terms" 4648 // we can reduce i modulo m, so that "constant terms" 4649 4649 // which are "zero" since they 4650 4650 // are in m will disappear; simplify(...,2) then really removes them 4651 4651 i=simplify(reduce(i,m),2); 4652 // if new variables have been introduced, we have 4652 // if new variables have been introduced, we have 4653 4653 // to return the ring containing i, a and m 4654 4654 // otherwise we can simply return a list containing i, a and m … … 4671 4671 static proc testw (ideal i,intvec w,int anzahlvariablen,list #) 4672 4672 "USAGE: testw(i,w,n); i ideal, w intvec, n number 4673 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k] and 4674 w=(w_0,...,w_n,0,...,0) 4675 RETURN: int b, 0 if the t-initial ideal of i considered in 4673 ASSUME: i is an ideal in Q[t,x_1,...,x_n,X_1,...,X_k] and 4674 w=(w_0,...,w_n,0,...,0) 4675 RETURN: int b, 0 if the t-initial ideal of i considered in 4676 4676 Q(X_1,...,X_k)[t,x_1,...,x_n] is monomial free, 1 else 4677 4677 NOTE: the procedure is called by tinitialform" … … 4687 4687 ideal tin=tInitialIdeal(i,w,1); 4688 4688 } 4689 4689 4690 4690 int j; 4691 4691 ideal variablen; … … 4719 4719 def BASERING=basering; 4720 4720 if (anzahlvariablen<nvars(basering)) 4721 { 4721 { 4722 4722 execute("ring TINRING=("+charstr(basering)+","+string(Parameter)+"),("+string(variablen)+"),dp;"); 4723 4723 } … … 4729 4729 poly monom=imap(BASERING,monom); 4730 4730 return(radicalMemberShip(monom,tin)); 4731 } 4731 } 4732 4732 4733 4733 ///////////////////////////////////////////////////////////////////////// … … 4735 4735 static proc simplifyToOrder (poly f) 4736 4736 "USAGE: simplifyToOrder(f); f a polynomial 4737 ASSUME: f is a polynomial in Q(t)[x_1,...,x_n] 4737 ASSUME: f is a polynomial in Q(t)[x_1,...,x_n] 4738 4738 RETURN: list, l[1] = t-order of leading term of f 4739 4739 l[2] = the rational coefficient of the term of lowest t-order … … 4758 4758 static proc scalarproduct (intvec w,intvec v) 4759 4759 "USAGE: scalarproduct(w,v); w,v intvec 4760 ASSUME: w and v are integer vectors of the same length 4760 ASSUME: w and v are integer vectors of the same length 4761 4761 RETURN: int, the scalarproduct of v and w 4762 4762 NOTE: the procedure is called by tropicalparametriseNoabs" … … 4816 4816 "USAGE: ordermaximalidealsNoabs(minassi); minassi list 4817 4817 ASSUME: minassi is a list of maximal ideals 4818 RETURN: list, the procedure orders the maximal ideals in minassi according 4819 to how many new variables are needed to describe the zeros 4818 RETURN: list, the procedure orders the maximal ideals in minassi according 4819 to how many new variables are needed to describe the zeros 4820 4820 of the ideal 4821 4821 l[j][1] = jth maximal ideal 4822 4822 l[j][2] = the number of variables needed 4823 l[j][3] = intvec, if for the kth variable a new variable is 4824 needed to define the corresponding zero of 4823 l[j][3] = intvec, if for the kth variable a new variable is 4824 needed to define the corresponding zero of 4825 4825 l[j][1], then the k+1st entry is one 4826 l[j][4] = list, if for the kth variable no new variable is 4827 needed to define the corresponding zero of 4826 l[j][4] = list, if for the kth variable no new variable is 4827 needed to define the corresponding zero of 4828 4828 l[j][1], then its value is the k+1st entry 4829 4829 NOTE: if a maximal ideal contains a variable, it is removed from the list; … … 4834 4834 int pruefer; // is set one if a maximal ideal contains a variable 4835 4835 list minassisort; // will contain the output 4836 for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort 4836 for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort 4837 4837 // to fix its initial length 4838 4838 list zwischen; // needed for reordering 4839 4839 list a;// (a_1,...,a_n)=(a[2],...,a[n+1]) will be a common zero of the ideal m 4840 4840 poly nf; // normalform of a variable w.r.t. m 4841 intvec neuevariablen; // ith entry is 1, if for the ith component of a zero 4841 intvec neuevariablen; // ith entry is 1, if for the ith component of a zero 4842 4842 // of m a new variable is needed 4843 4843 intvec testvariablen; // integer vector of length n=number of variables 4844 // compute for each maximal ideal the number of new variables, 4844 // compute for each maximal ideal the number of new variables, 4845 4845 // which are needed to describe 4846 // its zeros -- note, a new variable is needed if modulo 4847 // the maximal ideal it does not reduce 4846 // its zeros -- note, a new variable is needed if modulo 4847 // the maximal ideal it does not reduce 4848 4848 // to something which only depends on the following variables; 4849 // if no new variable is needed, then store the value 4850 // a variable reduces to in the list a; 4849 // if no new variable is needed, then store the value 4850 // a variable reduces to in the list a; 4851 4851 for (j=size(minassi);j>=1;j--) 4852 4852 { 4853 a[1]=poly(0); // the first entry in a and in neuevariablen 4853 a[1]=poly(0); // the first entry in a and in neuevariablen 4854 4854 // corresponds to the variable t, 4855 4855 neuevariablen[1]=0; // which is not present in the INITIALRING … … 4859 4859 { 4860 4860 nf=reduce(var(k),minassi[j]); 4861 // if a variable reduces to zero, then the maximal ideal 4861 // if a variable reduces to zero, then the maximal ideal 4862 4862 // contains a variable and we can delete it 4863 4863 if (nf==0) … … 4865 4865 pruefer=1; 4866 4866 } 4867 // set the entries of testvariablen corresponding to the first 4867 // set the entries of testvariablen corresponding to the first 4868 4868 // k variables to 1, and the others to 0 4869 4869 for (l=1;l<=nvars(basering);l++) 4870 4870 { 4871 4871 if (l<=k) 4872 { 4872 { 4873 4873 testvariablen[l]=1; 4874 4874 } … … 4878 4878 } 4879 4879 } 4880 // if the variable x_j reduces to a polynomial 4880 // if the variable x_j reduces to a polynomial 4881 4881 // in x_j+1,...,x_n,X_1,...,X_k modulo m 4882 // then we can eliminate x_j from the maximal ideal 4882 // then we can eliminate x_j from the maximal ideal 4883 4883 // (since we do not need any 4884 // further field extension to express a_j) and a_j 4884 // further field extension to express a_j) and a_j 4885 4885 // will just be this normalform, 4886 4886 // otherwise we have to introduce a new variable in order to express a_j; … … 4889 4889 a[k+1]=nf; // a_k is the normal form of the kth variable modulo m 4890 4890 neuevariablen[k+1]=0; // no new variable is needed 4891 } 4891 } 4892 4892 else 4893 4893 { 4894 a[k+1]=poly(0); // a_k is set to zero until we have 4894 a[k+1]=poly(0); // a_k is set to zero until we have 4895 4895 // introduced the new variable 4896 4896 neuevariablen[k+1]=1; … … 4900 4900 // if the maximal ideal contains a variable, we simply delete it 4901 4901 if (pruefer==0) 4902 { 4902 { 4903 4903 minassisort[j]=list(minassi[j],neuvar,neuevariablen,a); 4904 4904 } 4905 // otherwise we store the information on a, 4905 // otherwise we store the information on a, 4906 4906 // neuevariablen and neuvar together with the ideal 4907 4907 else … … 4912 4912 } 4913 4913 } 4914 // sort the maximal ideals ascendingly according to 4914 // sort the maximal ideals ascendingly according to 4915 4915 // the number of new variables needed to 4916 4916 // express the zero of the maximal ideal … … 4919 4919 l=j; 4920 4920 for (k=j-1;k>=1;k--) 4921 { 4921 { 4922 4922 if (minassisort[l][2]<minassisort[k][2]) 4923 4923 { … … 4937 4937 "USAGE: displaypoly(p,N,wj,w1); p poly, N, wj, w1 int 4938 4938 ASSUME: p is a polynomial in r=(0,X(1..k)),t,ls 4939 RETURN: string, the string of t^-wj/w1*p(t^1/N) 4939 RETURN: string, the string of t^-wj/w1*p(t^1/N) 4940 4940 NOTE: the procedure is called from displayTropicalLifting" 4941 4941 { … … 4955 4955 { 4956 4956 if (koeffizienten[j-ord(p)+1]!=0) 4957 { 4957 { 4958 4958 if ((j-(N*wj)/w1)==0) 4959 4959 { … … 5005 5005 static proc displaycoef (poly p) 5006 5006 "USAGE: displaycoef(p); p poly 5007 RETURN: string, the string of p where brackets around 5007 RETURN: string, the string of p where brackets around 5008 5008 have been added if they were missing 5009 5009 NOTE: the procedure is called from displaypoly" … … 5077 5077 static proc tropicalliftingresubstitute (ideal i,list liftring,int N,list #) 5078 5078 "USAGE: tropicalliftingresubstitute(i,L,N[,#]); i ideal, L list, N int, # string 5079 ASSUME: i is an ideal and L[1] is a ring which contains the lifting of a 5080 point in the tropical variety of i computed with tropicalLifting; 5081 t has to be replaced by t^1/N in the lifting; #[1]=m is the string 5082 of the maximal ideal defining the necessary field extension as 5079 ASSUME: i is an ideal and L[1] is a ring which contains the lifting of a 5080 point in the tropical variety of i computed with tropicalLifting; 5081 t has to be replaced by t^1/N in the lifting; #[1]=m is the string 5082 of the maximal ideal defining the necessary field extension as 5083 5083 computed by tropicalLifting, if #[1] is present 5084 5084 RETURN: string, the lifting has been substituted into i … … 5103 5103 ideal i=imap(BASERING,i); 5104 5104 } 5105 } 5105 } 5106 5106 else 5107 5107 { … … 5116 5116 } 5117 5117 // map the resulting i back to LIFTRing; 5118 // if noAbs, then reduce i modulo the maximal ideal 5118 // if noAbs, then reduce i modulo the maximal ideal 5119 5119 // before going back to LIFTRing 5120 5120 if ((size(parstr(LIFTRing))!=0) and size(#)>0) … … 5133 5133 for (j=1;j<=ncols(i);j++) 5134 5134 { 5135 SUBSTTEST[j]=displaypoly(i[j],N,0,1); 5135 SUBSTTEST[j]=displaypoly(i[j],N,0,1); 5136 5136 } 5137 5137 return(SUBSTTEST); … … 5143 5143 /// - eliminatecomponents 5144 5144 /// - findzerosAndBasictransform 5145 /// - ordermaximalideals 5145 /// - ordermaximalideals 5146 5146 /////////////////////////////////////////////////////////////////////////////// 5147 5147 5148 5148 static proc tropicalparametrise (ideal i,intvec ww,int ordnung,int gfanold,int findall,int nogfan,list #) 5149 5149 "USAGE: tropicalparametrise(i,tw,ord,gf,fa,ng[,#]); i ideal, tw intvec, ord int, gf,fa,ng int, # opt. list 5150 ASSUME: - i is an ideal in Q[t,x_1,...,x_n,@a], tw=(w_0,w_1,...,w_n,0) 5151 and (w_0,...,w_n,0) is in the tropical variety of i, 5152 and ord is the order up to which a point in V(i) 5153 over K{{t}} lying over w shall be computed; 5154 - moreover, @a should be not be there if the procedure is not 5150 ASSUME: - i is an ideal in Q[t,x_1,...,x_n,@a], tw=(w_0,w_1,...,w_n,0) 5151 and (w_0,...,w_n,0) is in the tropical variety of i, 5152 and ord is the order up to which a point in V(i) 5153 over K{{t}} lying over w shall be computed; 5154 - moreover, @a should be not be there if the procedure is not 5155 5155 called recursively; 5156 5156 - the point in the tropical variety is supposed to lie in the 5157 5157 NEGATIVE orthant; 5158 - the ideal is zero-dimensional when considered in 5159 (K(t)[@a]/m)[x_1,...,x_n], where m=#[2] is a maximal ideal in K[@a]; 5158 - the ideal is zero-dimensional when considered in 5159 (K(t)[@a]/m)[x_1,...,x_n], where m=#[2] is a maximal ideal in K[@a]; 5160 5160 - gf is 0 if version 2.2 or larger is used and it is 1 else 5161 5161 - fa is 1 if all solutions should be found … … 5164 5164 l[2] = int 5165 5165 NOTE: - the procedure is also called recursively by itself, and 5166 if it is called in the first recursion, the list # is empty, 5167 otherwise #[1] is an integer, one more than the number of 5168 true variables x_1,...,x_n, and #[2] will contain the maximal 5169 ideal m in the variable @a by which the ring K[t,x_1,...,x_n,@a] 5170 should be divided to work correctly in L[t,x_1,...,x_n] where 5166 if it is called in the first recursion, the list # is empty, 5167 otherwise #[1] is an integer, one more than the number of 5168 true variables x_1,...,x_n, and #[2] will contain the maximal 5169 ideal m in the variable @a by which the ring K[t,x_1,...,x_n,@a] 5170 should be divided to work correctly in L[t,x_1,...,x_n] where 5171 5171 L=Q[@a]/m is a field extension of K 5172 - the ring l[1] contains an ideal PARA, which contains the 5173 parametrisation of a point in V(i) lying over w up to the first 5172 - the ring l[1] contains an ideal PARA, which contains the 5173 parametrisation of a point in V(i) lying over w up to the first 5174 5174 ord terms; 5175 - the string m contains the code of the maximal ideal m, by which we 5175 - the string m contains the code of the maximal ideal m, by which we 5176 5176 have to divide K[@a] in order to have the appropriate field extension 5177 5177 over which the parametrisation lives; 5178 5178 - and if the integer l[3] is N then t has to be replaced by t^1/N in the 5179 parametrisation, or alternatively replace t by t^N in the defining 5179 parametrisation, or alternatively replace t by t^N in the defining 5180 5180 ideal 5181 - the procedure REQUIRES that the program GFAN is installed 5181 - the procedure REQUIRES that the program GFAN is installed 5182 5182 on your computer" 5183 5183 { … … 5185 5185 int recursively; // is set 1 if the procedure is called recursively by itself 5186 5186 int ii,jj,kk,ll,jjj,kkk,lll; 5187 if (typeof(#[1])=="int") // this means the precedure has been 5187 if (typeof(#[1])=="int") // this means the precedure has been 5188 5188 { // called recursively 5189 // how many variables are true variables, and how many come 5189 // how many variables are true variables, and how many come 5190 5190 // from the field extension 5191 5191 // only true variables have to be transformed 5192 5192 int anzahlvariablen=#[1]; 5193 5193 // find the zeros of the w-initial ideal and transform the ideal i; 5194 // findzeros and basictransformideal need to know 5194 // findzeros and basictransformideal need to know 5195 5195 // how many of the variables are true variables 5196 5196 // and do the basic transformation as well … … 5200 5200 else // the procedure has been called by tropicalLifting 5201 5201 { 5202 // how many variables are true variables, and 5202 // how many variables are true variables, and 5203 5203 // how many come from the field extension 5204 5204 // only true variables have to be transformed 5205 5205 int anzahlvariablen=nvars(basering); 5206 list zerolist; // will carry the zeros which are 5207 //computed in the recursion steps 5206 list zerolist; // will carry the zeros which are 5207 //computed in the recursion steps 5208 5208 // the initial ideal of i has been handed over as #[1] 5209 5209 ideal ini=#[1]; 5210 5210 // find the zeros of the w-initial ideal and transform the ideal i; 5211 // we should hand the t-initial ideal ine to findzeros, 5211 // we should hand the t-initial ideal ine to findzeros, 5212 5212 // since we know it already; 5213 5213 // and do the basic transformation as well … … 5215 5215 } 5216 5216 list wneulist; // carries all newly computed weight vector 5217 intvec wneu; // carries the newly computed weight vector 5217 intvec wneu; // carries the newly computed weight vector 5218 5218 int tweight; // carries the weight of t 5219 list PARALIST; // carries the result when tropicalparametrise 5219 list PARALIST; // carries the result when tropicalparametrise 5220 5220 // is recursively called 5221 5221 list eliminaterings; // carries the result of eliminatecomponents … … 5226 5226 list liftings,partliftings; // the computed liftings (all resp. partly) 5227 5227 // consider each ring which has been returned when computing the zeros of the 5228 // the t-initial ideal, equivalently, consider 5228 // the t-initial ideal, equivalently, consider 5229 5229 // each zero which has been returned 5230 5230 for (jj=1;jj<=size(trring);jj++) … … 5232 5232 def TRRING=trring[jj]; 5233 5233 setring TRRING; 5234 // check if a certain number of components lead to suitable 5234 // check if a certain number of components lead to suitable 5235 5235 // solutions with zero components; 5236 5236 // compute them all if findall==1 5237 5237 eliminaterings=eliminatecomponents(i,m,oldanzahlvariablen,findall,oldanzahlvariablen-1,deletedvariables); 5238 // consider each of the rings returned by eliminaterings ... 5238 // consider each of the rings returned by eliminaterings ... 5239 5239 // there is at least one !!! 5240 5240 for (ii=1;ii<=size(eliminaterings);ii++) 5241 5241 { 5242 5242 // #variables which have been eliminated 5243 numberdeletedvariables=oldanzahlvariablen-eliminaterings[ii][2]; 5243 numberdeletedvariables=oldanzahlvariablen-eliminaterings[ii][2]; 5244 5244 // #true variables which remain (including t) 5245 anzahlvariablen=eliminaterings[ii][2]; 5245 anzahlvariablen=eliminaterings[ii][2]; 5246 5246 // a 1 in this vector says that variable was eliminated 5247 deletedvariables=eliminaterings[ii][3]; 5247 deletedvariables=eliminaterings[ii][3]; 5248 5248 setring TRRING; // set TRRING - this is important for the loop 5249 5249 // pass the ring computed by eliminatecomponents 5250 def PREGFANRING=eliminaterings[ii][1]; 5250 def PREGFANRING=eliminaterings[ii][1]; 5251 5251 setring PREGFANRING; 5252 5252 poly m=imap(TRRING,m); // map the maximal ideal to this ring 5253 5253 list zero=imap(TRRING,zero); // map the vector of zeros to this ring 5254 // now we have to compute a point ww on the tropical 5254 // now we have to compute a point ww on the tropical 5255 5255 // variety of the transformed ideal i; 5256 // of course, we only have to do so, if we have 5256 // of course, we only have to do so, if we have 5257 5257 // not yet reached the order up to which we 5258 5258 // were supposed to do our computations 5259 if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains, 5259 if ((ordnung>1) and (anzahlvariablen>1)) // if only t remains, 5260 5260 { // all true variables are gone 5261 5261 if (nogfan!=1) 5262 { 5262 { 5263 5263 // pass to a ring which has variables which are suitable for gfan 5264 5264 execute("ring GFANRING=("+string(char(basering))+"),(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z),dp;"); 5265 ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; 5265 ideal phiideal=b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; 5266 5266 phiideal[nvars(PREGFANRING)]=a; // map t to a 5267 map phi=PREGFANRING,phiideal; 5267 map phi=PREGFANRING,phiideal; 5268 5268 ideal II=phi(i); 5269 // homogenise the ideal II with the first not yet 5270 // used variable in our ring, since gfan 5271 // only handles homogenous ideals; in principle for this 5269 // homogenise the ideal II with the first not yet 5270 // used variable in our ring, since gfan 5271 // only handles homogenous ideals; in principle for this 5272 5272 // one has first to compute a 5273 // standard basis of II and homogenise that, 5274 // but for the tropical variety (says Anders) 5273 // standard basis of II and homogenise that, 5274 // but for the tropical variety (says Anders) 5275 5275 // it suffices to homogenise an arbitrary system of generators 5276 // II=groebner(II); 5276 // II=groebner(II); 5277 5277 II=homog(II,maxideal(1)[nvars(PREGFANRING)+1]); 5278 5278 // if gfan version >= 0.3.0 is used and the characteristic … … 5312 5312 int goon=1; 5313 5313 trop; 5314 "CHOOSE A RAY IN THE OUTPUT OF GFAN WHICH HAS ONLY"; 5314 "CHOOSE A RAY IN THE OUTPUT OF GFAN WHICH HAS ONLY"; 5315 5315 "NON-POSITIVE ENTRIES AND STARTS WITH A NEGATIVE ONE,"; 5316 5316 "E.G. (-3,-4,-1,-5,0,0,0) - the last entry will always be 0 -"; … … 5319 5319 "IF YOU WANT wneu TO BE TESTED, THEN SET goon=0;"; 5320 5320 ~ 5321 // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY 5321 // THIS IS NOT NECESSARY !!!! IF WE COMPUTE NOT ONLY 5322 5322 // THE TROPICAL PREVARIETY 5323 // test, if wneu really is in the tropical variety 5323 // test, if wneu really is in the tropical variety 5324 5324 while (goon==0) 5325 5325 { … … 5339 5339 { 5340 5340 system("sh","gfan_tropicallifting -n "+string(anzahlvariablen)+" --noMult -c < /tmp/gfaninput > /tmp/gfanoutput"); 5341 // read the result from gfan and store it to a string, 5341 // read the result from gfan and store it to a string, 5342 5342 // which in a later version 5343 5343 // should be interpreded by Singular … … 5362 5362 } 5363 5363 } 5364 // if we have not yet computed our parametrisation up to 5364 // if we have not yet computed our parametrisation up to 5365 5365 // the required order and 5366 // zero is not yet a solution, then we have to go on 5366 // zero is not yet a solution, then we have to go on 5367 5367 // by calling the procedure recursively; 5368 5368 // if all variables were deleted, then i=0 and thus anzahlvariablen==0 5369 5369 lll=0; 5370 5370 if ((ordnung>1) and (anzahlvariablen>1)) 5371 { 5371 { 5372 5372 partliftings=list(); // initialise partliftings 5373 // we call the procedure with the transformed 5373 // we call the procedure with the transformed 5374 5374 // ideal i, the new weight vector, with the 5375 // required order lowered by one, and with 5375 // required order lowered by one, and with 5376 5376 // additional parameters, namely the number of 5377 // true variables and the maximal ideal that 5377 // true variables and the maximal ideal that 5378 5378 // was computed so far to describe the field extension 5379 5379 for (kk=1;kk<=size(wneulist);kk++) … … 5381 5381 wneu=wneulist[kk]; 5382 5382 PARALIST=tropicalparametrise(i,wneu,ordnung-1,gfanold,findall,nogfan,anzahlvariablen,zero); 5383 // the output will be a ring, in which the 5383 // the output will be a ring, in which the 5384 5384 // parametrisation lives, and a string, which contains 5385 5385 // the maximal ideal that describes the necessary field extension 5386 5386 for (ll=1;ll<=size(PARALIST);ll++) 5387 { 5387 { 5388 5388 def PARARing=PARALIST[ll][1]; 5389 5389 tweight=-ww[1]*PARALIST[ll][2]; 5390 5390 setring PARARing; 5391 // if some variables have been eliminated 5392 // in before, then we have to insert zeros 5391 // if some variables have been eliminated 5392 // in before, then we have to insert zeros 5393 5393 // into the parametrisation for those variables 5394 5394 if (numberdeletedvariables>0) … … 5396 5396 ideal PARAneu=PARA; 5397 5397 kkk=0; 5398 for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++) 5398 for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++) 5399 5399 { // t admits no parametrisation 5400 5400 if (deletedvariables[jjj]!=1) … … 5416 5416 } 5417 5417 } 5418 // otherwise we are done and we can start 5418 // otherwise we are done and we can start 5419 5419 // to compute the last step of the parametrisation 5420 5420 else 5421 5421 { 5422 // we define the weight of t, i.e. in the 5422 // we define the weight of t, i.e. in the 5423 5423 // parametrisation t has to be replaced by t^1/tweight 5424 5424 tweight=-ww[1]; 5425 // if additional variables were necessary, 5425 // if additional variables were necessary, 5426 5426 // we introduce them now as parameters; 5427 // in any case the parametrisation ring will 5428 // have only one variable, namely t, 5429 // and its order will be local, so that it 5427 // in any case the parametrisation ring will 5428 // have only one variable, namely t, 5429 // and its order will be local, so that it 5430 5430 // displays the lowest term in t first 5431 5431 if (anzahlvariablen<nvars(basering)) … … 5439 5439 } 5440 5440 ideal PARA; // will contain the parametrisation 5441 // we start by initialising the entries to be zero; 5441 // we start by initialising the entries to be zero; 5442 5442 // one entry for each true variable 5443 // here we also have to consider the variables 5443 // here we also have to consider the variables 5444 5444 // that we have eliminated in before 5445 5445 for (jjj=1;jjj<=anzahlvariablen+numberdeletedvariables-1;jjj++) … … 5453 5453 kill PARARing; 5454 5454 } 5455 // we now have to change the parametrisation by 5455 // we now have to change the parametrisation by 5456 5456 // reverting the transformations that we have done 5457 5457 for (lll=1;lll<=size(partliftings);lll++) 5458 5458 { 5459 if (size(partliftings[lll])==2) // when tropicalparametrise is called 5460 { // for the last time, it does not enter the part, where wneu is 5459 if (size(partliftings[lll])==2) // when tropicalparametrise is called 5460 { // for the last time, it does not enter the part, where wneu is 5461 5461 wneu=-1; // defined and the variable t should have weight -1 5462 5462 } … … 5473 5473 PARA[jjj]=(PARA[jjj]+zeros[size(zeros)][jjj+1])*t^(ww[jjj+1]*tweight/ww[1]); 5474 5474 } 5475 // delete the last entry in zero, since that one has 5475 // delete the last entry in zero, since that one has 5476 5476 // been used for the transformation 5477 5477 zeros=delete(zeros,size(zeros)); 5478 // in order to avoid redefining commands an empty 5478 // in order to avoid redefining commands an empty 5479 5479 // zeros list should be removed 5480 5480 if (size(zeros)==0) … … 5492 5492 } 5493 5493 // kill the gfan files in /tmp 5494 system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput"); 5495 // we return a list which contains lists of the parametrisation 5494 system("sh","cd /tmp; /usr/bin/touch gfaninput; /usr/bin/touch gfanoutput; /bin/rm gfaninput; /bin/rm gfanoutput"); 5495 // we return a list which contains lists of the parametrisation 5496 5496 // rings (with the parametrisation ideal) 5497 5497 // and an integer N such that t should be replaced by t^1/N … … 5503 5503 static proc eliminatecomponents (ideal i,ideal m,int anzahlvariablen,int findall,int lastvar,intvec deletedvariables) 5504 5504 "USAGE: eliminatecomponents(i,m,n,a,v,d); i,m ideal, n,a,v int, d intvec 5505 ASSUME: i is an ideal in Q[x_1,...,x_n,@a,t] and w=(-w_1/w_0,...,-w_n/w_0) 5506 is in the tropical variety of i considered in 5507 Q[@a]/m{{t}}[x_1,...,x_n]; 5508 considered in this ring i is zero-dimensional; @a need not be present 5505 ASSUME: i is an ideal in Q[x_1,...,x_n,@a,t] and w=(-w_1/w_0,...,-w_n/w_0) 5506 is in the tropical variety of i considered in 5507 Q[@a]/m{{t}}[x_1,...,x_n]; 5508 considered in this ring i is zero-dimensional; @a need not be present 5509 5509 in which case m is zero; 1<=v<=n 5510 5510 RETURN: list, L of lists … … 5512 5512 L[j][2] = an integer anzahlvariablen 5513 5513 L[j][3] = an intvec deletedvariables 5514 NOTE: - the procedure is called from inside the recursive 5514 NOTE: - the procedure is called from inside the recursive 5515 5515 procedure tropicalparametrise 5516 - the procedure checks for solutions which have certain 5517 components zero; these are separated from the rest by 5518 elimination and saturation; the integer deletedvariables 5519 records which variables have been eliminated; 5520 the integer anzahlvariablen records how many true variables remain 5516 - the procedure checks for solutions which have certain 5517 components zero; these are separated from the rest by 5518 elimination and saturation; the integer deletedvariables 5519 records which variables have been eliminated; 5520 the integer anzahlvariablen records how many true variables remain 5521 5521 after the elimination 5522 - if the integer a is one then all zeros of the ideal i are 5523 considered and found, otherwise only one is considered, so that L 5522 - if the integer a is one then all zeros of the ideal i are 5523 considered and found, otherwise only one is considered, so that L 5524 5524 has length one" 5525 5525 { … … 5529 5529 // if all solutions have to be found 5530 5530 if (findall==1) 5531 { 5531 { 5532 5532 list saturatelist,eliminatelist; // carry the solution of the two tests 5533 // we test first if there is a solution which has the component 5534 // lastvar zero and 5533 // we test first if there is a solution which has the component 5534 // lastvar zero and 5535 5535 // where the order of each component is strictly positive; 5536 // if so, we add this variable to the ideal and 5536 // if so, we add this variable to the ideal and 5537 5537 // eliminate it - which amounts to 5538 // to projecting the solutions with this component 5538 // to projecting the solutions with this component 5539 5539 // zero to the hyperplane without this component; 5540 // for the test we compute the saturation with 5540 // for the test we compute the saturation with 5541 5541 // respect to t and replace each variable 5542 // x_i and also t by zero -- if the result is zero, 5543 // then 1 is not in I:t^infty 5542 // x_i and also t by zero -- if the result is zero, 5543 // then 1 is not in I:t^infty 5544 5544 // (i.e. there is a solution which has the component lastvar zero) and 5545 // the result lives in the maximal 5546 // ideal <t,x_1,...,[no x_lastvar],...,x_n> so that 5545 // the result lives in the maximal 5546 // ideal <t,x_1,...,[no x_lastvar],...,x_n> so that 5547 5547 // there is a solution which has strictly positive valuation 5548 5548 /* 5549 5549 // DER NACHFOLGENDE TEIL IST MUELL UND WIRD NICHT MEHR GAMACHT 5550 // for the test we simply compute the leading ideal 5550 // for the test we simply compute the leading ideal 5551 5551 // and set all true variables zero; 5552 // since the ordering was an elimination ordering 5552 // since the ordering was an elimination ordering 5553 5553 // with respect to (@a if present and) t 5554 // there remains something not equal to zero 5554 // there remains something not equal to zero 5555 5555 // if and only if there is polynomial which only 5556 // depends on t (and @a if present), but that is 5556 // depends on t (and @a if present), but that is 5557 5557 // a unit in K{{t}}, which would show that there 5558 5558 // is no solution with the component lastvar zero; 5559 // however, we also have to ensure that if there 5559 // however, we also have to ensure that if there 5560 5560 // exists a solution with the component lastvar 5561 // equal to zero then this component has a 5561 // equal to zero then this component has a 5562 5562 // valuation with all strictly positive values!!!!; 5563 // for this we can either saturate the ideal 5563 // for this we can either saturate the ideal 5564 5564 // after elimination with respect to <t,x_1,...,x_n> 5565 // and see if the saturated ideal is contained in <t,x_1,...x_n>+m, 5566 // or ALTERNATIVELY we can pass to the 5565 // and see if the saturated ideal is contained in <t,x_1,...x_n>+m, 5566 // or ALTERNATIVELY we can pass to the 5567 5567 // ring 0,(t,x_1,...,x_n,@a),(ds(n+1),dp(1)), 5568 // compute a standard basis of the elimination 5568 // compute a standard basis of the elimination 5569 5569 // ideal (plus m) there and check if the dimension 1 5570 // (since we have not omitted the variable lastvar, 5570 // (since we have not omitted the variable lastvar, 5571 5571 // this means that we have the ideal 5572 // generated by t,x_1,...,[no x_lastvar],...,x_n 5572 // generated by t,x_1,...,[no x_lastvar],...,x_n 5573 5573 // and this defines NO curve after omitting x_lastvar) 5574 5574 I=std(ideal(var(lastvar)+i)); … … 5576 5576 LI=lead(reduce(I,std(m))); 5577 5577 //size(deletedvariables)=anzahlvariablen(before elimination) 5578 for (j=1;j<=anzahlvariablen-1;j++) 5578 for (j=1;j<=anzahlvariablen-1;j++) 5579 5579 { 5580 5580 LI=subst(LI,var(j),0); … … 5582 5582 if (size(LI)==0) // if no power of t is in lead(I) (where @a is considered as a field element) 5583 5583 */ 5584 I=reduce(sat(ideal(var(lastvar)+i),t)[1],std(m)); // get rid of the minimal 5584 I=reduce(sat(ideal(var(lastvar)+i),t)[1],std(m)); // get rid of the minimal 5585 5585 // polynomial for the test 5586 5586 LI=subst(I,var(nvars(basering)),0); 5587 5587 //size(deletedvariables)=anzahlvariablen(before elimination) 5588 for (j=1;j<=anzahlvariablen-1;j++) 5588 for (j=1;j<=anzahlvariablen-1;j++) 5589 5589 { 5590 5590 LI=subst(LI,var(j),0); 5591 5591 } 5592 if (size(LI)==0) // the saturation lives in the maximal 5592 if (size(LI)==0) // the saturation lives in the maximal 5593 5593 { // ideal generated by t and the x_i 5594 5594 // get rid of var(lastvar) … … 5605 5605 { 5606 5606 string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(simplify(reduce(maxideal(1),std(var(lastvar))),2))+"),("; 5607 } 5608 if (anzahlvariablen<nvars(basering)) // if @a was present, the 5607 } 5608 if (anzahlvariablen<nvars(basering)) // if @a was present, the 5609 5609 { // ordersting needs an additional entry 5610 5610 elring=elring+"dp(1),"; 5611 5611 } 5612 5612 elring=elring+"lp(1));"; 5613 execute(elring); 5613 execute(elring); 5614 5614 ideal i=imap(BASERING,I); // move the ideal I to the new ring 5615 // if not yet all variables have been checked, 5615 // if not yet all variables have been checked, 5616 5616 // then go on with the next smaller variable, 5617 // else prepare the elimination ring and the neccessary 5617 // else prepare the elimination ring and the neccessary 5618 5618 // information for return 5619 5619 if (lastvar>1) … … 5628 5628 setring BASERING; 5629 5629 } 5630 // next we have to test if there is also a solution 5630 // next we have to test if there is also a solution 5631 5631 // which has the variable lastvar non-zero; 5632 // to do so, we saturate with respect to this variable; 5633 // since when considered over K{{t}} 5634 // the ideal is zero dimensional, this really removes 5632 // to do so, we saturate with respect to this variable; 5633 // since when considered over K{{t}} 5634 // the ideal is zero dimensional, this really removes 5635 5635 // all solutions with that component zero; 5636 5636 // the checking is then done as above 5637 5637 i=std(sat(i,var(lastvar))[1]); 5638 5638 I=reduce(i,std(m)); // "remove" m from i 5639 // test first, if i still is in the ideal <t,x_1,...,x_n> -- if not, then 5640 // we know that i has no longer a point in the tropical 5639 // test first, if i still is in the ideal <t,x_1,...,x_n> -- if not, then 5640 // we know that i has no longer a point in the tropical 5641 5641 // variety with all components negative 5642 5642 LI=subst(I,var(nvars(basering)),0); 5643 for (j=1;j<=anzahlvariablen-1;j++) // set all variables 5643 for (j=1;j<=anzahlvariablen-1;j++) // set all variables 5644 5644 { // t,x_1,...,x_n equal to zero 5645 5645 LI=subst(LI,var(j),0); 5646 5646 } 5647 5647 if (size(LI)==0) // the entries of i have not constant part 5648 { 5649 // check now, if the leading ideal of i contains an element 5648 { 5649 // check now, if the leading ideal of i contains an element 5650 5650 // which only depends on t 5651 5651 LI=lead(I); 5652 5652 //size(deletedvariables)=anzahlvariablen(before elimination) 5653 for (j=1;j<=anzahlvariablen-1;j++) 5653 for (j=1;j<=anzahlvariablen-1;j++) 5654 5654 { 5655 5655 LI=subst(LI,var(j),0); 5656 5656 } 5657 if (size(LI)==0) // if no power of t is in lead(i) 5657 if (size(LI)==0) // if no power of t is in lead(i) 5658 5658 { // (where @a is considered as a field element) 5659 // if not yet all variables have been tested, go on with the 5659 // if not yet all variables have been tested, go on with the 5660 5660 // next smaller variable 5661 5661 // else prepare the neccessary information for return … … 5665 5665 } 5666 5666 else 5667 { 5667 { 5668 5668 execute("ring SATURATERING=("+charstr(basering)+"),("+varstr(basering)+"),("+ordstr(basering)+");"); 5669 5669 ideal i=imap(BASERING,i); … … 5676 5676 return(eliminatelist+saturatelist); 5677 5677 } 5678 else // only one solution is searched for, we can do a simplified 5678 else // only one solution is searched for, we can do a simplified 5679 5679 { // version of the above 5680 // check if there is a solution which has the n-th component 5680 // check if there is a solution which has the n-th component 5681 5681 // zero and with positive valuation, 5682 // if so, then eliminate the n-th variable from 5682 // if so, then eliminate the n-th variable from 5683 5683 // sat(i+x_n,t), otherwise leave i as it is; 5684 // then check if the (remaining) ideal has as 5684 // then check if the (remaining) ideal has as 5685 5685 // solution where the n-1st component is zero ..., 5686 5686 // and procede as before; do the same for the remaining variables; 5687 // this way we make sure that the remaining ideal has 5687 // this way we make sure that the remaining ideal has 5688 5688 // a solution which has no component zero; 5689 5689 ideal variablen; // will contain the variables which are not eliminated … … 5693 5693 LI=subst(I,var(nvars(basering)),0); 5694 5694 //size(deletedvariables)=anzahlvariablen-1(before elimination) 5695 for (k=1;k<=size(deletedvariables);k++) 5695 for (k=1;k<=size(deletedvariables);k++) 5696 5696 { 5697 5697 LI=subst(LI,var(k),0); 5698 5698 } 5699 if (size(LI)==0) // if no power of t is in lead(I) 5699 if (size(LI)==0) // if no power of t is in lead(I) 5700 5700 { // (where the X(i) are considered as field elements) 5701 // get rid of var(j) 5701 // get rid of var(j) 5702 5702 i=eliminate(I,var(j)); 5703 5703 deletedvariables[j]=1; 5704 anzahlvariablen--; // if a variable is eliminated, 5704 anzahlvariablen--; // if a variable is eliminated, 5705 5705 // then the number of true variables drops 5706 5706 } … … 5711 5711 } 5712 5712 variablen=invertorder(variablen); 5713 // store also the additional variable and t, 5713 // store also the additional variable and t, 5714 5714 // since they for sure have not been eliminated 5715 5715 for (j=size(deletedvariables)+1;j<=nvars(basering);j++) … … 5717 5717 variablen=variablen+var(j); 5718 5718 } 5719 // if there are variables left, then pass to a ring which 5720 // only realises these variables else we are done 5719 // if there are variables left, then pass to a ring which 5720 // only realises these variables else we are done 5721 5721 if (anzahlvariablen>1) 5722 5722 { … … 5726 5726 { 5727 5727 string elring="ring ELIMINATERING=("+charstr(basering)+"),("+string(variablen)+"),("; 5728 } 5729 if (size(deletedvariables)+1<nvars(basering)) // if @a was present, 5728 } 5729 if (size(deletedvariables)+1<nvars(basering)) // if @a was present, 5730 5730 { // the ordersting needs an additional entry 5731 5731 elring=elring+"dp(1),"; 5732 5732 } 5733 5733 elring=elring+"lp(1));"; 5734 execute(elring); 5734 execute(elring); 5735 5735 ideal i=imap(BASERING,i); 5736 5736 ideal m=imap(BASERING,m); … … 5745 5745 static proc findzerosAndBasictransform (ideal i,intvec w,list zerolist,int findall,list #) 5746 5746 "USAGE: findzerosAndBasictransform(i,w,z,f[,#]); i ideal, w intvec, z list, f int,# an optional list 5747 ASSUME: i is an ideal in Q[t,x_1,...,x_n,@a] and w=(w_0,...,w_n,0) 5747 ASSUME: i is an ideal in Q[t,x_1,...,x_n,@a] and w=(w_0,...,w_n,0) 5748 5748 is in the tropical variety of i; @a need not be present; 5749 5749 the list 'zero' contains the zeros computed in previous recursion steps; 5750 if 'f' is one then all zeros should be found and returned, 5750 if 'f' is one then all zeros should be found and returned, 5751 5751 otherwise only one 5752 RETURN: list, each entry is a ring corresponding to one conjugacy class of 5753 zeros of the t-initial ideal inside the torus; each of the rings 5752 RETURN: list, each entry is a ring corresponding to one conjugacy class of 5753 zeros of the t-initial ideal inside the torus; each of the rings 5754 5754 contains the following objects 5755 5755 ideal i = the ideal i, where the variable @a (if present) has 5756 possibly been transformed according to the new 5757 minimal polynomial, and where itself has been 5758 submitted to the basic transform of the algorithm 5756 possibly been transformed according to the new 5757 minimal polynomial, and where itself has been 5758 submitted to the basic transform of the algorithm 5759 5759 given by the jth zero found for the t-initial ideal; 5760 note that the new minimal polynomial has already 5760 note that the new minimal polynomial has already 5761 5761 been added 5762 poly m = the new minimal polynomial for @a 5762 poly m = the new minimal polynomial for @a 5763 5763 (it is zero if no @a is present) 5764 list zero = zero[k+1] is the kth component of a zero 5764 list zero = zero[k+1] is the kth component of a zero 5765 5765 the t-initial ideal of i 5766 NOTE: - the procedure is called from inside the recursive procedure 5766 NOTE: - the procedure is called from inside the recursive procedure 5767 5767 tropicalparametrise; 5768 if it is called in the first recursion, the list #[1] contains 5769 the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer, 5768 if it is called in the first recursion, the list #[1] contains 5769 the t-initial ideal of i w.r.t. w, otherwise #[1] is an integer, 5770 5770 one more than the number of true variables x_1,...,x_n 5771 - if #[2] is present, then it is an integer which tells whether 5771 - if #[2] is present, then it is an integer which tells whether 5772 5772 ALL zeros should be found or not" 5773 5773 { … … 5787 5787 int anzahlvariablen=#[1]; 5788 5788 // compute the initial ideal of i 5789 // - the last 1 just means that the variable t is the last 5789 // - the last 1 just means that the variable t is the last 5790 5790 // variable in the ring 5791 5791 ideal ini=tInitialIdeal(i,w,1); … … 5795 5795 int recursive=0; 5796 5796 int anzahlvariablen=nvars(basering); 5797 ideal ini=#[1]; // the t-initial ideal has been computed 5797 ideal ini=#[1]; // the t-initial ideal has been computed 5798 5798 // in before and was handed over 5799 } 5799 } 5800 5800 // collect the true variables x_1,...,x_n plus @a, if it is defined in BASERING 5801 5801 ideal variablen; 5802 5802 for (j=1;j<=nvars(basering)-1;j++) 5803 { 5803 { 5804 5804 variablen=variablen+var(j); 5805 5805 } 5806 // move to a polynomial ring with global monomial ordering 5806 // move to a polynomial ring with global monomial ordering 5807 5807 // - the variable t is superflous, 5808 5808 // the variable @a is not if it was already present 5809 5809 execute("ring INITIALRING=("+charstr(basering)+"),("+string(variablen)+"),dp;"); 5810 5810 ideal ini=imap(BASERING,ini); 5811 // compute the minimal associated primes of the 5811 // compute the minimal associated primes of the 5812 5812 // initialideal over the algebraic closure; 5813 // ordering the maximal ideals shall help to 5813 // ordering the maximal ideals shall help to 5814 5814 // avoid unneccessary field extensions 5815 5815 list absminass=absPrimdecGTZ(ini); 5816 def ABSRING=absminass[1]; // the ring in which the minimal 5816 def ABSRING=absminass[1]; // the ring in which the minimal 5817 5817 // associated primes live 5818 5818 setring ABSRING; … … 5827 5827 // check fort the jth maximal ideal a field extension is necessary; 5828 5828 // the latter condition says that @a is not in BASERING; 5829 // if some of the maximal ideals needs a field extension, 5829 // if some of the maximal ideals needs a field extension, 5830 5830 // then everything will live in this ring 5831 5831 if ((maximalideals[j][1]!=0) and (nvars(BASERING)==anzahlvariablen)) 5832 5832 { 5833 // define the extension ring which contains 5833 // define the extension ring which contains 5834 5834 // the new variable @a, if it is not yet present 5835 5835 execute("ring EXTENSIONRING=("+charstr(BASERING)+"),("+string(imap(BASERING,variablen))+",@a,"+tvar+"),(dp("+string(anzahlvariablen-1)+"),dp(1),lp(1));"); 5836 // phi maps x_i to x_i, @a to @a (if present in the ring), 5836 // phi maps x_i to x_i, @a to @a (if present in the ring), 5837 5837 // and the additional variable 5838 // for the field extension is mapped to @a as well 5838 // for the field extension is mapped to @a as well 5839 5839 // -- note that we only apply phi 5840 // to the list a, and in this list no @a is present; 5840 // to the list a, and in this list no @a is present; 5841 5841 // therefore, it does not matter where this is mapped to 5842 5842 map phi=ABSRING,imap(BASERING,variablen),@a; 5843 5843 } 5844 else // @a was already present in the BASERING or no 5844 else // @a was already present in the BASERING or no 5845 5845 { // field extension is necessary 5846 5846 execute("ring EXTENSIONRING=("+charstr(BASERING)+"),("+varstr(BASERING)+"),("+ordstr(BASERING)+");"); 5847 // phi maps x_i to x_i, @a to @a (if present in the ring), 5847 // phi maps x_i to x_i, @a to @a (if present in the ring), 5848 5848 // and the additional variable 5849 // for the field extension is mapped to @a as well respectively to 0, 5849 // for the field extension is mapped to @a as well respectively to 0, 5850 5850 // if no @a is present; 5851 // note that we only apply phi to the list a and to 5851 // note that we only apply phi to the list a and to 5852 5852 // the replacement rule for 5853 // the old variable @a, and in this list resp. 5854 // replacement rule no @a is present; 5853 // the old variable @a, and in this list resp. 5854 // replacement rule no @a is present; 5855 5855 // therefore, it does not matter where this is mapped to; 5856 5856 if (anzahlvariablen<nvars(EXTENSIONRING)) // @a is in EXTENSIONRING 5857 { 5857 { 5858 5858 // additional variable is mapped to @a 5859 map phi=ABSRING,imap(BASERING,variablen),@a; 5859 map phi=ABSRING,imap(BASERING,variablen),@a; 5860 5860 } 5861 5861 else 5862 5862 { 5863 5863 // additional variable is mapped to 0 5864 map phi=ABSRING,imap(BASERING,variablen),0; 5864 map phi=ABSRING,imap(BASERING,variablen),0; 5865 5865 } 5866 5866 } … … 5869 5869 poly m=maximalideals[j][1]; // extract m 5870 5870 list zeroneu=maximalideals[j][2]; // extract the new zero 5871 poly repl=maximalideals[j][3]; // extract the replacement rule 5872 // the list zero may very well exist as an EMPTY global list 5871 poly repl=maximalideals[j][3]; // extract the replacement rule 5872 // the list zero may very well exist as an EMPTY global list 5873 5873 // - in this case we have to remove it 5874 5874 // in order to avoid a redefining warning 5875 if (defined(zero)!=0) 5875 if (defined(zero)!=0) 5876 5876 { 5877 5877 if (size(zero)==0) … … 5884 5884 { 5885 5885 ideal i=imap(BASERING,i); 5886 if (defined(zerolist)==0) // if zerolist is empty, it does not 5886 if (defined(zerolist)==0) // if zerolist is empty, it does not 5887 5887 { // depend on BASERING ! 5888 5888 list zero=imap(BASERING,zerolist); 5889 5889 } 5890 else 5890 else 5891 5891 { 5892 5892 list zero=zerolist; 5893 5893 } 5894 5894 } 5895 else // in BASERING was @a present 5895 else // in BASERING was @a present 5896 5896 { 5897 5897 ideal variablen=imap(BASERING,variablen); 5898 // map i and zerolist to EXTENSIONRING replacing @a 5898 // map i and zerolist to EXTENSIONRING replacing @a 5899 5899 // by the replacement rule repl 5900 5900 map psi=BASERING,variablen[1..size(variablen)-1],repl,var(nvars(basering)); … … 5906 5906 zero[size(zero)+1]=zeroneu; 5907 5907 // do now the basic transformation sending x_l -> t^-w_l*(zero_l+x_l) 5908 for (l=1;l<=anzahlvariablen;l++) 5908 for (l=1;l<=anzahlvariablen;l++) 5909 5909 { 5910 5910 for (k=1;k<=size(i);k++) 5911 5911 { 5912 5912 if (l!=1) // corresponds to x_(l-1) -- note t is the last variable 5913 { 5913 { 5914 5914 i[k]=substitute(i[k],var(l-1),(zeroneu[l]+var(l-1))*t^(-w[l])); 5915 5915 } … … 5923 5923 for (l=1;l<=ncols(i);l++) 5924 5924 { 5925 if (wdegs[l]<0) // if wdegs[l]==0 there is no need to divide, 5925 if (wdegs[l]<0) // if wdegs[l]==0 there is no need to divide, 5926 5926 { // and we made sure that it is no positive 5927 5927 i[l]=i[l]/t^(-wdegs[l]); … … 5929 5929 } 5930 5930 // since we want to consider i now in the ring (Q[@a]/m)[t,x_1,...,x_n] 5931 // we can reduce i modulo m, so that "constant terms" 5931 // we can reduce i modulo m, so that "constant terms" 5932 5932 // which are "zero" since they 5933 5933 // are in m will disappear; simplify(...,2) then really removes them; … … 5936 5936 export(i); 5937 5937 export(m); 5938 export(zero); 5938 export(zero); 5939 5939 extensionringlist[j]=EXTENSIONRING; 5940 5940 kill EXTENSIONRING; … … 5948 5948 static proc ordermaximalideals (list minassi,int anzahlvariablen) 5949 5949 "USAGE: ordermaximalideals(minassi); minassi list 5950 ASSUME: minassi is a list of maximal ideals (together with the information 5951 how many conjugates it has), where the first polynomial is the 5952 minimal polynomial of the last variable in the ring which is 5950 ASSUME: minassi is a list of maximal ideals (together with the information 5951 how many conjugates it has), where the first polynomial is the 5952 minimal polynomial of the last variable in the ring which is 5953 5953 considered as a parameter 5954 RETURN: list, the procedure orders the maximal ideals in minassi according 5955 to how many new variables are needed (namely none or one) to 5956 describe the zeros of the ideal, and accordingly to the 5954 RETURN: list, the procedure orders the maximal ideals in minassi according 5955 to how many new variables are needed (namely none or one) to 5956 describe the zeros of the ideal, and accordingly to the 5957 5957 degree of the corresponding minimal polynomial 5958 5958 l[j][1] = the minimal polynomial for the jth maximal ideal 5959 l[j][2] = list, the k+1st entry is the kth coordinate of the 5960 zero described by the maximal ideal in terms 5959 l[j][2] = list, the k+1st entry is the kth coordinate of the 5960 zero described by the maximal ideal in terms 5961 5961 of the last variable 5962 l[j][3] = poly, the replacement for the old variable @a 5962 l[j][3] = poly, the replacement for the old variable @a 5963 5963 NOTE: if a maximal ideal contains a variable, it is removed from the list; 5964 5964 the procedure is called by findzerosAndBasictransform" … … 5967 5967 int pruefer; // is set one if a maximal ideal contains a variable 5968 5968 list minassisort; // will contain the output 5969 for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort 5969 for (j=1;j<=size(minassi);j++){minassisort[j]=0;} // initialise minassisort 5970 5970 // to fix its initial length 5971 5971 list zwischen; // needed for reordering 5972 list zero; // (a_1,...,a_n)=(zero[2],...,zero[n+1]) will be 5972 list zero; // (a_1,...,a_n)=(zero[2],...,zero[n+1]) will be 5973 5973 // a common zero of the ideal m 5974 5974 poly nf; // normalform of a variable w.r.t. m 5975 poly minimalpolynomial; // minimal polynomial for the field extension 5975 poly minimalpolynomial; // minimal polynomial for the field extension 5976 5976 poly parrep; // the old variable @a possibly has to be replaced by a new one 5977 // compute for each maximal ideal the number of new variables, which are 5978 // needed to describe its zeros -- note, a new variable is needed 5977 // compute for each maximal ideal the number of new variables, which are 5978 // needed to describe its zeros -- note, a new variable is needed 5979 5979 // if the first entry of minassi[j][1] is not the last variable 5980 // store the value a variable reduces to in the list a; 5980 // store the value a variable reduces to in the list a; 5981 5981 for (j=size(minassi);j>=1;j--) 5982 5982 { … … 5986 5986 minimalpolynomial=0; 5987 5987 } 5988 zero[1]=poly(0); // the first entry in zero and in 5988 zero[1]=poly(0); // the first entry in zero and in 5989 5989 // neuevariablen corresponds to the variable t, 5990 5990 minassi[j][1]=std(minassi[j][1]); … … 5992 5992 { 5993 5993 // zero_k+1 is the normal form of the kth variable modulo m 5994 zero[k+1]=reduce(var(k),minassi[j][1]); 5995 // if a variable reduces to zero, then the maximal 5994 zero[k+1]=reduce(var(k),minassi[j][1]); 5995 // if a variable reduces to zero, then the maximal 5996 5996 // ideal contains a variable and we can delete it 5997 5997 if (zero[k+1]==0) … … 6000 6000 } 6001 6001 } 6002 // if anzahlvariablen<nvars(basering), then the old ring 6002 // if anzahlvariablen<nvars(basering), then the old ring 6003 6003 // had already an additional variable; 6004 6004 // the old parameter @a then has to be replaced by parrep … … 6009 6009 // if the maximal ideal contains a variable, we simply delete it 6010 6010 if (pruefer==0) 6011 { 6011 { 6012 6012 minassisort[j]=list(minimalpolynomial,zero,parrep); 6013 6013 } 6014 // otherwise we store the information on a, neuevariablen 6014 // otherwise we store the information on a, neuevariablen 6015 6015 // and neuvar together with the ideal 6016 6016 else … … 6021 6021 } 6022 6022 } 6023 // sort the maximal ideals ascendingly according to the 6023 // sort the maximal ideals ascendingly according to the 6024 6024 // number of new variables needed to 6025 6025 // express the zero of the maximal ideal … … 6028 6028 l=j; 6029 6029 for (k=j-1;k>=1;k--) 6030 { 6030 { 6031 6031 if (deg(minassisort[l][1])<deg(minassisort[k][1])) 6032 6032 { … … 6063 6063 static proc verticesTropicalCurve (def tp,list #) 6064 6064 "USAGE: verticesTropicalCurve(tp[,#]); tp list, # optional list 6065 ASSUME: tp is represents an ideal in Z[x,y] representing a tropical 6065 ASSUME: tp is represents an ideal in Z[x,y] representing a tropical 6066 6066 polynomial (in the form of the output of the procedure tropicalise) 6067 6067 defining a tropical plane curve 6068 RETURN: list, each entry corresponds to a vertex in the tropical plane 6068 RETURN: list, each entry corresponds to a vertex in the tropical plane 6069 6069 curve defined by tp 6070 6070 l[i][1] = x-coordinate of the ith vertex 6071 6071 l[i][2] = y-coordinate of the ith vertex 6072 l[i][3] = a polynomial whose monimials mark the vertices in 6073 the Newton polygon corresponding to the entries in 6072 l[i][3] = a polynomial whose monimials mark the vertices in 6073 the Newton polygon corresponding to the entries in 6074 6074 tp which take the common minimum at the ith vertex 6075 6075 NOTE: - the information in l[i][3] represents the subdivision of the Newton 6076 polygon of tp (respectively a polynomial which defines tp); 6077 - if # is non-empty and #[1] is the string 'max', then in the 6078 computations minimum and maximum are exchanged; 6079 - if # is non-empty and the #[1] is not a string, only the vertices 6076 polygon of tp (respectively a polynomial which defines tp); 6077 - if # is non-empty and #[1] is the string 'max', then in the 6078 computations minimum and maximum are exchanged; 6079 - if # is non-empty and the #[1] is not a string, only the vertices 6080 6080 will be computed and the information on the Newton subdivision will 6081 6081 be omitted; 6082 - here the tropical polynomial is supposed to be the MINIMUM of the 6083 linear forms in tp, unless the optional input #[1] is the 6082 - here the tropical polynomial is supposed to be the MINIMUM of the 6083 linear forms in tp, unless the optional input #[1] is the 6084 6084 string 'max' 6085 - the procedure is called from tropicalCurve and from 6085 - the procedure is called from tropicalCurve and from 6086 6086 conicWithTangents" 6087 6087 { 6088 // if you insert a single polynomial instead of an ideal representing 6088 // if you insert a single polynomial instead of an ideal representing 6089 6089 // a tropicalised polynomial, 6090 // then we compute first the tropicalisation of this polynomial 6090 // then we compute first the tropicalisation of this polynomial 6091 6091 // -- this feature is not documented in the above help string 6092 6092 if (typeof(tp)=="poly") … … 6097 6097 } 6098 6098 int i,j,k,l,z; // indices 6099 // make sure that no constant entry of tp has type int since that 6099 // make sure that no constant entry of tp has type int since that 6100 6100 // would lead to trouble 6101 6101 // when using the procedure substitute … … 6115 6115 int e=1; 6116 6116 option(redSB); 6117 // for each triple (i,j,k) of entries in tp check if they have a 6118 // point in common and if they attain at this point the minimal 6117 // for each triple (i,j,k) of entries in tp check if they have a 6118 // point in common and if they attain at this point the minimal 6119 6119 // possible value for all linear forms in tp 6120 6120 for (i=1;i<=size(tp)-2;i++) … … 6169 6169 e++; 6170 6170 } 6171 } 6171 } 6172 6172 } 6173 6173 } … … 6192 6192 static proc bunchOfLines (def tp,list #) 6193 6193 "USAGE: bunchOfLines(tp[,#]); tp list, # optional list 6194 ASSUME: tp is represents an ideal in Q[x,y] representing a tropical 6194 ASSUME: tp is represents an ideal in Q[x,y] representing a tropical 6195 6195 polynomial (in the form of the output of the procedure tropicalise) 6196 6196 defining a bunch of ordinary lines in the plane, 6197 6197 i.e. the Newton polygone is a line segment 6198 RETURN: list, see the procedure tropicalCurve for an explanation of 6198 RETURN: list, see the procedure tropicalCurve for an explanation of 6199 6199 the syntax of this list 6200 NOTE: - the tropical curve defined by tp will consist of a bunch of 6201 parallel lines and throughout the procedure a list with the 6202 name bunchoflines is computed, which represents these lines and 6200 NOTE: - the tropical curve defined by tp will consist of a bunch of 6201 parallel lines and throughout the procedure a list with the 6202 name bunchoflines is computed, which represents these lines and 6203 6203 has the following interpretation: 6204 list, each entry corresponds to a vertex in the tropical plane 6204 list, each entry corresponds to a vertex in the tropical plane 6205 6205 curve defined by tp 6206 6206 l[i][1] = the equation of the ith line in the tropical curve 6207 l[i][2] = a polynomial whose monimials mark the vertices in 6208 the Newton polygon corresponding to the entries in 6207 l[i][2] = a polynomial whose monimials mark the vertices in 6208 the Newton polygon corresponding to the entries in 6209 6209 tp which take the common minimum at the ith vertex 6210 6210 - the information in l[i][2] represents the subdivision of the Newton 6211 polygon of tp (respectively a polynomial which defines tp); 6212 - if # is non-empty and #[1] is the string 'max', then in the 6213 computations minimum and maximum are exchanged; 6214 - if # is non-empty and the #[1] is not a string, only the vertices 6215 will be computed and the information on the Newton subdivision 6211 polygon of tp (respectively a polynomial which defines tp); 6212 - if # is non-empty and #[1] is the string 'max', then in the 6213 computations minimum and maximum are exchanged; 6214 - if # is non-empty and the #[1] is not a string, only the vertices 6215 will be computed and the information on the Newton subdivision 6216 6216 will be omitted; 6217 - here the tropical polynomial is supposed to be the MINIMUM of the 6218 linear forms in tp, unless the optional input #[1] is the 6217 - here the tropical polynomial is supposed to be the MINIMUM of the 6218 linear forms in tp, unless the optional input #[1] is the 6219 6219 string 'max' 6220 6220 - the procedure is called from tropicalCurve" … … 6233 6233 intvec direction=leadexp(detropicalise(tp[1]))-leadexp(detropicalise(tp[2])); 6234 6234 direction=direction/gcd(direction[1],direction[2]); 6235 // change the coordinates in such a way, that the Newton polygon 6235 // change the coordinates in such a way, that the Newton polygon 6236 6236 // lies on the x-axis 6237 if (direction[1]==0) // there is no x-term - exchange x and y 6237 if (direction[1]==0) // there is no x-term - exchange x and y 6238 6238 { // and get rid of the new y part 6239 6239 for (i=1;i<=size(tp);i++) … … 6249 6249 } 6250 6250 } 6251 // For all tuples (i,j) of entries in tp check if they attain 6251 // For all tuples (i,j) of entries in tp check if they attain 6252 6252 // at their point of intersection 6253 6253 // the minimal possible value for all linear forms in tp … … 6265 6265 { 6266 6266 vergleich=substitute(tp[l],var(1),px); 6267 if (vergleich==wert) 6267 if (vergleich==wert) 6268 6268 { 6269 6269 newton=newton+detropicalise(oldtp[l]); … … 6276 6276 e++; 6277 6277 } 6278 } 6278 } 6279 6279 } 6280 6280 // if a vertex appears several times, only its first occurence will be kept … … 6283 6283 for (j=i-1;j>=1;j--) 6284 6284 { 6285 if (bunchoflines[i][1]==bunchoflines[j][1]) 6285 if (bunchoflines[i][1]==bunchoflines[j][1]) 6286 6286 { 6287 6287 bunchoflines=delete(bunchoflines,i); … … 6290 6290 } 6291 6291 } 6292 // sort the lines in an descending way according to the leading 6292 // sort the lines in an descending way according to the leading 6293 6293 // exponent of the polynomial 6294 6294 // defining the Newton polygone … … 6325 6325 xc=substitute(bunchoflines[i][1]-cc,var(2),0,var(1),1); 6326 6326 yc=substitute(bunchoflines[i][1]-cc,var(2),1,var(1),0); 6327 6327 if (xc!=0) // then there is a point on the line with y-coordinate zero 6328 6328 { 6329 6329 gr[1]=-cc/leadcoef(xc); 6330 6330 gr[2]=0; 6331 6331 } 6332 else // if there is no point with y-coordinate zero, then 6332 else // if there is no point with y-coordinate zero, then 6333 6333 { // there is point with x-coordinate zero 6334 6334 gr[1]=0; … … 6347 6347 6348 6348 static proc clearintmat (intmat vv) 6349 "USAGE: clearintmat(vv); vv intmat 6350 ASSUME: all entries of the first column of vv are non-negative, 6349 "USAGE: clearintmat(vv); vv intmat 6350 ASSUME: all entries of the first column of vv are non-negative, 6351 6351 not all entries are zero unless vv has only one column 6352 RETURN: intmat, vv has been ordered in an ascending way by the entries 6353 of the first row; 6354 if an entry in the first row occurs several times, the 6355 entries in the second row have been added and only one 6352 RETURN: intmat, vv has been ordered in an ascending way by the entries 6353 of the first row; 6354 if an entry in the first row occurs several times, the 6355 entries in the second row have been added and only one 6356 6356 row has been kept; 6357 colums with a zero in the first row have been removed 6357 colums with a zero in the first row have been removed 6358 6358 unless vv has only one column 6359 6359 NOTE: called by tropicalCurve" … … 6362 6362 for (int i=ncols(vv)-1;i>=1;i--) 6363 6363 { 6364 if (vv[1,i]==vv[1,i+1]) 6364 if (vv[1,i]==vv[1,i+1]) 6365 6365 { 6366 6366 vv[2,i]=vv[2,i]+vv[2,i+1]; … … 6394 6394 k++; 6395 6395 } 6396 else 6396 else 6397 6397 { 6398 6398 stop=1; … … 6422 6422 static proc sortintmat (intmat vv) 6423 6423 "USAGE: sortintmat(vv); vv intmat 6424 RETURN: intmat, the columns of vv have been ordered in an ascending 6424 RETURN: intmat, the columns of vv have been ordered in an ascending 6425 6425 way by the first entry 6426 6426 NOTE: called by clearintmat" … … 6476 6476 { 6477 6477 int m=nrows(M); 6478 6478 6479 6479 } 6480 6480 else … … 6492 6492 static proc minInIntvec (intvec v) 6493 6493 "USAGE: minInIntvec(v); v intvec 6494 RETURN: list, first entry is the minimal value in v, second entry 6494 RETURN: list, first entry is the minimal value in v, second entry 6495 6495 is its position in v 6496 6496 NOTE: called by sortintmat" … … 6529 6529 static proc sortlist (list v,int pos) 6530 6530 "USAGE: sortlist(v,pos); v list, pos int 6531 RETURN: list, the list L ordered in an ascending way according 6531 RETURN: list, the list L ordered in an ascending way according 6532 6532 to the pos-th entries 6533 6533 NOTE: called by tropicalCurve" … … 6568 6568 static proc vergleiche (poly wert,poly vglwert,list #) 6569 6569 "USAGE: vergleiche(wert,vglwert,liste), wert, vglwert poly, liste list 6570 RETURN: int, if list contains a string as first entry then 1 6571 is returned if wert is at most vglwert and 0 if wert is 6570 RETURN: int, if list contains a string as first entry then 1 6571 is returned if wert is at most vglwert and 0 if wert is 6572 6572 larger than vglwert, if liste is anything else 1 is returned if 6573 6573 wert is at least vglwert and 0 if wert s less than vglwert" … … 6601 6601 static proc koeffizienten (poly f,int k) 6602 6602 "USAGE: koeffizienten(f,k) f poly, k int 6603 ASSUME: f=a*x+b*y+c is a linear polynomial in two variables, 6603 ASSUME: f=a*x+b*y+c is a linear polynomial in two variables, 6604 6604 k is either 0, 1 or 2 6605 6605 RETURN: poly, one of the coefficients of f, depending on the value of k: … … 6614 6614 return(c); 6615 6615 } 6616 f=f-c; 6616 f=f-c; 6617 6617 if (k==1) 6618 6618 { 6619 6619 return(substitute(f,var(1),1,var(2),0)); 6620 } 6620 } 6621 6621 else 6622 6622 { 6623 6623 return(substitute(f,var(1),0,var(2),1)); 6624 } 6624 } 6625 6625 } 6626 6626 … … 6660 6660 ASSUME: AA has three entries representing decimal numbers a, b and c 6661 6661 RETURN: list, containing strings representing the numbers a and b scaled 6662 down so that the absolute maximum of the two is no 6662 down so that the absolute maximum of the two is no 6663 6663 larger than c 6664 6664 NOTE: the procedure is called by texDrawTropical" … … 6713 6713 static proc decimal (poly n,list #) 6714 6714 "USAGE: decimal(f[,#]); f poly, # list 6715 ASSUME: f is a polynomial in Q[x_1,...,x_n], and # is either empty 6715 ASSUME: f is a polynomial in Q[x_1,...,x_n], and # is either empty 6716 6716 or #[1] is a positive integer 6717 RETURN: string, a decimal expansion of the leading coefficient of f up 6717 RETURN: string, a decimal expansion of the leading coefficient of f up 6718 6718 to order two respectively #[1] 6719 NOTE: the procedure is called by texDrawTropical and conicWithTangents 6719 NOTE: the procedure is called by texDrawTropical and conicWithTangents 6720 6720 and f will actually be a number" 6721 6721 { … … 6744 6744 } 6745 6745 for (j=i;j<=i+nachkomma;j++) 6746 { 6746 { 6747 6747 news=news+s[j]; 6748 6748 } … … 6776 6776 } 6777 6777 return(0); 6778 } 6778 } 6779 6779 6780 6780 ///////////////////////////////////////////////////////////////////////// … … 6792 6792 { 6793 6793 return(""); 6794 6794 6795 6795 } 6796 6796 if (i==1) … … 6851 6851 k=j+2; 6852 6852 while (k<=size(F) and ((F[k]=="0") or (F[k]=="1") or (F[k]=="2") or (F[k]=="3") or 6853 (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8") 6853 (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8") 6854 6854 or (F[k]=="9"))) 6855 6855 { … … 6865 6865 k=j+2; 6866 6866 while (k<=size(F) and ((F[k]=="0") or (F[k]=="1") or (F[k]=="2") or (F[k]=="3") or 6867 (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8") 6867 (F[k]=="4") or (F[k]=="5") or (F[k]=="6") or (F[k]=="7") or (F[k]=="8") 6868 6868 or (F[k]=="9"))) 6869 6869 { … … 6878 6878 F=stringdelete(F,j); 6879 6879 j--; 6880 } 6880 } 6881 6881 } 6882 6882 short=altshort; 6883 6883 return(F); 6884 6884 } 6885 6885 6886 6886 ///////////////////////////////////////////////////////////////////////// 6887 6887 6888 6888 static proc texcoefficient (poly f,list #) 6889 6889 "USAGE: texcoefficient(f[,#]); f poly, # optional list 6890 RETURN: string, the tex command representing the leading coefficient 6890 RETURN: string, the tex command representing the leading coefficient 6891 6891 of f using \frac as coefficient 6892 NOTE: if # is non-empty, then the cdot at the end is omitted; 6892 NOTE: if # is non-empty, then the cdot at the end is omitted; 6893 6893 this is needed for the constant term" 6894 6894 { … … 6922 6922 } 6923 6923 if (size(koeffizient)>5) 6924 { 6924 { 6925 6925 string tfractest=koeffizient[2..6]; 6926 6926 if (tfractest=="tfrac") … … 7009 7009 static proc coordinatechange (poly f,intmat A,intvec v) 7010 7010 "USAGE: coordinatechange(f,A,v); f poly, A intmat, v intvec 7011 ASSUME: f is a polynomial in two variables, A is a 2x2 7011 ASSUME: f is a polynomial in two variables, A is a 2x2 7012 7012 integer matrix, and v is an integer vector with 2 entries 7013 7013 RETURN: poly, the polynomial transformed by (x,y)->A*(x,y)+v … … 7031 7031 "USAGE: weierstrassFormOfACubic(wf[,#]); wf poly, # list 7032 7032 ASSUME: poly is a cubic polynomial 7033 RETURN: poly, the Weierstrass normal form of the cubic, 0 if poly is 7033 RETURN: poly, the Weierstrass normal form of the cubic, 0 if poly is 7034 7034 not a cubic 7035 7035 NOTE: - the algorithm for the coefficients of the Weierstrass form is due 7036 7036 to Fernando Rodriguez Villegas, villegas@math.utexas.edu 7037 - if an additional argument # is given, the simplified Weierstrass 7037 - if an additional argument # is given, the simplified Weierstrass 7038 7038 form is computed 7039 7039 - the procedure is called by weierstrassForm 7040 - the characteristic of the base field should not be 2 or 3 7040 - the characteristic of the base field should not be 2 or 3 7041 7041 if # is non-empty" 7042 7042 { … … 7052 7052 return (f); 7053 7053 } 7054 // compute the coefficients a1,a2,a3,a4, and a6 of the Weierstrass 7054 // compute the coefficients a1,a2,a3,a4, and a6 of the Weierstrass 7055 7055 // form y^2+a1xy+a3y=x^3+a2x^2+a4x+a6 7056 7056 poly a1=r1; … … 7059 7059 poly a4=((-3*t0*r0+s0^2)*q1+(-3*s1*s0*q0+s1*r0^2))*q3 7060 7060 +(t0*r0*q2^2+(s1*s0*q1+((-3*t0*r2+s1^2)*q0+s0*r0*r2))*q2 7061 +(t0*r2*q1^2+s1*r0*r2*q1+s0*r2^2*q0)); 7061 +(t0*r2*q1^2+s1*r0*r2*q1+s0*r2^2*q0)); 7062 7062 poly a6=(-27*t0^2*q0^2+(9*t0*s0*r0-s0^3)*q0-t0*r0^3)*q3^2+ 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7063 (((9*t0^2*q0-t0*s0*r0)*q1+((-3*t0*s0*r1+(3*t0*s1*r0+ 7064 2*s1*s0^2))*q0+(t0*r0^2*r1-s1*s0*r0^2)))*q2+(-t0^2*q1^3 7065 +(t0*s0*r1+(2*t0*s1*r0-s1*s0^2))*q1^2+((3*t0*s0*r2+ 7066 (-3*t0*s1*r1+2*s1^2*s0))*q0+((2*t0*r0^2-s0^2*r0)*r2+ 7067 (-t0*r0*r1^2+s1*s0*r0*r1-s1^2*r0^2)))*q1+((9*t0*s1*r2- 7068 s1^3)*q0^2+(((-3*t0*r0+s0^2)*r1-s1*s0*r0)*r2+(t0*r1^3 7069 -s1*s0*r1^2+s1^2*r0*r1))*q0)))*q3+(-t0^2*q0*q2^3+ 7070 (-t0*s1*r0*q1+((2*t0*s0*r2+(t0*s1*r1-s1^2*s0))*q0- 7071 t0*r0^2*r2))*q2^2+(-t0*s0*r2*q1^2+(-t0*s1*r2*q0+ 7072 (t0*r0*r1-s1*s0*r0)*r2)*q1+((2*t0*r0-s0^2)*r2^2+ 7073 (-t0*r1^2+s1*s0*r1-s1^2*r0)*r2)*q0)*q2+ 7074 (-t0*r0*r2^2*q1^2+(t0*r1-s1*s0)*r2^2*q0*q1- 7075 7075 t0*r2^3*q0^2)); 7076 7076 poly b2=a1^2+4*a2; … … 7124 7124 i.e. a polynomial of the form a+bx+cx2+dy+exy+fx2y+gy2+hxy2+ix2y2 7125 7125 RETURN: poly, a Weierstrass form of the elliptic curve defined by poly 7126 NOTE: - the algorithm is based on the paper Sang Yook An, Seog Young Kim, 7127 David C. Marshall, Susan H. Marshall, William G. McCallum and 7128 Alexander R. Perlis: Jacobians of Genus One Curves. Journal of Number 7126 NOTE: - the algorithm is based on the paper Sang Yook An, Seog Young Kim, 7127 David C. Marshall, Susan H. Marshall, William G. McCallum and 7128 Alexander R. Perlis: Jacobians of Genus One Curves. Journal of Number 7129 7129 Theory 90,2 (2001), 304-315. 7130 7130 - the procedure is called by weierstrassForm … … 7135 7135 // define P1xP1 as quadric in P3 7136 7136 matrix A[4][4]=0,0,0,1/2,0,0,1/2,0,0,1/2,0,0,1/2,0,0,0; 7137 // define the image of the (2,2)-curve under the Segre embedding 7137 // define the image of the (2,2)-curve under the Segre embedding 7138 7138 // as quadric which should be 7139 7139 // intersected with the image of P1xP1 7140 7140 matrix B[4][4]=A00,A10/2,A01/2,0,A10/2,A20,A11/2,A21/2,A01/2,A11/2,A02,A12/2,0,A21/2,A12/2,A22; 7141 // compute the coefficients of the Weierstrass form of 7141 // compute the coefficients of the Weierstrass form of 7142 7142 // the input polynomial and its j-invariant 7143 7143 poly a=det(x*A+B); … … 7152 7152 7153 7153 static proc jInvariantOfACubic (poly f,list #) 7154 "USAGE: jInvariantOfACubic(f[,#]); f poly, # list 7154 "USAGE: jInvariantOfACubic(f[,#]); f poly, # list 7155 7155 ASSUME: poly is a cubic polynomial defining an elliptic curve 7156 7156 RETURN: poly, the j-invariant of the elliptic curve defined by poly 7157 7157 NOTE: - if the base field is Q(t) an optional argument # may be given; 7158 then the algorithm only computes the negative of the order 7158 then the algorithm only computes the negative of the order 7159 7159 of the j-invariant" 7160 7160 { … … 7163 7163 ERROR("The input polynomial is not a cubic!"); 7164 7164 } 7165 // compute first the Weierstrass form of the cubic 7165 // compute first the Weierstrass form of the cubic 7166 7166 // - this does not change the j-invariant 7167 7167 f=weierstrassFormOfACubic(f); … … 7181 7181 ERROR("The input is a rational curve and has no j-invariant!"); 7182 7182 } 7183 if (size(#)>0) // if the optional argument is given, then only the 7183 if (size(#)>0) // if the optional argument is given, then only the 7184 7184 { // negative of the order is computed 7185 7185 int zaehler=3*simplifyToOrder(c4)[1]; … … 7197 7197 7198 7198 static proc jInvariantOfA2x2Curve (poly f,list #) 7199 "USAGE: jInvariantOfA2x2Curve(f[,#]); f poly, # list 7199 "USAGE: jInvariantOfA2x2Curve(f[,#]); f poly, # list 7200 7200 ASSUME: poly, is a polynomial defining an elliptic curve of type (2,2) on P^1xP^1 7201 7201 i.e. a polynomial of the form a+bx+cx2+dy+exy+fx2y+gy2+hxy2+ix2y2 7202 7202 RETURN: poly, the j-invariant of the elliptic curve defined by poly 7203 7203 NOTE: - if the base field is Q(t) an optional argument # may be given; 7204 then the algorithm only computes the negative of the order of the 7204 then the algorithm only computes the negative of the order of the 7205 7205 j-invariant 7206 7206 - the characteristic should not be 2 or 3 … … 7215 7215 // intersected with the image of P1xP1 7216 7216 matrix B[4][4]=A00,A10/2,A01/2,0,A10/2,A20,A11/2,A21/2,A01/2,A11/2,A02,A12/2,0,A21/2,A12/2,A22; 7217 // compute the coefficients of the Weierstrass form of 7217 // compute the coefficients of the Weierstrass form of 7218 7218 // the input polynomial and its j-invariant 7219 7219 poly a=det(var(1)*A+B); … … 7231 7231 ERROR("The input is a rational curve and has no j-invariant!"); 7232 7232 } 7233 if (size(#)>0) // if the optional argument is given, 7233 if (size(#)>0) // if the optional argument is given, 7234 7234 { // then only the negative of the order is computed 7235 7235 int zaehler=simplifyToOrder(jinvnum)[1]; … … 7247 7247 7248 7248 static proc jInvariantOfA4x2Curve (poly f,list #) 7249 "USAGE: jInvariantOfA4x2Curve(f[,#]); f poly, # list 7249 "USAGE: jInvariantOfA4x2Curve(f[,#]); f poly, # list 7250 7250 ASSUME: poly, is a polynomial defining an elliptic curve of type (4,2), 7251 7251 i.e. a polynomial of the form a+bx+cx2+dx3+ex4+fy+gxy+hx2y+iy2 7252 7252 RETURN: poly, the j-invariant of the elliptic curve defined by poly 7253 7253 NOTE: - if the base field is Q(t) an optional argument # may be given; 7254 then the algorithm only computes the negative of the order 7254 then the algorithm only computes the negative of the order 7255 7255 of the j-invariant 7256 7256 - the characteristic should not be 2 or 3 7257 - the procedure is not called at all, it is just stored 7257 - the procedure is not called at all, it is just stored 7258 7258 for the purpose of comparison" 7259 7259 { … … 7275 7275 poly c4cube=c4^3; 7276 7276 poly jdenom=c4cube-c6^2; 7277 if (size(#)>0) // if the optional argument is given, 7277 if (size(#)>0) // if the optional argument is given, 7278 7278 { // then only the negative of the order is computed 7279 7279 int zaehler=3*simplifyToOrder(c4)[1]; … … 7290 7290 7291 7291 static proc jInvariantOfAPuiseuxCubic (poly f,list #) 7292 "USAGE: jInvariantOfAPuiseuxCubic(f[,#]); f poly, # list 7293 ASSUME: poly is a cubic polynomial over Q(t) defining an elliptic curve 7292 "USAGE: jInvariantOfAPuiseuxCubic(f[,#]); f poly, # list 7293 ASSUME: poly is a cubic polynomial over Q(t) defining an elliptic curve 7294 7294 and # is empty 7295 RETURN: list, containing two polynomials whose ratio is the j-invariant 7295 RETURN: list, containing two polynomials whose ratio is the j-invariant 7296 7296 of the elliptic curve defined by poly 7297 ASSUME: poly is a cubic polynomial over Q(t) defining an elliptic curve 7297 ASSUME: poly is a cubic polynomial over Q(t) defining an elliptic curve 7298 7298 and # is non-empty 7299 7299 RETURN: int, the order of the j-invariant of the elliptic curve defined by poly … … 7304 7304 ERROR("The input polynomial is not a cubic!"); 7305 7305 } 7306 // compute first the Weierstrass form of the cubic 7306 // compute first the Weierstrass form of the cubic 7307 7307 // - this does not change the j-invariant 7308 7308 f=weierstrassFormOfACubic(f); … … 7329 7329 ERROR("The input is a rational curve and has no j-invariant!"); 7330 7330 } 7331 if (size(#)>0) // if the optional argument is given, 7331 if (size(#)>0) // if the optional argument is given, 7332 7332 { // then only the negative of the order is computed 7333 7333 int zaehler=3*simplifyToOrder(c4)[1]; … … 7372 7372 /* 7373 7373 7374 /// Note, only the following procedures need further examples 7374 /// Note, only the following procedures need further examples 7375 7375 /// (the others are too simple): 7376 7376 /// A) tropicalLifting (best tested via displayTropicalLifting) … … 7403 7403 // Example 3 - the ideal is not zero dimensional 7404 7404 // -------------------------------------------------------- 7405 ring r1=0,(t,x,y),dp; 7405 ring r1=0,(t,x,y),dp; 7406 7406 poly f=(9t27-12t26-5t25+21t24+35t23-51t22-40t21+87t20+56t19-94t18-62t17+92t16+56t15-70t14-42t13+38t12+28t11+18t10-50t9-48t8+40t7+36t6-16t5-12t4+4t2)*x2+(-9t24+12t23-4t22-42t20+28t19+30t18-20t17-54t16+16t15+48t14-16t12+8t11-18t10-26t9+30t8+20t7-24t6+4t5+28t4-8t3-16t2+4)*xy+(6t16-10t15-2t14+16t13+4t12-18t11-10t10+24t9+6t8-20t7+8t6+8t5-20t4-4t3+12t2+4t-4)*y2+(-9t28+3t27+8t26-4t25-45t24-6t23+42t22+30t21-94t20-40t19+68t18+82t17-38t16-60t15+26t14+36t13-22t12-20t11+4t10+4t9+12t8+8t7-8t6-8t5+4t4)*x+(9t27-21t26+16t25+14t24+12t23-61t22+27t21+80t20-19t19-100t18+26t17+96t16-24t15-84t14+44t12-2t11-18t10+2t9+40t8+4t7-32t6-12t5+4t3+12t2-4)*y+(9t27-12t26+4t25+36t23-18t22-28t21-2t20+54t19+14t18-52t17-44t16+24t15+40t14-4t13-12t12+4t11-4t10-4t9+4t8); 7407 7407 f; … … 7589 7589 poly f=t*(x7+y7+1)+1/t*(x4+y4+x2+y2+x3y+xy3)+1/t7*x2y2; 7590 7590 list graph=tropicalCurve(f); 7591 graph; 7591 graph; 7592 7592 size(graph)-1; 7593 7593 drawTropicalCurve(graph); … … 7658 7658 proc drawTwoTropicalCurves (list ff,list #) 7659 7659 "USAGE: drawTropicalCurve(f[,#]); f poly or list, # optional list 7660 ASSUME: f is list of linear polynomials of the form ax+by+c with 7661 integers a, b and a rational number c representing a tropical 7660 ASSUME: f is list of linear polynomials of the form ax+by+c with 7661 integers a, b and a rational number c representing a tropical 7662 7662 Laurent polynomial defining a tropical plane curve; 7663 alternatively f can be a polynomial in Q(t)[x,y] defining 7664 a tropical plane curve via the valuation map; 7665 the basering must have a global monomial ordering, two 7663 alternatively f can be a polynomial in Q(t)[x,y] defining 7664 a tropical plane curve via the valuation map; 7665 the basering must have a global monomial ordering, two 7666 7666 variables and up to one parameter! 7667 7667 RETURN: NONE 7668 NOTE: - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and 7669 /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four 7670 digit integer; 7668 NOTE: - the procedure creates the files /tmp/tropicalcurveNUMBER.tex and 7669 /tmp/tropicalcurveNUMBER.ps, where NUMBER is a random four 7670 digit integer; 7671 7671 moreover it displays the tropical curve via kghostview; 7672 if you wish to remove all these files from /tmp, 7672 if you wish to remove all these files from /tmp, 7673 7673 call the procedure cleanTmp 7674 7674 @* - edges with multiplicity greater than one carry this multiplicity 7675 7675 @* - if # is empty, then the tropical curve is computed w.r.t. minimum, 7676 if #[1] is the string 'max', then it is computed w.r.t. maximum 7677 @* - if the last optional argument is 'onlytexfile' then only the 7678 latex file is produced; this option should be used if kghostview 7676 if #[1] is the string 'max', then it is computed w.r.t. maximum 7677 @* - if the last optional argument is 'onlytexfile' then only the 7678 latex file is produced; this option should be used if kghostview 7679 7679 is not installed on your system 7680 @* - note that lattice points in the Newton subdivision which are 7681 black correspond to markings of the marked subdivision, 7680 @* - note that lattice points in the Newton subdivision which are 7681 black correspond to markings of the marked subdivision, 7682 7682 while lattice points in grey are not marked 7683 7683 EXAMPLE: example drawTropicalCurve shows an example" … … 7699 7699 int i,j; 7700 7700 for (i=1;i<=size(ff);i++) 7701 { 7702 def f=ff[i]; 7701 { 7702 def f=ff[i]; 7703 7703 if (typeof(f)=="poly") 7704 7704 { 7705 // exclude the case that the basering has not precisely 7705 // exclude the case that the basering has not precisely 7706 7706 // one parameter and two indeterminates 7707 7707 if ((npars(basering)!=1) or (nvars(basering)!=2)) 7708 7708 { 7709 ERROR("The basering should have precisely one parameter and two indeterminates!"); 7709 ERROR("The basering should have precisely one parameter and two indeterminates!"); 7710 7710 } 7711 7711 texf=texPolynomial(f); // write the polynomial over Q(t) … … 7715 7715 { 7716 7716 if (size(#)==0) 7717 { 7717 { 7718 7718 texf="\\min\\{"; 7719 7719 } … … 7724 7724 for (j=1;j<=size(f);j++) 7725 7725 { 7726 texf=texf+texPolynomial(f[j]); 7726 texf=texf+texPolynomial(f[j]); 7727 7727 if (j<size(f)) 7728 7728 { … … 7733 7733 texf=texf+"\\}"; 7734 7734 } 7735 } 7735 } 7736 7736 graph=tropicalCurve(f,#); // the graph of the tropical polynomial f 7737 7737 // detropicalise ff[i] … … 7755 7755 list verticess; 7756 7756 for (i=1;i<=size(ff);i++) 7757 { 7757 { 7758 7758 graph=graphs[i]; 7759 7759 for (j=1;j<=size(graph)-2;j++) … … 7772 7772 \\addtolength{\\topmargin}{-\\headheight} 7773 7773 \\addtolength{\\topmargin}{-\\topskip} 7774 \\setlength{\\textheight}{267mm} 7774 \\setlength{\\textheight}{267mm} 7775 7775 \\addtolength{\\textheight}{\\topskip} 7776 7776 \\addtolength{\\textheight}{-\\footskip} 7777 7777 \\addtolength{\\textheight}{-30pt} 7778 \\setlength{\\oddsidemargin}{-1in} 7778 \\setlength{\\oddsidemargin}{-1in} 7779 7779 \\addtolength{\\oddsidemargin}{20mm} 7780 7780 \\setlength{\\evensidemargin}{\\oddsidemargin} 7781 \\setlength{\\textwidth}{170mm} 7781 \\setlength{\\textwidth}{170mm} 7782 7782 7783 7783 \\begin{document} … … 7791 7791 string fname; 7792 7792 for (i=1;i<=size(ff);i++) 7793 { 7793 { 7794 7794 if (i==1) 7795 7795 { … … 7801 7801 } 7802 7802 TEXBILD=TEXBILD+" 7803 The vertices of the tropical curve 7803 The vertices of the tropical curve 7804 7804 \\begin{center} 7805 7805 \\begin{math} … … 7825 7825 string TDT; 7826 7826 for (i=1;i<=size(ff);i++) 7827 { 7827 { 7828 7828 #[size(#)+1]="\\setgray "+decimal(1-(number(i)/(size(ff)+1)))+" 7829 7829 "; … … 7840 7840 #=delete(#,1); 7841 7841 } 7842 } 7842 } 7843 7843 // add lattice points if the scalefactor is >= 1/2 7844 7844 // and was not handed over … … 7896 7896 7897 7897 \\begin{center} 7898 "+texDrawNewtonSubdivision(graphs[i],oldsharp)+" 7898 "+texDrawNewtonSubdivision(graphs[i],oldsharp)+" 7899 7899 \\end{center} 7900 7900 … … 7908 7908 int rdnum=random(1000,9999); 7909 7909 write(":w /tmp/tropicalcurve"+string(rdnum)+".tex",TEXBILD); 7910 system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log; /bin/rm tropicalcurve"+string(rdnum)+".aux; /bin/rm tropicalcurve"+string(rdnum)+".ps?; /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &"); 7910 system("sh","cd /tmp; latex /tmp/tropicalcurve"+string(rdnum)+".tex; dvips /tmp/tropicalcurve"+string(rdnum)+".dvi -o; /bin/rm tropicalcurve"+string(rdnum)+".log; /bin/rm tropicalcurve"+string(rdnum)+".aux; /bin/rm tropicalcurve"+string(rdnum)+".ps?; /bin/rm tropicalcurve"+string(rdnum)+".dvi; kghostview tropicalcurve"+string(rdnum)+".ps &"); 7911 7911 } 7912 7912 else … … 7934 7934 { 7935 7935 list graph; 7936 int j,i,k; 7937 poly minx,miny,maxx,maxy; 7938 poly minX,minY,maxX,maxY; 7936 int j,i,k; 7937 poly minx,miny,maxx,maxy; 7938 poly minX,minY,maxX,maxY; 7939 7939 poly maxdiffx,maxdiffy; 7940 7940 poly centerx,centery; … … 7944 7944 list SFCS; 7945 7945 for (k=1;k<=size(graphs);k++) 7946 { 7946 { 7947 7947 graph=graphs[k]; 7948 7948 // find the minimal and maximal coordinates of vertices … … 8007 8007 nachkomma++; 8008 8008 } 8009 } 8010 // if the scalefactor is < 1/100, then we should rather scale the 8009 } 8010 // if the scalefactor is < 1/100, then we should rather scale the 8011 8011 // coordinates directly, since otherwise texdraw gets into trouble 8012 8012 if (nachkomma > 2)
Note: See TracChangeset
for help on using the changeset viewer.