version="$Id: foliation.lib, v 2.42 28/12/2020"; info=" LIBRARY: foliation.lib A library for computing Mixed Hodge structures, Gauss-Manin connections, Picard-Fuchs equations and modular foliations, Hodge cycles and much more... AUTHOR: Hossein Movasati, email:[email protected] SEE ALSO:standard_lib NOTE: When inside a procedure we use another procedure of this library or a library of Singular, then we mention it explicitly in the help section of the procedure. If nothing is mentioned it means that we have used only the standard library of Singular. The present library before the version 1.12 is based on the results of the articles: [Mo1] H. Movasati, Mixed Hodge structures of affine varieties, Ann. Inst. Fourier., Tome 57, (2007), fasicule 3, 775-801. [Mo2] H. Movasati, Calculation of mixed Hodge structures, Gauss-Manin connections and Picard-Fuchs equations. Real and Complex Singularities, Trends in Mathematics, 247-262, 2006, Birkhauser (proceeding of Sao Carlos Conference in Singularities, CIRM, 2004). and after version 1.2 is the implementation of the algorithm in the text [Mo3 ] H. Movasati, Multiple Integrals and Modular Differential Equations, 28 Coloquio Brasileiro de Matematica, p. 168, 2011. After version 1.5 the library is mainly designed for the book [Mo4] H. Movasati, A Course in Hodge Theory: With Emphasis on Multiple Integrals and subsequent articles. Some procedures do not exists after v 1.2. Please see the comments for Version 1.2. After this version there has been a big change in the library. All the computations in this library turns around a tame polynomial f. Differential n-forms are stored as 1*(n+1) matrices. Except for some general procedures, we have used the following fixed notations in each procedure: g is a homogeneous polynomial f is a tame polynomial with last homogeneous part g, g=lasthomo(f); I is the Jacobian ideal of g, I=jacob(g); gI is the standard basis of I, gI=std(I); V=okbase(gI); mu=vdim(gI); mu=size(V); The Milnor number of g. There is difference between these two mu's when f has no singularity. n=nvars(basering)-1; d=deg(g); Version 1.00: The first version. Version 1.10: 1/4/2005: It has new proceedures substpar, diffparpol, diffpar, gaussmaninp, PFeqp and PFEq. It is basically the extension of the Gauss-Manin connection calculations to an arbitrary parameter. Version 1.11: 4/6/2005: It contains the new proceedure hodgenum. Version 1.12: 29/7/2005: It contains the new proceedure sysdif and the procedure PFeqp uses sysdif and is just written in few lines. 15/8/2005, the proceedure 'singlocus' has the new name 'discriminant' Version 1.2: 27/10/2005: From this version on, it is not necessary more that the base ring to have a parameter(except for two static procedure 'linear1' and 'linear2'). To calculate with the the polynomial 'f' in the sense of previous versions, we have to introduce the parameter 's' and work with the polynomial 'f-s'. Many procedures create the parameter 's' and then start to calculate with 'f-s'. The following changes on each procedure are made: The type of the procedure 'discriminant' is now 'number' and not 'polynomial'. Procedure 'S' does not exists more. Please use 'discriminant' instead of 'S'. The procedure 'addparam' is added. In the previous versions of 'mulmat' and 'muldF' twice the command 'std' was used. Now it is once. The proceedures 'etaof' and 'infoof' are added. The proceedure 'infoof' is created in order to avoid repeated calculations. The static procedures 'linear1' and 'linear2' has been changed by adding 'list lula'. But still they need the first parameter of the base ring for calculations. To use the procedures 'linear' and 'linearp' we do not need more to introduce an additional parameter for the basering. These procedures in the new version use the procedure 'addparam' to define a new ring with an additional parameter and after doing calculations they export the result to the previous ring. A list of the output type of 'infoof' is added as an optional entry. The procedure 'gaussmanin' calculate the Gauss-Manin connection of a single differential form in both Brieskorn modules. The procedure 'gaussmaninp' does not exist more. Instead there is 'gaussmaninmatrix' which works for both Brieskorn modules. The static procedure QP which is used in 'nabla' and 'nablap' of the previous version has been changed. 'nabla' and 'nablap' do not exist more. Version 1.21: 12/1/2006: The procedure 'foliation' is added. Version 1.3: 20/4/2006 A revision of the procedures. 'gaussmanin' and 'PFeq' do not work properly for the examples of [Mo2]. Wowwww, I found the reason. In the procedure 'etaof' the tame polynomial f mines a new parameter was written instead of f. I am not at all a good programmer. The procedure 'PFEq' does not exist more. Version 1.31: 8/7/2006 Some modifications on the procedure 'hodgenum'. Also the help of some procedures are improved. In the 'infoof' it is only use 'std' and if we want to use 'groebner' we have to modify 'infoof' directly. Version 1.32: 10/7/2006 Now, it is possible to give the discriminant to etaof and get its corresponding eta. Version 1.33: 12/7/2006 The new procedures 'gaussmaninvf' and 'PFequ' are added. 'gaussmaninvf' has the same structure as 'gaussmanin'. The difference is that it calculates the Gauss-Manin connection along a vector field and at the end it does not write the output in the canonical basis. The body of 'PFequ' is similar to 'sysdif' and it uses 'gaussmaninvf'. In general it is faster than 'PFeq'. Version 1.34: 19/7/2006 The procedure dbeta is modified and the procedures Imk, Abeta, changebase do not exit more. I may put them in the future versions. The procedure PFequ returns a matrix in which the some zeros are deleted. The procedure gaussmaninvf uses linear/linearp to simplify its output. For this reason some part of PFequ is deleted. Version 1.36: 13/10/2011 The procedure qexpansion, HalphenRamanujan, derivatives and LinearRelations is added. From this version on, I am just collecting here all procedures that I am writing. Version 1.40: 20/03/2012 The procedure t1t2t3 and t1t2t3primepowers is added. Version 1.41: 03/04/2012 The procedure EisensteinTriangular is added. Version 1.42: 29/08/2012 The procedures OneOver and LambertSeries is added. Version 1.43: 05/12/2012 The procedures t1t2t3, t1t2t3primepower, EisensteinTriangular, OneOver and LambertSeries are moved to a new library called triangulargroup.lib. The library linalg.lib is automatically loaded. Version 1.5: 2/01/2016 The procedure lcm, MixedHodgeFermat, HodgeNumber, PeriodMatrix, IntersectionMatrix, DimHodgeCycles, BasisHodgeCycles, MulMat, Matrixpij, CodModInt is added. 'finvar.lib' is automatically dowloaded. Version 1.52: 08/04/2016 OneOver and LambertSeries are added. Version 1.5 01/05/2016 TraAlg added. Version 1.5 12/05/2016 PochhammerSymbol is added Version 2.00 15/01/2017 This version is prepared for the publication of the Book: A course in Hodge theory: with emphasis on multiple integrals. For more details see this book. Version 2.01, 20/01/2017 The input and output of 'PochhammerSymbol' are now numbers and not polynomials. Version 2.02, 27/03/2017 The procedures 'CodComIntZar' and 'SumTwoLinearCycle' are added. Version 2.10, 15/06/2017 In the procedure 'PeriodLinearCycle' the sign of the permutation was not included. This was producring a contradictory results. The procedure 'SignPerm', 'Monomials', 'TaylorSeries', 'EquHodge' and 'SmoothReduced' are added. Version 2.11 20/06/2017 The last optional entry of 'Monomials' is modified. An optional entry is added to 'TaylorSeries' so that it returns the homogeneous pieces of the Taylor series as a list. 'EquaHodge' and 'SmoothReduced1' and 'SmoothReduced2' are added. Version 2.15 30/06/2017 The following procedures ar added: 'aIndex', 'bIndex', 'ListPeriodLinearCycle', 'SumThreeLinearCycle', 'DistinctHodeLocus' 'RandomIntVec' and 'GoodMinor'. 'PeriodsLinearCycle' has the new name 'PeriodLinearCycle'. Version 2.17 03/07/2017 'SumTwoLinearCycle' has now an optional entry. Its example is modified. The procedures 'aIndex' and 'ListPeriodLinearCycle' are modified. The procedures 'SmoothReduced1', 'SmoothReduced2' and 'EquaHodge' are outdated. Instead use 'SmoothReduced' and 'HodgeLocusIdeal'. 'SmoothReduced1' is completely removed. Version 2.18 13/07/2017 'SumTwoLinearCycle' has now a third option in its optional entry. 'ConstantRank' is added. 'Monomials' has a fourth option. 'SmoothReduced' another optional entry for half-half hypersurfaces. Version 2.19 24/07/2017 'SmoothReduced' is improved. Version 2.20 14/08/2017 Enzo Aljovin's 'bIndex' procedure is added. For the old version of 'bIndex' see version 2.19 of foliation.lib. The new version of 'bIndex' uses 'remove_element', 'find_min' and 'bIndex_helper'. The resentation of 'SumThreeLinearCycle', 'ListPeriodLinearCycle' and 'DistinctHodeLocus' are improved. 'mTwoLinearCycle' is added. 'InsertNew' and 'ndm' are added. Version 2.22 04/06/2018 'mLinearCycle' and 'Diffvf' are added. Version 2.25 04/12/2018 'InterTang' is added. A new option is added to 'SmoothReduced' so that it can receive the output of 'InterTang'. Version 2.26 10/12/2018 'SmoothReduced' has an extra option which reports what it is doing. Version 2.28 27/01/2019 'RandomPoly' and 'CodRuledCubic' is added. Version 2.29 21/02/2019 'CodQuarticScroll' and 'CoVer' are added. A mistake in 'CodRuledCubic is repaired: Instead of '2' one should have written d-1 (for d=3 this was ok). Version 2.30 12/05/2019 A new option is added to 'SmoothReduced' so that it can consider a sum of two complete intersection algebraic cycles. Version 2.32 15/05/2019 The procedure 'DeformSpace' is added. This is a better version of 'InterTang' and it is designed to have smaller deformation spaces in the case of sum of complete intersection cycles. A new option is added to 'SmoothReduced' so that it can consider a sum of two complete intersection algebraic cycles with samller deformation space computed from 'DeformSpace'. Version 2.33 19/05/2019 'TwoCI' is added. A list of two complete intersection cycles. Version 2.34 24/05/2019 After a conversation with Walter, I realized that there is a mistake in 'multdF' and hence 'debta'. The previous version was not working for families of K3 in my articlewith Doran et al. The mistake in 'multdF' is corrected. Version 2.35 15/04/2020 The procedure 'ListMon' is added. This is a simple modification of 'MixedHodgeFermat'. Version 2.37 15/06/2020 The procedure 'SyzFol', 'Minfol' and 'BadPrD' are added. Version 2.39 22/07/2020 'BadPrV', 'Discrim' and 'LCurves' are added. Version 2.40 03/08/2020 The procedure 'MinFol' had wrong output for smooth curves. This has benn fixed. The help section of 'MinFol' is also improved. Version 2.41 17/11/2020 In 'IntersectionMatrix' the sign is changed from 'n(n+1)/2' to 'n(n-1)/2'. Version 2.42 28/12/2020 The procedure 'MinFol' has an optional parameter which gives the foliation omega_f in the article Camacho-Movasati KEYWORDS:See the articles above. PROCEDURES: GENERAL PROCEDURES: okbase, it is similar to kbase lasthomo, last homogeneous polynomial of a given polynomial mulmat, multiplication matrix of f in the Milnor vector space of g muldF, multiplication matrix of homogeneous polynomial, divmat, similar to division eta, the canonical n-form eta difofn. differential of an n-form, addparam, adding parameters to a ring, cleardenommat, clear denominators of a matrix expression substpar, substitute in a paramter, dfwedge, wedge product of df with an n form, diffpar, differentiation with respect to a parameter, SignPerm, Sign of a permutation. Monomials, the list of monomials in a given variables, RandomIntVec, a random integer vector, GoodMinor, a maximal minor of a matrix with non-zero determinant, InsertNew, insert an element in a list if it is new. Diffvf, differentiating along a vector field. RandomPoly, a random homogeneous polynomial. PROCEDURES RELATED TO THE TAME POLYNOMIAL f: discriminant, discriminant of a polynomial, etaof, the differential n-form eta, infoof, calulates many useful information of a tame polynomial. dAbeta, Abeta numbers associated to a basis of Milnor vector space linear, writes an element of H'' in its canonical basis linearp, writes an element of H' in its canonical basis gaussmanin, Gauss-Manin connection in the Brieskon modules H', H''. gaussmaninvf, Gauss-Manin connection along a vector field. PFequ, Picard-Fuchs equations in both Brieskorn module H', H''. gaussmaninmatrix, Gauss-Manin connection matrix in the Brieskon modules H', H''. PFeq, Picard-Fuchs equations in both Brieskorn module H', H''. dbeta, the numbers dbeta which gives us a basis compatible with MHS. sysdif, getting Picard-Fuchs equations from a Fuchsian system. LinearRelations, linear relations in the Brieskorn module of a singular tame polynomial. PROCEDURES RELATED TO THE FERMAT VARIETY: MixedHodgeFermat, Mixed Hodge structure of an affine Fermat variety. lcm, the lowest common divisor. HodgeNumber, Hodge numbers of hypersurfaces. PeriodMatrix, the period matrix of the Fermat variety. RemoveList, remove a list from another list. DimHodgeCycles, Dimension of the space of Hodge cycles. BasisHodgeCycles, Basis of the space of Hodge cycles. IntersectionMatrix, Intersection matrix in homology. Matrixpij, Martrix of periods pij. TranCoho, Transcendetal part of the cohomology. LinearCoho, Part of the cohomology representing Linear cycles. PeriodLinearCycle, periods of linear cycles. CodComInt, codimension of the loci of hypersurfaces, Codim, a number related to Koszul complex. SumTwoLinearCycle, codimension of a Hodge locus. TaylorSeries, the taylor series of periods of hypersurfaces. EquHodge, a list of possible minimal generators of the Hodge locus. SmoothReduced1, old version of SmoothReduced2, Check whether the Hodge locus is smooth and reduced. aIndex, a Index of linear cycles. bIndex, b index of linear cycles. ListPeriodLinearCycle, List of period vectors of linear cycles. SumThreeLinearCycle, the rank of [p_{i+j}] for sum of three linear cycles. DistinctHodeLocus, To verify that two Hodge loci are distinct. GoodMinor, a maximal square minor of a matrix with nonzero determinant. RandomIntVec, Random integer vector. SmoothReduced, a better version of SmoothReduced2. ConstantRank, the constant rank for sum of two linear cycles. mTwoLinearCycle, the intersection dimension of two linear cycles. ndm, verifying that a number related to Hodge cycles depends only on n, d, m. mLinearCycles, the intersection dimension of a list of linear cycles. InterTang, A perpendicular space to intersections of tangent spaces of some Hodge loci. CodRuledCubic, codimension of the loci of hypersurfaces containing a ruled cubic cycle. CodQuarticScroll, codimension of the loci of hypersurfaces containing a quartic scroll cycle. CodVeronese, codimension of the loci of hypersurfaces containing a Veronese cycle. DeformSpace, an orthogonal space to the intersection of tangent spaces of many Hodge loci. TwoCI, a list of two complete intersection algebraic cycle inside the Fermat variety. ListMon, a list of monomials with A_beta less than a fixed number. PROCEDURES RELATED TO MODULAR DIFFERENTIAL EQUATIONS: foliation, the foliations obtained by level surface of integrals. qexpansion, claculating q-expansion using the modular differential equations. HalphenRamanujan, the data bank of modular differential equations. derivatives, derivatives of a list with respect to variables. OneOver, one over a formal power series. LamberSeries, Lambert series format of a formal power series. PochhammerSymbol, Pochhammer Symbol. SyzFol, the syzygy attached to a foliation with an invariant curve (used in the article with C. Camacho). MinFol, the syzygy of the space foliations in C2 having a fixed invariant curve (used in the article with C. Camacho). BadPrD, the bad primes of a linear differential equation. BadPrV, the bad primes of a vector field. Discrim, the descriminant of a tame polynomial written in the first variable of the base ring. LCurves, list of curved I was discussing with C. Camacho during 2020 (corona virus year). OLD PROCEDURES: hodgenum, Hodge numbers of weighted hypersurfaces. DimensionOfHodgeCycles, Dimension of Hodge cycles, old version. MulMat, Multiplcation with a polynomial. MatrixpijOld, Matrix of periods (might be used beyond Fermat!) "; LIB "linalg.lib"; LIB "finvar.lib"; LIB "latex.lib"; //--------------------------------------------------------------------------- //---------------------------GENERAL PROCEDURES------------------------------ //--------------------------------------------------------------------------- proc okbase (ideal I) "USAGE: okbase(ideal_expression) RETURN: The same as the input type of the first argument. It is the same as kbase. The degree function on the output monomials is decreasing. SEE ALSO: kbase EXAMPLE: example okbase; shows an example " { ideal V=kbase(I); int mu=size(V); int i; int j; poly p; for (i=1;i<=mu;i=i+1) { for (j=i+1;j<=mu;j=j+1) { if ( deg(V[j]) > deg(V[i]) ){ p=V[j]; V[j]=V[i]; V[i]=p;} } } return(V); } example {"EXAMPLE:"; echo=2; ring r=0, (x,y),dp; poly f=x3+y3; okbase(std(jacob(f))); } //-------------------------------------------------------------------------- proc lasthomo (poly f) "USAGE: lasthomo(poly_expression) RETURN: The same as the input type. This procedure finds the last homogeneous part of the polynomial f. SEE ALSO: poly, deg EXAMPLE: example lasthomo; shows an example " { int s=size(f); int d=deg(f); poly g=0; for (int k=1; k<=s; k=k+1) { if (deg(f[k])==d) { g=g+f[k]; } } return(g); } example {"Example:"; echo=2; ring r=0, (x,y),dp; poly f=2*(x3+y3)-3*(x2+y2); lasthomo(f); } //--------------------------------------------------------------------------- proc mulmat (poly f, poly g,list #) "USAGE: mulmat(poly_expression,poly_expression) mulmat(poly_expression,poly_expression,ideal_expression) RETURN: Quadratic matrix. It computes the matrix of multiplication by 'f' in the Milnor vectorspace of 'g'. If you know the standard basis of the jacobian ideal of 'g' please give it as the third entry. SEE ALSO: okbase, matrix EXAMPLE: example mulmat; shows an example " { if (size(#)==0){ideal gI=std(jacob(g));}else{ideal gI=#[1];} ideal V=okbase(gI); int mu=vdim(gI); if (mu==0) { "// **", g, " has no singularity **"; } if (mu<0) {"// **", g, "has not isolated singularities **";} if (mu>0) { matrix A[mu][mu]; int s,i,k; poly h1; for (k=1; k<=mu; k=k+1) { h1=reduce(f*V[k], gI); for (s=1; s<=size(h1); s=s+1) { for (i=1; i<=mu; i=i+1) { if ( leadmonom(h1[s]) == leadmonom(V[i]) ) {A[k,i]=leadcoef(h1[s]);} } } } return(A); } } example {"Example:"; echo=2; ring r=0, (x,y),dp; poly f=2*(x3+y3)-3*(x2+y2); print(mulmat(f,f)); ideal gI=std(jacob(f)); print(mulmat(f,f, gI)); } //-------------------------------------------------------------------------- proc muldF(poly f,list #) " USAGE: muldF(polynomial expression); muldF(polynomial expression, ideal_expression); RETURN: Quadratic matrix It uses mulmat to calculate the multiplication of dF/dx_0 in C[x,x_0]/, where F is the homogenization of f. Since the base ring is not supposed to have the variable x_0, we have used the first varible of the base ring instead of x_0 for the output. If you know the standard basis of the jacobian of f give it as the second entry. SEE ALSO: mulmat, okbase " { if (size(#)==0){ideal gI=std(jacob(f));}else{ideal gI=#[1];} ideal V=okbase(gI); int mu=vdim(gI); int d=deg(f); matrix A[mu][mu]=mulmat(f,f,gI); int i; int j; for (i=1;i<=mu;i=i+1) { for (j=1;j<=mu;j=j+1) { if ((deg(V[i])-deg(V[j])+d-1)>=0 ) { A[i,j]=d*var(1)^(deg(V[i])-deg(V[j])+d-1)*A[i,j]; } } } //for (i=1;i<=mu;i=i+1){A[i,i]=A[i,i]-d*par(1)*var(1)^(d-1);} return(A); } example {"Example:"; echo=2; ring r=(0,s), (x,y),dp; poly f=2*(x3+y3)-3*(x2+y2); print(muldF(f)); ideal gI=std(jacob(f)); print(muldF(f,gI)); } //-------------------------------------------------------------------------- proc divmat (poly h, ideal I, list #) " USAGE: divmat(poly_expression, ideal_expression) divmat(poly_expression, ideal_expression, ideal_expression) RETURN: A list. This procedure is a modification of the procedure division. If the quotient of the ideal I is finite dimensional then this procedure returns a list. The first entry is the matrix of coefficients of the reminder and the other is a matrix of polynomials which appear in the division. The matrix of coefficients is indexed by the entries of okbase(std(I)). If you know 'ideal V=okbase(std(I))' give it as the third entry. NOTE: This procedure is only used in linear1. SEE ALSO: okbase, division EXAMPLE: example divmat; shows an example " { if (size(#)==0){ideal V=okbase(std(I));}else{ ideal V=#[1];} int mu=size(V); matrix A[1][mu]; int s,i,k; list lh=division(h, I); int sh=size(lh[2][1]); for (s=1; s<=sh; s=s+1) { for (i=1; i<=mu; i=i+1) { if ( leadmonom(lh[2][1][s]) == leadmonom(V[i]) ) {A[1,i]=leadcoef(lh[2][1][s]);} } } list l=lh[1], A; return(l); } example {"Example:"; echo=2; ring r=0, (x,y),dp; ideal I=x2,y3; poly h=xy+x3; divmat(h,I); ideal V=okbase(std(I)); divmat(h,I,V); } //--------------------------------------------------------------------------- proc eta() " USAGE: eta() RETURN: This is the canonical n-form in C^{n+1} stored as a 1*(n+1) matrix. To obtain the eta in the text [Movasati2005] one has to divide it by d, the degree of f. EXAMPLE: example eta; shows an example " { int n=nvars(basering)-1; int i; matrix e[1][n+1]; for (i=1;i<=n+1;i=i+1) {e[1,i]=deg(var(i))*(-1)^(i-1)*var(i);} return(e); } example {"Example:"; echo=2; ring r=0, (x,y),dp; eta(); } //--------------------------------------------------------------------------- proc difofn (matrix P) " USAGE: difofn(poly_expression) RETURN: An n-form P in C^{n+1} is stored as a 1*(n+1) matrix. The 1*i entry of P is the coefficient of dx_1\wedge d_{i-1}\wedge dx_{i+1}\cdots dx_{n+1} This procedure calculates the polynomial Q such that d(P)=Q dx. " { int n=ncols(P)-1; poly Q=0; for (int i=1; i<=n+1;i=i+1) { Q=Q+(-1)^(i-1)*diff(P[1,i],var(i)); } return(Q); } example {"Example:"; echo=2; ring r=0, (x,y),dp; difofn(x^3*eta()); } //---------------------------------------------------------------------- proc addparam (string @t) " USAGE: addparam(string_expression) RETURN: It adds a new parameter , which is the string in @t, to the 'ringlist' of the basering and returns a new list 'Lring'. The new parameter is the first parameter of the new ring. Using the command 'def new=ring(Lring)' one can define the new ring with the additional parameter. This procedure works only for the field Z_p,Q and their transcendental extensions. EXAMPLE: example addparam; shows an example " { // Set up new ring and make it the active ring: //====== list Lring = ringlist(basering); // An integer which distinguishes the base field. //It becomes 1 if the base field changes. int abc=0; //If base field is Q or Z_p if (typeof(Lring[1])=="int") { list lili=Lring[1], list(@t), list(list("lp",intvec(1))), ideal(0); Lring[1]=lili; abc=1; } //If the base field has already parameters. if (typeof(Lring[1])=="list" and size(Lring[1])==4 and abc==0) { Lring[1][2]=insert(Lring[1][2], @t); // add new parameter with name // what exists inside @t. Lring[1][3]=insert(Lring[1][3], list("lp",intvec(1))); // implement product ordering abc=1; } if (abc==0) { "//** You are not allowed to work in this base ring. Please look at the help section of the command you have used**"; } else { return(Lring); } } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; ringlist(basering); //We add a new parameter called newpa. addparam("newpa"); } //---------------------------------------------------------------------- proc cleardenommat (matrix A) "USAGE: cleardenommat (matrix_expression) RETURN: A list of a number k and a matrix B such that A=kB. This procedure multiplies a matrix by a suitable constant to cancel all denominators from its coefficients and then divide it by its content. For this the matrix is changed to a vector and then cleardenom (vector_expression) is used. SEE ALSO: cleardenom, matrix " { vector v; int i,j,s; s=1; int nc=ncols(A); int nr=nrows(A); matrix B[nr][nc]; number cons; int inotzero,jnotzero; for (i=1;i<=nr;i=i+1) //This part find a non-zero coefficient of A { for (j=1;j<=nc;j=j+1) { if (A[i,j]<>0){cons=leadcoef(A[i,j]); inotzero=i; jnotzero=j; i=nr+1;j=nc+1;}} } for (i=1;i<=nr;i=i+1) { for (j=1;j<=nc;j=j+1) { v=v+A[i,j]*gen(s); s=s+1; } } v=cleardenom(v); s=1; for (i=1;i<=nr;i=i+1) { for (j=1;j<=nc;j=j+1) { B[i,j]=v[s]; s=s+1; } } matrix zerocheck=A; zerocheck=0; list l; if (A==zerocheck) {cons=0;} else { cons=cons/leadcoef(B[inotzero,jnotzero]); } l=cons,B; return(l); } example {"Example:"; echo=2; ring r=0, (x,y),dp; matrix A[1][2]=(4/3)*(x3+y3)-2*(x2+y2),2; print(cleardenommat(A)); } //--------------------------------------------------------------------------- proc substpar(P, number para, poly Q) "USAGE: substpar(poly_expression, par_expression, poly_expression) substpar(matrix_expression, par_expression, poly_expression) substpar(number_expression, par_expression, poly_expression) RETURN: The same as the first argument of the input, except in the third case which is a polynomial. It substitutes in parameter 'para' of 'P' the poynomial 'Q'. If one gets zero in the denominator then a 'Division by zero' is shown. If one tries to substitute a non constant polynomial in the denominator then 'Substitition of a polynomial in a denominator' is shown. We have used subst(poly_expression, par_expression, poly_expression) in this proceedure. SEE ALSO: cleardenommat, subst EXAMPLE: example substpar; shows an example " { poly denom; list l; string hefz=typeof(P); if (typeof(P)=="poly" or typeof(P)=="number") {matrix P1[1][1]=P;} //First we change P into a matrix. if (typeof(P)=="matrix") {matrix P1=P;} l=cleardenommat(P1); P1=numerator(l[1])*l[2]; P1=subst(P1, para,Q); denom=subst( denominator(l[1]),para,Q); if (leadcoef(denom)==denom) //If in the denominator we have not a //constant polynomial. { if (denom==0) {"// ** Division by zero **";} else { P1=(1/denom)*P1; if (hefz=="matrix"){return(P1);} if (hefz=="poly"){return(P1[1,1]);} if (hefz=="number") { if (typeof(Q)=="number"){return(number(P1[1,1]));} else{return(P1[1,1]);} } } } else {"// ** Substitition of a polynomial in a denominator **";} } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; poly f=2*(t*x3+y3)/(t+1); substpar(f,par(1),t^2-1); } //--------------------------------------------------------------------------- proc dfwedge(poly f, matrix et) " USAGE: dfwedge(poly_expression, matrix_expression) RETURN: This procedure takes the wedge product of df with the n-form et and return it as a polynomial. " { poly P=0; int i; int n=nvars(basering)-1; for (i=1;i<=n+1;i=i+1) {P=P+(-1)^(i-1)*diff(f,var(i))*et[1,i];} return(P); } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; poly f=2*(x3+y3)-3*(x2+y2); dfwedge(f,eta()); } //--------------------------------------------------------------------------- static proc diffparpol(poly chuz, number parame) " USAGE: This proceedure takes the derivation of the polynomial 'chuz' with respect to the parameter 'parame'. See diffpar for more details. " { int mc; //monomial counter of the entries of chiz poly komaki1, komaki2; // In this poly we save the coefficients and //then derivate them. list lofmonom; // list of derivated monomials of the entries of chiz int s; //To add the elements of the list together poly Nom, Denom; //We separate denominator and numerator of a //coefficient to be able to derivate it. poly dercoef; //the derived coefficient is stored here. for (mc=1;mc<=size(chuz);mc=mc+1) { Denom=denominator(leadcoef(chuz[mc])); Nom=numerator(leadcoef(chuz[mc])); komaki1=subst(Nom, parame, var(1)); //The variable var(1) is //used for derivation. komaki2=subst(Denom, parame, var(1)); komaki1=diff(komaki1, var(1)); komaki2=diff(komaki2, var(1)); komaki1=subst(komaki1, var(1),parame); komaki2=subst(komaki2, var(1),parame); dercoef=leadmonom(chuz[mc])*(Denom*komaki1-Nom*komaki2)/Denom^2; lofmonom=insert(lofmonom, dercoef); } chuz=0; for (s=1;s<=size(lofmonom); s=s+1){chuz=chuz+lofmonom[s];} return(chuz); } //-------------------------------------------------------------------------- proc diffpar (chiz, number param) "USAGE: diffpar(poly_expression, par_expression) diffpar(matrix_expression, par_expression) diffpar(number_expression, par_expression) RETURN: The same as the first argument of the input. It takes the derivative of 'chiz' with respect to the parameter 'param'. It first separates the denominator and nominator of coefficients of 'chiz' and then substitutes the first variable of the base ring for the parameter 'param' and then uses the command 'diff' to derivate both the denominator and nominator. SEE ALSO: diff EXAMPLE: example diffpar; shows an example " { if (typeof(chiz)=="poly") { return(diffparpol(chiz, param)); } if (typeof(chiz)=="matrix") { int i,j; //rows and columns counters of chiz int nc=ncols(chiz); int nr=nrows(chiz); for (i=1;i<=nr;i=i+1) { for (j=1;j<=nc; j=j+1) { chiz[i,j]=diffparpol(chiz[i,j],param); } } return(chiz); } if (typeof(chiz)=="number") { poly bia=chiz; return(number(diffparpol(bia,param))); } } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; poly f=2*(t*x3+y3)/(t); diffpar(f,par(1)); matrix A[1][2]=f,x/(t+1); print(diffpar(A,par(1))); } //-------------------------------------------------------------------------- //---------------PROCEDURES RELATED TO A TAME POLYNOMIAL-------------------- //-------------------------------------------------------------------------- proc discriminant(poly f) "USAGE: discriminant(poly_expression) RETURN: a number in the base field This procedure takes f and find the matrix A of multiplication by f in the Milnor vector space and then takes the determinant P=det(A). The equation P=0 is the locus of parameters in which f=0 is singular. SEE ALSO: okbase EXAMPLE: example discriminant; shows an example " { ideal I=jacob(f); ideal gI=std(I); ideal V=okbase(gI); int mu=vdim(gI); if (mu<0) {"// **", f, "is not a tame polynomial**";} if (mu==0) {return(1);} if (mu>0) { matrix A[mu][mu]; int s,i,k; poly h1; for (k=1; k<=mu; k=k+1) { h1=reduce(f*V[k], gI); for (s=1; s<=size(h1); s=s+1) { for (i=1; i<=mu; i=i+1) { if ( leadmonom(h1[s]) == leadmonom(V[i]) ) {A[k,i]=leadcoef(h1[s]);} } } } number sf=leadcoef(det(A)); return(sf); } } example {"Example:"; echo=2; ring r=(0,t,s), (x,y),dp; poly f=2*(x3+y3)-3*(s*x2+y2)-t; discriminant(f); } //--------------------------------------------------------------------------- proc etaof(poly f, list #) " USAGE: etaof(poly_expression) etaof(poly_expression, number_expression, par_expression) RETURN: This procedure calculates the discriminant 'S(s)' of 'f-s' for an additional parameter 's' , the n-differential form 'etaf' in 'S(f)dx=df\wedge etaf'. and returns a list. The first entry is the discriminant of of 'f' and the second entry is etaf as '1*(n+1)' matrix, where 'n+1' is the number of variables. If your polynomial is already of the form 'f-s', where 's' is a parameter which does not appear in 'f' and you know a reduced form of the discriminant of 'f' then give the reduced form and the parameter 's' as the second and third entries, respectively. This may be useful because in general the discriminant is a huge rational function in parameters. SEE ALSO: discriminant, addparam, substpar EXAMPLE: example etaof; shows an example " { if (size(#)==0) { // Set up new ring with an additional parameter @@t and make it the active ring: //====== def prevRing=basering; def newRing=ring(addparam("@@t")); //Note that in the new ring par(1)=@@t setring newRing; poly f=imap(prevRing, f); poly newf; //Starting to calculate in the new ring. newf=f-par(1); number Sf=discriminant(newf); number delta=number(substpar(Sf, par(1),0)); poly Sff=substpar(Sf, par(1),f); matrix etif=transpose( division(Sff, jacob(f))[1] ); int i; int n=ncols(etif)-1; //The entries of the division by jacob(f) of //Sff differs from the entries //of the differential form eta_f by some minus ones! for (i=1;i<=n+1;i=i+1) { etif[1,i]=(-1)^(i-1)*etif[1,i]; } //Getting back to the previous ring setring prevRing; number delta=number(imap(newRing,delta)); //Here I do not know why imap changes //delta to a poly. For this reason I //have put number() matrix etif=imap(newRing, etif); list finaly=delta, etif; return(finaly); } else { poly Sff=substpar(#[1], #[2], f+#[2]); list afterdiv=division(Sff, jacob(f)); if (afterdiv[2]==0) { matrix etif=transpose(afterdiv[1]); int i; int n=ncols(etif)-1; //The entries of the division by jacob(f) of //Sff differs from the entries //of the differential form eta_f by some minus ones! for (i=1;i<=n+1;i=i+1) { etif[1,i]=(-1)^(i-1)*etif[1,i]; } list finaly=#[1], etif; return(finaly); }else {"// **", #[1], "does not work**";} } } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; poly f=2*(t*x3+y3-t*x); etaof(f); } //-------------------------------------------------------------------------- proc infoof (poly f, list #) "USAGE: infoof(poly_expression) infoof(poly_expression, number_expression, matrix_expression) RETURN: This procedure gives us the following list of objects calculated from a tame polynomial: 1. The last homogeneous piece 'g' of 'f', 2. the jcobian ideal of 'g', 'I=jacob(g)', 3. the polynomial 'f1=f-g', 4. the jacobian ideal of 'f1', 'I1=jacob(f1)', 5. the jacobian ideal of 'f', 'I2=jacob(f)', 6. the standard basis of 'I', 'gI=std(I)', if the list # has less than three entries. If not then the procedure uses 'groebner'. 7. 'V=okbase(gI)', 8. the Milnor number 'mu=vdim(gI)', 9. the discriminant of f, 'delta=discriminant(f)', 10. the differential n-form 'eta' with 'S(f)dx=df wedge eta', where S(s) is the discriminant of f-s. If you already know the delta and eta then give them as the second and third entries. Note that we have to multiply the i-th entry of 'transpose(division(S(f), jacob(f))[1])' with '(-1)^(i-1)' in order to obtain eta. This procedure is created because I want to avoid calculating the same objects many times in the procedures of this library. SEE ALSO: okbase, jacob, std, groebner, vdim, lasthomo, etaof. EXAMPLE: example infoof; shows an example " { list final; poly g=lasthomo(f); final=g; ideal I=jacob(g); final=insert(final, I, 1); poly f1=f-g; final=insert(final, f1, 2); ideal I1=jacob(f1); final=insert(final, I1, 3); ideal I2=jacob(f); final=insert(final, I2, 4); ideal gI=std(I); final=insert(final, gI, 5); //You may want to use here groebner instead of std ideal V=okbase(gI); final=insert(final, V, 6); int mu=vdim(gI); final=insert(final, mu, 7); if (size(#)==2){list da=#;} else{list da=etaof(f);} final=insert(final, da[1], 8); final=insert(final, da[2], 9); return(final); } example {"EXAMPLE:"; echo=2; ring r=(0,t(0..3)), (x,y),wp(2,3); poly f=y^2-4*t(0)*(x-t(1))^3+t(2)*(x-t(1))+t(3); infoof(f); list genkin=etaof(f); infoof(f,genkin); } //-------------------------------------------------------------------------- static proc dAbeta(poly P) "RETURN: This procedure multiplies the polynomial P with all variables of the base ring and then takes degree. NOTE: It is used in linear1 and linear2. " { poly Q=P; int n=nvars(basering)-1; for (int i=1;i<=n+1; i=i+1){Q=Q*var(i);} return(deg(Q)); } //----------------------------------------------------------------------- static proc epsilon(int i, int j) "RETURN: 1 or 0 depending if i>j or not. " { int k=0; if (i>j) {k=1;} return(k); } //---------------------------------------------------------------------- static proc linear1 (poly P, list lula) "USAGE: linear1(poly_expression, list_expresion) RETURN: A list with three entries. The list lula is the output list of 'infoof'. This procedure takes a homogeneous polynomial g and a (n+1)-form [Pdx] in the Brieskorn module H'', where (n+1) is the number of variables of the base ring, and write [Pdx] as a linear combination of [V[1]dx], [V[2]dx],..., where V is produced by okbase(g). The output is a list. The first entry is a 1*mu matrix C containing the coefficients of [V[1]dx],[V[2]dx],..., where mu is the Milnor number of g If n>0 the second is a mu*mu matrix representing the (n-1)-form xi such that Pdx=C[1,1]*V[1]dx+C[1,2]*V[2]dx+...+df\wedge d(xi). The base ring must contain at least one parameter and C is written in the first parameter. In this case the third entry is zero. If n=0 then the output list has third entry p_of_g. This is a polynomial in the first parameter of the base ring such that Pdx=C[1,1]*V[1]dx+ C[1,2]*V[2]dx+...+p_of_g(f)f'dx. In this xi is 1*1 zero matrix. The first parameter of the base ring is reserved for the computer. SEE ALSO: divmat " { poly g=lula[1]; ideal I=lula[2]; ideal gI=lula[6]; int mu=lula[8]; ideal V=lula[7]; int n=nvars(basering)-1; int d=deg(g); matrix C[1][mu]; matrix eta[n+1][1]; matrix xi[n+1][n+1]; //In this matrix we keep the (n-1)-form which appears //in the equality. int pg=0; //this natural number is for the powers of g poly p_of_g; //In the case n=0, dAbeta-deg(V[i]) can be zero. //In this we do not have xi as above but a function //of g. The p_of_g(g)g' is zero in H'' list l; int i;int j; int s; int k; poly c; poly P1=P; while (P<>0) { l=divmat(P, I, V); P=0; C=C+l[2]*par(1)^pg; eta=l[1]; for (i=1;i<=n+1;i=i+1) { k=size(eta[i,1]); for (s=1;s<=k; s=s+1) { c=dAbeta(eta[i,1][s])-deg(var(i)); if (c==0){p_of_g=p_of_g+eta[i,1][s]*par(1)^pg;} //This happens only in the case n=0 else { P=P+ (d/c)*diff(eta[i,1][s], var(i)); for (j=1;j<=n+1;j=j+1) { if (j<>i) { xi[i,j]=xi[i,j]+g^(pg)* (-1)^(i+j+1+epsilon(i,j))* (var(j)*eta[i,1][s]*deg(var(j))/c); } } } } } pg=pg+1; } for (j=1;j<=n+1;j=j+1) { for (i=1;i0 the second is mu*mu matrices representing the (n-1)-form xi such that P -C[1,1]*V[1] eta/d-C[1,2]*V[2] eta/d-...+df\wedge xi is exact(Note the sum addition attached to term of xi). In this case the third entry is zero. The base ring must contain at least one parameter and C is written in the first parameter. If n=0 then the output list has third entry p_of_g. This is a polynomial in the first parameter of the base ring such that P1 -C[1,1]*V[1] eta/d-C[1,2]*V[2]eta/d-... is of the form p(g) and derivation of p is equal to p_of_g. In this xi is 1*1 zero matrix. The first parameter of the base ring is reserved for the computer. SEE ALSO: substpar " { poly g=lula[1]; ideal V=lula[7]; int n=nvars(basering)-1; int d=deg(g); int mu=lula[8]; int i, j; ideal I=lula[2]; ideal gI=lula[6]; list l=linear1(P,lula); matrix C=substpar(l[1], par(1),var(1)); //We do not have the degree //of a polynomial in parameter. //For this reason we use var(1) matrix C1[1][mu]; for (i=1; i<=mu; i=i+1) { for (j=1;j<=size(C[1,i]); j=j+1) { C1[1,i]=C1[1,i]+ deg(var(1))*d*C[1,i][j]/(dAbeta(V[i])*deg(var(1))+d*deg(C[1,i][j])); } } C1=subst(C1, var(1),par(1)); l=C1, l[2],l[3]; //Note that l[3] is the reminder of P return(l); } //---------------------------------------------------------------------- proc linear (poly f, poly P, list #) " USAGE: linear(poly_expression, poly_expression) linear(poly_expression, poly_expression, list_expression) RETURN: A list. This procedure takes a tame polynomial f and a (n+1)-form [Pdx] in the Brieskorn module H'', where (n+1) is the number of variables of the base ring, and write [Pdx] as a linear combination of [V[1]dx], [V[2]dx],..., where V is produced by okbase(g) and g is the last homogeneous part of f. The output is a list. The first entry is a 1*mu matrix C containing the coefficients of [V[1]dx],[V[2]dx],..., where mu is the Milnor number of f. If n>0 then the second entry is a mu*mu matrix representing the (n-1)-form xi such that Pdx=C[1,1]*V[1]dx+C[1,2]*V[2]dx+...+df\wedge d(xi) mod . If n=0 then the second entry of the output is p_of_g. This is a number in the base ring such that Pdx=C[1,1]*V[1]dx+C[1,2]*V[2]dx+...+p_of_g f'(x)dx mod . In this case xi is a 1*1 zero matrix. The third optional entry is a list as the output of 'infoof'. SEE ALSO: addparam, substpar, infoof EXAMPLE: example linear; shows an example " { list lula; if (size(#)<>0){lula=#;} else {lula=infoof(f);} // Set up new ring with an additional parameter @@t and make it the active ring: //==================================== def prevRing=basering; def newRing=ring(addparam("@@t")); //Note that in the new ring par(1)=@@t setring newRing; poly f=imap(prevRing, f); poly P=imap(prevRing, P); list lula=imap(prevRing,lula); //Starting to calculate in the new ring. poly g=lula[1]; poly f1=lula[3]; ideal I=lula[2]; ideal I1=lula[4]; ideal gI=lula[6]; int mu=lula[8]; ideal V=lula[7]; list l; int n=nvars(basering)-1; poly P1=P; int i,j; matrix C[1][mu]; matrix Cp[1][mu]; matrix xi[n+1][n+1]; matrix xip[n+1][n+1]; //These represents n-forms poly p_of_g; poly p_of_gp; while (P<>0) { l=linear1(P,lula); C=C+l[1]; Cp=l[1]; xip=l[2]; xi=xi+l[2]; p_of_g=p_of_g+l[3]; p_of_gp=l[3]; P=0; for (i=1;i<=mu;i=i+1) {P=P+(substpar(Cp[1,i],par(1),g)-substpar(Cp[1,i],par(1),f))*V[i];} if (n==0) {P=P+ diff(g,var(1))*substpar(p_of_gp, par(1),g)- diff(f,var(1))*substpar(p_of_gp, par(1),f);} for (j=1;j<=n+1;j=j+1) { for (i=1;i0 then the second entry is a mu*mu matrices representing the (n-1)-form xi such that P -C[1,1]*V[1] eta/d-C[1,2]*V[2]eta/d-...-df\wedge xi is exact mod . If n=0 then the second entry is p_of_g. In this case P -C[1,1]*V[1] eta/d-C[1,2]*V[2]eta/d-... mod is a number in the base ring mod. To see the relation between this number and p_of_g see the version<1.2 of the procedure. In this case xi is 1*1 zero matrix. SEE ALSO: eta, difofn, addparam, substpar, infoof EXAMPLE: example linearp; shows an example " { list lula; if (size(#)<>0){lula=#;} else {lula=infoof(f);} // Set up new ring with an additional parameter @@t and make it the active ring: //==================================== def prevRing=basering; def newRing=ring(addparam("@@t")); //Note that in the new ring par(1)=@@t setring newRing; poly f=imap(prevRing, f); matrix P=imap(prevRing, P); list lula=imap(prevRing, lula); //Starting to calculate in the new ring. list l; poly g=lula[1]; poly f1=lula[3]; ideal I=lula[2]; ideal I1=lula[4]; ideal gI=lula[6]; int mu=lula[8]; ideal V=lula[7]; int d=deg(g); matrix etaaa=eta()/d; matrix P1=P; int n=nvars(basering)-1; int i,j; matrix C[1][mu]; matrix Cp[1][mu]; //This matrices contain the coefficients //of V[i]. C contains the result and Cp // is for calculations matrix xi[n+1][n+1]; matrix xip[n+1][n+1]; //The n-1 form poly p_of_g, p_of_gp; //In the case n=0, we have not the n-form //xi but a polynomial p_of_g poly R=difofn(P); while (R<>0) { l=linear2(R,lula); C=C+l[1]; Cp=l[1]; xip=l[2]; xi=xi+(-1)*l[2]; p_of_gp=l[3]; p_of_g=p_of_g+l[3]; P=0; R=0; for (i=1;i<=mu;i=i+1) {P=P+(substpar(Cp[1,i],par(1),g)-substpar(Cp[1,i],par(1),f))*V[i]*etaaa;} R=R+difofn(P); if (n==0) {R=R+ diff(g,var(1))*substpar(p_of_gp, par(1),g)- diff(f,var(1))*substpar(p_of_gp, par(1),f);} for (j=1;j<=n+1;j=j+1) { for (i=1;i1) { resofgm=gaussmaninvf(f,vecfield, PP,lula); PP=resofgm[2]-(beta-2)*dvecdelta*PP; } if (typeofP=="matrix") { BP=linearp(f, PP,lula)[1]; } if (typeofP=="poly") { BP=linear(f,PP,lula)[1]; } A[beta,1..mu]=BP; B[beta,1..mu]=BP; for (j=1;j<=beta-1;j=j+1) { ge=-A[beta,sotun[1,j]]/A[j,sotun[1,j]]; A[beta,1..mu]= submat(A, beta,1..mu)+ge*submat(A,j,1..mu); pf[beta,1..mu+1]=submat(pf, beta,1..mu+1)+ ge*submat(pf, j,1..mu+1); } i=1; while (A[beta,i]==0 and i0)) { Abet[1,j]=deg(A[i,j]) div deg(var(1)); Aij=subst(A[i,j],var(1),1); coeff[1,i]=Aij; for (i1=i-1 ;1<=i1; i1=i1-1) { A[i1,1..mu]=submat(A, i1,1..mu)- (A[i1, j]*submat(A,i,1..mu))/A[i,j]; } } else { f, "=0, is singular"; critvalue=1;} } } if (which==1) { for (i=1;i<=mu;i=i+1){Abet[1,i]=d-1;} for (i=mu; 1<=i; i=i-1) { coeff[1,i]=subst(A[i,i], var(1),1); for (i1=i-1 ;1<=i1; i1=i1-1) { A[i1,1..mu]=submat(A, i1,1..mu)- (A[i1, i]*submat(A,i,1..mu))/A[i,i]; } } } int s=0; for (i=1;i<=mu;i=i+1){s=s+Abet[1,i];} if (s==mu*(d-1)) {return(list(Abet,coeff));} else {"// ** The algorithm for computing dbeta's is not is correct. Report your example to H. Movasati **";} } example {"Example:"; echo=2; ring r=(0,t), (x,y),dp; poly f=2*(x3+y3)-3*(x2+y2)-t; dbeta(f,1); dbeta(f,2); } //--------------------------------added 29/7/2005------------------------ proc sysdif (matrix GM, matrix BP, number pa, list #) "USAGE: sysdif (matrix_expression, matrix_expression, parameter_expression); sysdif (matrix_expression, matrix_expression, parameter_expression, number_expression); RETURN: In the first case it returns a '1*(mu+1)' matrix 'A'. Here 'GM' is a mu*mu matrix of the system and 'BP' is a 1*mu matrix, both with entries in the coefficient field of the base ring. This proceedure calculates the linear differential equation of ' BP*Y ', where 'Y'( a 'mu*1' matrix) is a solution of the system Y'=GP*Y and the derivation is taken with respect to the parameter 'pa'. The obtained linear differential equation is A[1,1]+A[1,2]d/dt+...A[1,mu+1]d^mu/dt^mu=0, pa=t In the second case it returns a list of A and a (nuit-1)*mu matrix B, where nuit-1 is order of the above linear differential equation and ' BY ' satisfies a system of the following type: It is of dimension 'nuit-1' and the last row of the system is [-A[1,1]/A[1,nuit],-A[1,2]/A[1,nuit],...,-A[1,nuit-1]/A[1,nuit]] and the i*(i+1) entries are 1. All other entries are zero. NOTE: The command submat from the library matrix.lib, and 'cleardenommat' is used in this procedure. At the end it checks if the result is true or not. SEE ALSO: submat, cleardenommat, diffpar EXAMPLE: example sysdif; shows an example " { int mu=ncols(GM); int nuit=0; //It counts the number of iterations of the // system int i,j, beta; beta=1; matrix pf[mu+1][mu+1]; //This matrix keeps the coefficients of GM(BP*Y)'s for (i=1;i<=mu+1; i=i+1){pf[i,i]=1;} // matrix B[mu+1][mu]; //In this matrix we keep GP^k(BP*Y)'s without //modification. We need it at the end to check our //result. matrix A[mu+1][mu]; //The main operation is done on this matrix. //GP^k(BP*Y) are stored in A poly ge; intmat sotun[1][mu]; //The sotun[1,i] is the first A[1,i] which is not //zero, every time that we modify A. while (nuit==0) { //The iteration of BP*Y beta-1 times under the Gauss-Manin connection. //Note that BP is already iterated beta-2 times. if (beta>1){BP=diffpar(BP,pa)+BP*GM}; A[beta,1..mu]=BP; B[beta,1..mu]=BP; for (j=1;j<=beta-1;j=j+1) { ge=-A[beta,sotun[1,j]]/A[j,sotun[1,j]]; A[beta,1..mu]= submat(A, beta,1..mu)+ge*submat(A,j,1..mu); pf[beta,1..mu+1]=submat(pf, beta,1..mu+1)+ ge*submat(pf, j,1..mu+1); } i=1; while (A[beta,i]==0 and i0) { list ret=final,transform; } else {matrix ret=final;} if (check1==0) {return(ret);} else {"// ** The procedure sysdif has failed for your example. Please report this to Hossein Movasati **";} } example {"Example:"; echo=2; ring r=(0,z,a,b,c),x,dp; matrix A0[2][2]=0,-b,0,1-c; matrix A1[2][2]=0,0,a,c-a-b-1; matrix A[2][2]=(1/z)*A0+(1/(z-1))*A1; print(A); matrix B[1][2]=1,0; sysdif(A,B,z); } //--------------------------------------------------------------------------------------------------------------- proc LinearRelations (poly f) " USAGE: LinearRelations(poly_expression) RETURN: A list. This procedure takes a tame polynomial f with zero discriminant. It returns a list of polynomials P such that Pdx is zero in the Gauss-Manin system. P is a linear combination of a set of monomials obtained by okbase(std(jacob(g))), wehre g is the last homogenous piece of f. SEE ALSO: difofn, substpar, infoof, mulmat, gaussred_pivot EXAMPLE: example LinearRelations; shows an example " { matrix MM=mulmat(f,f); list ll=gaussred_pivot(MM); int ran=ll[4]; int mu=ncols(MM); matrix lrc[mu-ran][mu]; int i,j; for (i=1;i<=mu-ran;i=i+1){lrc[i, i+ran]=1;} matrix A=lrc*inverse(ll[2])*ll[1]; ideal II=jacob(f); ideal V=okbase(std(II)); matrix mon[mu][1]=V; matrix alph=A*mon; list divl; list resu; int nv=nvars(basering); poly ohh; for (i=1;i<=mu-ran;i=i+1) { divl=division(f*alph[i,1],II); for (j=1;j<=nv;j=j+1){divl[1][j,1]=(-1)^(j-1)*divl[1][j,1];} ohh=alph[i,1]-difofn(transpose(divl[1])); resu=insert(resu, ohh, size(resu)); } return(resu); } example {"Example:"; echo=2; ring r=(0,a,b,d),(x,y,w),wp(8,9,6); poly f=y^2*w-4*x^3+3*a*x*w^2+b*w^3-(1/2)*(d*w^2+w^4); LinearRelations(f); } //-----------------------The procedures added after studying the Hodge cycles of Fermat varieties and IVHS--------- //------------------------------------------------------------------------------------------------------------------ proc lcm (intvec mlist) "USAGE: lcm(integer vector_expression) RETURN: An integer which is the lowest common multiple of the entries of mlist. SEE ALSO: gcm EXAMPLE: example lcm; shows an example " { int i,j; int res; res=mlist[1]; for (i=2; i<=size(mlist); i=i+1){ j=gcd(res, mlist[i]); res=res*mlist[i] div j;} return(res); } example {"EXAMPLE:"; echo=2; intvec dl=3,5,6; lcm(dl); } //----------------------------------------------------------------------------------- proc MixedHodgeFermat(intvec mlist) "USAGE: MixedHodgeFermat(integer vector_expression) RETURN: A list of four lists. The first two lists are the pieces of the mixed Hodge structure of the de Rham cohomology of the affine Fermat variety var(1)^mlist[1]+\cdots+\var(n+1)^mlist[n+1]=1 where 'n+1' is the size of 'mlist'. The third list is just obtained by okbase(std(jacob(f))) where 'f' is the polynomial above. The fourth list is the list of monomials in the third list with sum 1/m_i k_1) { l1[k+1]=insert(l1[k+1],I[i], size(l1[k+1])); } else { l2[k]=insert(l2[k],I[i],size(l2[k])); } if ( deg(I[i])<=d and deg(I[i])>=2 ) {l3=insert(l3,I[i],size(l3));} } return(list(l1,l2, list(I[1..size(I)]), l3)); } example {"EXAMPLE:"; echo=2; ring r=0, (x,y,z),wp(10,5,4); list li=MixedHodgeFermat(intvec(2,4,5)); list h20=li[1][1]; list h11=li[1][2]; list h02=li[1][3]; h20[1..size(h20)]; h11[1..size(h11)]; h02[1..size(h02)]; li[2]; li[3]; li[4]; } //-------------------------------------------------------------------------------------- proc HodgeNumber(intvec mlist) "USAGE: HodgeNumber(integer vector_expression) RETURN: A list of two lists of integers. The first list is the list of the Hodge numbers of the compactified Fermat variety var(1)^mlist[1]+\cdots+\var(n+1)^mlist[n+1]=1 where 'n+1' is the size of 'mlist'. The second is the list of the Hodge numbers of the Fermat variety at infinity. SEE ALSO: MixedHodgeFermat EXAMPLE: example HodgeNumber; shows an example " { int n=size(mlist)-1; int d=lcm(mlist); list wlist; //--weight of the variables for (int i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring rlocal=0, (x(1..n+1)),wp(wlist[1..n+1]); list ll=MixedHodgeFermat(mlist); list hn=list(),list(); for (i=1; i<=size(ll[1]); i=i+1){ hn[1]=insert(hn[1], size(ll[1][i]), size(hn[1])); } for (i=1; i<=size(ll[2]); i=i+1){ hn[2]=insert(hn[2], size(ll[2][i]), size(hn[2])); } return(hn); } example {"EXAMPLE:"; echo=2; HodgeNumber(intvec(2,4,5)); } //---------------------------------------------------------------------------------------- proc PeriodMatrix (list J, list I, number ru) "USAGE: PeriodMatrix(list_expression,list_expression, number_expression) RETURN: A matrix. It gives the period matrix of elements 'J' of the de Rham cohomology of the generalized Fermat variety x_1^m_1+...x_{n+1}^{m_{n+1}}=1 over a basis of vanishing cycles 'I'. For the formula of this see H. Movasati, Topics In Hodge Theory: With Emphasis on Multiple Integrals. The number 'ru' is supposed to be the d-th primitive root of unity which is the first parameter of the ring, where 'd' is the lowest common multiple of 'mlist'. 'I' and 'J' are supposed to be lists of monomials. The first 'n+1' variable of the base ring are reserved for the equation of the Fermat variety. Their weights must be 'd/mlist[i]'. SEE ALSO: EXAMPLE: example PeriodMatrix; shows an example " { poly komak=1; matrix PM[size(I)][size(J)]; number zk; int i; int j; int k; int n=nvars(basering)-1; int beta_1; int beta_2; for (i=1; i<=size(I); i=i+1){ for (j=1; j<=size(J); j=j+1){ komak=1; for (k=1; k<=n+1; k=k+1) { beta_1=deg(coef(I[i],var(k))[1,1]) div deg(var(k)); beta_2=deg(coef(J[j],var(k))[1,1]) div deg(var(k)); zk=ru^deg(var(k)); komak=komak*(zk^((beta_1+1)*(beta_2+1))- zk^(beta_1*(beta_2+1))); } PM[i,j]=komak; } } return(PM); } example {"EXAMPLE:"; echo=2; ring r=(0,z), (x,y),dp; minpoly=z^2+z+1; poly f=x3+y3; ideal I=std(jacob(f)); I=kbase(I); list Il=I[1..size(I)]; Il[1..size(Il)]; print(PeriodMatrix(Il,Il, z)); } //--------------------------------------------------------------------------- proc RemoveList (list l1, list l2) "USAGE: okbase(list_expression, list_expression) RETURN: It removes common elements of 'l2' and 'l1' from 'l1' and returns the result list. SEE ALSO: EXAMPLE: example RemoveList; shows an example " { int i; int j; for (i=1; i<=size(l2); i=i+1) { j=1; while (j<=size(l1)) { if (l1[j]==l2[i]){ l1=delete(l1, j);} else {j=j+1;} } } return(l1); } example {"EXAMPLE:"; echo=2; ring r=0, (x,y),dp; list l1=x,y,x^2,6,23; list l2=6, y^3, x; RemoveList(l1,l2); RemoveList(l2,l2); } //-------------------------------------------------------------------------------- proc DimHodgeCycles(intvec mlist, list #) "USAGE: DimHodgeCycles(integer vector_expression) DimeHodgeCycles(integer vector_expression, integer_expression) DimeHodgeCycles(integer vector_expression, list_expression) RETURN: An integer which is the the dimension of the primitive part of the vector space of Hodge cycles of the generalized Fermat variety. The exponent of each variable is given in 'mlist'. The second entry is optional. If it 0 is then the procedure gives an integer valued matrix such that a perpendicular vector to its columns correpond to a Hodge cycle. A base ring must be active. If it is a list of exponents of monomials (representing elemenents of the de Rham cohomology) then the space of cycles with zero periods of such monomials is computed. The output is an integer valued matrix such that a perpendicular vector to its columns correpond to such a cycle. SEE ALSO: PeriodMatrix, rank. EXAMPLE: example DimHodgeCycles; shows an example " { int n=size(mlist)-1; int d=lcm(mlist); list wlist; //--weight of the variables for (int i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} def prevring=basering; ring rlocal=(0,z), (x(1..n+1)),wp(wlist[1..n+1]); poly cp=cyclotomic(d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //--z is the d-th root of unity--- list ll=MixedHodgeFermat(mlist); int mu_1; for (i=1; i<=n+1; i=i+1) {mu_1=mu_1+size(ll[1][i]);} //---the dimension of the primitive cohomology of the compactified variety-- list J; int hFn; if ( size(#)>0) { if ( typeof(#[1])=="int" and #[1]==0) { J=ll[1][1]; hFn=size(ll[1][1]); for (i=2; i<=(n div 2); i=i+1){hFn=hFn+size(ll[1][i]); J=J+ll[1][i];} } else { hFn=size(#); for (i=1; i<=hFn; i=i+1) { J=J+list(monomial(#[i]));} } } else { J=ll[1][1]; hFn=size(ll[1][1]); for (i=2; i<=(n div 2); i=i+1){hFn=hFn+size(ll[1][i]); J=J+ll[1][i];} } list I=ll[3]; int mu=size(I); if (hFn<>0) { matrix PM[mu][hFn]=PeriodMatrix(J,I, par(1)); matrix perp[mu][degext*hFn]; matrix komak[mu][hFn]; for (i=1; i<=degext; i=i+1) { komak=subst(PM,par(1),0); perp[1..mu, ((i-1)*hFn+1)..(i*hFn)]=komak; PM=(PM-komak)/par(1); } if (size(#)==0) {return(mu_1- rank(perp));} else { setring prevring; matrix perp=imap(rlocal, perp); return(perp); } } else { int DHC=mu_1; if (size(#)<>0) {"All the homology classes are Hodge/have zero periods with respect to your list"; } else{return(DHC);} } } example {"EXAMPLE:"; echo=2; ring r=0,x,dp; DimHodgeCycles(intvec(6,6,6)); print(DimHodgeCycles(intvec(2,4,5),0)); } //----------------------------------------------------------------------------------------------------- proc BasisHodgeCycles (intvec mlist, list #) "USAGE: BasisHodgeCycles(integer vector_expression) RETURN: A matrix. The rows of this matrix form a basis of the space of affine Hodge cycles of the generalized Fermat variety var(1)^mlist[1]+...+var(n+1)^{mlist[n+1]}=1 over rational numbers and written in the basis of vanishing cycles. It includes the cycles at inifinity. The second input is optional, if it is the d-th root of unity then the output is a list of two matrices. The first matrix is as before. The rows of the second matrix are the periods of the Hodge cycles written in a root of unity which is given in #[1]. In this case, the first 'n+1' variable of the base ring are reserved for the equation of the Fermat variety. Their weights must be 'd/mlist[i]'. If the optional input is a list of the d-th root of unity and a list of integer vectors then the output is similar to the previous one. Here, the list of integer vectors is the same as the optional input of 'DimHodgeCycles'. SEE ALSO: gaussred_pivot, DimHodgeCycles EXAMPLE: example BasisHodgeCycles; shows an example " { list lula=#; if (size(lula)>1) { matrix perp=DimHodgeCycles(mlist,lula[2]); } else { matrix perp=DimHodgeCycles(mlist,0); } list perplist=gaussred_pivot(perp); int mu=nrows(perp); int dahc=mu-perplist[4]; matrix Y[dahc][mu]; for (int i=1; i<=dahc; i=i+1) { Y[i, perplist[4]+i]=1;} matrix X=Y*inverse(perplist[2])*perplist[1]; if (size(lula)>=1) { int n=size(mlist)-1; list ll=MixedHodgeFermat(mlist); list I=ll[3]; list Imiddle=ll[1][(n div 2)+1]; matrix PM=PeriodMatrix(Imiddle, I, #[1]); matrix PHC=X*PM; return(list(X, PHC)); } if (size(lula)==0) {return(X);} } example {"EXAMPLE:"; echo=2; ring r=0,x,dp; print(BasisHodgeCycles(intvec(2,4,5))); ring rr=(0,z),x(1..3),wp(10,5,4); minpoly =z8-z6+z4-z2+1; //20-th root of unity list A=BasisHodgeCycles(intvec(2,4,5),z); print(A[2], "%s"); } //---------------------------------------------------------------------------------------------------------------- proc IntersectionMatrix (list I) "USAGE: IntersectionMatrix(list_expression) RETURN: The intersection matrix in the basis of vanishing cycles 'I' of the generalized Fermat variety x_1^m_1+...x_{n+1}^{m_{n+1}}=1. SEE ALSO: EXAMPLE: example IntersectionMatrix; shows an example " { int i; int j; int k; int n=nvars(basering)-1; poly XX=1; for (i=1; i<=n+1; i=i+1){XX=XX*var(i);} matrix Psi[size(I)][size(I)]; poly komak; for (i=1; i<=size(I); i=i+1){ for (j=1; j<=size(I); j=j+1) { komak=I[j]/I[i]; if ( komak<>0 and (I[i]*XX)/I[j]<>0 ) { for (k=1; k<=n+1; k=k+1){ komak=subst(komak, var(k),-1);} Psi[i,j]= (-1)^( (n*(n-1) div 2) )*komak; } } } Psi=Psi+(-1)^n* transpose(Psi); for (i=1; i<=size(I); i=i+1){Psi[i,i]=(-1)^( n*(n-1) div 2 )*( 1+(-1)^n);} return(Psi); } example {"EXAMPLE:"; echo=2; ring r=0, (x,y,z),dp; poly f=x3+y3+z3; ideal I=std(jacob(f)); I=kbase(I); list Il=I[1..size(I)]; Il[1..size(Il)]; print(IntersectionMatrix(Il)); } //-------------------------------------------------------------------------- proc Matrixpij(intvec mlist, matrix Pe) "USAGE: Matrixpij(integer vector_expression, matrix_expression) RETURN: A matrix. The matrix 'Pe' is supposed to be the periods of a basis of the middle piece of the Hodge decomposition of the Fermat variety F: x_1^m_1+...x_{n+1}^{m_{n+1}}=1. over a Hodge/algebraic cycle. It is a 1 times h matrix, where h is the middle Hodge number of F. This procedure computes the matrix [p_{i+j}] The first 'n+1' variable of the base ring are reserved for the equation of the Fermat variety. Their weights must be 'd/mlist[i]'. " { int n=size(mlist)-1; int nh2=(n div 2); int k; int i; int j; list ll=MixedHodgeFermat(mlist); list A=ll[1][nh2]; list B=ll[1][nh2+1]; list R=ll[4]; int an=size(A); int rn=size(R); int bn=size(B); matrix Pij[an][rn]; for (i=1; i<=an; i=i+1) { for (j=1; j<=rn; j=j+1) { for (k=1; k<=bn; k=k+1) { if (A[i]*R[j]==B[k] ){ Pij[i,j]=Pe[1,k];} } } } return(Pij); } example {"EXAMPLE:"; echo=2; ring r=0,(x,y,z), wp(20,15,12); matrix P[1][20]; P[1,1..20]=1..20; print(Matrixpij(intvec(3,4,5),P)); MixedHodgeFermat(intvec(3,4,5)); } //--------------------------------------------------------------------------------------------- proc TranCoho (intvec mlist, list #) "USAGE: TranCoho(integer vector_expression) TranCoho(integer vector_expression, any_expression) RETURN: A list. This is the list of exponents of the ingredient monomials of the transcendental piece of the (n/2,n/2) de Rham cohomology of the Fermat variety x_1^m_1+...x_{n+1}^{m_{n+1}}=1, where 'mlist' contains 'm_1,m_2,...'. The periods of these differential forms over a cycle times '(2 pi i)^(-n/2)' are conjectured to be transcendental numbers. In the case of Hodge cycles these periods are zero. Other differential forms in the (n/2,n/2) cohomology have algebraic periods. A ring must be active. If you want the list of corresponding monomials then write anything in the second entry which is optional. In this case the base ring must contain 'n+1' variables corresponding to 'x_1,x_2,...,x_{n+1}'. SEE ALSO: MixedHodgeFermat, leadexp. EXAMPLE: example TranCoho; shows an example " { int n=size(mlist)-1; int nh=n div 2; int d=lcm(mlist); def prevring=basering; list wlist; //--weight of the variables for (int i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring rlocal=0, (x(1..n+1)),wp(wlist[1..n+1]); list ll=MixedHodgeFermat(mlist)[1]; int j; int k; int s; int tekrar; int uch; intvec beta; intvec betanew; number komak; list final; for (i=1; i<=nh; i=i+1) { for (j=1; j<=size(ll[i]); j=j+1) { beta=leadexp(ll[i][j]); for (k=2; k<=d-1; k=k+1) { if (gcd(k,d)==1) { komak=0; betanew=0; for (s=1; s<=n+1; s=s+1) { komak=komak+ (k*(beta[s]+1) mod mlist[s])/number(mlist[s]); betanew=betanew, (k*(beta[s]+1) mod mlist[s])-1; } if (nh0 and check<>1) { sl=size(libeta); for (s=2; s<=sl; s=s+1) { if ( libeta[1]+libeta[s]==1 ) { lko=insert(lko,libeta[1],size(lko)); libeta=delete(libeta, s); libeta=delete(libeta, 1); s=sl+1975; } } if (size(libeta)==sl) {check=1; } } if (size(libeta)==0){ final=insert(final, beta, size(final)); lz=insert(lz,lko,size(lz)); } } if (size(#)==0) {return(final);} else { setring prevring; for (i=1; i<=size(final); i=i+1) { final[i]=monomial(final[i]); } list lz=imap(rlocal, lz); return(list(final,lz)); } } example {"EXAMPLE:"; echo=2; ring r1=0,x,dp; intvec V=2,4,5; list li1=LinearCoho(V); li1[1..size(li1)]; ring r2=0,(x,y,z),dp; list li2=LinearCoho(V,0); li2[1]; li2[2]; } //------------------------------------------------------------------------- proc PeriodLinearCycle(intvec mlist, intvec al, intvec pl, number ze) "USAGE: PeriodLinearCycle(integer vector_expression, integer vector_expression, integer vector_expression, number_expression) RETURN: A matrix 'Pe'. It is supposed to be the periods of a basis of the middle piece of the Hodge decomposition of the Fermat variety X: x_1^m_1+...x_{n+1}^{m_{n+1}}=1. over the linear cycle identified with 'al' and 'pl'. It is a 1 times h matrix, where h is the middle Hodge number of X. The first 'n+1' variable of the base ring are reserved for the equation of the Fermat variety. Their weights must be 'd/mlist[i]', where 'd' is the least common multiple of 'm_i's. The number 'ze' is supposed to be the '2d'-th primitive root of unity. " { int n=size(mlist)-1; int d=lcm(mlist); int nh2=n div 2; list ll=MixedHodgeFermat(mlist)[1][nh2+1]; int mhn=size(ll); matrix Pe[1][mhn]; int beta_0; poly XX=1; for (int i=1; i<=n+1; i=i+1){XX=XX*var(i);} intvec expmon; int j; int check; for (i=1; i<=mhn; i=i+1) { beta_0= (nh2+1)*d-deg(ll[i]*XX)-1; expmon=leadexp(ll[i]); expmon=beta_0, expmon; check=0; for (j=0; j<=n; j=j+2) { if (expmon[pl[j+1]+1]+expmon[pl[j+2]+1]<>d-2){check=1;} } if (check==1) { Pe[1,i]=0;} else { Pe[1,i]=1; for (j=0; j<=n; j=j+2) { Pe[1,i]=Pe[1,i]*ze^( (2*al[j+2]-2*al[j+1]+1 )*(expmon[pl[j+1]+1]+1) ); } } } Pe=Pe*SignPerm(pl); return(Pe); } example {"EXAMPLE:"; echo=2; int d=5; intvec aa=0,0,0,0,0,0; intvec pp=0,1,2,3,4,5; intvec mlist=d,d,d,d,d; int n=size(mlist)-1; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); matrix Per=PeriodLinearCycle(mlist, aa, pp,z); matrix A=Matrixpij(mlist, Per); rank(A), binomial(n div 2+d,d)-(n div 2+1)^2; } //--------------------------------------------------------------------------------------------- proc CodComInt(int n, int d, intvec dl) "USAGE: CodComInt(integer_expression, integer_expression, integer vector_expression) RETURN: A positive integer. It is the codimension of the loci of hypersurfaces of dimension 'n' and degree 'd'containing a complete intersection of type 'dl'. SEE ALSO: okbase, lcm EXAMPLE: example CodComInt; shows an example " { int sn=size(dl); int i; int j; for (i=1; i<=sn; i=i+1){dl=dl, d-dl[i];} ring rlocal=0, x(1..2*sn), dp; poly f; for (i=1; i<=2*sn; i=i+1){f=f+var(i)^3;} ideal I=kbase(std(jacob(f))); poly komak; int sumdi; poly signint; bigint finalint; for (j=1; j<=size(I); j=j+1) { komak=I[j]; signint=I[j]; for (i=1; i<=2*sn; i=i+1) { komak=subst(komak,var(i), var(1)^(dl[i])); signint=subst(signint,var(i), -1); sumdi=deg(komak); } if (sumdi<=d){finalint=finalint+int(signint)*binomial(n+1+d-sumdi,n+1);} } return(finalint); } example {"EXAMPLE:"; echo=2; CodComInt(4,6,intvec(3,3,3)); } //---------------------------------------------------------------------------- proc Codim(int n, int d, intvec dl) "USAGE: Codim(integer_expression, integer_expression, integer vector_expression) RETURN: A positive integer. It is a sum of certain binomials related to the codimension of the loci of hypersurfaces of dimension 'n' and degree 'd'containing a certain algebraic cycle. This is a modification of the procedure 'CodComInt'. SEE ALSO: okbase, lcm EXAMPLE: example ; shows an example " { int sn=size(dl); int i; int j; ring rlocal=0, x(1..sn), dp; poly f; for (i=1; i<=sn; i=i+1){f=f+var(i)^3;} ideal I=kbase(std(jacob(f))); poly komak; int sumdi; poly signint; bigint finalint; for (j=1; j<=size(I); j=j+1) { komak=I[j]; signint=I[j]; for (i=1; i<=sn; i=i+1) { komak=subst(komak,var(i), var(1)^(dl[i])); signint=subst(signint,var(i), -1); sumdi=deg(komak); } if (sumdi<=d){finalint=finalint+int(signint)*binomial(n+1+d-sumdi,n+1);} } return(finalint); } example {"EXAMPLE:"; echo=2; Codim(4,6,intvec(1,1,1,5,5,5)); CodComInt(4,6,intvec(1,1,1)); } //----------------------------------------------------------------------------- proc CodComIntZar(int n, int d, intvec dl) "USAGE: CodComIntZar(integer_expression, integer_expression, integer vector_expression) RETURN: A positive integer. This is the codimension of the Zariski tangenet space of the Hodge locus corresponding to deformations of a complete intersection algebraic cycle of type 'dl' inside the Fermat variety of degree 'd' and dimension 'n'. This procedure computes the periods p_i of such a complete intersection algebraic cycle and then returns the rank of the corresponding [p_{i+j}] matrix. The base ring must contain 'n+1' variables and a parameter which is '2d'-th root of unity. The equality of its output with 'CodComInt' implies a proof for the main theorem in [Movasati-Villaflor]. SEE ALSO: PeriodLinearCycle, Matrixpij EXAMPLE: example ; shows an example " { int i; int j; poly ko; for (i=1;i<=size(dl); i=i+1){ko=ko+var(i)^(dl[i]+1);} for (i=size(dl);i<=n+1; i=i+1){ko=ko+var(i)^2;} ideal I=okbase(std(jacob(ko))); intvec aa=0,0; intvec pp=0,1; for (i=1;i<=(n div 2); i=i+1){aa=aa,0,0; pp=pp,2*i,2*i+1; } intvec komak; list Ilist; for (i=1;i<=size(I); i=i+1) { komak=leadexp(I[i]); for (j=1;j<=size(dl); j=j+1){ aa[2*j]=komak[j];} Ilist=insert(Ilist, aa, size(Ilist)); } intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} matrix Per=PeriodLinearCycle(mlist, Ilist[1], pp,par(1)); for (i=2;i<=size(Ilist); i=i+1) {Per=Per+PeriodLinearCycle(mlist, Ilist[i], pp,par(1)); } matrix A=Matrixpij(mlist, Per); rank(A); } example {"EXAMPLE:"; echo=2; LIB "foliation.lib"; int d=8; int n=2; intvec dl=4,4; int i; intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); CodComIntZar(n,d,dl); } //----------------------------------------------------------------------- proc SumTwoLinearCycle(int n, int d, int m, list #) "USAGE: SumTwoLinearCycle(integer_expression, integer_expression, integer_expression, list_expresion) RETURN: A positive integer. This is the codimension of the Zariski tangenet space of the Hodge locus corresponding to deformations of a sum of two linear cycles inside the Fermat variety of degree 'd' and dimension 'n'. The intersection of these two linear cycles is a projective space of dimension 'm'. This procedure computes the periods p_i of such an algebraic cycle and then returns the rank of the corresponding [p_{i+j}] matrix. The base ring must contain 'n+1' variables and a parameter which is '2d'-th root of unity. If the last optional entry is 0: it only gives the period vector of the sum of two linear cycles. 1: A list of two list, each containg the (a,b) of a linear cycles. These are the linear cycles mainly used in the article 'Why should one'. 2: A list of two matrices, each being the period matrices of two linear cycles with intersection P^m. SEE ALSO: PeriodLinearCycle, Matrixpij EXAMPLE: example SumTwoLinearCycle; shows an example " { int i; intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} intvec aa1=0,0; intvec pp=0,1; for (i=1;i<=(n div 2); i=i+1){aa1=aa1,0,0; pp=pp,2*i,2*i+1; } matrix Per1=PeriodLinearCycle(mlist, aa1, pp,par(1)); intvec aa2; for (i=0;i<=m; i=i+1){aa2=aa2,0,0;} for (i=m+1;i<=(n div 2); i=i+1){aa2=aa2,0,1;} aa2=aa2[2..size(aa2)]; matrix Per2=PeriodLinearCycle(mlist, aa2, pp,par(1)); matrix Periods=Per1+Per2; if (size(#)==0) { matrix A=Matrixpij(mlist, Periods); return(rank(A)); } else { if (#[1]==0){return(Periods);} if (#[1]==1){return(list(list(aa1,pp),list(aa2,pp)));} if (#[1]==2){return(list(Per1,Per2));} } } example {"EXAMPLE:"; echo=2; int d=6; int n=2; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); intvec C1; intvec C2; list resu; int i; for (int m=n div 2;m>=-1; m=m-1) { C1=1; C2=d-1; for (i=1;i<=n div 2; i=i+1){C1=C1,1; C2=C2,d-1;} C1=C2,C1; C2=C1; for (i=m+1;i<=n div 2; i=i+1){C2[i+1]=1;} "Dim of inter of l. cycles=m=", m; "Dim of Zariski tang. space= ", SumTwoLinearCycle(n,d,m); "Dim of inter of Hodge Loci= ", 2*Codim(n,d, C1)-Codim(n,d,C2); "****************************"; } m=-1; SumTwoLinearCycle(n,d,m,0); SumTwoLinearCycle(n,d,m,1); SumTwoLinearCycle(n,d,m,2); } //--------------------------------------------------------------------------- proc ConstantRank(int n, int d, int m) "USAGE: ConstantRank(integer_expression, integer_expression, integer_expression) RETURN: This procedure checks whether the [p_{i+j}] matrix for sum of two linear cycles with arbitrary non-zero coefficients and with intersection 'P^m' has constant rank. The basering must have 'n+1' variables with a parameter which is a '2d'-th root of unity. SEE ALSO: PeriodLinearCycle, SumTwoLinearCycle, GoodMinor. EXAMPLE: example ConstantRank; shows an example " { intvec mlist=d; for (int i=1;i<=n; i=i+1){mlist=mlist,d;} list ll=SumTwoLinearCycle(n,d,m,2); matrix Per1=ll[1]; matrix Per2=ll[2]; matrix A=Matrixpij(mlist, Per1+Per2); int ran=rank(A); int check=0; "Checking the generic rank"; for (i=2;i<=ran+2; i=i+1) {i; if (rank(Matrixpij(mlist, Per1+i*Per2))<>ran){check=1;} } if (check==1){"The generic rank is not", ran;} list v=GoodMinor(A); A=Matrixpij(mlist, Per1+x(1)*Per2); return(factorize(det(submat(A, v[1],v[2])))); } example {"EXAMPLE:"; echo=2; int n=12; int d; int m; int upd=3; int lod=3; //upper and lower bound of the degree. for (d=lod; d<=upd; d=d+1) { ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); for (m=-1;m<=n div 2-1; m=m+1) { list ll=ConstantRank(n,d,m); "(n,d,m)=(", n,d,m, ")"; ll; write(":a ConstantRankData", "(n,d,m)=", n,d,m); write(":a ConstantRankData", ll); } } } //---------------------------------------------------------------------------- proc SignPerm(intvec A) " USAGE: SignPerm(integer vector_expression) RETURN: Integer plus or minus one which is the sign of the permutation 'A'. 'A' is supposed to be a permutation of 0,1,2,...,a-1, where a is its size of 'A'. " { int a=size(A); intmat B[a][a]; int i; int j; for (i=1; i<=a;i=i+1) {for (j=1; j<=a;j=j+1) {if (A[i]+1==j){B[i,j]=1;}} } return(det(B)); } example {"Example:"; echo=2; intvec A=intvec(0,1,2,4,3,5); SignPerm(A); } //-------------------------------------------------------------------------------- proc Monomials(list lvar, int tr, int which) " USAGE: Monomials(list_expression, integer_expression, int_expression) RETURN: The list of all monomials in the variables of 'lvar' and if which=0, of degree less that or equal to 'tr' in each variable, if which=1, of degree less than or equal to 'tr', if which =2, a list of list, the i-th list containing homogeneous polynomials of degree i. if which=3, of degree less than or equal to 'tr', greater than or equal to 2 and in each degree less than or equal to 'tr-2'. It is the same as the fourth list in the output of 'MixedHodgeFermat'. if which==4 of degree equal to 'tr', and in each degree less than or equal to 'tr-2'. This is mainly for the deformation space of the Fermat variety. The variables are supposed to have weight one even if in the base ring they have non-one weights. In the first case the procedure first produce the list of exponent integer vectors and then the monomials. EXAMPLE: example Monomials; shows an example " { if (which==0) { list out=1; poly P; list outexp; intvec kom=0; intvec finalvec=tr; for (int i=2;i<=size(lvar); i=i+1) {finalvec=finalvec, tr; kom=kom,0;} outexp=kom; int j; int dig; i=1; while (kom<>finalvec) { if (kom[1]0) { pf=1; abetabar=abeta; sumintrn=0; xbetabar=1; for (j=1; j<=n+1; j=j+1) { rn=(leadexp(P)[j]+1)/number(mlist[j]); pf=pf*PochhammerSymbol( rn-int(rn), int(rn)); abetabar=abetabar-int(rn); sumintrn=sumintrn+int(rn); if (pf<>0){xbetabar=xbetabar*var(j)^(leadexp(P)[j]-int(rn)*mlist[j]);} } pf=pf/PochhammerSymbol(abetabar, sumintrn); //----Periods in the Griffiths-Steenbrink basis--- if (pf<>0) { pf=pf*factorial(int(abetabar))/PochhammerSymbol(abetabar-int(abetabar), int(abetabar))*snum^(int(abeta)+1); for (j=1; j<=size(BasisDR); j=j+1){if (BasisDR[j]==xbetabar){pernum=Periods[1,j];} } PoSe=PoSe+lmont[i][e]*cos*pf*pernum; lPoSe[i]=lPoSe[i]+lmont[i][e]*cos*pf*pernum; } } } } if (size(#)<>0){return(lPoSe);}else{return(PoSe);} } example {"Example:"; echo=2; //This example is mainly for one parameter families. intvec mlist=3,2; int n=size(mlist)-1; int d=lcm(mlist); list wlist; for (int i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring r=(0,t(1)), (x(1..n+1)),wp(wlist[1..n+1]); poly f; for (i=1; i<=n+1; i=i+1){f=f+var(i)^mlist[i];} f=f-(-1)-t(1)*var(1); matrix PF=PFeq(f,poly(1),t(1)); list ll=MixedHodgeFermat(mlist); list BasisDR=ll[1][1]; for (int i=2; i<=size(ll[1]); i=i+1){ BasisDR=BasisDR+ll[1][i];} wlist=insert(wlist, 1 , size(wlist)); ring r1=0, (x(1..n+1),t(1)),wp(wlist[1..size(wlist)]); list lmonx=var(1); poly xbeta=1; number snum=-1; int tru=10; int kint=int(Abeta(xbeta,n,d))+1; list BasisDR=imap(r, BasisDR); BasisDR; matrix Periods[1][size(BasisDR)]; Periods[1,1]=1; Periods[1,2]=0; poly Po=TaylorSeries(mlist, lmonx, snum, xbeta, kint, BasisDR, Periods, tru); matrix PF=imap(r, PF); Po; PF; poly check; for (int i=1; i<=ncols(PF); i=i+1){check=check+PF[1,i]*Po; Po=diff(Po,t(1));} check; //-----valid only for kint=1; TaylorSeries(mlist, lmonx, snum, xbeta, kint, BasisDR, Periods, tru,0); } //--------------------------------------------------------------------------------------------------- proc aIndex(intvec zarib1, intvec zarib2) "USAGE: aIndex(integer vector_expression, integer vector_expression) RETURN: A list of elements of all elements '(a_1,a_2,...a_k)' such that 'a_i's are integers with zarib1[i]<= a_i<=zarib2[i] This was originally designed for the 'a' index of the set of linear cycles in the Fermat variety of degree 'd' and dimension 'n' for which zarib1=0,0,..,0 and zarib2=d-1,d-1,..,d-1. SEE ALSO: EXAMPLE: example aIndex; shows an example " { int pow=size(zarib1); list outexp=zarib1; int j; int dig; intvec z1=zarib1; while (zarib1<>zarib2) { if (zarib1[pow] n){ return(vec); }else{ intvec vec_update = -1; for(int j = 1; j 'tru'. The base ring and the last optional entry are the same as in 'TaylorSeries'. 'xbeta' is replaced with the list 'Fn2p1' and 'snum' is set to one. 'kint' is computed for each entry of 'Fn2p1'. SEE ALSO: TaylorSeries, EXAMPLE: example HodgeLocusIdeal; shows an example " { int n=size(mlist)-1; int d=lcm(mlist); int i; //--"Defining the truncated ideal of the Hodge locus"; list II; int kint; list Po; int snum=-1; int hn2=size(Fn2p1); //---Hodge number h^{n/2+1} int hn2n2=size(BasisDR)-2*hn2; //---Hodge number h^{n/2, n/2} matrix Periods[1][size(BasisDR)]; Periods[1,hn2+1..hn2+hn2n2]=MiddlePeriods; "Number of generators of the Hodge locus ideal:", size(Fn2p1); for (i=1; i<=size(Fn2p1); i=i+1) { Fn2p1[i]; kint=int(Abeta(Fn2p1[i],n,d))+1; if (size(#)==0) { Po=TaylorSeries(mlist, lmonx, snum, Fn2p1[i], kint, BasisDR, Periods, tru); II=insert(II,Po[1],size(II)); } else { Po=TaylorSeries(mlist, lmonx, snum, Fn2p1[i], kint, BasisDR, Periods, tru,#[1]); II=insert(II,Po,size(II)); } } return(II); } example {"Example:"; echo=2; //---The period of sum of two linear cycles------------ intvec mlist=3,3,3,3,3; int m=0; int tru=3; int n=size(mlist)-1; int d=lcm(mlist); int i; list wlist; //--weight of the variables for (i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring r=0, (x(1..n+1)),wp(wlist[1..n+1]); list ll=MixedHodgeFermat(mlist); list BasisDR; for (i=1; i<=size(ll[1]); i=i+1) { BasisDR=BasisDR+ll[1][i];} list Fn2p1; for (i=1; i<=n div 2; i=i+1) { Fn2p1=Fn2p1+ll[1][i];} list lmonx=ll[4]; //Put ll[4] if you want a full family of hypersurfaces for (i=1; i<=size(lmonx); i=i+1) { wlist=insert(wlist, 1 , size(wlist));} ring r2=(0,z), (x(1..n+1), t(1..size(lmonx))),wp(wlist[1..n+1+size(lmonx)]); poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //--z is the 2d-th root of unity--- list BasisDR=imap(r,BasisDR); list lmonx=imap(r,lmonx); matrix GPeriods[1][size(BasisDR)]; GPeriods=BasisDR[1..size(BasisDR)]; int snum=-1; //-----defining the period vector def brin=basering; ring rr=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); matrix Per=SumTwoLinearCycle(n,d,m,0); //------------------------------ setring brin; matrix MPeriods=imap(rr, Per); list Fn2p1=imap(r,Fn2p1); HodgeLocusIdeal(mlist, lmonx, Fn2p1, BasisDR, MPeriods, tru,0); } //-------------------------------------------------------------------------------------------------- proc SmoothReduced(intvec mlist, int tru, list lcycles, intvec zarib1, intvec zarib2, list #) "USAGE: SmoothReduced(integer vector_expression, integer_expression, list_expression, integer vector_expression, integer_vector expression) RETURN: A list of two lists. This procedure verifies whether the Hodge locus of the Fermat variety x_1^d+...x_{n+1}^d-sum_i t_i*lmonx[i]+1=0 is 'tru'-smooth and reduced or not, where 'd's are given in 'mlist'. The list of (a,b)-index of linear cycles is given by 'lcycles'. The Hodge loci corresponds to all algebraic cycles 'sum_i r_i*P^{n/2}_{i}' for all 'zarib1[i]<=r_i<=zarib2[i]'. The first list contains the reduced cases (r_i) and the second list contains the nonreduced (r_i)'s. If the last optional entry is not given then it will consider the full family of hypersurfaces. If it is given and it is '0' then it will report what it is doing. If it is '1' it will consider the half-half family of hypersurfaces. If it is a list of linear cycles then it uses 'InterTang' and compute a deformation 'lmonx' which is perpendicular to the tangent space of all Hodge loci in that list. If it is a list of linear cycles and '0' then the same as before and additionally, it will report what it is doing. If it is an integer vector 'v', then it must start from 1 and end in 'size(lcycles)+1'. In this case it considers the collection of cycles which are sum of cycles from 'lcycles[v[i]] till 'lcycles[v[i+1]]' for i=1,2,.... This is mainly introduced to consider sum of complete intersection algebraic cycles. If it is an integer vector 'v' and '0' then it uses 'DeformSpace' and compute a deformation 'lmonx' which is perpendicular to the tangent spaces of all Hodge loci in the list 'lcycles' (considering the effect 'v'). SEE ALSO: TaylorSeries, HodgeLocusIdeal, EXAMPLE: example SmoothReduced; shows an example " { int n=size(mlist)-1; int d=lcm(mlist); int i; int j; list wlist; //--weight of the variables for (i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring r=(0,z), (x(1..n+1)),wp(wlist[1..n+1]); poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); list ll=MixedHodgeFermat(mlist); list BasisDR; for (i=1; i<=size(ll[1]); i=i+1) { BasisDR=BasisDR+ll[1][i];} list Fn2p1; for (i=1; i<=n div 2; i=i+1) { Fn2p1=Fn2p1+ll[1][i];} //--------Defining the period vectors--------------------------------- list Periods; for (i=1; i<=size(lcycles); i=i+1) { Periods=insert(Periods, PeriodLinearCycle(mlist, lcycles[i][1], lcycles[i][2],par(1)), size(Periods)); } //------Here you can give any list of monomials for the deformation space. list lmonx; int checking; list lula=#; if (size(lula)==0) { lmonx=ll[4]; "Full family of hypersurfaces";} else { if (typeof(lula[1])=="int") { if (lula[1]==1) { list vareven; list varodd; //half-half family of hypersurfaces. for (i=1; i<=n-1; i=i+2) { vareven=insert(vareven, var(i+1), size(vareven)); varodd =insert(varodd, var(i), size(varodd)); } varodd =insert(varodd, var(n+1), size(varodd)); lmonx=Monomials(vareven, d,3)+Monomials(varodd, d,4); "half-half hypersurface"; lmonx; } if( lula[1]==0){ lmonx=ll[4]; checking=1;} } if (typeof(lula[1])=="list") { int omid=size(lula); if (typeof(lula[omid])=="list") {lmonx=InterTang(n,d, lula); "Perpendicular"; lmonx; } if (typeof(lula[omid])=="int") { if (lula[omid]==0) { lula=lula[1]; lmonx=InterTang(n,d, lula); "Deformation space: perpendicular to tangent spaces of Hodge loci"; lmonx; checking=1; } } } if (typeof(lula[1])=="intvec") { list pkom; matrix kom[1][ncols(Periods[1])]; for (i=1; i<=size(lula[1])-1; i=i+1) { kom=0; for (j=lula[1][i]; j<=lula[1][i+1]-1; j=j+1) { kom=kom+Periods[j]; } pkom=insert(pkom, kom, size(pkom)); } Periods=pkom; if (size(lula)==1){lmonx=ll[4]; "Full family of hypersurfaces";} else { if (lula[2]==0){lmonx=DeformSpace(n,d,lcycles, lula[1]); "Deformation space"; lmonx; } } } } for (i=1; i<=size(lmonx); i=i+1) { wlist=insert(wlist, 1 , size(wlist));} ring r2=(0,z), (x(1..n+1), t(1..size(lmonx))),wp(wlist[1..n+1+size(lmonx)]); poly cp=cyclotomic(2*d); degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //--z is the 2d-th root of unity--- list BasisDR=imap(r,BasisDR); list lmonx=imap(r,lmonx); list Fn2p1=imap(r,Fn2p1); list Periods=imap(r, Periods); //---Defining the truncated ideal of the Hodge locus.-------- //---specifying 'size(Periods)'-variables to each zarib would make this faster. list lII; list II; intvec z1mosaviz2; if (zarib1==zarib2) { Periods[1]=zarib1[1]*Periods[1]; for (i=2; i<=size(Periods); i=i+1){Periods[1]=Periods[1]+zarib1[i]*Periods[i];} II=HodgeLocusIdeal(mlist, lmonx, Fn2p1, BasisDR, Periods[1], tru,0); lII=list(II); z1mosaviz2=zarib1; zarib1=1; zarib2=1; //I am changing the content of zarib1 and zarib2 } else { for (i=1; i<=size(Periods); i=i+1) { lII=insert(lII, HodgeLocusIdeal(mlist, lmonx, Fn2p1, BasisDR, Periods[i], tru,0), size(lII)); } } if (checking==1){"The ideal of Hodge locus with separated homogeneous pieces"; Fn2p1; } list Al=aIndex(zarib1,zarib2); int N; poly P; int k; list komak; int k_1; int k_2; list lofg; list SR; ideal Ikom; ideal IIi; list SR2; list IIel; list redli; list nonredli; "Checking the reducedness"; for (N=1; N<=size(Al); N=N+1) { II=list(); for (k=1; k<=size(Fn2p1); k=k+1) { komak=list(); for (j=0; j<=tru; j=j+1) { P=0; for (i=1; i<=size(lII); i=i+1) { P=P+Al[N][i]*lII[i][k][j+1]; } komak=insert(komak, P, size(komak)); } II=insert(II, komak, size(II)); } //--"Defining a minimal number of generators for the ideal of Hodge locus"; k=1; while (II[k][2]==0){k=k+1;} Ikom=II[k][2]; IIi=II[k][2]; SR=k; for (i=k+1; i<=size(Fn2p1); i=i+1) { Ikom=std(Ikom); if (reduce(II[i][2], Ikom)<>0) { Ikom=Ikom, II[i][2]; SR=insert(SR, i, size(SR)); IIi=IIi, II[i][2]; } } if (checking==1){"Minimum number of generators:", size(SR); "Minimal generators of the ideal of Hodge locus"; for (i=1; i<=size(SR); i=i+1){ Fn2p1[SR[i]];} "Other generators modulo the smaller ideal"; } SR2=list(); for (i=1; i<=size(Fn2p1); i=i+1){SR2=insert(SR2,i, size(SR2));} SR2=RemoveList(SR2, SR); komak=list(); P=0; IIel=list(); for (i=1; i<=size(SR2); i=i+1) { if (checking==1){"The generator:", Fn2p1[SR2[i]];} IIel=II[SR2[i]]; P=0; lofg=list(); for (j=2; j<=size(IIel); j=j+1) { if (checking==1){"Checking ",j-1,"-reducedness.";} P=IIel[j]-P; komak=division(P, IIi); P=0; if (komak[2][1]<>0) { if (checking==1){"The Hodge locus for (a_1,a_2)=", Al[N], "is not", j-1, "-smooth or reduced.";} nonredli=insert(nonredli, Al[N], size(nonredli)); j=size(IIel)+1; i=size(SR2)+1; //---getting out of the loop. } lofg=insert(lofg, komak[1], size(lofg)); for (k_1=1; k_1<=size(lofg); k_1=k_1+1) { for (k_2=1; k_2<=size(SR); k_2=k_2+1) { if (j0){IIi=IIi, II[i]; out=insert(out, i, size(out)); } } return(out) } example {"Example:"; echo=2; intvec mlist=3,3,3,3,3,3,3; int n=size(mlist)-1; int d=lcm(mlist); intvec av=0,0; intvec bv=0,1; for (int i=1;i<=(n div 2); i=i+1){av=av,0,0; bv=bv,2*i,2*i+1;} //--The data of a linear cycle. list wlist; //--weight of the variables for (i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring r=0, (x(1..n+1)),wp(wlist[1..n+1]); list ll=MixedHodgeFermat(mlist); list BasisDR; for (i=1; i<=size(ll[1]); i=i+1) { BasisDR=BasisDR+ll[1][i];} list Fn2p1; for (i=1; i<=n div 2; i=i+1) { Fn2p1=Fn2p1+ll[1][i];} list lmonx=ll[4]; //Put ll[4] if you want a full family of hypersurfaces for (i=1; i<=size(lmonx); i=i+1) { wlist=insert(wlist, 1 , size(wlist));} ring r2=(0,z), (x(1..n+1), t(1..size(lmonx))),wp(wlist[1..n+1+size(lmonx)]); poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //--z is the 2d-th root of unity--- list BasisDR=imap(r,BasisDR); list lmonx=imap(r,lmonx); matrix GPeriods[1][size(BasisDR)]; GPeriods=BasisDR[1..size(BasisDR)]; int snum=-1; def brin=basering; ring rr=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); matrix Per=PeriodLinearCycle(mlist, av, bv,z); setring brin; matrix Per=imap(rr, Per); matrix Periods[1][size(BasisDR)]; list ll=imap(r, ll); int hn2; int hn2n2=size(ll[1][(n div 2)+1]); for (i=1; i<=(n div 2); i=i+1){hn2=hn2+size(ll[1][i]); } Periods[1,hn2+1..hn2+hn2n2]=Per; list Fn2p1=imap(r,Fn2p1); EquHodge(mlist, lmonx, snum, BasisDR, Periods, Fn2p1); Fn2p1[1..size(Fn2p1)]; } //---------------------------------------------------------------------------------------------------- proc SmoothReduced2(intvec mlist, int m, int tru, int a_1, int a_2) "USAGE: SmoothReduced2(integer vector_expression, integer_expression, integer_expression, integer_expression, integer_expression) RETURN: This procedure verifies whether the Hodge locus corresponding to sum of two linear cycles 'a_1*P^{n/2}+a_2*cP^{n/2}' with intersection 'P^m' in the Fermat variety x_1^m_1+...x_{n+1}^{m_{n+1}}-sum_i t_i*lmonx[i]+1=0 is 'N'-smooth and reduced or not, where m_i's are given in 'mlist'. For now, use it for equal m_i's. It also reports what it is doing. If at the end of the report one gets only zeros then the Hodge locus is smooth and reduced, otherwise not. SEE ALSO: TaylorSeries, PeriodLinearCycle EXAMPLE: example SmoothReduced2; shows an example " { int n=size(mlist)-1; int d=lcm(mlist); int i; list wlist; //--weight of the variables for (i=1; i<=size(mlist); i=i+1) { wlist=insert(wlist, (d div mlist[i]), size(wlist));} ring r=0, (x(1..n+1)),wp(wlist[1..n+1]); list ll=MixedHodgeFermat(mlist); list BasisDR; for (i=1; i<=size(ll[1]); i=i+1) { BasisDR=BasisDR+ll[1][i];} list Fn2p1; for (i=1; i<=n div 2; i=i+1) { Fn2p1=Fn2p1+ll[1][i];} list lmonx=ll[4]; //Put ll[4] if you want a full family of hypersurfaces for (i=1; i<=size(lmonx); i=i+1) { wlist=insert(wlist, 1 , size(wlist));} ring r2=(0,z), (x(1..n+1), t(1..size(lmonx))),wp(wlist[1..n+1+size(lmonx)]); poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //--z is the 2d-th root of unity--- list BasisDR=imap(r,BasisDR); list lmonx=imap(r,lmonx); matrix GPeriods[1][size(BasisDR)]; GPeriods=BasisDR[1..size(BasisDR)]; int snum=-1; def brin=basering; "Defining the period vector of sum of two linear cycles"; ring rr=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); intvec av1=0,0; intvec bv=0,1; for (i=1;i<=(n div 2); i=i+1){av1=av1,0,0; bv=bv,2*i,2*i+1;} matrix Per1=PeriodLinearCycle(mlist, av1, bv,par(1)); intvec av2; for (i=0;i<=m; i=i+1){av2=av2,0,0;} for (i=m+1;i<=(n div 2); i=i+1){av2=av2,0,1;} av2=av2[2..size(av2)]; matrix Per2=PeriodLinearCycle(mlist, av2, bv,par(1)); matrix Per=a_1*Per1+a_2*Per2; setring brin; matrix Per=imap(rr, Per); matrix Periods[1][size(BasisDR)]; list ll=imap(r, ll); int hn2; int hn2n2=size(ll[1][(n div 2)+1]); for (i=1; i<=(n div 2); i=i+1){hn2=hn2+size(ll[1][i]); } Periods[1,hn2+1..hn2+hn2n2]=Per; "Defining the truncated ideal of the Hodge locus"; //--From now on this procedure is different from SmoothReduced1 list Fn2p1=imap(r,Fn2p1); list II; int kint; list Po; list SR2; for (i=1; i<=size(Fn2p1); i=i+1) { "The generator:", Fn2p1[i]; kint=int(Abeta(Fn2p1[i],n,d))+1; Po=TaylorSeries(mlist, lmonx, snum, Fn2p1[i], kint, BasisDR, Periods, tru,0); II=insert(II,Po,size(II)); SR2=insert(SR2, i, size(SR2)); } "Defining a minimal number of generators for the ideal of Hodge locus"; //--You could use II and avoid the usage of EquHodge.----- list SR=EquHodge(mlist, lmonx, snum, BasisDR, Periods, Fn2p1); "Number of generators is:", size(Fn2p1); "Minimum number of generators:", size(SR); "The ideal of linear parts of a minimum number of generators"; ideal IIi; for (i=1; i<=size(SR); i=i+1) { IIi=IIi, II[SR[i]][2];//--linear parts } IIi=IIi[2..size(SR)+1]; "Other generators modulo the smaller ideal"; SR2=RemoveList(SR2, SR); int Answer=0; list lofg; list komak; poly Pol; int j; int k_1; int k_2; list IIel; for (i=1; i<=size(SR2); i=i+1) { "The generator:", Fn2p1[SR2[i]]; IIel=II[SR2[i]]; Pol=0; lofg=list(); for (j=2; j<=size(IIel); j=j+1) { "Checking ",j-1,"-reducedness."; Pol=IIel[j]-Pol; komak=division(Pol, IIi); Pol=0; if (komak[2][1]<>0){ "The Hodge locus is not smooth or reduced."; Answer=1; } lofg=insert(lofg, komak[1], size(lofg)); for (k_1=1; k_1<=size(lofg); k_1=k_1+1) { for (k_2=1; k_2<=size(SR); k_2=k_2+1) { if (jele) {j=j+1; } else {return(li);} } if (j==size(li)) { li=insert(li,ele, size(li)); return(li); } } example {"Example:"; echo=2; list li=1,2,3,4,5; InsertNew(li,3); InsertNew(li,6); } //--------------------------------------------------------------- proc ndm(int n,int d) " USAGE: ndm(integer_expression, integer_expression) RETURN: This procedure verfies that the rank of [p_{i+j}] for sum of two linear cycles in the Fermat variety of dimension 'n' and degree 'd' depends only on 'n', 'd' and 'm', the dimension of the intersection of the linear cycles. EXAMPLE: example ndm; shows an example SEE ALSO: " { list lp=ListPeriodLinearCycle(n,d,2); int i; "The number of linear cycles:", size(lp); intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} matrix P1=PeriodLinearCycle(mlist, lp[1][1], lp[1][2],par(1)); matrix P2=P1; intvec vec; list lvec; for(i=2;i<=size(lp); i=i+1) { P2=PeriodLinearCycle(mlist, lp[i][1], lp[i][2], par(1)); vec=rank(Matrixpij(mlist, P1+P2)); vec=vec,mTwoLinearCycle(n,d, lp[1],lp[i]); lvec=InsertNew(lvec,vec); lp[i][1], " ",lp[i][2]; i, "(Rank, Intersection dimension)=(", vec[1], ",", vec[2], ")"; } return(lvec); } example {"Example:"; echo=2; int n=6; int d=3; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); cp=subst(cp, x(1),z); minpoly =number(cp); ndm(n,d); } //------------------------------------------------------- proc SumThreeLinearCycle(int n, int d, list #) "USAGE: SumThreeLinearCycle(integer_expression, integer_expression, integer_expression) RETURN: A list of positive integers. This is the codimensions of the Zariski tangenet space of the Hodge locus corresponding to deformations of a sum of 'N=3' linear cycles inside the Fermat variety of degree 'd' and dimension 'n'. This procedure uses 'ListPeriodLinearCycle' and then returns the rank of the corresponding [p_{i+j}] matrix. The base ring must contain 'n+1' variables and a parameter which is '2d'-th root of unity. For now the procedure works 'N=3'. You can modify 'alist' and creat 'SetSubsets' so that this works for arbitrary 'N'. The last entry is optional if it is '0' and 'M', the procedure will take three random distinct linear cycles, 'M'-times. SEE ALSO: ListPeriodLinearCycle EXAMPLE: example SumThreeLinearCycle; shows an example " { int a_1; int a_2; int a_3; int i; "Computing the period matrix of linear cycles"; list lp=ListPeriodLinearCycle(n,d,0); int nlc=size(lp[2]); "The number of linear cycles:", nlc; intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} if (size(#)==0) { for(a_1=1;a_1<=nlc; a_1=a_1+1) { for(a_2=a_1+1;a_2<=nlc; a_2=a_2+1) { for(a_3=a_2+1;a_3<=nlc; a_3=a_3+1) { lp[1][a_1][1], " ",lp[1][a_1][2]; lp[1][a_2][1], " ",lp[1][a_2][2]; lp[1][a_3][1], " ",lp[1][a_3][2]; "rank=", rank(Matrixpij(mlist, lp[2][a_1]+lp[2][a_2]+lp[2][3])), "Intersection dimensions:", mTwoLinearCycle(n,d, lp[1][a_1],lp[1][a_2]), mTwoLinearCycle(n,d, lp[1][a_2],lp[1][a_3]), mTwoLinearCycle(n,d, lp[1][a_3],lp[1][a_1]); } } } } else { if (#[1]==0) { for (i=1;i<=#[2]; i=i+1) { a_1=random(1, nlc-2); a_2=random(a_1+1,nlc-1); a_3=random(a_2+1,nlc); lp[1][a_1][1], " ",lp[1][a_1][2]; lp[1][a_2][1], " ",lp[1][a_2][2]; lp[1][a_3][1], " ",lp[1][a_3][2]; "rank=", rank(Matrixpij(mlist, lp[2][a_1]+lp[2][a_2]+lp[2][3])), "Intersection dimensions:", mTwoLinearCycle(n,d, lp[1][a_1],lp[1][a_2]), mTwoLinearCycle(n,d, lp[1][a_2],lp[1][a_3]), mTwoLinearCycle(n,d, lp[1][a_3],lp[1][a_1]); } } } } example {"EXAMPLE:"; echo=2; int n=4; int d=6; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); cp=subst(cp, x(1),z); minpoly =number(cp); SumThreeLinearCycle(n,d); } //--------------------------------------------------------------------- proc DistinctHodgeLocus(int n, int d) "USAGE: DistinctHodgeLocus(integer_expression, integer_expression) RETURN: This preocedure verifies that there is no inclusion beween the Zariski tangent space of two Hodge loci corresponding to two distinct sum of two linear cycles. This procedure uses 'ListPeriodLinearCycle'. The base ring must contain 'n+1' variables and a parameter which is '2d'-th root of unity. SEE ALSO: ListPeriodLinearCycle EXAMPLE: example DistinctHodeLocus; shows an example " { int a_1; int a_2; int i; int b_1; int b_2; int check=0; int rank_1; int rank_2; "Computing the period matrix of linear cycles"; list lp=ListPeriodLinearCycle(n,d); int nlc=size(lp[2]); intvec mlist=d; for (i=1;i<=n; i=i+1){mlist=mlist,d;} "The number of linear cycles is", nlc; for(a_1=1;a_1<=nlc; a_1=a_1+1) { for(a_2=a_1+1;a_2<=nlc; a_2=a_2+1) { for(b_1=1;b_1<=nlc; b_1=b_1+1) { for(b_2=b_1+1;b_2<=nlc; b_2=b_2+1) { if (b_1<>a_1 or b_2<>a_2) { rank_1=rank( concat( transpose(Matrixpij(mlist, lp[2][a_1]+lp[2][a_2])), transpose(Matrixpij(mlist, lp[2][b_1]+lp[2][b_2])) ) ); rank_2=rank(Matrixpij(mlist, lp[2][a_1]+lp[2][a_2])); if (rank_1<=rank_2){check=1;} "Cycle 1:"; lp[1][a_1][1], " ", lp[1][a_1][2]; lp[1][a_2][1], " ", lp[1][a_2][2]; "Cycle 2:"; lp[1][b_1][1], " ", lp[1][b_1][2]; lp[1][b_2][1], " ", lp[1][b_2][2]; "rank:", rank_2, "<", rank_1; } } } } } if (check==1){"The conjecture on distinct Hodge loci is wrong."} else{"The conjecture on distinct Hodge loci is true."} } example {"EXAMPLE:"; echo=2; int n=4; int d=4; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); DistinctHodgeLocus(n,d); } //--------------------------------------------------------- proc RandomIntVec(int a, int b, int s) " USAGE: RandomIntVec(integer_expression, integer_expression, integer_expression) RETURN: A random integer vector of size 's' with entries between 'a' and 'b'. EXAMPLE: example RandomIntVec; shows an example SEE ALSO: random " { intvec out; for (int i=1;i<=s; i=i+1){out=out,random(a,b);} out=out[2..size(out)]; return(out); } example {"Example:"; echo=2; RandomIntVec(1,100,10); } //-------------------------------------------------------------------- proc GoodMinor(matrix A) " USAGE: GoodMinor(matrix_expression) RETURN: This uses 'gaussred_pivot' twice and returns a square minor of 'A' of size 'rank(A)' with non-zero determinant. The matrix 'A' must be in the base field of the ring. EXAMPLE: example GoodMinor; shows an example SEE ALSO: gaussred_pivot " { int k=1; list plu; intvec out; int i; int j; list Al=A; list fout; intvec ko; for (k=1;k<=2; k=k+1) { out=0; plu=gaussred_pivot(Al[k]); for (i=1;i<=plu[4]; i=i+1) { for (j=1;j<=ncols(plu[1]); j=j+1) { if (plu[1][i,j]==1){ out=out,j;} } } out=out[2..size(out)]; fout=insert(fout, out, size(fout)); ko=1..ncols(Al[k]); Al=insert(Al, transpose(submat(Al[k], out, ko)), size(Al)); } return(fout); } example {"Example:"; echo=2; ring r=0,(x),dp; matrix A[3][4]=1,2,3,4,1,1,1,1,2,2,1,1; list v=GoodMinor(A); matrix B=submat(A,v[1],v[2]); det(B); } //-------------------------------------------------------------------- proc mLinearCycle(int n, int d, list P) " USAGE: mLinearCycle(integer_expression, integer_expression, list_expression) RETURN: An integer 'm'. This is the dimension of the intersection of linear cycles listed in 'P' and in the Fermat variety of dimension 'n' and degree 'd'. 'P' is a list containing the (a,b) index of the corresponding linear cycles. EXAMPLE: example mLinearCycle; shows an example SEE ALSO: std " { ring r=(0,z), (x(0..n+1)),dp; poly cp=cyclotomic(2*d); cp=subst(cp, var(1),z); minpoly =number(cp); ideal II; int i; intvec av; intvec bv; int j; for (i=0;i<=n+1; i=i+2) { for (j=1;j<=size(P); j=j+1) { av=P[j][1]; bv=P[j][2]; II=II, x(bv[i+1])-z^(1+2*av[i+2]-2*av[i+1])* x(bv[i+2]); } } II=std(II); return(dim(II)-1); } example {"Example:"; echo=2; int n=4; int d=4; list P1= intvec(0,0,0,0,0,0), intvec(0,1,2,3,4,5); list P2= intvec(0,0,0,0,0,1), intvec(0,1,2,3,4,5); list P3= intvec(0,0,0,1,0,0), intvec(0,1,2,3,4,5); list P=P1,P2,P3; mLinearCycle(n,d,P); } //------------------------------------------------------------------------ proc Diffvf(poly P, list varl, list vfl) " USAGE: Diffvf(poly_expression, list_expression, list_expression) RETURN: Polynomial. This is the derivation of 'P' along the vector field 'vfl'. 'varl' is the list of variables of the vector field. SEE ALSO: EXAMPLE: example Diffvf; shows an example " { poly Q; for (int i=1; i<=size(vfl);i=i+1) { Q=Q+diff(P, varl[i])*vfl[i]; } return(Q); } example { "Example:"; echo = 2; ring r = 0, (x,y), dp; list val=x,y; list vcl=x2, y2; Diffvf(x^3,val, vcl); } //-------------------------------------------------------------------------------------- proc InterTang(int n, int d, list liab) "USAGE: InterTang(integer_expression, integer_expression, list expression) RETURN: This procedure first compute the intersection of the tangent spaces of Hodge loci associated to each linear cycle in the list 'liab' and at the Fermat point/variety of degree 'd' and dimension 'n'. Then it uses 'kbase' to find a monomial basis (in the affine coordinate system x(0)=1) for the degree 'd' part of the quotient ring. The loci of deformations of the algebraic cycle obrained from 'liab' and in the corresponding deformation of the Fermat variety, is just a point. The base ring must contain 'n+1' variables (not 'n+2'). SEE ALSO: intersect; EXAMPLE: example InterTang; shows an example " { def prevRing=basering; ring rlocal=(0,z), (x(0..n+1)),dp; poly cp=cyclotomic(2*d); cp=subst(cp, x(0),z); minpoly =number(cp); int i; int j; intvec av; intvec bv; ideal Ik; list lI; poly komak; for (j=1; j<=size(liab); j=j+1) { Ik=0; for (i=0; i<=n; i=i+2) { av=liab[j][1]; bv=liab[j][2]; komak=x(bv[i+1])-z^(1+2*av[i+2]-2*av[i+1])* x(bv[i+2]); Ik=Ik, komak, (x(bv[i+1])^d+x(bv[i+2])^d)/komak; } lI=insert(lI, Ik, size(lI)); } Ik=lI[1]; for (j=2; j<=size(lI); j=j+1) { Ik=intersect(Ik, lI[j]); } ideal monom=kbase(std(Ik)); list final; for (i=1; i<=size(monom); i=i+1) { if (deg(monom[i])==d){final=insert(final, monom[i]);} } for (i=1; i<=size(final); i=i+1){ final[i]=subst(final[i],x(0),1);} setring prevRing; list final=imap(rlocal, final); return(final); } example {"EXAMPLE:"; echo=2; int n=10; int d=3; intvec bv; for (int i=1; i<=n+1; i=i+1){bv=bv,i; } list l1=intvec(0,0,0,0,0,0,0,0,0,0,0,0),bv; list l2=intvec(0,0,0,0,0,0,0,0,0,1,0,1),bv; list liab=l1,l2; ring r=0, (x(1..n+1)),dp; InterTang(n,d,liab); } //------------------------------------------------------------------------ proc RandomPoly(list lvar, int de, int minco, int maxco) " USAGE: RandomPoly(list_expression, integer_expression, integer_expression, integer_expression) RETURN: A random homogeneous polynomial of degree 'de' in variables 'lvar' and with integer coefficients coefficients between 'minco' and 'maxco'. SEE ALSO: random, Monomials. EXAMPLE: example RandomPoly; shows an example " { list lmon=Monomials(lvar, de,2)[de+1]; poly P; for (int i=1;i<=size(lmon); i=i+1 ){P=P+random(minco,maxco)*lmon[i];} return(P); } example { "EXAMPLE:"; echo=2; ring r=0, (x(1..3)),dp; list lvar=x(1..3); int de=4; int minco=-3; int maxco=3; RandomPoly(lvar,de, minco,maxco); } //--------------------------------------------------------------------------- proc CodRuledCubic(int n, int d, int minco, int maxco, list #) " USAGE: CodRuledCubic(integer_expression, integer_expression, integer_expression, integer_expression) RETURN: The codimension of the tangent space of the loci of hypersurfaces of dimension 'n' and degree 'd' containing a cubic ruled cycle and at a random point. For further details see the paper "Hodge cycles for cubic hypersurfaces". The random point consists of polynomials with integer coefficients between 'minco' and 'maxco'. If the optional entry is given and it is '0', then it also returns a list of an ideal and a matrix which contain the polynomial data of the hypersurface randomely chosen. SEE ALSO: RandomPoly, random, Monomials, hilb. EXAMPLE: example CodRuledCubic; shows an example " { ring r=0,(x(0..n+1)),dp; matrix fm[3][3]; list lvar=x(0..n+1); int i; int j; for (i=1; i<=3; i=i+1){fm[i,3]=RandomPoly(lvar,d-2,minco,maxco);} for (i=1; i<=3; i=i+1) { for (j=1; j<=2; j=j+1) { fm[i,j]=RandomPoly(lvar,1,minco,maxco); } } ideal I=minor(fm,2); list hyp=fm,list(); poly P1; poly P2; for (i=1; i<=(n div 2)-1; i=i+1){ P1=RandomPoly(lvar,1,minco,maxco); P2=RandomPoly(lvar,d-1,minco,maxco); hyp[2]=insert(hyp[2],P1, size(hyp[2])); hyp[2]=insert(hyp[2],P2, size(hyp[2])); I=I,P1,P2; } I=std(I); intvec av=hilb(I,1); poly h; for (i=1; i<=size(av); i=i+1){h=h+av[i]*x(1)^(i-1); } poly final=h*OneOver((1-x(1))^(n+2),std(ideal(x(1)^(d+2))),d+1); for (i=1; i<=d; i=i+1){final=diff(final,x(1));} int fin=int(subst(final,x(1),0)/factorial(d)); if (size(#)==0) { return(fin);} else { hyp; return(fin);} } example { "EXAMPLE:"; echo=2; int n=12; int d=3; int minco=-1; int maxco=1; CodRuledCubic(n,d, minco,maxco); } //----------------------------------------------------------------------- proc CodQuarticScroll(int n, int d, int minco, int maxco, list #) " USAGE: CodQuarticScroll(integer_expression, integer_expression, integer_expression, integer_expression, list_expression) RETURN: The codimension of the tangent space of the loci of hypersurfaces of dimension 'n' and degree 'd' containing a quartic scroll cycle and at a random point. It first produces a ring which has weighted variables 'f(1..N)' and 'f' is a homogeneous polynomial of degree 'd' in these variables. Each variable 'f(i)'is substitued by a random homogeneous polynomial of degree 'weight(f(i))' in new variables 'x(0..n+1)'. The random polynomials have integer coefficients between 'minco' and 'maxco'. If the optional entry is given and it is '0', then it also returns a list of polynomials randomely chosen. For further details see the paper "Hodge cycles for cubic hypersurfaces". Note that this procedure might be used to compute the dimension of the image of a morphism from a polynomial space to the the space of homogeneous polynomials of degree 'd' and in 'n+2' variables. One needs only to modify its first part. For the order of random polynomials and their relation with the equation of the hypersurface, see the first part of the code. SEE ALSO: RandomPoly, random, Monomials, hilb. EXAMPLE: example CodQuarticScroll; shows an example " { //-----For different cycles modify only this part------- int nd2= n div 2; intvec wei; int i; for (i=1; i<=nd2-2; i=i+1){wei=wei,1;} wei=wei,1,1,1,1,1,1; for (i=1; i<=nd2-2; i=i+1){wei=wei,d-1;} wei=wei,d-2,d-2,d-2,d-2,d-2,d-2; wei=wei[2..size(wei)]; //removing the zero for (i=0; i<=n+1; i=i+1){wei=wei,1;} if (nd2>2) {ring r=0, (f(1..nd2-2),f(1..3)(1..2),g(1..nd2-2+6),x(0..n+1)), wp(wei);} else {ring r=0, (f(1..3)(1..2),g(1..nd2-2+6),x(0..n+1)), wp(wei);} poly f; for (i=1; i<=nd2-2; i=i+1){f=f+f(i)*g(i);} f=f+(f(2)(1)*f(2)(2)-f(1)(1)*f(3)(2))*g(nd2-1) +(f(2)(1)^2-f(1)(1)*f(3)(1))*g(nd2) +(f(2)(2)^2-f(1)(2)*f(3)(2))*g(nd2+1) +(f(2)(2)*f(3)(1)-f(2)(1)*f(3)(2))*g(nd2+2) +(f(1)(2)*f(3)(1)-f(1)(1)*f(3)(2))*g(nd2+3) +(f(1)(2)*f(2)(1)-f(1)(1)*f(2)(2))*g(nd2+4); //---------------------------------------------- list lvar=x(0..n+1); list ranpoint; number N=nvars(basering)-n-2; for (i=1; i<=N; i=i+1){ranpoint=insert(ranpoint, RandomPoly(lvar,deg(var(i)),minco,maxco), size(ranpoint));} ideal I=diff(f,var(1)); for (i=2; i<=N; i=i+1){I=I, diff(f,var(i)) ;} for (i=1; i<=N; i=i+1){I=subst(I, var(i), ranpoint[i]);} ring rr=0,(x(0..n+1)), dp; ideal I=imap(r, I); I=std(I); intvec av=hilb(I,1); poly h; for (i=1; i<=size(av); i=i+1){h=h+av[i]*x(1)^(i-1); } poly final=h*OneOver((1-x(1))^(n+2),std(ideal(x(1)^(d+2))),d+1); for (i=1; i<=d; i=i+1){final=diff(final,x(1));} int fin=int(subst(final,x(1),0)/factorial(d)); if (size(#)==0) { return(fin);} else { list ranpoint=imap(r,ranpoint); ranpoint; return(fin);} } example { "EXAMPLE:"; echo=2; int n=6; int d=3; int minco=-10; int maxco=10; CodQuarticScroll(n,d, minco,maxco); CodQuarticScroll(n,d, minco,maxco,0); } //----------------------------------------------------------------------- proc CodVeronese(int n, int d, int minco, int maxco, list #) " USAGE: CodVeronese(integer_expression, integer_expression, integer_expression, integer_expression, list_expression) RETURN: The codimension of the tangent space of the loci of hypersurfaces of dimension 'n' and degree 'd' containing a Veronese cycle and at a random point. It first produces a ring which has weighted variables 'f(1..N)' and 'f' is a homogeneous polynomial of degree 'd' in these variables. Each variable 'f(i)'is substitued by a random homogeneous polynomial of degree 'weight(f(i))' in new variables 'x(0..n+1)'. The random polynomials have integer coefficients between 'minco' and 'maxco'. If the optional entry is given and it is '0', then it also returns a list of polynomials randomely chosen. For further details see the paper "Hodge cycles for cubic hypersurfaces". Note that this procedure might be used to compute the dimension of the image of a morphism from a polynomial space to the the space of homogeneous polynomials of degree 'd' and in 'n+2' variables. One needs only to modify its first part. SEE ALSO: RandomPoly, random, Monomials, hilb. EXAMPLE: example CodVeronese; shows an example " { //-----For different cycles modify only this part------- int nd2= n div 2; intvec wei; int i; for (i=1; i<=nd2-2; i=i+1){wei=wei,1;} wei=wei,1,1,1,1,1,1; for (i=1; i<=nd2-2; i=i+1){wei=wei,d-1;} wei=wei,d-2,d-2,d-2,d-2,d-2,d-2; wei=wei[2..size(wei)]; //removing the zero for (i=0; i<=n+1; i=i+1){wei=wei,1;} if (nd2>2) {ring r=0, (f(1..nd2-2),f(1..3)(1..2),g(1..nd2-2+6),x(0..n+1)), wp(wei);} else {ring r=0, (f(1..3)(1..2),g(1..nd2-2+6),x(0..n+1)), wp(wei);} poly f; for (i=1; i<=nd2-2; i=i+1){f=f+f(i)*g(i);} f=f+(f(1)(1)*f(2)(1)-f(3)(2)^2)*g(nd2-1) +(f(1)(1)*f(3)(1)-f(2)(2)^2)*g(nd2) +(f(2)(1)*f(3)(1)-f(1)(2)^2)*g(nd2+1) +(f(1)(2)*f(2)(2)-f(3)(1)*f(3)(2))*g(nd2+2) +(f(1)(2)*f(3)(2)-f(2)(1)*f(2)(2))*g(nd2+3) +(f(2)(2)*f(3)(2)-f(1)(1)*f(1)(2))*g(nd2+4); //---------------------------------------------- list lvar=x(0..n+1); list ranpoint; number N=nvars(basering)-n-2; for (i=1; i<=N; i=i+1){ranpoint=insert(ranpoint, RandomPoly(lvar,deg(var(i)),minco,maxco), size(ranpoint));} ideal I=diff(f,var(1)); for (i=2; i<=N; i=i+1){I=I, diff(f,var(i)) ;} for (i=1; i<=N; i=i+1){I=subst(I, var(i), ranpoint[i]);} ring rr=0,(x(0..n+1)), dp; ideal I=imap(r, I); I=std(I); intvec av=hilb(I,1); poly h; for (i=1; i<=size(av); i=i+1){h=h+av[i]*x(1)^(i-1); } poly final=h*OneOver((1-x(1))^(n+2),std(ideal(x(1)^(d+2))),d+1); for (i=1; i<=d; i=i+1){final=diff(final,x(1));} int fin=int(subst(final,x(1),0)/factorial(d)); if (size(#)==0) { return(fin);} else { list ranpoint=imap(r,ranpoint); ranpoint; return(fin);} } example { "EXAMPLE:"; echo=2; int n=6; int d=3; int minco=-10; int maxco=10; CodVeronese(n,d, minco,maxco); } //----------------------------------------------------------------------- proc DeformSpace(int n, int d, list lcycles, intvec besh) "USAGE: DeformSpace(integer_expression, integer_expression, list_expression, list_expression) RETURN: A list of monomials. The vector space generated by these monomials is orthogonal to the intersection of the tangent spaces of Hodge loci associated to piecewise sum of linear cycles in the list 'lcycles' and at the Fermat point/variety of degree 'd' and dimension 'n'. The piecewise sum is determined by the integer vector 'besh'. It must start from 1 and end in 'size(lcycles)+1'. It considers the collection of cycles which are sum of cycles from 'lcycles[besh[i]] till 'lcycles[besh[i+1]]' for i=1,2,.... This is mainly introduced to consider some of complete intersection algebraic cycles. The base ring must contain 'n+1' variables and a parameter which is '2d'-th root of unity. This procedure is created because of the limited applications of 'InterTang'. Its output is not necessarily the same as the output of 'InterTang' but the sizes are equal. It first constructs the concatenation of the period matrices '[p_{i+j}]' attached to the cycles in 'lcycles' and then it uses 'GoodMinor'. SEE ALSO: GoodMinor; EXAMPLE: example DeformSpace; shows an example " { int j; intvec mlist=d; for (int i=1;i<=n; i=i+1){mlist=mlist,d;} list Periods; for (i=1; i<=size(lcycles); i=i+1) { Periods=insert(Periods, PeriodLinearCycle(mlist, lcycles[i][1], lcycles[i][2],par(1)), size(Periods)); } list pkom; matrix kom[1][ncols(Periods[1])]; for (i=1; i<=size(besh)-1; i=i+1) { kom=0; for (j=besh[i]; j<=besh[i+1]-1; j=j+1) { kom=kom+Periods[j]; } pkom=insert(pkom, kom, size(pkom)); } Periods=pkom; list lMpij; for (i=1; i<=size(Periods); i=i+1) { lMpij=insert(lMpij, Matrixpij(mlist, Periods[i]), size(lMpij)); } matrix sMpij=lMpij[1]; matrix conM=transpose(lMpij[1]); for (i=2; i<=size(lMpij); i=i+1) { conM=concat(conM, transpose(lMpij[i])); sMpij=lMpij[i]+sMpij; } intvec ro=GoodMinor(conM)[1]; "Codimensions of tangent spaces"; for (i=1; i<=size(lMpij); i=i+1){ rank(lMpij[i]);} "Codimension of the tangent space of sum of cycles"; rank(sMpij); "Codimension of the intersection of tangent spaces"; size(ro); list final; list fulldeform=MixedHodgeFermat(mlist)[4]; for (i=1; i<=size(ro); i=i+1) {final=insert(final, fulldeform[ro[i]], size(final)); } return(final); } example {"EXAMPLE:"; echo=2; int n=2; int d=6; intvec bv; for (int i=1; i<=n+1; i=i+1){bv=bv,i; } list l1=intvec(0,0,0,0),bv; list l2=intvec(0,1,0,1),bv; list lcycles=l1,l2; intvec besh=1,2,3; ring r=(0,z), (x(1..n+1)),dp; poly cp=cyclotomic(2*d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); DeformSpace(n,d, lcycles, besh); } //-------------------------------------------------------------------------------------- proc TwoCI(int n, int d, intvec ci1, intvec ci2, intvec ml) "USAGE: TwoCI(integer_expression, integer_expression, integer vector_expression, integer vectot_expression, integer vector expresion) RETURN: A list of two complete intersection. SEE ALSO: aIndex, bIndex; EXAMPLE: example TwoCI; shows an example " { int i; int j; intvec b; for (i=1;i<=n+1; i=i+1){b=b,i;} list lcycles; for (i=1;i<=ci1[1]; i=i+1) { for (j=1;j<=ci1[2]; j=j+1) { lcycles=insert(lcycles, list( intvec(0,i-1,0,j-1),b), size(lcycles)); } } int i1; int j1; for (i=1;i<=ci2[1]; i=i+1) { for (j=1;j<=ci2[2]; j=j+1) { if (i<=ml[1]){i1=i;}else{i1=ci1[1]+i-ml[1];} if (j<=ml[2]){j1=j;}else{j1=ci1[2]+j-ml[2];} lcycles=insert(lcycles, list( intvec(0,i1-1,0,j1-1),b), size(lcycles)); } } intvec besh=1, ci1[1]*ci1[2]+1, ci1[1]*ci1[2]+ci2[1]*ci2[2]+1; return(list(lcycles, besh)); } example {"EXAMPLE:"; echo=2; int n=2; int d=6; intvec ci1=1,1; intvec ci2=1,2; intvec ml=0,0; TwoCI(n,d,ci1,ci2,ml); } //-------------------------------------------------------------------------------------- proc ListMon(intvec mlist, number ub) "USAGE: ListMon(integer vector_expression, number_expression) RETURN: A list of two lists. This procedure first compute a basis of the de Rham cohomology of the affine Fermat variety var(1)^mlist[1]+\cdots+\var(n+1)^mlist[n+1]=1 where 'n+1' is the size of 'mlist'. This is just the list of monomials in okbase(std(jacob(f))) where 'f' is the polynomial above. The first list consists of monomials with 'A_betak_1 and number(k_1)/number(d)0){"Please increse the power pd of the factor s of the discriminant. The output is not correct";} } else {vector om=[0,0]; //---This is the smooth case } resolution ls=SyzFol(om,f); if (size(#)==0) {return(ls);} else { if (typeof(#[1])=="vector"){return(list(ls, division(#[1], ls[1])));} if (#[1]==0){return(om);} } } example {"Example:"; echo=2; ring r=(0,s), (x,y), dp; poly f=x6+3x4y2+3x2y4+y6-x4+2x2y2-y4; //---Rose with four petals MinFol(f,2); vector df=[diff(f,x),diff(f,y)]; MinFol(f,2, df); vector om=MinFol(f,2,0); om[1]; om[2]; } //----------------------------------------------------------------- proc BadPrD(matrix lde, number parm, int ub) "USAGE: BadPrD(matrix_expression, number_expression, integer_expression) RETURN: Computes the bad and good primes of a linear differential 'lde' in parameter 'parm' for primes less than or euqaul 'ub'. If 'lde' is not written as a system then the procedure transforms it into a system in a canonical way. The output consists of three list of primes 1. primes in the denominator of the system 2. primes such that the p-curvature is not zero 3. primes that the p-curvature is zero. SEE ALSO: cleardenommat, denominator, primes EXAMPLE: example BadPrD; shows an example " { int i; int j; int di=ncols(lde)-1; matrix A[di][di]; if (ncols(lde)<>nrows(lde)) { lde=lde/(-lde[1,di+1]); for (i=1;i<=di-1;i=i+1){A[i,i+1]=1;} A[di,1..di]=lde[1,1..di]; } else {A=lde;} number disc=denominator(cleardenommat(A)[1]); intvec prli=primes(1,ub); int pr; matrix B=A; list BP; list GP; list BPD; number fu; for (j=1;j<=size(prli);j=j+1) { pr=prli[j]; B=A; for (i=1;i<=pr-1;i=i+1) { B=diffpar(B,parm)+B*A; } B=B*disc^(pr); fu=cleardenommat(B)[1]; if (denominator(disc/pr)==1) {BPD=insert(BPD, pr,size(BPD));} else { if (denominator(fu/pr)<>denominator(fu) ){BP=insert(BP, pr,size(BP));} else{GP=insert(GP, pr,size(GP));} } } return(list(BPD, BP,GP)); } example {"Example:"; echo=2; ring r=(0,z),x,dp; matrix lde[1][3]; number a; number b; number c; number al; number be; number ga; al=1/4;be=1/7; ga=3/11; //--Angular parameters a=1/2*(1-al-be+ga); b=1/2*(1-al-be-ga); c=1-al; lde=-a*b, c-(a+b+1)*z, z*(1-z); int ub=50; number parm=z; BadPrD(lde, parm, ub); matrix A_0[2][2]=c-1,-b,0,0; matrix A_1[2][2]=0,0,a,c-a-b-1; matrix lde=1/z*A_0+1/(z-1)*A_1; BadPrD(lde, parm, ub); } //---------------------------------------------------------------------- proc BadPrV(list vecfield, int ub) "USAGE: BadPrV(list_expression, integer_expression) RETURN: Computes the bad and good primes of a polynomial vector field 'vecfield' for primes less than or euqaul 'ub'. The output consists of three list of primes 1. primes in the denominator 'vecfield' 2. primes such that the p-iteration of 'vecfield' is not parallel to 'vecfield' 3. the rest. The first two lists are considered to be bad. SEE ALSO: cleardenommat, denominator, primes EXAMPLE: example BadPrV; shows an example " { int di=size(vecfield); matrix vf_1[1][di]=vecfield[1..di]; number den=denominator(cleardenommat(vf_1)[1]); intvec prli=primes(1,ub); int i; int j; int k; poly Q; matrix vf[1][di]; matrix paral[2][di]; matrix final[1][int(binomial(di,2))]; int pc; int pr; number fu; ideal Ik; list BP; list GP; list BPD; for (pc=1; pc<=size(prli);pc=pc+1) { pr=prli[pc]; for (i=1; i<=di;i=i+1){vf[1,i]=var(i);} for (k=1; k<=di;k=k+1) { for (i=1; i<=pr;i=i+1) { Q=0; for (j=1; j<=di;j=j+1) { Q=Q+diff(vf[1,k], var(j))*vecfield[j]; } vf[1,k]=Q; } } paral=vf[1,1..di], vecfield[1..di]; Ik=minor(paral,2); final=Ik[1..size(Ik)]; fu=cleardenommat(final)[1]; if (denominator(den/pr)==1) {BPD=insert(BPD, pr,size(BPD));} else { if (denominator(fu/pr)<>denominator(fu) ){BP=insert(BP, pr,size(BP));} else{GP=insert(GP, pr,size(GP));} } } return(list(BPD, BP,GP)); } example {"Example:"; echo=2; ring r=0, (x,y),dp; poly f=x^3+y^4-xy/3; list vecfield=diff(f,y), -diff(f,x); int ub=40; BadPrV(vecfield, ub); list vf=-y4+y,-x2y3+x2; //--Alcides example with first integral BadPrV(vf, ub); } //------------------------------------------------------------------------------- proc LCurves(int which, list #) "USAGE: LCurves(integer_expression, list_expression) RETURN: The curves in the complex plane discussed in Movasati-Camacho 2020 are listed in this procedure. The integer 'which' means which one (see the procedure's inside or type a random integer). The last entry is optional and it is the list of parameters used in the curve. It returns a polynomial in two variables which gives us the equation of the curve. SEE ALSO: EXAMPLE: example LCurves; shows an example " { poly f; int i; int j; if (which==1) { if (size(#)==0) {f=var(1)^3-var(2)^2; return(f);} else {f=var(1)^#[1]-var(2)^#[2]; return(f);} } if (which==2) { if (size(#)==0) {f=var(1)*var(2)*(var(1)-var(2)); return(f);} else { f=1; for (i=1; i<=size(#);i=i+1){f=f*(var(2)-#[i]*var(1));} return(f); } } if (which==3) { if (size(#)==0) {i=3; f=(x^i-1)*(y^i-1)*(x^i-y^i); "Alcides degree 9 curve"; f; return(f); } else {i=#[1]; f=(x^i-1)*(y^i-1)*(x^i-y^i); "Alcides degree ", 3*i, " curve"; f; return(f);} } if (which==4) { f=4*y^2*(1-3*x)-4*x^3+(3*x^2+y^2)^2; "Alcides degree four curve"; f; return(f); } if (which==5) { f=(x^2-1)*(y^2-1)*(x^2-(2*par(1)+1)^2)*(y^2-(2*par(1)+1)^2)*(x^2-y^2)*(y+1+1/par(1)*(x+1))*(y+1+par(1)*(x+1))*(y-1+par(1)*(x-1))*(y-1+1/par(1)*(x-1)); "Pereira-Mendes arrangement of lines"; f; return(f); } if (which==6) { f=-1728x5+720x3y-80xy2+64*(5x2-y)^2 + y3; "Pereira-Mendes degree 5 curve"; f; return(f); } if (which==7) { f=4*x^4 + 8*x^2*y^2 + 4*y^4- 4*x^6 - 12*x^4*y^2 - 12*x^2*y^4 - 4*y^6 - y^2; "Rose with k=1/2"; f; return(f); } if (which==8) { f=x4+x2+y2; "Lemniscate of Gerono"; f; return(f); } if (which==9) { f= (x^2+y^2)^2+8*par(1)*x*(x^2-3*y^2)+18*par(1)^2*(x^2+y^2)-27*par(1)^4 ; "Deltoid"; f; return(f); } if (which==10) { f= x^2*(4*x^2-3*par(1)^2)^2+4*par(1)^2*y^2*(y^2-par(1)^2); "Lissajous"; f; return(f); } } example {"EXAMPLE:"; echo=2; ring r=0,(x,y),dp; LCurves(3); LCurves(3,6); } //---------------------------------------------------------------------- proc Discrim(poly f) "USAGE: Discrim(poly_expression) RETURN: A polynomial in the first variable of the base ring. This procedure takes 'f' and find the matrix 'A' of multiplication by f in the Milnor vector space and then takes the determinant 'P=det(A-var(1)I)'. The zeros of 'P' are the acritical values of f. This procedure is a small modification of 'discriminnat'. It does not need the presence of a parameter in the base ring, whereas 'discriminnat' needs. It has been used in SEE ALSO: okbase EXAMPLE: example Discrim; shows an example " { ideal I=jacob(f); ideal gI=std(I); ideal V=okbase(gI); int mu=vdim(gI); if (mu<0) {"// **", f, "is not a tame polynomial**";} if (mu==0) {return(1);} if (mu>0) { matrix A[mu][mu]; int s,i,k; poly h1; for (k=1; k<=mu; k=k+1) { h1=reduce(f*V[k], gI); for (s=1; s<=size(h1); s=s+1) { for (i=1; i<=mu; i=i+1) { if ( leadmonom(h1[s]) == leadmonom(V[i]) ) {A[k,i]=leadcoef(h1[s]);} } } } matrix Id[mu][mu]; for (i=1; i<=mu; i=i+1) { Id[i,i]=1;} return( det(A-var(1)*Id) ); } } example {"Example:"; echo=2; ring r=(0,s), (x,y),dp; poly f=2*(x3+y3)-3*(s*x2+y2); Discrim(f); } //------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------Modular Differential Equations----------------------------- //-------------------------------------------------------------------------------------- proc foliation(poly f, list ll, diform, list #) "USAGE: foliation(poly_expression, list_expression, poly_expression, list_expression) foliation(poly_expression, list_expression, matrix_expression, list_expression) RETURN: For a tame polynomial 'f', a list of its parameters 'll', a differential form 'diform' in the Brieskorn module H'(resp. H'') for 'diform' a matrix (resp. a polynomial) and an optional list which has the same structure as the output of 'infoof', this procedure calculates a list of vector fields which spans the tangent space of the holomorphic foliation given by integral(diform)=constant. SEE ALSO: gaussmanin; guassred; cleardenommat; infoof; EXAMPLE: example foliation; shows an example " { //First we obtain the information of f list lula; if (size(#)==0) {lula=infoof(f);} else {lula=#;} int mu=lula[8]; int np=size(ll); list k=gaussmanin(f, ll, diform,lula); int i; matrix A[np][mu]; // Its rwos are the gaussmanin connection of the diform with respect to parameters // in ll. for (i=1;i<=np; i=i+1) { A[i,1..mu]=k[i+1]; } list gred=gaussred(A); // gred[1]*A=gred[2]*gred[3]. if (gred[4]==np) {"// ** The number of parameters is not sufficient **";} else { matrix U1P[np][np]=inverse(gred[2])*gred[1]; //It will be useful to use a better algorithm for calculating inverse, because gred[2] is triangular. matrix XX[1][np]; list live; for (i=gred[4]+1; i<=np; i=i+1) { XX=0; XX=submat(U1P, i,1..np); XX=cleardenommat(XX)[2]; live=insert(live, XX, size(live)); } return(live); } } example {"EXAMPLE:"; echo=2; ring r=(0,t(1..3)),(x,y),wp(2,3); poly f=y^2-(4*(x-t(1))^3-t(2)*(x-t(1))-t(3)); list li=t(1..3); poly p=x; foliation(f,li,p); ring r=(0,t(1..3)),(x,y),wp(2,3); poly f=y^2-4*(x-t(1))*(x-t(2))*(x-t(3)); list li=t(1..3); poly p=x; foliation(f,li,p); } //---------------------------------------------------------------------------------------------------------- proc qexpansion (list vecfield, list denomv, list pose, intvec upto, intvec whichpow, number c_2, list #) "USAGE: qexpansion(list_expression, list_expression, list_expression, integer vector_expression, integer vector_expression, number_expression) RETURN: A list. The same as the third entry. The i-th entry of the first list divided by the i-th entry of the second list is the i-th entry of the ODE for which you want to calculate the q-expansion of its solutions. All the entries of the first three lists are polynomials. The variables of the ODE must be the first variables of your ring and the q-variable must be the next. The procedure takes pose[i]+var(i)*q^upto[i], substitute it in the ODE and compare the coefficients of q^whichpow[i] in the i-th row of the ODE. The derivation is supposed to be c_2*q*d/dq. The last entry is optional. If it is not empty, then it must be a list with one or two entries. If #[1]=1 then the procedure in each step will check if the calculated q-series satisfy the ODE or not. If not, it will give you an error message. If #[2] is empty then the procedure uses the command std in order to solve a system of linear equations. This may slow down the speed of calculations. In the case upto=whichpow and all the entries of denomv starting with a non-zero constant term, we can use a more effective method avoiding the command std. In this case the recursion is of the form T_n=(A-n*c_2*diag)^(-1)T_! where T_! is an expression in terms of T_m, m0) { if (#[1]==1) { if (vecfield1[i]-q^(whichpow[i])*vecfield2[i]<>0){"You initial power series is not correct!"; i;} } } vecfield1[i]=subst(vecfield2[i],q,0); } if (size(#)>1) { matrix KK[di][1]; for (i=1; i<=di;i=i+1) { KK[i,1]=vecfield1[i]; } KK=#[2]*KK; for (i=1; i<=di;i=i+1) { pose[i]=pose[i]+KK[i,1]*q^(upto[i]); } return(pose); } else { ideal II; for (i=1; i<=di;i=i+1) {II=II, vecfield1[i];} II=std(II); for (i=1; i<=di;i=i+1){ pose[i]=subst(pose[i], var(i), reduce(var(i), II)); } return(pose); } } example {"EXAMPLE:"; echo=2; LIB "linalg.lib"; ring r=0, (t_1,t_2,t_3,q),dp; list vecfield=1/12*(t_1^2-t_2), 1/3*(t_1*t_2-t_3), 1/2*(t_1*t_3-t_2^2); //This is the classical Ramanujan differential equation between Eisenstein series. list pose=1-24*q,1+240*q,1-504*q; list denomv=1,1,1; intvec upto; intvec whichpow; int iter=180; int n; for (n=2; n<=iter;n=n+1) { upto=n,n,n; whichpow=upto; pose=qexpansion(vecfield,denomv,pose,upto,upto,1); } list ber=-24,240,-504; for (n=1; n<=3;n=n+1){pose[n]=pose[n]/ber[n];} pose; } //--------------------------------------------------------------------------------------------- proc HalphenRamanujan (int which, list tlist, list #) "USAGE: HalphenRamanujan(integer_expression, list_expression, list_expression) RETURN: The modular differential equations are listed in this procedure. The integer which means which one according to the numbering below. tlist is the list of variables used in the differential equation. The last entry is the list of parameters used in the differential equation. It returns one list or two lists of the same size. If it is two lists then the i-th entry of the first list divided by the i-th entry of the second list is the i-th entry of the differential equation. If it is one list then the second list is supposed to be the one with only 1 in its entries. 1. The Ramanujan differential equation between Eisenstein series 2. The Halphen differential equation with three parameters 3. The modular differential equation attached to mirror quintic Calabi-Yau threefolds. 4. The modular differential equation attached to mirror quintic Calabi-Yau threefolds (in 10 dimension). SEE ALSO: EXAMPLE: example HalphenRamanujan; shows an example " { if (which==1) { poly t(1..3); int i; for (i=1;i<=3;i=i+1){t(i)=tlist[i]; } list vecfield=1/12*(t(1)^2-t(2)), 1/3*(t(1)*t(2)-t(3)), 1/2*(t(1)*t(3)-t(2)^2); return(vecfield); } if (which==2) { poly t(1..3); poly a=#[1]; poly b=#[2]; poly c=#[3]; int i; for (i=1;i<=3;i=i+1){t(i)=tlist[i]; } list vecfield= ((b+c-1)*t(1)^2+(a-1)*(t(1)*t(2)+t(1)*t(3) -t(2)*t(3))), ((a+c-1)*t(2)^2+(b-1)*(t(2)*t(1)+t(2)*t(3) -t(1)*t(3))), ((a+b-1)*t(3)^2+(c-1)*(t(3)*t(1)+t(3)*t(2) -t(1)*t(2))); return(vecfield); } if (which==3) { poly t(0..6); int i; for (i=0;i<=6;i=i+1){t(i)=tlist[i+1];} list Ravec=(3750*t(0)^5+t(0)*t(3)-625*t(4)),(-390625*t(0)^6+3125*t(0)^4*t(1)+390625*t(0)*t(4)+t(1)*t(3)),(-5859375*t(0)^7-625*t(0)^5*t(1)+6250*t(0)^4*t(2)+5859375*t(0)^2*t(4)+625*t(1)*t(4)+2*t(2)*t(3)),(-9765625*t(0)^8-625*t(0)^5*t(2)+9375*t(0)^4*t(3)+9765625*t(0)^3*t(4)+625*t(2)*t(4)+3*t(3)^2),(15625*t(0)^4*t(4)+5*t(3)*t(4)),(-625*t(0)^5*t(6)+9375*t(0)^4*t(5)+2*t(3)*t(5)+625*t(4)*t(6)),(9375*t(0)^4*t(6)-3125*t(0)^3*t(5)-2*t(2)*t(5)+3*t(3)*t(6)); list denom=t(5),t(5),t(5),t(5),t(5),t(5),t(5); return(list(Ravec,denom)); } if (which==4) { poly t(0..9); int i; for (i=0;i<=9;i=i+1){t(i)=tlist[i+1];} list Ravec=t(8)-t(0)*t(9), -625*t(0)*t(8)-t(1)*t(9), -9375*t(0)^2*t(8)-t(1)*t(8)-2*t(2)*t(9), -5*t(7)*t(8)^2+5*t(6)*t(8)*t(9)+4*t(2)*t(8)-3*t(3)*t(9),-5*t(4)*t(9),-t(6)*t(8)-3*t(5)*t(9)-t(3), -t(7)*t(8)-2*t(6)*t(9)-t(2), -t(7)*t(9)-t(1), t(8)^2*t(6)-3*t(8)*t(9)*t(5), t(8)^2*t(7)-t(9)^2*t(5); list denom=1,1,1,1,1,1,1,1,t(5),t(5); return(list(Ravec,denom)); } } example {"EXAMPLE:"; echo=2; ring r=0,(t(1..7),a,b,c),dp; HalphenRamanujan(1,list(t(1..3))); HalphenRamanujan(2,list(t(1..3)),list(a,b,c)); HalphenRamanujan(3,list(t(1..7))); } //--------------------------------------------------------------------------------------------- proc derivatives (list Plist, list varlist) "USAGE: derivatives(list_expression, list_expression) RETURN: A m*n matrix, where 'm' is the size of the list 'Plist' and 'n' is the size of 'varlist'. The (i,j)-entry of the matrix contains the derivative of Plist[i] with respect to the variable varlist[j]. SEE ALSO: diff EXAMPLE: example derivatives; shows an example " { int i; int j; int nn=size(Plist); int mm=size(varlist); matrix Vm[nn][mm]; for (i=1; i<=nn;i=i+1) { for (j=1; j<=mm;j=j+1) { Vm[i,j]=diff(Plist[i],varlist[j]); } } return(Vm); } example {"EXAMPLE:"; echo=2; ring r=0,(t(1..3)),dp; list AA=t(1)^2+t(2),t(3)^3*t(1), t(1)*t(2)*t(3); print(derivatives(AA,list(t(1..2)))); } //-------------------------------------------------------------------------------- proc OneOver(poly P, ideal modI, int N) "USAGE: OneOver(poly_expression, ideal_expression, integer_expression) RETURN: The same as the first entry. This procedure writes P=c-Q, where c is a constant and Q is a polynomial vanishing at the origin (all variables to be zero) and then it gives the geometric series 1/P=(1/c)*1/(1-Q/c)=(1/c)*(1+(Q/c)+(Q/c)^2+...) The result is calculated mod the ideal 'modI'. The powers are calculated until (Q/c)^N. The ideal 'modI' must be in the standard basis. SEE ALSO: reduce, EXAMPLE: example OneOver; shows an example " { int i; poly cons=P; for (i=1;i<=nvars(basering); i=i+1){ cons=subst(cons, var(i),0);} poly Q; Q=1-P/number(cons); poly oneov=1; for (i=1;i<=N; i=i+1){ oneov= oneov+reduce(Q^i,modI);} oneov=1/number(cons)*oneov; return(oneov); } example {"Example:"; echo=2; ring r=(0,t),q,dp; OneOver(1-t*q,std(ideal(q^10)),9); } //-------------------------------------------------------------------------- //-------------------------------------------------------- proc LambertSeries(poly P, poly Q) "USAGE: LambertSeries(poly_expression) RETURN: A list. The polynomials 'P' and 'Q' are in one variable q:=var(1) and 'Q' has no constant term. It computes the coefficients b_m in P=b_0+b_1*Q(q)+b_2*Q(q^2)+b_3*Q(q^3)+... For 'Q=q/(1-q)=q+q^2+q^3+...' this is the well-known Lambert series format of 'P'. SEE ALSO: EXAMPLE: example LambertSeries; shows an example " { int i; int N=deg(P); list outp=subst(P,var(1),0); number Q_1=number(subst(diff(Q,var(1)),var(1),0)); Q=Q/Q_1; P=P-outp[1]; poly hilfe; for (i=1;i<=N; i=i+1) { hilfe=P/var(1)^i; hilfe=subst(hilfe,var(1),0); outp=insert(outp, hilfe, size(outp)); P=P-hilfe*subst(Q,var(1),var(1)^i); } for (i=2;i<=size(outp); i=i+1){outp[i]=outp[i]/Q_1;} return(outp); } example {"Example:"; echo=2; ring r=0,q,dp; poly E_2=12*q^11+18*q^10+13*q^9+15*q^8+8*q^7+12*q^6+6*q^5+7*q^4+4*q^3+3*q^2+q-1/24; //The Eisenstein series poly lam=q*OneOver(1-q,std(ideal(q^12)),11); LambertSeries(E_2,lam); poly Q=2875*q+609250*q^2+317206375*q^3+242467530000*q^4+229305888887625*q^5; poly Yu=28663236110956000*q^5+15517926796875*q^4+8564575000*q^3+4876875*q^2+2875*q+5; Q=q*diff(Q,q); Q=q*diff(Q,q); Q=q*diff(Q,q); LambertSeries(Yu,Q); } //------------------------------------------------------------------------------------------ proc PochhammerSymbol(number P, int n) "USAGE: PochhammerSymbol(number_expression, integer_expression) RETURN: The same as the first entry. It returns 'P(P+1)(P+2)...(P+n-1)' SEE ALSO: EXAMPLE: example PochhammerSymbol; shows an example " { int i; number ps=P; for (i=1;i<=n-1; i=i+1) { ps=ps*(P+i); } if (n>0){return(ps);} if (n==0){return(number(1));} } example {"Example:"; echo=2; ring r=(0,t),q,dp; PochhammerSymbol(t,3); } //------------------------------------------------------------------------------------- //-----------------------------------------Old procedures-Out of use--------------------------------- //----------------------------HODGE NUMBERS-------------------------------- proc hodgenum(int n, int d, list #) "USAGE: hodgenum (int_expression, int_expression) hodgenum (int_expression, int_expression, list_of_integers); RETURN: (n+1)*1 matrix A. The i-th entry of A contains the hodge number 'h^{i-1,n-(i-1)}' of a hypersurface of degree d in the weighted projective space P^# of dimension n+1. If the list # is empty then the ordinary projective space is considered. The procedure works only for 'n<5'. Also, it works in the case where all weights divide 'd'. EXAMPLE: example hodgenum; shows an example " { int i, i1, i2, i3, i4, i5, i6, a; int todo; int out=0; // a counts the hodge pieces, todo=1 is for illegal entries. list wei; //The list of weights if (size(#)==0) { for (i=1; i<=n+2; i=i+1) {wei=insert(wei,1);} } else {wei=#;} for (i=1; i<=size(#); i=i+1) { if (#[i]*(d div #[i])<> d) { "//** Sorry, I can only compute Hodge numbers for weights dividing d"; todo=1; i=size(#)+1; } } if (n+2<>size(wei)) {"//** Please give", n+2, "weights"; todo=1;} if (n>=5) {"//** Sorry, I compute the Hodge numbers of hypersurfaces of dimension less than 5"; todo=1;} if (todo==0) { intmat hn[n+1][1]; if (n==4) { for (a=0; a<=n; a=a+1) { for (i1=1; i1<= (d div wei[1])-1; i1=i1+1) { for (i2=1; i2<= (d div wei[2])-1; i2=i2+1) { for (i3=1; i3<=(d div wei[3])-1; i3=i3+1) { for (i4=1; i4<= (d div wei[4])-1; i4=i4+1) { for (i5=1; i5<= (d div wei[5])-1; i5=i5+1) { for (i6=1; i6<=(d div wei[6])-1; i6=i6+1) { if (i1*wei[1]+i2*wei[2]+i3*wei[3]+i4*wei[4]+ i5*wei[5]+i6*wei[6]==d*(a+1)) {out=out+1;} } } } } } } hn[a+1,1]=out; out=0; } return(hn); } if (n==3) { for (a=0; a<=n; a=a+1) { for (i1=1; i1<= (d div wei[1])-1; i1=i1+1) { for (i2=1; i2<= (d div wei[2])-1; i2=i2+1) { for (i3=1; i3<=(d div wei[3])-1; i3=i3+1) { for (i4=1; i4<= (d div wei[4])-1; i4=i4+1) { for (i5=1; i5<= (d div wei[5])-1; i5=i5+1) { if (i1*wei[1]+i2*wei[2]+i3*wei[3]+i4*wei[4]+ i5*wei[5]==d*(a+1)) {out=out+1;} } } } } } hn[a+1,1]=out; out=0; } return(hn); } if (n==2) { for (a=0; a<=n; a=a+1) { for (i1=1; i1<= (d div wei[1])-1; i1=i1+1) { for (i2=1; i2<= (d div wei[2])-1; i2=i2+1) { for (i3=1; i3<=(d div wei[3])-1; i3=i3+1) { for (i4=1; i4<= (d div wei[4])-1; i4=i4+1) { if (i1*wei[1]+i2*wei[2]+i3*wei[3]+i4*wei[4] ==d*(a+1)) {out=out+1;} } } } } hn[a+1,1]=out; out=0; } return(hn); } if (n==1) { for (a=0; a<=n; a=a+1) { for (i1=1; i1<= (d div wei[1])-1; i1=i1+1) { for (i2=1; i2<= (d div wei[2])-1; i2=i2+1) { for (i3=1; i3<=(d div wei[3])-1; i3=i3+1) { if (i1*wei[1]+i2*wei[2]+i3*wei[3] ==d*(a+1)) {out=out+1;} } } } hn[a+1,1]=out; out=0; } return(hn); } if (n==0) { for (a=0; a<=n; a=a+1) { for (i1=1; i1<= (d div wei[1])-1; i1=i1+1) { for (i2=1; i2<= (d div wei[2])-1; i2=i2+1) { if (i1*wei[1]+i2*wei[2] ==d*(a+1)) {out=out+1;} } } hn[a+1,1]=out; out=0; } return(hn); } } } example {"Example:"; echo=2; ring r=0,x,dp; hodgenum(4,3); } //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- proc DimensionOfHodgeCycles(intvec dlist, list #) "USAGE: DimensionOfHodgeCycles(integer vector_expression) DimensionOfHodgeCycles(integer vector_expression, integer_expression) RETURN: An integer which is the the dimension of the vector space of Hodge cycles of the generalized Fermat variety. The exponent of each variable is given in 'dlist'. The second entry is optional. If it is 0: then the procedure gives the mentioned number and a list of the Hodge numbers of the compactified Fermat variety. 1: then the procedure gives an integer valued matrix such that a perpendicular vector to its columns correpond to a Hodge cycle. SEE ALSO: PeriodMatrix, rank. EXAMPLE: example DimensionOfHodgeCyles; shows an example " { def prevRing=basering; int n=size(dlist)-1; //---dimension---- int i,j,k; int d=lcm(dlist); list wlist; //-----------------------------------------weight of the variables---------- for (i=1; i<=size(dlist); i=i+1){ wlist=insert(wlist, (d div dlist[i]), size(wlist));} //-------------------------------------------the basering with the d-th root of unity------ ring rlocal=(0,z), (x(1..n+1)),wp(wlist[1..n+1]); poly cp=cyclotomic(d); int degext=deg(cp) div deg(var(1)); cp=subst(cp, x(1),z); minpoly =number(cp); //-here we have to use the minimal polynomial of the d-th root of unity--- poly f; for (i=1; i<=n+1; i=i+1){f=f+x(i)^dlist[i];} ideal I=kbase(std(jacob(f)));//-I have identified I with a basis of vanishing cycles------------ int mu=1; poly XX=1; for (i=1; i<=n+1; i=i+1){mu=mu*(dlist[i]-1); XX=XX*var(i);} //-------------------------------We order I according to its mixed Hodge structure--------------- list l1; list l2; int k_1; for (i=1; i<=n; i=i+1){ l1=insert(l1,list()); l2=insert(l2,list()); } l1=insert(l1,list()); for (i=1; i<=mu; i=i+1){ k_1=deg(I[i]*XX); k=k_1 div d; if (k*d<>k_1) { l1[k+1]=insert(l1[k+1], I[i], size(l1[k+1])); }else { l2[k]=insert(l2[k], I[i], size(l2[k])); } } list hn1, hn2; //----------------list of Hodge numbers------------------------------------------ list l1l2; for (i=1; i<=n+1; i=i+1){ l1l2=l1l2+l1[i]; hn1=insert(hn1, size(l1[i]), size(hn1)); } for (i=1; i<=n; i=i+1) { l1l2=l1l2+l2[i]; hn2=insert(hn2, size(l2[i]), size(hn2)); } ideal J; for (i=1; i<=size(l1l2); i=i+1){J[i]=l1l2[i]; } int mu_1; for (i=1; i<=n+1; i=i+1) {mu_1=mu_1+hn1[i];}//---the dimension of the primitive cohomology of the compactified variety-- //--------------------------------Period Matrix of F^{n/2+1}-------------------------------------- int hFn=0; for (i=1; i<=(n div 2); i=i+1){hFn=hFn+hn1[i];} if (hFn<>0) { matrix PM[mu][hFn]=PeriodMatrix(ideal(J[1..hFn]),I, z); matrix perp[mu][degext*hFn]; matrix komak[mu][hFn]; for (i=1; i<=degext; i=i+1) { komak=subst(PM,z,0); perp[1..mu, ((i-1)*hFn+1)..(i*hFn)]=komak; PM=(PM-komak)/z; } int DHC=(mu_1+1)- rank(perp); setring prevRing; matrix perp=imap(rlocal, perp); if (size(#)<>0) { if (#[1]==0){return(list(DHC, hn1));} if (#[1]==1){return(perp);} } else{return(DHC);} } else { int DHC=mu_1+1; if (size(#)<>0) { if (#[1]==0){return(list(DHC, hn1));} if (#[1]==1){"All the homology classes are Hodge";} } else{return(DHC);} } } example {"EXAMPLE:"; echo=2; ring r=0,x,dp; intvec dl=5,5,5; DimensionOfHodgeCycles(dl); } //--------------------------------------------------------------------------------- proc MulMat (poly P, list V1, list V2, ideal gI) "USAGE: MulMat(poly_expression,list_expression, list_expression, ideal_expression) RETURN: A matrix. It is designated for computing IVHS of homogeneous polynomials. It computes the matrix of multiplication by 'P' of the elements of the list 'V1'. The result mod the ideal 'gI' is in the vector space generated by 'V2'. The matrix is written in the basis V1 and V2. It is supposed that such a multiplication maps the vector space generated by 'V1' to the vector space generated by 'V2' and modulo the ideal 'gI'. 'V1' and 'V2' are supposed to be part of okbase(gI). " { int mu1=size(V1); int mu2=size(V2); matrix A[mu1][mu2]; int s,i,k; poly h1; poly komak; for (k=1; k<=mu1; k=k+1) { h1=reduce(P*V1[k], gI); komak=0; for (s=1; s<=size(h1); s=s+1) { for (i=1; i<=mu2; i=i+1) { if ( leadmonom(h1[s]) == leadmonom(V2[i]) ) {A[k,i]=leadcoef(h1[s]); komak=komak+V2[i]*A[k,i]; } } } if (h1<>komak){"There is a problem in your data! Type help MulMat to get some information";} } return(A); } example {"EXAMPLE:"; echo=2; ring r=0, (x,y),dp; poly f=x3+y3; ideal I=std(jacob(f)); list l1=x,y; list l2=xy; print(MulMat(x, l1, l2, I)); } //-----------------------------This might be used for IVHS for an arbitrary hypersurface---------------------------------------------- proc MatrixpijOld(int de, int dn, matrix Pe) "USAGE: Matrixpij(integer_expression, integer_expression, matrix_expression) RETURN: A matrix. The matrix 'Pe' is supposed to be the periods of a basis of the middle piece of the Hodge decomposition of the Fermat variety F: x_0^de+x_1^de+x_2^de+...x_{dn+1}^de=0. of degree 'de' and dimension 'dn' over a Hodge cycles. It is a 1 times h matrix, where h is the middle Hodge number of F. Its entries are in the field extension of rational numbers with a de-th primitive root of unity. This procedure computes the matrix [x_{i+j}] introduced in the article H. Movasati, Gauss-Manin connection in disguise: Noether-Lefschetz and Hodge loci. " { int Ik=(dn div 2)-1; //The k-th level of IVHS int k; int i; int j; def prevRing=basering; ring newRing=0, (x(0..dn+1)),dp; poly f; for (i=0; i<=dn+1;i=i+1){f=f+x(i)^de;} ideal jb=std(jacob(f)); ideal moba=kbase(jb); int mu=size(moba); int n_d=de; list defor; int n_1=(Ik+1)*de-(dn+2); list hodge1; int n_2=(Ik+2)*de-(dn+2); list hodge2; for (k=1; k<=mu; k=k+1) { if (deg(moba[k])==n_d){defor=insert(defor,moba[k], size(defor)) ;} if (deg(moba[k])==n_1){hodge1=insert(hodge1,moba[k], size(hodge1));} if (deg(moba[k])==n_2){hodge2=insert(hodge2,moba[k], size(hodge2));} } int rn=size(defor); int an=size(hodge1); int bn=size(hodge2); list lofB; for (k=1; k<=rn; k=k+1) { lofB=insert(lofB, MulMat(defor[k],hodge1, hodge2, jb), size(lofB)); } setring prevRing; list lofB=imap(newRing,lofB); matrix Xm[an][rn]; for (k=1; k<=size(lofB); k=k+1) { Xm[1..an,k]=lofB[k]*transpose(Pe); } return(Xm); } example {"EXAMPLE:"; echo=2; ring r=0, x(1..36),dp; matrix P[1][44]=x(1..36); print(Matrixpij(5,2,P)); } //-------------------------------------------------------