From 15962fc528891807a0dd8f3af0c774879857b3c7 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Mon, 13 May 2024 12:38:06 +0200 Subject: [PATCH 01/21] initial setup --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 188 ++++++++++++++++++ .../HasseSchmidt/examplesHasseSchmidt.jl | 76 +++++++ 2 files changed, 264 insertions(+) create mode 100644 src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl create mode 100644 src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl new file mode 100644 index 000000000000..f7b36c5435c6 --- /dev/null +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -0,0 +1,188 @@ + +export adjugate +export pseudo_diff +export integer_generator +export hasse_deriv + + +#################################################################################### +##################### ADJUGATE MATRIX ########################################## +# Name: adjugate +# +# INPUT: square matrix M +# OUTPUT: adjugate matrix of M + +# function provided by Max Horn. Thx +function adjugate(M) + c = charpoly(M) + f = divexact(c - c(0), gen(parent(c))) + a = f(M) + iseven(nrows(M)) ? -a : a +end + +#################################################################################### +################## DERIVATE WITH RESPECT TO PARAMETERSYSTEM #################### +# Name: pseudo_diff +# +# INPUT: +# OUTPUT: + +function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector) + R = base_ring(I) + + # Check for correct input? No, it'll be checked in main functions. + gensR = gens(R) + RetPoly = q * derivative(f, systemOfParameters[j]) + + # Generating a list of Variables which aren't in parametersystem y + OtherVars = empty(gensR) + n = ngens(R) + for k in 1:n + gensR[k] in systemOfParameters || push!(OtherVars, gensR[k]) + end + + # See formular in remark 4.2 + for k in 1:ncols(A) + for l in 1:nrows(A) + SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) + RetPoly = RetPoly - SubPoly + end + end + Istd = standard_basis(I) + RetPoly = reduce(RetPoly, gens(Istd)) # mod IZ + return (RetPoly) +end + +#################################################################################### +##################### INTEGER GENERATOR ######################################## +# Name: integer_generator +# +# INPUT: Ideal I +# OUTPUT: Ideal J, was den Schnitt von I mit dem Ring repräsentiert, über den der Polynomring definiert ist + +function integer_generator(I) + vars = gens(base_ring(I)) + J = eliminate(I, vars) # eliminiere die Variablen des Polynomrings aus dem Ideal I + return (J) +end + + + +# function hasse_deriv(f) # Hs-derivative for one polynomial + +# end + +#################################################################################### +##################### HASSE-SCHMIDT DERIVATIVE (IZ == <0>) ##################### +# Name: hasse_deriv +# +# INPUT: Ideals = IX (IZ = <0>) +# OUTPUT: List of ideals generated by hasse derivatives until but without <1> + +function hasse_deriv(IX) + + R = base_ring(IX) + n = ngens(R) # number of variables of R + r = ngens(IX) # number of generators of IX + + # Variables of Rtemp don't have names. This way there are less problems with the names of variables of R. + Rtemp, _ = polynomial_ring(base_ring(R), "y" => 1:n, "t" => 1:n) + F = gens(IX) + # replace f_j(x_i) -> f(y_i + t_i) + for j in 1:r + F[j] = evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) # F(x) -> F(y+t) + end + # F = [evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) for j in 1:r] + # Initializing Variables + i=1 # counter to iterate through degrees of monomials + tempid = gens(IX) # list to collect generators of IX and their Hasse Schmidt derivatives + RetList = [IX] # list to collect ideals generated by tempid + # RetList = empty([IX]) + varR = vcat(gens(R), ones(ZZRingElem, n)) # TODO: fmpz gibts nicht mehr wenn der dev-tree genutzt wird # fmpz -> ZZRingElem, fmpq -> QQFieldElem + + while i == 1 || tempid != gens(RetList[i-1]) # Comparing ideals was a bad idea # A little loophole: 2nd condition would throw an error at the first iteration but because i==1 is true the 2nd conditions check is skipped. + for polynome in F + for term in terms(polynome) + if sum(degrees(term)[n+1:2n]) == i + tempid = vcat(tempid, [evaluate(term, varR)]) # maybe use vector operations for shorter code? + end + end + end + i = i + 1 + RetList = vcat(RetList, ideal(R, tempid)) + end + return (RetList[1:i-1]) +end + +#################################################################################### +##################### HASSE-SCHMIDT DERIVATIVE (IZ != <0>) #################### +# Name: hasse_deriv +# +# INPUT: Ideals IZ,IX, system of parameters y, matrix M +# OUTPUT: List of ideals generated by hasse derivatives until but without <1> + +function hasse_deriv(IZ,IX,y,M) + R = base_ring(IZ) + if IZ == ideal(R, [zero(R)]) + return hasse_deriv(IX) + end + + # Checking for correct input. + IZ !== IX || error("IZ and IX cannot be equal.") + issubset(IZ,IX) || error("IZ needs to be a subset of IX.") + + # IZstd = standard_basis(ideal(R, reduce(IX, standard_basis(IZ)))) # why is this returning gens(IZ) + n = ngens(R) # number of variables of R + t = ngens(IZ) + r = ngens(IX) - t # number of generators of IX without number of generators of IZ + f = empty([R(0)]) + for poly in gens(IX) + println("# ", poly) + poly in IZ || push!(f, poly) + end # f = [Generators of IX but not of IZ] + detM = det(M) + A = adjugate(M) + + Itemp = IX + RetList = [IX] # List of ideals to return. + # RetList = empty([IX]) # Maybe we don't need IX as first entry? + Null = zeros(ZZ, length(y)) + + L = [[f[i],Null] for i in 1:r] + old = 0 + cur = r + + while integer_generator(Itemp) == ideal(R, [zero(R)]) # intersect(Itemp, ZZ) == <0> + println("# Intersection(Itemp, ZZ) == <0>") + println("# old = ", old) + println("# cur = ", cur) + for i in old+1:cur # for every f in Itemp without gens(IZ) + # println("# i = ", i) + for j in 1:length(y) # for every varialbe of system of parameters y + # println("# yj = ", y[j], " ") + ftemp = L[i][1] + note = copy(L[i][2]) # "copy" is important, otherwise "note" would only be a pointer to L[i][2] and NOT a copy + note[j] = note[j] + 1 + # normal pseudo_diff divided by faktor a + ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, y), R(note[j])) + if ftemp != zero(R) + L = push!(L, [ftemp, copy(note)]) # "copy" is important, (see above) + Itemp = Itemp + ideal(R, ftemp) + end + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + println("# ftemp = ", ftemp, " # note = ", note) + # println("# L = ", L) + end + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + end + println("# Itemp before saturation: ", Itemp) + Itemp = saturation(Itemp, ideal(R, detM)) # saturate with to get rid of the factor q = det(M) we got using pseudo_diff + println("# Itemp saturated with ", detM, ": ", Itemp) + RetList = push!(RetList, Itemp) + old = cur + cur = length(L) + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + # println("# RetList = ", RetList) + end + return (RetList) +end \ No newline at end of file diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl new file mode 100644 index 000000000000..ece2c70fc9d6 --- /dev/null +++ b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl @@ -0,0 +1,76 @@ + + +# EXAMPLE hasse_deriv (IZ == 0) +R, x = polynomial_ring(ZZ, 4, "x") +IZ = ideal(R, [zero(R)]) +IX = ideal(R, [3*x[2], 4*x[4]^3]) +hasse_deriv(IZ, IX) + +R, x = polynomial_ring(ZZ, 8, "x") +IZ = ideal(R, [zero(R)]) +IX = ideal(R, [5*x[2]*x[4]^2*x[5]]) +hasse_deriv(IZ, IX) + +# EXAMPLE hasse_deriv (IZ != 0) +R, x = polynomial_ring(ZZ, 4, "x") +IX = ideal(R, [3*x[2],4*x[4]^3]) +IZ = ideal(R, [zero(0)]) +y = x +M = matrix(R, 1, 1, [R(0)]) +hasse_deriv(IZ, IX, y, M) # working, since i call hasse_deriv(IZ, IX) for IZ = 0 + +R, x = polynomial_ring(ZZ, 4, "x") +IZ = ideal(R, [x[1]]) +IX = IZ + ideal(R, [3*x[2], 4*x[4]^3]) +y = x[2:4] +M = matrix(R, 1, 1, [R(1)]) +hasse_deriv(IZ, IX, y, M) # working + +R, x = polynomial_ring(ZZ, 8, "x") +IZ = ideal(R, [x[1]]) +y = x[2:8] +M = matrix(R, 1, 1, [R(1)]) +IX = IZ + ideal(R, [x[2]*x[3]]) # working +IX = IZ + ideal(R, [x[2]^2]) # working +IX = IZ + ideal(R, [x[2]^2 + 3]) # working +IX = IZ + ideal(R, [x[2]^2*x[3]]) # working +IX = IZ + ideal(R, [x[4]^5, x[2]*x[3]*x[7]]) # working +hasse_deriv(IZ, IX, y, M) + +R, x = polynomial_ring(ZZ, 8, "x") +IZ = ideal(R, [x[1]*x[2] - 1]) +y = x[2:8] +M = matrix(R, 1, 1, [x[2]]) +IX = IZ # working # error (IZ and IX cannot be equal.) +IX = IZ + ideal(R, [x[1]]) # working +IX = IZ + ideal(R, [x[3]]) # working +IX = IZ + ideal(R, [x[2]^2]) # working +IX = IZ + ideal(R, [x[3]^2]) # working +IX = IZ + ideal(R, [x[2]*x[3]]) # working +IX = IZ + ideal(R, [x[4]^2*x[3]]) # working +IX = IZ + ideal(R, [x[5]^3, x[6]^4]) # working +IX = IZ + ideal(R, [x[6]^4, 7]) # working +IX = IZ + ideal(R, [x[8]^6]) # working +IX = IZ + ideal(R, [x[3]^3 + x[2]^2]) # not working # expected result might be wrong +IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working +hasse_deriv(IZ, IX, y, M) + +R, x = polynomial_ring(ZZ, 8, "x") +IZ = ideal(R, [x[1]*x[2] - 1]) +y = vcat(x[1], x[3:8]) +M = matrix(R, 1, 1, [x[1]]) +IX = IZ + ideal(R, [x[2]]) # working +IX = IZ + ideal(R, [x[2], x[3]]) # working +IX = IZ + ideal(R, [x[3]]) # working +IX = IZ + ideal(R, [x[3]^2]) # working +IX = IZ + ideal(R, [x[3]^2 - 5]) # working +IX = IZ + ideal(R, [x[4]^2*x[3]]) # working +IX = IZ + ideal(R, [x[5]^3, x[6]^4]) # working +IX = IZ + ideal(R, [x[2]*x[3]]) # working +IX = IZ + ideal(R, [x[2]*x[3]^2]) # working +IX = IZ + ideal(R, [x[6]^4, 7]) # working +IX = IZ + ideal(R, [x[6]^4]) # working +IX = IZ + ideal(R, [x[3]^3 + x[4]^2]) # working +IX = IZ + ideal(R, [x[3]^3 + x[2]^2]) # working +IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working +hasse_deriv(IZ, IX, y, M) \ No newline at end of file From 344688cfd199f7718068c6d1f8f8bdba3db3e3e4 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 24 May 2024 19:54:41 +0200 Subject: [PATCH 02/21] hasse_deriv for Rloc and RQ --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 85 +++++++++++++++++-- .../HasseSchmidt/examplesHasseSchmidt.jl | 49 +++++++++-- 2 files changed, 119 insertions(+), 15 deletions(-) diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl index f7b36c5435c6..ac70a2b66bdc 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -27,7 +27,7 @@ end # INPUT: # OUTPUT: -function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector) +function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector{Int}) R = base_ring(I) # Check for correct input? No, it'll be checked in main functions. @@ -42,8 +42,8 @@ function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector) end # See formular in remark 4.2 - for k in 1:ncols(A) - for l in 1:nrows(A) + for k in 1:n_cols(A) + for l in 1:n_rows(A) SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) RetPoly = RetPoly - SubPoly end @@ -79,7 +79,44 @@ end # INPUT: Ideals = IX (IZ = <0>) # OUTPUT: List of ideals generated by hasse derivatives until but without <1> -function hasse_deriv(IX) +function hasse_deriv(IX::MPolyQuoIdeal) + # println("Funktion hasse_deriv für Ideale aus Faktor- bzw. Quotientenringen") + RQ = base_ring(IX) + R = base_ring(RQ) # could cause problems if this isn't a MPolyRing + # embedding the generators of IX into the base_ring of RQ + IX_R = ideal(R, [R(gen) for gen in gens(IX)]) + + list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals + + # projecting the hasse derivs onto the original Quotient Ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(RQ, [RQ(gen) for gen in gens(list_IX_derivs[i])])) + end + return return_list +end + +function hasse_deriv(IX::Oscar.MPolyLocalizedIdeal) + Rloc = base_ring(IX) + R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing + # projecting the generators of IX onto the base_ring of Rloc by taking the numerators + IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) + + list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals + + # embedding the hasse derivs into original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + # println("Type of IX: ",typeof(IX)) + # println("Type of IX_R: ",typeof(IX_R)) + # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) + # println("Type of return_list: ",typeof(return_list)) + return return_list +end + +function hasse_deriv(IX::MPolyIdeal) R = base_ring(IX) n = ngens(R) # number of variables of R @@ -121,7 +158,39 @@ end # INPUT: Ideals IZ,IX, system of parameters y, matrix M # OUTPUT: List of ideals generated by hasse derivatives until but without <1> -function hasse_deriv(IZ,IX,y,M) +function hasse_deriv(IZ::MPolyQuoIdeal, IX::MPolyQuoIdeal, systemOfParameters::Vector{Int}, M) + +end + +function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters, M) + Rloc = base_ring(IX) + R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing + # projecting the generators of IX and IZ onto the base_ring of Rloc by taking the numerators + IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) + IZ_R = ideal(R, [numerator(gen) for gen in gens(IZ)]) + + # systemOfParameters needs no change because it beeing Vector{Int} ist just fine + + # M_R = M, aber alle Einträge sind aus R (MPolyRing) + nRows = n_rows(M) + nCols = n_columns(M) + M_R = matrix(R, nRows, nCols, [numerator(M[i,j]) for i in 1:nRows for j in 1:nCols]) + + list_IX_derivs = hasse_deriv(IZ_R, IX_R) # calling hasse_deriv for MPolyIdeals + + # embedding the hasse derivs into original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + # println("Type of IX: ",typeof(IX)) + # println("Type of IX_R: ",typeof(IX_R)) + # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) + # println("Type of return_list: ",typeof(return_list)) + return return_list +end + +function hasse_deriv(IZ::MPolyIdeal, IX::MPolyIdeal, systemOfParameters::Vector{Int}, M) R = base_ring(IZ) if IZ == ideal(R, [zero(R)]) return hasse_deriv(IX) @@ -146,7 +215,7 @@ function hasse_deriv(IZ,IX,y,M) Itemp = IX RetList = [IX] # List of ideals to return. # RetList = empty([IX]) # Maybe we don't need IX as first entry? - Null = zeros(ZZ, length(y)) + Null = zeros(ZZ, length(systemOfParameters)) L = [[f[i],Null] for i in 1:r] old = 0 @@ -158,13 +227,13 @@ function hasse_deriv(IZ,IX,y,M) println("# cur = ", cur) for i in old+1:cur # for every f in Itemp without gens(IZ) # println("# i = ", i) - for j in 1:length(y) # for every varialbe of system of parameters y + for j in 1:length(systemOfParameters) # for every varialbe of system of parameters y # println("# yj = ", y[j], " ") ftemp = L[i][1] note = copy(L[i][2]) # "copy" is important, otherwise "note" would only be a pointer to L[i][2] and NOT a copy note[j] = note[j] + 1 # normal pseudo_diff divided by faktor a - ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, y), R(note[j])) + ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, systemOfParameters), R(note[j])) if ftemp != zero(R) L = push!(L, [ftemp, copy(note)]) # "copy" is important, (see above) Itemp = Itemp + ideal(R, ftemp) diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl index ece2c70fc9d6..fa41126f8996 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl @@ -1,5 +1,5 @@ - +### POLYNOMIALRING # EXAMPLE hasse_deriv (IZ == 0) R, x = polynomial_ring(ZZ, 4, "x") IZ = ideal(R, [zero(R)]) @@ -15,20 +15,23 @@ hasse_deriv(IZ, IX) R, x = polynomial_ring(ZZ, 4, "x") IX = ideal(R, [3*x[2],4*x[4]^3]) IZ = ideal(R, [zero(0)]) -y = x +# y = x +systemOfParameters = [1] M = matrix(R, 1, 1, [R(0)]) hasse_deriv(IZ, IX, y, M) # working, since i call hasse_deriv(IZ, IX) for IZ = 0 R, x = polynomial_ring(ZZ, 4, "x") IZ = ideal(R, [x[1]]) IX = IZ + ideal(R, [3*x[2], 4*x[4]^3]) -y = x[2:4] +# y = x[2:4] +systemOfParameters = [2, 3, 4] M = matrix(R, 1, 1, [R(1)]) hasse_deriv(IZ, IX, y, M) # working R, x = polynomial_ring(ZZ, 8, "x") IZ = ideal(R, [x[1]]) -y = x[2:8] +# y = x[2:8] +systemOfParameters = [2, 3, 4, 5, 6, 7, 8] M = matrix(R, 1, 1, [R(1)]) IX = IZ + ideal(R, [x[2]*x[3]]) # working IX = IZ + ideal(R, [x[2]^2]) # working @@ -39,7 +42,8 @@ hasse_deriv(IZ, IX, y, M) R, x = polynomial_ring(ZZ, 8, "x") IZ = ideal(R, [x[1]*x[2] - 1]) -y = x[2:8] +# y = x[2:8] +systemOfParameters = [2, 3, 4, 5, 6, 7, 8] M = matrix(R, 1, 1, [x[2]]) IX = IZ # working # error (IZ and IX cannot be equal.) IX = IZ + ideal(R, [x[1]]) # working @@ -57,7 +61,8 @@ hasse_deriv(IZ, IX, y, M) R, x = polynomial_ring(ZZ, 8, "x") IZ = ideal(R, [x[1]*x[2] - 1]) -y = vcat(x[1], x[3:8]) +# y = vcat(x[1], x[3:8]) +systemOfParameters = [1, 3, 4, 5, 6, 7, 8] M = matrix(R, 1, 1, [x[1]]) IX = IZ + ideal(R, [x[2]]) # working IX = IZ + ideal(R, [x[2], x[3]]) # working @@ -73,4 +78,34 @@ IX = IZ + ideal(R, [x[6]^4]) # working IX = IZ + ideal(R, [x[3]^3 + x[4]^2]) # working IX = IZ + ideal(R, [x[3]^3 + x[2]^2]) # working IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working -hasse_deriv(IZ, IX, y, M) \ No newline at end of file +hasse_deriv(IZ, IX, y, M) + +### FAKTORRING / QUOTIENTENRING + +### LOKALISIERTER RING + +# Oscar.MPolyLocalizedIdeal +R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) +P = ideal(R, [x]) +U = complement_of_prime_ideal(P) +Rloc, iota = localization(R, U) +IZ = ideal(Rloc, [zero(Rloc)]) +IX = ideal(Rloc, [-y^3 + x^2]) + +# MPolyQuoIdeal +# T, t = polynomial_ring(QQ, "t") +# K, a = number_field(2*t^2-1, "a") +R, (x, y) = polynomial_ring(QQ, ["x", "y"]) +I = ideal(R, [x - 1]) # I = ideal(R, [x-1, x-a]) +RQ, _ = quo(R, I) +IZ = ideal(RQ, [zero(RQ)]) +IX = ideal(RQ, [-y^3 + x^2]) + +R, (x, y) = polynomial_ring(QQ, ["x", "y"]) +I = ideal(R, [x^3 - 1]) +RQ, phi = quo(R, I) +P = ideal(R, [y]) +U = complement_of_prime_ideal(P) +RQL, iota = localization(RQ, U) +IZ = ideal(RQL, [zero(RQL)]) +IX = ideal(RQL, [-y^3 + x^2]) # RESOVLED: IZ and IX are equal (need to understand why ^^ ) # Need to find an example with IZ != IX \ No newline at end of file From 1237dfd5d30fda3872faa6cd4e27e1d93b67041f Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 31 May 2024 13:15:15 +0200 Subject: [PATCH 03/21] hasse_deriv finished for MPolyLocRing and MPolyQuoRing --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 33 +++++++++++++------ .../HasseSchmidt/examplesHasseSchmidt.jl | 21 ++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl index ac70a2b66bdc..d36c19691ae9 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -42,8 +42,8 @@ function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector{Int}) end # See formular in remark 4.2 - for k in 1:n_cols(A) - for l in 1:n_rows(A) + for k in 1:ncols(A) + for l in 1:nrows(A) SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) RetPoly = RetPoly - SubPoly end @@ -66,12 +66,6 @@ function integer_generator(I) return (J) end - - -# function hasse_deriv(f) # Hs-derivative for one polynomial - -# end - #################################################################################### ##################### HASSE-SCHMIDT DERIVATIVE (IZ == <0>) ##################### # Name: hasse_deriv @@ -97,6 +91,7 @@ function hasse_deriv(IX::MPolyQuoIdeal) end function hasse_deriv(IX::Oscar.MPolyLocalizedIdeal) + # Rloc.(I.gens) Rloc = base_ring(IX) R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing # projecting the generators of IX onto the base_ring of Rloc by taking the numerators @@ -159,10 +154,28 @@ end # OUTPUT: List of ideals generated by hasse derivatives until but without <1> function hasse_deriv(IZ::MPolyQuoIdeal, IX::MPolyQuoIdeal, systemOfParameters::Vector{Int}, M) + RQ = base_ring(IX) + R = base_ring(RQ) # could cause problems if this isn't a MPolyRing + # embedding the generators of IX and IZ into the base_ring of RQ + IX_R = ideal(R, [R(gen) for gen in gens(IX)]) + IZ_R = ideal(R, [R(gen) for gen in gens(IZ)]) + # systemOfParameters needs no change because it beeing Vector{Int} ist just fine + nRows = n_rows(M) + nCols = n_columns(M) + M_R = matrix(R, nRows, nCols, [R(M[i,j]) for i in 1:nRows for j in 1:nCols]) + + list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals + + # projecting the hasse derivs onto original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + return return_list end -function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters, M) +function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters::Vector{Int}, M) Rloc = base_ring(IX) R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing # projecting the generators of IX and IZ onto the base_ring of Rloc by taking the numerators @@ -176,7 +189,7 @@ function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdea nCols = n_columns(M) M_R = matrix(R, nRows, nCols, [numerator(M[i,j]) for i in 1:nRows for j in 1:nCols]) - list_IX_derivs = hasse_deriv(IZ_R, IX_R) # calling hasse_deriv for MPolyIdeals + list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals # embedding the hasse derivs into original localized ring return_list = empty([]) diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl index fa41126f8996..3077d6b3423f 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl @@ -81,8 +81,28 @@ IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working hasse_deriv(IZ, IX, y, M) ### FAKTORRING / QUOTIENTENRING +R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) +I = ideal(R, [x - 1]) +RQ, _ = quo(R, I) +IZ = ideal(RQ, [y - 1]) +IX = IZ + ideal(RQ, [-y^3 + x^2]) +systemOfParameters = [3] +M = matrix(RQ, 1, 1, [z]) + +hasse_deriv(IZ, IX, systemOfParameters, M) # debuggen (endlosschleife), ? x-1 und y-1 sorgen für IX = 0 in RQ ? +# sollte ich auf IX = 0 prüfen? wo prüfe ich bisher auf IX = 0 ? kommt hasse_deriv mit IX = 0 nicht klar? ### LOKALISIERTER RING +R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) +P = ideal(R, [x]) +U = complement_of_prime_ideal(P) +Rloc, iota = localization(R, U) +IZ = ideal(Rloc, [y - 1]) +IX = IZ + ideal(Rloc, [-y^3 + x^2]) +systemOfParameters = [1, 3] +M = matrix(Rloc, 1, 1, [z]) + +hasse_deriv(IZ, IX, systemOfParameters, M) # Oscar.MPolyLocalizedIdeal R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) @@ -92,6 +112,7 @@ Rloc, iota = localization(R, U) IZ = ideal(Rloc, [zero(Rloc)]) IX = ideal(Rloc, [-y^3 + x^2]) + # MPolyQuoIdeal # T, t = polynomial_ring(QQ, "t") # K, a = number_field(2*t^2-1, "a") From f0209272f79101f35a465a00c55d971feaf86752 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 31 May 2024 14:38:14 +0200 Subject: [PATCH 04/21] hasse_derivatives for MPolyElem finished --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 245 ++-------------- .../HasseSchmidtDerivativeForIdeals.jl | 270 ++++++++++++++++++ .../HasseSchmidt/examplesHasseSchmidt.jl | 12 + 3 files changed, 299 insertions(+), 228 deletions(-) create mode 100644 src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl index d36c19691ae9..62b6d3e97f0d 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -1,114 +1,26 @@ -export adjugate -export pseudo_diff -export integer_generator -export hasse_deriv - -#################################################################################### -##################### ADJUGATE MATRIX ########################################## -# Name: adjugate -# -# INPUT: square matrix M -# OUTPUT: adjugate matrix of M - -# function provided by Max Horn. Thx -function adjugate(M) - c = charpoly(M) - f = divexact(c - c(0), gen(parent(c))) - a = f(M) - iseven(nrows(M)) ? -a : a -end - -#################################################################################### -################## DERIVATE WITH RESPECT TO PARAMETERSYSTEM #################### -# Name: pseudo_diff -# -# INPUT: -# OUTPUT: - -function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector{Int}) - R = base_ring(I) - - # Check for correct input? No, it'll be checked in main functions. - gensR = gens(R) - RetPoly = q * derivative(f, systemOfParameters[j]) - - # Generating a list of Variables which aren't in parametersystem y - OtherVars = empty(gensR) +# HASSE-SCHMIDT Derivative for MPolyRingElem +function hasse_derivatives(f::MPolyRingElem) + R = parent(f) n = ngens(R) - for k in 1:n - gensR[k] in systemOfParameters || push!(OtherVars, gensR[k]) - end + # degreef = maximum(degrees(f)) + # define new ring with more variables: R[x1, ..., xn] -> R[x1, ..., xn, t1, ..., tn] + Rtemp, _ = polynomial_ring(R, "y" => 1:n, "t" => 1:n) + # replace f(x_i) -> f(y_i + t_i) + F = evaluate(f, gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) + # i = 1 # counter to iterate though degrees of monomials + HasseDerivativesList = empty([f]) + varR = vcat(gens(R), ones(typeof(base_ring(R)(1)), n)) + # varR = vcat(gens(R), ones(ZZRingElem, n)) - # See formular in remark 4.2 - for k in 1:ncols(A) - for l in 1:nrows(A) - SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) - RetPoly = RetPoly - SubPoly - end + # getting hasse derivs without extra attention on ordering + for term in terms(F) + # hasse derivatives are the factors in front of the monomial in t + push!(HasseDerivativesList, evaluate(term, varR)) end - Istd = standard_basis(I) - RetPoly = reduce(RetPoly, gens(Istd)) # mod IZ - return (RetPoly) -end -#################################################################################### -##################### INTEGER GENERATOR ######################################## -# Name: integer_generator -# -# INPUT: Ideal I -# OUTPUT: Ideal J, was den Schnitt von I mit dem Ring repräsentiert, über den der Polynomring definiert ist - -function integer_generator(I) - vars = gens(base_ring(I)) - J = eliminate(I, vars) # eliminiere die Variablen des Polynomrings aus dem Ideal I - return (J) -end - -#################################################################################### -##################### HASSE-SCHMIDT DERIVATIVE (IZ == <0>) ##################### -# Name: hasse_deriv -# -# INPUT: Ideals = IX (IZ = <0>) -# OUTPUT: List of ideals generated by hasse derivatives until but without <1> - -function hasse_deriv(IX::MPolyQuoIdeal) - # println("Funktion hasse_deriv für Ideale aus Faktor- bzw. Quotientenringen") - RQ = base_ring(IX) - R = base_ring(RQ) # could cause problems if this isn't a MPolyRing - # embedding the generators of IX into the base_ring of RQ - IX_R = ideal(R, [R(gen) for gen in gens(IX)]) - - list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals - - # projecting the hasse derivs onto the original Quotient Ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(RQ, [RQ(gen) for gen in gens(list_IX_derivs[i])])) - end - return return_list -end - -function hasse_deriv(IX::Oscar.MPolyLocalizedIdeal) - # Rloc.(I.gens) - Rloc = base_ring(IX) - R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing - # projecting the generators of IX onto the base_ring of Rloc by taking the numerators - IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) - - list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals - - # embedding the hasse derivs into original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - # println("Type of IX: ",typeof(IX)) - # println("Type of IX_R: ",typeof(IX_R)) - # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) - # println("Type of return_list: ",typeof(return_list)) - return return_list + return HasseDerivativesList end function hasse_deriv(IX::MPolyIdeal) @@ -144,127 +56,4 @@ function hasse_deriv(IX::MPolyIdeal) RetList = vcat(RetList, ideal(R, tempid)) end return (RetList[1:i-1]) -end - -#################################################################################### -##################### HASSE-SCHMIDT DERIVATIVE (IZ != <0>) #################### -# Name: hasse_deriv -# -# INPUT: Ideals IZ,IX, system of parameters y, matrix M -# OUTPUT: List of ideals generated by hasse derivatives until but without <1> - -function hasse_deriv(IZ::MPolyQuoIdeal, IX::MPolyQuoIdeal, systemOfParameters::Vector{Int}, M) - RQ = base_ring(IX) - R = base_ring(RQ) # could cause problems if this isn't a MPolyRing - # embedding the generators of IX and IZ into the base_ring of RQ - IX_R = ideal(R, [R(gen) for gen in gens(IX)]) - IZ_R = ideal(R, [R(gen) for gen in gens(IZ)]) - - # systemOfParameters needs no change because it beeing Vector{Int} ist just fine - nRows = n_rows(M) - nCols = n_columns(M) - M_R = matrix(R, nRows, nCols, [R(M[i,j]) for i in 1:nRows for j in 1:nCols]) - - list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals - - # projecting the hasse derivs onto original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - return return_list -end - -function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters::Vector{Int}, M) - Rloc = base_ring(IX) - R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing - # projecting the generators of IX and IZ onto the base_ring of Rloc by taking the numerators - IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) - IZ_R = ideal(R, [numerator(gen) for gen in gens(IZ)]) - - # systemOfParameters needs no change because it beeing Vector{Int} ist just fine - - # M_R = M, aber alle Einträge sind aus R (MPolyRing) - nRows = n_rows(M) - nCols = n_columns(M) - M_R = matrix(R, nRows, nCols, [numerator(M[i,j]) for i in 1:nRows for j in 1:nCols]) - - list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals - - # embedding the hasse derivs into original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - # println("Type of IX: ",typeof(IX)) - # println("Type of IX_R: ",typeof(IX_R)) - # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) - # println("Type of return_list: ",typeof(return_list)) - return return_list -end - -function hasse_deriv(IZ::MPolyIdeal, IX::MPolyIdeal, systemOfParameters::Vector{Int}, M) - R = base_ring(IZ) - if IZ == ideal(R, [zero(R)]) - return hasse_deriv(IX) - end - - # Checking for correct input. - IZ !== IX || error("IZ and IX cannot be equal.") - issubset(IZ,IX) || error("IZ needs to be a subset of IX.") - - # IZstd = standard_basis(ideal(R, reduce(IX, standard_basis(IZ)))) # why is this returning gens(IZ) - n = ngens(R) # number of variables of R - t = ngens(IZ) - r = ngens(IX) - t # number of generators of IX without number of generators of IZ - f = empty([R(0)]) - for poly in gens(IX) - println("# ", poly) - poly in IZ || push!(f, poly) - end # f = [Generators of IX but not of IZ] - detM = det(M) - A = adjugate(M) - - Itemp = IX - RetList = [IX] # List of ideals to return. - # RetList = empty([IX]) # Maybe we don't need IX as first entry? - Null = zeros(ZZ, length(systemOfParameters)) - - L = [[f[i],Null] for i in 1:r] - old = 0 - cur = r - - while integer_generator(Itemp) == ideal(R, [zero(R)]) # intersect(Itemp, ZZ) == <0> - println("# Intersection(Itemp, ZZ) == <0>") - println("# old = ", old) - println("# cur = ", cur) - for i in old+1:cur # for every f in Itemp without gens(IZ) - # println("# i = ", i) - for j in 1:length(systemOfParameters) # for every varialbe of system of parameters y - # println("# yj = ", y[j], " ") - ftemp = L[i][1] - note = copy(L[i][2]) # "copy" is important, otherwise "note" would only be a pointer to L[i][2] and NOT a copy - note[j] = note[j] + 1 - # normal pseudo_diff divided by faktor a - ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, systemOfParameters), R(note[j])) - if ftemp != zero(R) - L = push!(L, [ftemp, copy(note)]) # "copy" is important, (see above) - Itemp = Itemp + ideal(R, ftemp) - end - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - println("# ftemp = ", ftemp, " # note = ", note) - # println("# L = ", L) - end - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - end - println("# Itemp before saturation: ", Itemp) - Itemp = saturation(Itemp, ideal(R, detM)) # saturate with to get rid of the factor q = det(M) we got using pseudo_diff - println("# Itemp saturated with ", detM, ": ", Itemp) - RetList = push!(RetList, Itemp) - old = cur - cur = length(L) - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - # println("# RetList = ", RetList) - end - return (RetList) end \ No newline at end of file diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl new file mode 100644 index 000000000000..d36c19691ae9 --- /dev/null +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl @@ -0,0 +1,270 @@ + +export adjugate +export pseudo_diff +export integer_generator +export hasse_deriv + + +#################################################################################### +##################### ADJUGATE MATRIX ########################################## +# Name: adjugate +# +# INPUT: square matrix M +# OUTPUT: adjugate matrix of M + +# function provided by Max Horn. Thx +function adjugate(M) + c = charpoly(M) + f = divexact(c - c(0), gen(parent(c))) + a = f(M) + iseven(nrows(M)) ? -a : a +end + +#################################################################################### +################## DERIVATE WITH RESPECT TO PARAMETERSYSTEM #################### +# Name: pseudo_diff +# +# INPUT: +# OUTPUT: + +function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector{Int}) + R = base_ring(I) + + # Check for correct input? No, it'll be checked in main functions. + gensR = gens(R) + RetPoly = q * derivative(f, systemOfParameters[j]) + + # Generating a list of Variables which aren't in parametersystem y + OtherVars = empty(gensR) + n = ngens(R) + for k in 1:n + gensR[k] in systemOfParameters || push!(OtherVars, gensR[k]) + end + + # See formular in remark 4.2 + for k in 1:ncols(A) + for l in 1:nrows(A) + SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) + RetPoly = RetPoly - SubPoly + end + end + Istd = standard_basis(I) + RetPoly = reduce(RetPoly, gens(Istd)) # mod IZ + return (RetPoly) +end + +#################################################################################### +##################### INTEGER GENERATOR ######################################## +# Name: integer_generator +# +# INPUT: Ideal I +# OUTPUT: Ideal J, was den Schnitt von I mit dem Ring repräsentiert, über den der Polynomring definiert ist + +function integer_generator(I) + vars = gens(base_ring(I)) + J = eliminate(I, vars) # eliminiere die Variablen des Polynomrings aus dem Ideal I + return (J) +end + +#################################################################################### +##################### HASSE-SCHMIDT DERIVATIVE (IZ == <0>) ##################### +# Name: hasse_deriv +# +# INPUT: Ideals = IX (IZ = <0>) +# OUTPUT: List of ideals generated by hasse derivatives until but without <1> + +function hasse_deriv(IX::MPolyQuoIdeal) + # println("Funktion hasse_deriv für Ideale aus Faktor- bzw. Quotientenringen") + RQ = base_ring(IX) + R = base_ring(RQ) # could cause problems if this isn't a MPolyRing + # embedding the generators of IX into the base_ring of RQ + IX_R = ideal(R, [R(gen) for gen in gens(IX)]) + + list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals + + # projecting the hasse derivs onto the original Quotient Ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(RQ, [RQ(gen) for gen in gens(list_IX_derivs[i])])) + end + return return_list +end + +function hasse_deriv(IX::Oscar.MPolyLocalizedIdeal) + # Rloc.(I.gens) + Rloc = base_ring(IX) + R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing + # projecting the generators of IX onto the base_ring of Rloc by taking the numerators + IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) + + list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals + + # embedding the hasse derivs into original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + # println("Type of IX: ",typeof(IX)) + # println("Type of IX_R: ",typeof(IX_R)) + # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) + # println("Type of return_list: ",typeof(return_list)) + return return_list +end + +function hasse_deriv(IX::MPolyIdeal) + + R = base_ring(IX) + n = ngens(R) # number of variables of R + r = ngens(IX) # number of generators of IX + + # Variables of Rtemp don't have names. This way there are less problems with the names of variables of R. + Rtemp, _ = polynomial_ring(base_ring(R), "y" => 1:n, "t" => 1:n) + F = gens(IX) + # replace f_j(x_i) -> f(y_i + t_i) + for j in 1:r + F[j] = evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) # F(x) -> F(y+t) + end + # F = [evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) for j in 1:r] + # Initializing Variables + i=1 # counter to iterate through degrees of monomials + tempid = gens(IX) # list to collect generators of IX and their Hasse Schmidt derivatives + RetList = [IX] # list to collect ideals generated by tempid + # RetList = empty([IX]) + varR = vcat(gens(R), ones(ZZRingElem, n)) # TODO: fmpz gibts nicht mehr wenn der dev-tree genutzt wird # fmpz -> ZZRingElem, fmpq -> QQFieldElem + + while i == 1 || tempid != gens(RetList[i-1]) # Comparing ideals was a bad idea # A little loophole: 2nd condition would throw an error at the first iteration but because i==1 is true the 2nd conditions check is skipped. + for polynome in F + for term in terms(polynome) + if sum(degrees(term)[n+1:2n]) == i + tempid = vcat(tempid, [evaluate(term, varR)]) # maybe use vector operations for shorter code? + end + end + end + i = i + 1 + RetList = vcat(RetList, ideal(R, tempid)) + end + return (RetList[1:i-1]) +end + +#################################################################################### +##################### HASSE-SCHMIDT DERIVATIVE (IZ != <0>) #################### +# Name: hasse_deriv +# +# INPUT: Ideals IZ,IX, system of parameters y, matrix M +# OUTPUT: List of ideals generated by hasse derivatives until but without <1> + +function hasse_deriv(IZ::MPolyQuoIdeal, IX::MPolyQuoIdeal, systemOfParameters::Vector{Int}, M) + RQ = base_ring(IX) + R = base_ring(RQ) # could cause problems if this isn't a MPolyRing + # embedding the generators of IX and IZ into the base_ring of RQ + IX_R = ideal(R, [R(gen) for gen in gens(IX)]) + IZ_R = ideal(R, [R(gen) for gen in gens(IZ)]) + + # systemOfParameters needs no change because it beeing Vector{Int} ist just fine + nRows = n_rows(M) + nCols = n_columns(M) + M_R = matrix(R, nRows, nCols, [R(M[i,j]) for i in 1:nRows for j in 1:nCols]) + + list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals + + # projecting the hasse derivs onto original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + return return_list +end + +function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters::Vector{Int}, M) + Rloc = base_ring(IX) + R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing + # projecting the generators of IX and IZ onto the base_ring of Rloc by taking the numerators + IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) + IZ_R = ideal(R, [numerator(gen) for gen in gens(IZ)]) + + # systemOfParameters needs no change because it beeing Vector{Int} ist just fine + + # M_R = M, aber alle Einträge sind aus R (MPolyRing) + nRows = n_rows(M) + nCols = n_columns(M) + M_R = matrix(R, nRows, nCols, [numerator(M[i,j]) for i in 1:nRows for j in 1:nCols]) + + list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals + + # embedding the hasse derivs into original localized ring + return_list = empty([]) + for i in 1:length(list_IX_derivs) + push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) + end + # println("Type of IX: ",typeof(IX)) + # println("Type of IX_R: ",typeof(IX_R)) + # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) + # println("Type of return_list: ",typeof(return_list)) + return return_list +end + +function hasse_deriv(IZ::MPolyIdeal, IX::MPolyIdeal, systemOfParameters::Vector{Int}, M) + R = base_ring(IZ) + if IZ == ideal(R, [zero(R)]) + return hasse_deriv(IX) + end + + # Checking for correct input. + IZ !== IX || error("IZ and IX cannot be equal.") + issubset(IZ,IX) || error("IZ needs to be a subset of IX.") + + # IZstd = standard_basis(ideal(R, reduce(IX, standard_basis(IZ)))) # why is this returning gens(IZ) + n = ngens(R) # number of variables of R + t = ngens(IZ) + r = ngens(IX) - t # number of generators of IX without number of generators of IZ + f = empty([R(0)]) + for poly in gens(IX) + println("# ", poly) + poly in IZ || push!(f, poly) + end # f = [Generators of IX but not of IZ] + detM = det(M) + A = adjugate(M) + + Itemp = IX + RetList = [IX] # List of ideals to return. + # RetList = empty([IX]) # Maybe we don't need IX as first entry? + Null = zeros(ZZ, length(systemOfParameters)) + + L = [[f[i],Null] for i in 1:r] + old = 0 + cur = r + + while integer_generator(Itemp) == ideal(R, [zero(R)]) # intersect(Itemp, ZZ) == <0> + println("# Intersection(Itemp, ZZ) == <0>") + println("# old = ", old) + println("# cur = ", cur) + for i in old+1:cur # for every f in Itemp without gens(IZ) + # println("# i = ", i) + for j in 1:length(systemOfParameters) # for every varialbe of system of parameters y + # println("# yj = ", y[j], " ") + ftemp = L[i][1] + note = copy(L[i][2]) # "copy" is important, otherwise "note" would only be a pointer to L[i][2] and NOT a copy + note[j] = note[j] + 1 + # normal pseudo_diff divided by faktor a + ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, systemOfParameters), R(note[j])) + if ftemp != zero(R) + L = push!(L, [ftemp, copy(note)]) # "copy" is important, (see above) + Itemp = Itemp + ideal(R, ftemp) + end + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + println("# ftemp = ", ftemp, " # note = ", note) + # println("# L = ", L) + end + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + end + println("# Itemp before saturation: ", Itemp) + Itemp = saturation(Itemp, ideal(R, detM)) # saturate with to get rid of the factor q = det(M) we got using pseudo_diff + println("# Itemp saturated with ", detM, ": ", Itemp) + RetList = push!(RetList, Itemp) + old = cur + cur = length(L) + sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) + # println("# RetList = ", RetList) + end + return (RetList) +end \ No newline at end of file diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl index 3077d6b3423f..d5ded5f35188 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl @@ -1,4 +1,16 @@ +# MPolyRingElem +R, x = polynomial_ring(ZZ, 4, "x") +f1 = 3*x[2] +f2 = 4*x[4]^3 +hasse_derivative(f1) + + + + + +### EXAMPLES FOR HASSE-SCHMIDT DERIVATE FOR IDEALS (old) + ### POLYNOMIALRING # EXAMPLE hasse_deriv (IZ == 0) R, x = polynomial_ring(ZZ, 4, "x") From 37bf2d3a1e04ba41ef09f5c1b80b139672c58587 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 31 May 2024 17:47:14 +0200 Subject: [PATCH 05/21] Foundation for Hasse Derivatives for Polynomials --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 81 +++++++++++-------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl index 62b6d3e97f0d..e951fc5807d9 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -1,6 +1,10 @@ +export hasse_derivatives -# HASSE-SCHMIDT Derivative for MPolyRingElem + +### HASSE-SCHMIDT derivatives for single polynomials + +# MPolyRingElem function hasse_derivatives(f::MPolyRingElem) R = parent(f) n = ngens(R) @@ -12,48 +16,55 @@ function hasse_derivatives(f::MPolyRingElem) # i = 1 # counter to iterate though degrees of monomials HasseDerivativesList = empty([f]) varR = vcat(gens(R), ones(typeof(base_ring(R)(1)), n)) - # varR = vcat(gens(R), ones(ZZRingElem, n)) - # getting hasse derivs without extra attention on ordering for term in terms(F) # hasse derivatives are the factors in front of the monomial in t push!(HasseDerivativesList, evaluate(term, varR)) end - return HasseDerivativesList end -function hasse_deriv(IX::MPolyIdeal) +function hasse_derivatives(f::MPolyQuoRingElem) + error("Not implemented.") + error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type MPolyQuoRingElem") +end + +function hasse_derivatives(f::Oscar.MPolyLocRingElem) + error("Not implemented.") + error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") +end - R = base_ring(IX) - n = ngens(R) # number of variables of R - r = ngens(IX) # number of generators of IX +function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) + error("Not implemented.") + error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") +end - # Variables of Rtemp don't have names. This way there are less problems with the names of variables of R. - Rtemp, _ = polynomial_ring(base_ring(R), "y" => 1:n, "t" => 1:n) - F = gens(IX) - # replace f_j(x_i) -> f(y_i + t_i) - for j in 1:r - F[j] = evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) # F(x) -> F(y+t) - end - # F = [evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) for j in 1:r] - # Initializing Variables - i=1 # counter to iterate through degrees of monomials - tempid = gens(IX) # list to collect generators of IX and their Hasse Schmidt derivatives - RetList = [IX] # list to collect ideals generated by tempid - # RetList = empty([IX]) - varR = vcat(gens(R), ones(ZZRingElem, n)) # TODO: fmpz gibts nicht mehr wenn der dev-tree genutzt wird # fmpz -> ZZRingElem, fmpq -> QQFieldElem - - while i == 1 || tempid != gens(RetList[i-1]) # Comparing ideals was a bad idea # A little loophole: 2nd condition would throw an error at the first iteration but because i==1 is true the 2nd conditions check is skipped. - for polynome in F - for term in terms(polynome) - if sum(degrees(term)[n+1:2n]) == i - tempid = vcat(tempid, [evaluate(term, varR)]) # maybe use vector operations for shorter code? - end - end - end - i = i + 1 - RetList = vcat(RetList, ideal(R, tempid)) - end - return (RetList[1:i-1]) + + +### HASSE-SCHMIDT derivatives for a list of polynomials + +function hasse_derivatives(v::Vector) + return hasse_derivatives.(v) +end + + + + + +### internal functions for experts + +# MPolyQuoRingElem (internal, expert use only) +function _hasse_derivatives(f::MPolyQuoRingElem) + R = base_ring(f) # QUESTION: Is base_ring of Quotient ring always a MPolyRing? + return hasse_derivatives(R(f)) +end + +# Oscar.MPolyLocRingElem (internal, expert use only) +function _hasse_derivatives(f::Oscar.MPolyLocRingElem) + return hasse_derivatives(numerator(f)) +end + +# Oscar.MPolyQuoLocRingElem (internal, expert use only) +function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) + # QUESTION: How do i do this? How do i work around the localization and the modulus? end \ No newline at end of file From fdaa169c800c8125d71d578bd0e9db129c6486a4 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Wed, 5 Jun 2024 16:52:28 +0200 Subject: [PATCH 06/21] Examples for RQ, Rloc and RQL --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 16 ++-- .../HasseSchmidt/examplesHasseSchmidt.jl | 81 +++++++++++++++++-- 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl index e951fc5807d9..35427eacb0b6 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl @@ -25,18 +25,15 @@ function hasse_derivatives(f::MPolyRingElem) end function hasse_derivatives(f::MPolyQuoRingElem) - error("Not implemented.") - error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type MPolyQuoRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type MPolyQuoRingElem") end function hasse_derivatives(f::Oscar.MPolyLocRingElem) - error("Not implemented.") - error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") end function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) - error("Not implemented.") - error("For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") end @@ -51,7 +48,7 @@ end -### internal functions for experts +### internal functions for expert use # MPolyQuoRingElem (internal, expert use only) function _hasse_derivatives(f::MPolyQuoRingElem) @@ -67,4 +64,9 @@ end # Oscar.MPolyQuoLocRingElem (internal, expert use only) function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) # QUESTION: How do i do this? How do i work around the localization and the modulus? +end + +# for a list of elements (internal, expert use only) +function _hasse_derivatives(v::Vector) + return _hasse_derivatives.(v) end \ No newline at end of file diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl index d5ded5f35188..329339fd6365 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl +++ b/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl @@ -1,9 +1,78 @@ -# MPolyRingElem +### MPolyRingElem R, x = polynomial_ring(ZZ, 4, "x") -f1 = 3*x[2] -f2 = 4*x[4]^3 -hasse_derivative(f1) +f1 = R(3*x[2]) +f2 = R(4*x[4]^3) +hasse_derivatives(f1) +hasse_derivatives([f1, f2]) + +R, x = polynomial_ring(QQ, 4, "x") +f1 = R(3*x[2]) +f2 = R(4*x[4]^3) +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +### MPolyQuoRingElem +R, x = polynomial_ring(ZZ, 4, "x") +I = ideal(R, [x[2] - 1]) +RQ, _ = quo(R, I) +f1 = 4*x[3] +f2 = 5*x[2]^2 + 2*x[4] +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +R, x = polynomial_ring(QQ, 4, "x") +I = ideal(R, [x[2] - 1]) +RQ, _ = quo(R, I) +f1 = RQ(4*x[3] ) +f2 = RQ(5*x[2]^2 + 2*x[4]) +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +### Oscar.MPolyLocRingElem + +# (1) Localization at maximal ideal +R, x = polynomial_ring(QQ, 4, "x") +m = ideal(R, [x[1] - 3, x[2] - 2, x[3] + 2, x[4]]) +U = complement_of_prime_ideal(m) +Rloc, _ = localization(R, U) +f1 = Rloc(4*x[3] ) +f2 = Rloc(5*x[2]^2 + 2*x[4]^5) +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +# (2) Localization at prime ideal +R, x = polynomial_ring(QQ, 4, "x") +p = ideal(R, [x[1]]) +U = complement_of_prime_ideal(p) +Rloc, _ = localization(R, U) +f1 = Rloc(4*x[3] ) +f2 = Rloc(5*x[2]^2 + 2*x[4]) +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +# (3) Localization at ring element + + +### Oscar.MPolyQuoLocRingElem + +# (1) Localization at prime ideal +R, x = polynomial_ring(QQ, 4, "x") +I = ideal(R, [x[1]^3 - 1]) +RQ, _ = quo(R, I) +p = ideal(R, [x[2]]) +U = complement_of_prime_ideal(p) +RQL, _ = localization(RQ, U) +f1 = RQL(4*x[3] ) +f2 = RQL(5*x[2]^2 + 2*x[4]) +hasse_derivatives(f2) +hasse_derivatives([f1, f2]) + +# (2) Localization at maximal ideal + +# (3) Localization at ring element + + @@ -136,9 +205,9 @@ IX = ideal(RQ, [-y^3 + x^2]) R, (x, y) = polynomial_ring(QQ, ["x", "y"]) I = ideal(R, [x^3 - 1]) -RQ, phi = quo(R, I) +RQ, _ = quo(R, I) P = ideal(R, [y]) U = complement_of_prime_ideal(P) -RQL, iota = localization(RQ, U) +RQL, _ = localization(RQ, U) IZ = ideal(RQL, [zero(RQL)]) IX = ideal(RQL, [-y^3 + x^2]) # RESOVLED: IZ and IX are equal (need to understand why ^^ ) # Need to find an example with IZ != IX \ No newline at end of file From 16d75de90c4c1fdd95cdd09d3d2f7c20e494f0b4 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Tue, 18 Jun 2024 16:09:06 +0200 Subject: [PATCH 07/21] HSD for RQL rings working --- .../src}/HasseSchmidtDerivative.jl | 36 +++++++++++++++---- .../src}/HasseSchmidtDerivativeForIdeals.jl | 2 ++ .../test}/examplesHasseSchmidt.jl | 13 ++++--- experimental/HasseSchmidt/test/runtests.jl | 3 ++ 4 files changed, 44 insertions(+), 10 deletions(-) rename {src/AlgebraicGeometry/HasseSchmidt => experimental/HasseSchmidt/src}/HasseSchmidtDerivative.jl (76%) rename {src/AlgebraicGeometry/HasseSchmidt => experimental/HasseSchmidt/src}/HasseSchmidtDerivativeForIdeals.jl (99%) rename {src/AlgebraicGeometry/HasseSchmidt => experimental/HasseSchmidt/test}/examplesHasseSchmidt.jl (96%) create mode 100644 experimental/HasseSchmidt/test/runtests.jl diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl similarity index 76% rename from src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl rename to experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl index 35427eacb0b6..e8f4f6ec4d0a 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl @@ -1,9 +1,34 @@ export hasse_derivatives - +################################################################################ ### HASSE-SCHMIDT derivatives for single polynomials +@doc raw""" + hasse_derivatives(f::MPolyRingElem) + +Return the Hasse-Schmidt derivatives of `f`. + +# Examples +```jldoctest +julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); + +julia> f = R(5*x^2 + 3*y^5); + +julia> hasse_derivatives(f) +9-element Vector{ZZMPolyRingElem}: + 3*y^5 + 15*y^4 + 30*y^3 + 30*y^2 + 15*y + 3 + 5*x^2 + 10*x + 5 +``` +""" + # MPolyRingElem function hasse_derivatives(f::MPolyRingElem) R = parent(f) @@ -37,7 +62,7 @@ function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) end - +################################################################################ ### HASSE-SCHMIDT derivatives for a list of polynomials function hasse_derivatives(v::Vector) @@ -47,13 +72,12 @@ end - +################################################################################ ### internal functions for expert use # MPolyQuoRingElem (internal, expert use only) function _hasse_derivatives(f::MPolyQuoRingElem) - R = base_ring(f) # QUESTION: Is base_ring of Quotient ring always a MPolyRing? - return hasse_derivatives(R(f)) + return hasse_derivatives(lifted_numerator(f)) end # Oscar.MPolyLocRingElem (internal, expert use only) @@ -63,7 +87,7 @@ end # Oscar.MPolyQuoLocRingElem (internal, expert use only) function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) - # QUESTION: How do i do this? How do i work around the localization and the modulus? + return hasse_derivatives(lifted_numerator(f)) end # for a list of elements (internal, expert use only) diff --git a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl b/experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl similarity index 99% rename from src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl rename to experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl index d36c19691ae9..b0ac56ce1321 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/HasseSchmidtDerivativeForIdeals.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl @@ -1,4 +1,6 @@ + + export adjugate export pseudo_diff export integer_generator diff --git a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl b/experimental/HasseSchmidt/test/examplesHasseSchmidt.jl similarity index 96% rename from src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl rename to experimental/HasseSchmidt/test/examplesHasseSchmidt.jl index 329339fd6365..3e13e3593cc6 100644 --- a/src/AlgebraicGeometry/HasseSchmidt/examplesHasseSchmidt.jl +++ b/experimental/HasseSchmidt/test/examplesHasseSchmidt.jl @@ -1,10 +1,15 @@ ### MPolyRingElem +R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); +f = R(5*x^2 + 3*y^5); +hasse_derivatives(f) + R, x = polynomial_ring(ZZ, 4, "x") +f = R(5*x[2]^2 + 2*x[4]^5) f1 = R(3*x[2]) f2 = R(4*x[4]^3) -hasse_derivatives(f1) -hasse_derivatives([f1, f2]) +hasse_derivatives(f) +hasse_derivatives([f, f1, f2]) R, x = polynomial_ring(QQ, 4, "x") f1 = R(3*x[2]) @@ -16,8 +21,8 @@ hasse_derivatives([f1, f2]) R, x = polynomial_ring(ZZ, 4, "x") I = ideal(R, [x[2] - 1]) RQ, _ = quo(R, I) -f1 = 4*x[3] -f2 = 5*x[2]^2 + 2*x[4] +f1 = RQ(4*x[3]) +f2 = RQ(5*x[2]^2 + 2*x[4]) hasse_derivatives(f2) hasse_derivatives([f1, f2]) diff --git a/experimental/HasseSchmidt/test/runtests.jl b/experimental/HasseSchmidt/test/runtests.jl new file mode 100644 index 000000000000..f009f58d90c1 --- /dev/null +++ b/experimental/HasseSchmidt/test/runtests.jl @@ -0,0 +1,3 @@ +@testset + +end \ No newline at end of file From 52bcd94de1dcc4dc94bbb7e23fbccd5bd5a75260 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Wed, 19 Jun 2024 12:37:57 +0200 Subject: [PATCH 08/21] updating newest Oscar version --- .../{src => }/HasseSchmidtDerivative.jl | 0 .../src/HasseSchmidtDerivativeForIdeals.jl | 272 ------------------ .../HasseSchmidt/test/examplesHasseSchmidt.jl | 218 -------------- experimental/HasseSchmidt/test/runtests.jl | 3 - 4 files changed, 493 deletions(-) rename experimental/HasseSchmidt/{src => }/HasseSchmidtDerivative.jl (100%) delete mode 100644 experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl delete mode 100644 experimental/HasseSchmidt/test/examplesHasseSchmidt.jl delete mode 100644 experimental/HasseSchmidt/test/runtests.jl diff --git a/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl similarity index 100% rename from experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl rename to experimental/HasseSchmidt/HasseSchmidtDerivative.jl diff --git a/experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl b/experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl deleted file mode 100644 index b0ac56ce1321..000000000000 --- a/experimental/HasseSchmidt/src/HasseSchmidtDerivativeForIdeals.jl +++ /dev/null @@ -1,272 +0,0 @@ - - - -export adjugate -export pseudo_diff -export integer_generator -export hasse_deriv - - -#################################################################################### -##################### ADJUGATE MATRIX ########################################## -# Name: adjugate -# -# INPUT: square matrix M -# OUTPUT: adjugate matrix of M - -# function provided by Max Horn. Thx -function adjugate(M) - c = charpoly(M) - f = divexact(c - c(0), gen(parent(c))) - a = f(M) - iseven(nrows(M)) ? -a : a -end - -#################################################################################### -################## DERIVATE WITH RESPECT TO PARAMETERSYSTEM #################### -# Name: pseudo_diff -# -# INPUT: -# OUTPUT: - -function pseudo_diff(f, j, A, q, I::Ideal, systemOfParameters::Vector{Int}) - R = base_ring(I) - - # Check for correct input? No, it'll be checked in main functions. - gensR = gens(R) - RetPoly = q * derivative(f, systemOfParameters[j]) - - # Generating a list of Variables which aren't in parametersystem y - OtherVars = empty(gensR) - n = ngens(R) - for k in 1:n - gensR[k] in systemOfParameters || push!(OtherVars, gensR[k]) - end - - # See formular in remark 4.2 - for k in 1:ncols(A) - for l in 1:nrows(A) - SubPoly = derivative(gens(I)[l], systemOfParameters[j]) * A[l,k] * derivative(f, OtherVars[k]) - RetPoly = RetPoly - SubPoly - end - end - Istd = standard_basis(I) - RetPoly = reduce(RetPoly, gens(Istd)) # mod IZ - return (RetPoly) -end - -#################################################################################### -##################### INTEGER GENERATOR ######################################## -# Name: integer_generator -# -# INPUT: Ideal I -# OUTPUT: Ideal J, was den Schnitt von I mit dem Ring repräsentiert, über den der Polynomring definiert ist - -function integer_generator(I) - vars = gens(base_ring(I)) - J = eliminate(I, vars) # eliminiere die Variablen des Polynomrings aus dem Ideal I - return (J) -end - -#################################################################################### -##################### HASSE-SCHMIDT DERIVATIVE (IZ == <0>) ##################### -# Name: hasse_deriv -# -# INPUT: Ideals = IX (IZ = <0>) -# OUTPUT: List of ideals generated by hasse derivatives until but without <1> - -function hasse_deriv(IX::MPolyQuoIdeal) - # println("Funktion hasse_deriv für Ideale aus Faktor- bzw. Quotientenringen") - RQ = base_ring(IX) - R = base_ring(RQ) # could cause problems if this isn't a MPolyRing - # embedding the generators of IX into the base_ring of RQ - IX_R = ideal(R, [R(gen) for gen in gens(IX)]) - - list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals - - # projecting the hasse derivs onto the original Quotient Ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(RQ, [RQ(gen) for gen in gens(list_IX_derivs[i])])) - end - return return_list -end - -function hasse_deriv(IX::Oscar.MPolyLocalizedIdeal) - # Rloc.(I.gens) - Rloc = base_ring(IX) - R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing - # projecting the generators of IX onto the base_ring of Rloc by taking the numerators - IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) - - list_IX_derivs = hasse_deriv(IX_R) # calling hasse_deriv for MPolyIdeals - - # embedding the hasse derivs into original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - # println("Type of IX: ",typeof(IX)) - # println("Type of IX_R: ",typeof(IX_R)) - # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) - # println("Type of return_list: ",typeof(return_list)) - return return_list -end - -function hasse_deriv(IX::MPolyIdeal) - - R = base_ring(IX) - n = ngens(R) # number of variables of R - r = ngens(IX) # number of generators of IX - - # Variables of Rtemp don't have names. This way there are less problems with the names of variables of R. - Rtemp, _ = polynomial_ring(base_ring(R), "y" => 1:n, "t" => 1:n) - F = gens(IX) - # replace f_j(x_i) -> f(y_i + t_i) - for j in 1:r - F[j] = evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) # F(x) -> F(y+t) - end - # F = [evaluate(F[j], gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) for j in 1:r] - # Initializing Variables - i=1 # counter to iterate through degrees of monomials - tempid = gens(IX) # list to collect generators of IX and their Hasse Schmidt derivatives - RetList = [IX] # list to collect ideals generated by tempid - # RetList = empty([IX]) - varR = vcat(gens(R), ones(ZZRingElem, n)) # TODO: fmpz gibts nicht mehr wenn der dev-tree genutzt wird # fmpz -> ZZRingElem, fmpq -> QQFieldElem - - while i == 1 || tempid != gens(RetList[i-1]) # Comparing ideals was a bad idea # A little loophole: 2nd condition would throw an error at the first iteration but because i==1 is true the 2nd conditions check is skipped. - for polynome in F - for term in terms(polynome) - if sum(degrees(term)[n+1:2n]) == i - tempid = vcat(tempid, [evaluate(term, varR)]) # maybe use vector operations for shorter code? - end - end - end - i = i + 1 - RetList = vcat(RetList, ideal(R, tempid)) - end - return (RetList[1:i-1]) -end - -#################################################################################### -##################### HASSE-SCHMIDT DERIVATIVE (IZ != <0>) #################### -# Name: hasse_deriv -# -# INPUT: Ideals IZ,IX, system of parameters y, matrix M -# OUTPUT: List of ideals generated by hasse derivatives until but without <1> - -function hasse_deriv(IZ::MPolyQuoIdeal, IX::MPolyQuoIdeal, systemOfParameters::Vector{Int}, M) - RQ = base_ring(IX) - R = base_ring(RQ) # could cause problems if this isn't a MPolyRing - # embedding the generators of IX and IZ into the base_ring of RQ - IX_R = ideal(R, [R(gen) for gen in gens(IX)]) - IZ_R = ideal(R, [R(gen) for gen in gens(IZ)]) - - # systemOfParameters needs no change because it beeing Vector{Int} ist just fine - nRows = n_rows(M) - nCols = n_columns(M) - M_R = matrix(R, nRows, nCols, [R(M[i,j]) for i in 1:nRows for j in 1:nCols]) - - list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals - - # projecting the hasse derivs onto original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - return return_list -end - -function hasse_deriv(IZ::Oscar.MPolyLocalizedIdeal, IX::Oscar.MPolyLocalizedIdeal, systemOfParameters::Vector{Int}, M) - Rloc = base_ring(IX) - R = base_ring(Rloc) # could cause problems if this isn't a MPolyRing - # projecting the generators of IX and IZ onto the base_ring of Rloc by taking the numerators - IX_R = ideal(R, [numerator(gen) for gen in gens(IX)]) - IZ_R = ideal(R, [numerator(gen) for gen in gens(IZ)]) - - # systemOfParameters needs no change because it beeing Vector{Int} ist just fine - - # M_R = M, aber alle Einträge sind aus R (MPolyRing) - nRows = n_rows(M) - nCols = n_columns(M) - M_R = matrix(R, nRows, nCols, [numerator(M[i,j]) for i in 1:nRows for j in 1:nCols]) - - list_IX_derivs = hasse_deriv(IZ_R, IX_R, systemOfParameters, M_R) # calling hasse_deriv for MPolyIdeals - - # embedding the hasse derivs into original localized ring - return_list = empty([]) - for i in 1:length(list_IX_derivs) - push!(return_list, ideal(Rloc, [Rloc(gen) for gen in gens(list_IX_derivs[i])])) - end - # println("Type of IX: ",typeof(IX)) - # println("Type of IX_R: ",typeof(IX_R)) - # println("Type of list_IX_derivs: ",typeof(list_IX_derivs)) - # println("Type of return_list: ",typeof(return_list)) - return return_list -end - -function hasse_deriv(IZ::MPolyIdeal, IX::MPolyIdeal, systemOfParameters::Vector{Int}, M) - R = base_ring(IZ) - if IZ == ideal(R, [zero(R)]) - return hasse_deriv(IX) - end - - # Checking for correct input. - IZ !== IX || error("IZ and IX cannot be equal.") - issubset(IZ,IX) || error("IZ needs to be a subset of IX.") - - # IZstd = standard_basis(ideal(R, reduce(IX, standard_basis(IZ)))) # why is this returning gens(IZ) - n = ngens(R) # number of variables of R - t = ngens(IZ) - r = ngens(IX) - t # number of generators of IX without number of generators of IZ - f = empty([R(0)]) - for poly in gens(IX) - println("# ", poly) - poly in IZ || push!(f, poly) - end # f = [Generators of IX but not of IZ] - detM = det(M) - A = adjugate(M) - - Itemp = IX - RetList = [IX] # List of ideals to return. - # RetList = empty([IX]) # Maybe we don't need IX as first entry? - Null = zeros(ZZ, length(systemOfParameters)) - - L = [[f[i],Null] for i in 1:r] - old = 0 - cur = r - - while integer_generator(Itemp) == ideal(R, [zero(R)]) # intersect(Itemp, ZZ) == <0> - println("# Intersection(Itemp, ZZ) == <0>") - println("# old = ", old) - println("# cur = ", cur) - for i in old+1:cur # for every f in Itemp without gens(IZ) - # println("# i = ", i) - for j in 1:length(systemOfParameters) # for every varialbe of system of parameters y - # println("# yj = ", y[j], " ") - ftemp = L[i][1] - note = copy(L[i][2]) # "copy" is important, otherwise "note" would only be a pointer to L[i][2] and NOT a copy - note[j] = note[j] + 1 - # normal pseudo_diff divided by faktor a - ftemp = div(pseudo_diff(ftemp, j, A, detM, IZ, systemOfParameters), R(note[j])) - if ftemp != zero(R) - L = push!(L, [ftemp, copy(note)]) # "copy" is important, (see above) - Itemp = Itemp + ideal(R, ftemp) - end - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - println("# ftemp = ", ftemp, " # note = ", note) - # println("# L = ", L) - end - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - end - println("# Itemp before saturation: ", Itemp) - Itemp = saturation(Itemp, ideal(R, detM)) # saturate with to get rid of the factor q = det(M) we got using pseudo_diff - println("# Itemp saturated with ", detM, ": ", Itemp) - RetList = push!(RetList, Itemp) - old = cur - cur = length(L) - sleep(0.001) # hasse_deriv did not work without letting it sleep (julia-stuff) - # println("# RetList = ", RetList) - end - return (RetList) -end \ No newline at end of file diff --git a/experimental/HasseSchmidt/test/examplesHasseSchmidt.jl b/experimental/HasseSchmidt/test/examplesHasseSchmidt.jl deleted file mode 100644 index 3e13e3593cc6..000000000000 --- a/experimental/HasseSchmidt/test/examplesHasseSchmidt.jl +++ /dev/null @@ -1,218 +0,0 @@ - -### MPolyRingElem -R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); -f = R(5*x^2 + 3*y^5); -hasse_derivatives(f) - -R, x = polynomial_ring(ZZ, 4, "x") -f = R(5*x[2]^2 + 2*x[4]^5) -f1 = R(3*x[2]) -f2 = R(4*x[4]^3) -hasse_derivatives(f) -hasse_derivatives([f, f1, f2]) - -R, x = polynomial_ring(QQ, 4, "x") -f1 = R(3*x[2]) -f2 = R(4*x[4]^3) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -### MPolyQuoRingElem -R, x = polynomial_ring(ZZ, 4, "x") -I = ideal(R, [x[2] - 1]) -RQ, _ = quo(R, I) -f1 = RQ(4*x[3]) -f2 = RQ(5*x[2]^2 + 2*x[4]) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -R, x = polynomial_ring(QQ, 4, "x") -I = ideal(R, [x[2] - 1]) -RQ, _ = quo(R, I) -f1 = RQ(4*x[3] ) -f2 = RQ(5*x[2]^2 + 2*x[4]) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -### Oscar.MPolyLocRingElem - -# (1) Localization at maximal ideal -R, x = polynomial_ring(QQ, 4, "x") -m = ideal(R, [x[1] - 3, x[2] - 2, x[3] + 2, x[4]]) -U = complement_of_prime_ideal(m) -Rloc, _ = localization(R, U) -f1 = Rloc(4*x[3] ) -f2 = Rloc(5*x[2]^2 + 2*x[4]^5) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -# (2) Localization at prime ideal -R, x = polynomial_ring(QQ, 4, "x") -p = ideal(R, [x[1]]) -U = complement_of_prime_ideal(p) -Rloc, _ = localization(R, U) -f1 = Rloc(4*x[3] ) -f2 = Rloc(5*x[2]^2 + 2*x[4]) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -# (3) Localization at ring element - - -### Oscar.MPolyQuoLocRingElem - -# (1) Localization at prime ideal -R, x = polynomial_ring(QQ, 4, "x") -I = ideal(R, [x[1]^3 - 1]) -RQ, _ = quo(R, I) -p = ideal(R, [x[2]]) -U = complement_of_prime_ideal(p) -RQL, _ = localization(RQ, U) -f1 = RQL(4*x[3] ) -f2 = RQL(5*x[2]^2 + 2*x[4]) -hasse_derivatives(f2) -hasse_derivatives([f1, f2]) - -# (2) Localization at maximal ideal - -# (3) Localization at ring element - - - - - - - -### EXAMPLES FOR HASSE-SCHMIDT DERIVATE FOR IDEALS (old) - -### POLYNOMIALRING -# EXAMPLE hasse_deriv (IZ == 0) -R, x = polynomial_ring(ZZ, 4, "x") -IZ = ideal(R, [zero(R)]) -IX = ideal(R, [3*x[2], 4*x[4]^3]) -hasse_deriv(IZ, IX) - -R, x = polynomial_ring(ZZ, 8, "x") -IZ = ideal(R, [zero(R)]) -IX = ideal(R, [5*x[2]*x[4]^2*x[5]]) -hasse_deriv(IZ, IX) - -# EXAMPLE hasse_deriv (IZ != 0) -R, x = polynomial_ring(ZZ, 4, "x") -IX = ideal(R, [3*x[2],4*x[4]^3]) -IZ = ideal(R, [zero(0)]) -# y = x -systemOfParameters = [1] -M = matrix(R, 1, 1, [R(0)]) -hasse_deriv(IZ, IX, y, M) # working, since i call hasse_deriv(IZ, IX) for IZ = 0 - -R, x = polynomial_ring(ZZ, 4, "x") -IZ = ideal(R, [x[1]]) -IX = IZ + ideal(R, [3*x[2], 4*x[4]^3]) -# y = x[2:4] -systemOfParameters = [2, 3, 4] -M = matrix(R, 1, 1, [R(1)]) -hasse_deriv(IZ, IX, y, M) # working - -R, x = polynomial_ring(ZZ, 8, "x") -IZ = ideal(R, [x[1]]) -# y = x[2:8] -systemOfParameters = [2, 3, 4, 5, 6, 7, 8] -M = matrix(R, 1, 1, [R(1)]) -IX = IZ + ideal(R, [x[2]*x[3]]) # working -IX = IZ + ideal(R, [x[2]^2]) # working -IX = IZ + ideal(R, [x[2]^2 + 3]) # working -IX = IZ + ideal(R, [x[2]^2*x[3]]) # working -IX = IZ + ideal(R, [x[4]^5, x[2]*x[3]*x[7]]) # working -hasse_deriv(IZ, IX, y, M) - -R, x = polynomial_ring(ZZ, 8, "x") -IZ = ideal(R, [x[1]*x[2] - 1]) -# y = x[2:8] -systemOfParameters = [2, 3, 4, 5, 6, 7, 8] -M = matrix(R, 1, 1, [x[2]]) -IX = IZ # working # error (IZ and IX cannot be equal.) -IX = IZ + ideal(R, [x[1]]) # working -IX = IZ + ideal(R, [x[3]]) # working -IX = IZ + ideal(R, [x[2]^2]) # working -IX = IZ + ideal(R, [x[3]^2]) # working -IX = IZ + ideal(R, [x[2]*x[3]]) # working -IX = IZ + ideal(R, [x[4]^2*x[3]]) # working -IX = IZ + ideal(R, [x[5]^3, x[6]^4]) # working -IX = IZ + ideal(R, [x[6]^4, 7]) # working -IX = IZ + ideal(R, [x[8]^6]) # working -IX = IZ + ideal(R, [x[3]^3 + x[2]^2]) # not working # expected result might be wrong -IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working -hasse_deriv(IZ, IX, y, M) - -R, x = polynomial_ring(ZZ, 8, "x") -IZ = ideal(R, [x[1]*x[2] - 1]) -# y = vcat(x[1], x[3:8]) -systemOfParameters = [1, 3, 4, 5, 6, 7, 8] -M = matrix(R, 1, 1, [x[1]]) -IX = IZ + ideal(R, [x[2]]) # working -IX = IZ + ideal(R, [x[2], x[3]]) # working -IX = IZ + ideal(R, [x[3]]) # working -IX = IZ + ideal(R, [x[3]^2]) # working -IX = IZ + ideal(R, [x[3]^2 - 5]) # working -IX = IZ + ideal(R, [x[4]^2*x[3]]) # working -IX = IZ + ideal(R, [x[5]^3, x[6]^4]) # working -IX = IZ + ideal(R, [x[2]*x[3]]) # working -IX = IZ + ideal(R, [x[2]*x[3]^2]) # working -IX = IZ + ideal(R, [x[6]^4, 7]) # working -IX = IZ + ideal(R, [x[6]^4]) # working -IX = IZ + ideal(R, [x[3]^3 + x[4]^2]) # working -IX = IZ + ideal(R, [x[3]^3 + x[2]^2]) # working -IX = IZ + ideal(R, [x[4]^3 + x[6]^4]) # working -hasse_deriv(IZ, IX, y, M) - -### FAKTORRING / QUOTIENTENRING -R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) -I = ideal(R, [x - 1]) -RQ, _ = quo(R, I) -IZ = ideal(RQ, [y - 1]) -IX = IZ + ideal(RQ, [-y^3 + x^2]) -systemOfParameters = [3] -M = matrix(RQ, 1, 1, [z]) - -hasse_deriv(IZ, IX, systemOfParameters, M) # debuggen (endlosschleife), ? x-1 und y-1 sorgen für IX = 0 in RQ ? -# sollte ich auf IX = 0 prüfen? wo prüfe ich bisher auf IX = 0 ? kommt hasse_deriv mit IX = 0 nicht klar? - -### LOKALISIERTER RING -R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) -P = ideal(R, [x]) -U = complement_of_prime_ideal(P) -Rloc, iota = localization(R, U) -IZ = ideal(Rloc, [y - 1]) -IX = IZ + ideal(Rloc, [-y^3 + x^2]) -systemOfParameters = [1, 3] -M = matrix(Rloc, 1, 1, [z]) - -hasse_deriv(IZ, IX, systemOfParameters, M) - -# Oscar.MPolyLocalizedIdeal -R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]) -P = ideal(R, [x]) -U = complement_of_prime_ideal(P) -Rloc, iota = localization(R, U) -IZ = ideal(Rloc, [zero(Rloc)]) -IX = ideal(Rloc, [-y^3 + x^2]) - - -# MPolyQuoIdeal -# T, t = polynomial_ring(QQ, "t") -# K, a = number_field(2*t^2-1, "a") -R, (x, y) = polynomial_ring(QQ, ["x", "y"]) -I = ideal(R, [x - 1]) # I = ideal(R, [x-1, x-a]) -RQ, _ = quo(R, I) -IZ = ideal(RQ, [zero(RQ)]) -IX = ideal(RQ, [-y^3 + x^2]) - -R, (x, y) = polynomial_ring(QQ, ["x", "y"]) -I = ideal(R, [x^3 - 1]) -RQ, _ = quo(R, I) -P = ideal(R, [y]) -U = complement_of_prime_ideal(P) -RQL, _ = localization(RQ, U) -IZ = ideal(RQL, [zero(RQL)]) -IX = ideal(RQL, [-y^3 + x^2]) # RESOVLED: IZ and IX are equal (need to understand why ^^ ) # Need to find an example with IZ != IX \ No newline at end of file diff --git a/experimental/HasseSchmidt/test/runtests.jl b/experimental/HasseSchmidt/test/runtests.jl deleted file mode 100644 index f009f58d90c1..000000000000 --- a/experimental/HasseSchmidt/test/runtests.jl +++ /dev/null @@ -1,3 +0,0 @@ -@testset - -end \ No newline at end of file From 8428119fca568c3936b83d8a5ba8c3d048b85400 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Wed, 19 Jun 2024 16:11:31 +0200 Subject: [PATCH 09/21] added several documentation --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 140 +++++++++++++++++- 1 file changed, 135 insertions(+), 5 deletions(-) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index e8f4f6ec4d0a..76a9cffd7e08 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -1,5 +1,9 @@ export hasse_derivatives +### Implementation of Hasse-Schmidt derivatives as seen in +### +### Fruehbis-Krueger, Ristau, Schober: 'Embedded desingularization for arithmetic surfaces -- toward a parallel implementation' + ################################################################################ ### HASSE-SCHMIDT derivatives for single polynomials @@ -7,7 +11,7 @@ export hasse_derivatives @doc raw""" hasse_derivatives(f::MPolyRingElem) -Return the Hasse-Schmidt derivatives of `f`. +Return Hasse-Schmidt derivatives of `f`. # Examples ```jldoctest @@ -28,8 +32,6 @@ julia> hasse_derivatives(f) 5 ``` """ - -# MPolyRingElem function hasse_derivatives(f::MPolyRingElem) R = parent(f) n = ngens(R) @@ -65,7 +67,26 @@ end ################################################################################ ### HASSE-SCHMIDT derivatives for a list of polynomials -function hasse_derivatives(v::Vector) +@doc raw""" + hasse_derivatives(v::Vector{MPolyRingElem}) + +For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lifted numerator of `f`. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(ZZ, 4, "x"); + +julia> f1 = R(3*x[2]^2); + +julia> f2 = R(6*x[4]^3); + +julia> hasse_derivatives([f1, f2]) +2-element Vector{Vector{ZZMPolyRingElem}}: + [3*x2^2, 6*x2, 3] + [6*x4^3, 18*x4^2, 18*x4, 6] +``` +""" +function hasse_derivatives(v::Vector{MPolyRingElem}) return hasse_derivatives.(v) end @@ -76,21 +97,130 @@ end ### internal functions for expert use # MPolyQuoRingElem (internal, expert use only) +@doc raw""" + _hasse_derivatives(f::MPolyQuoRingElem) + +Return Hasse-Schmidt derivatives of lifted numerator of `f`. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(ZZ, 4, "x"); + +julia> I = ideal(R, [x[2] - 1]); + +julia> RQ, _ = quo(R, I); + +julia> f = RQ(2*x[2]^4); + +julia> _hasse_derivatives(f) +5-element Vector{ZZMPolyRingElem}: + 2*x2^4 + 8*x2^3 + 12*x2^2 + 8*x2 + 2 +``` +""" function _hasse_derivatives(f::MPolyQuoRingElem) return hasse_derivatives(lifted_numerator(f)) end # Oscar.MPolyLocRingElem (internal, expert use only) +@doc raw""" + _hasse_derivatives(f::Oscar.MPolyLocRingElem) + +Return Hasse-Schmidt derivatives of numerator of `f`. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(QQ, 4, "x"); + +julia> m = ideal(R, [x[1] - 3, x[2] - 2, x[3] + 2, x[4]]); + +julia> U = complement_of_prime_ideal(m); + +julia> Rloc, _ = localization(R, U); + +julia> f = Rloc(2*x[4]^5); + +julia> _hasse_derivatives(f) +9-element Vector{QQMPolyRingElem}: + 2*x4^5 + 10*x4^4 + 20*x4^3 + 20*x4^2 + 10*x4 + 2 +``` +""" function _hasse_derivatives(f::Oscar.MPolyLocRingElem) return hasse_derivatives(numerator(f)) end # Oscar.MPolyQuoLocRingElem (internal, expert use only) +@doc raw""" + _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) + +Return Hasse-Schmidt derivatives of lifted numerator of `f`. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(QQ, 4, "x"); + +julia> I = ideal(R, [x[1]^3 - 1]); + +julia> RQ, _ = quo(R, I); + +julia> p = ideal(R, [x[2]]); + +julia> U = complement_of_prime_ideal(p); + +julia> RQL, _ = localization(RQ, U); + +julia> f = RQL(4*x[3]^3); + +julia> _hasse_derivatives(f) +4-element Vector{QQMPolyRingElem}: + 4*x3^3 + 12*x3^2 + 12*x3 + 4 +``` +""" function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) return hasse_derivatives(lifted_numerator(f)) end # for a list of elements (internal, expert use only) -function _hasse_derivatives(v::Vector) +@doc raw""" + _hasse_derivatives(v::Vector{Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) + +For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lifted numerator of `f`. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(QQ, 4, "x"); + +julia> I = ideal(R, [x[1]^3 - 1]); + +julia> RQ, _ = quo(R, I); + +julia> p = ideal(R, [x[2]]); + +julia> U = complement_of_prime_ideal(p); + +julia> RQL, _ = localization(RQ, U); + +julia> f1 = RQ(4*x[3]^3); + +julia> f2 = RQL(3*x[2]^2); + +julia> _hasse_derivatives([f1, f2]) +2-element Vector{Vector{QQMPolyRingElem}}: + [4*x3^3, 12*x3^2, 12*x3, 4] + [3*x2^2, 6*x2, 3] +``` +""" +function _hasse_derivatives(v::Vector{Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) return _hasse_derivatives.(v) end \ No newline at end of file From 7049c904b911fb3e6a96ff53c5f8890e16ee259d Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 28 Jun 2024 17:26:07 +0200 Subject: [PATCH 10/21] tests for hasse_derivatives --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 14 ++++++----- test/HasseSchmidt/HasseSchmidtDerivative.jl | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 test/HasseSchmidt/HasseSchmidtDerivative.jl diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index 76a9cffd7e08..9ffbe71d5141 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -21,13 +21,12 @@ julia> f = R(5*x^2 + 3*y^5); julia> hasse_derivatives(f) 9-element Vector{ZZMPolyRingElem}: - 3*y^5 + 5*x^2 + 3*y^5 15*y^4 30*y^3 30*y^2 15*y 3 - 5*x^2 10*x 5 ``` @@ -41,12 +40,15 @@ function hasse_derivatives(f::MPolyRingElem) # replace f(x_i) -> f(y_i + t_i) F = evaluate(f, gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) # i = 1 # counter to iterate though degrees of monomials - HasseDerivativesList = empty([f]) + # HasseDerivativesList = empty([f]) + HasseDerivativesList = [f] varR = vcat(gens(R), ones(typeof(base_ring(R)(1)), n)) # getting hasse derivs without extra attention on ordering for term in terms(F) - # hasse derivatives are the factors in front of the monomial in t - push!(HasseDerivativesList, evaluate(term, varR)) + if sum(degrees(term)[n+1:2n]) != 0 + # hasse derivatives are the factors in front of the monomial in t + push!(HasseDerivativesList, evaluate(term, varR)) + end end return HasseDerivativesList end @@ -86,7 +88,7 @@ julia> hasse_derivatives([f1, f2]) [6*x4^3, 18*x4^2, 18*x4, 6] ``` """ -function hasse_derivatives(v::Vector{MPolyRingElem}) +function hasse_derivatives(v::Vector{<:MPolyRingElem}) return hasse_derivatives.(v) end diff --git a/test/HasseSchmidt/HasseSchmidtDerivative.jl b/test/HasseSchmidt/HasseSchmidtDerivative.jl new file mode 100644 index 000000000000..b23c0bfb65de --- /dev/null +++ b/test/HasseSchmidt/HasseSchmidtDerivative.jl @@ -0,0 +1,25 @@ +@testset "HasseSchmidt Derivatives MPolyRingElem" begin + R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); + + @test [x^3, 3x^2, 3x, R(1)] == hasse_derivatives(R(x^3)) + @test [5x^2 + 3y^5, 15y^4, 30y^3, 30y^2, 15y, R(3), 10x, R(5)] == hasse_derivatives(R(5*x^2 + 3*y^5)) + @test [[3*x^2, 6*x, R(3)], [6*y^3, 18*y^2, 18*y, R(6)]] == hasse_derivatives([R(3*x^2), R(6*y^3)]) +end + +@testset "HasseSchmidt Derivatives MPolyQuoRingElem" begin + + + +end + +@testset "HasseSchmidt Derivatives Oscar.MPolyLocRingElem" begin + + + +end + +@testset "HasseSchmidt Derivatives Oscar.MPolyQuoLocRingElem" begin + + + +end \ No newline at end of file From 78245dba30cd242be10460c5c03d74d82271fcc0 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Tue, 2 Jul 2024 19:55:05 +0200 Subject: [PATCH 11/21] more tests, problem with types of elemets of vector --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 24 +++++-- test/HasseSchmidt/HasseSchmidtDerivative.jl | 62 +++++++++++++++---- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index 9ffbe71d5141..4367d1cd69e1 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -76,16 +76,16 @@ For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lift # Examples ```jldoctest -julia> R, x = polynomial_ring(ZZ, 4, "x"); +julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); -julia> f1 = R(3*x[2]^2); +julia> f1 = R(3*x^2); -julia> f2 = R(6*x[4]^3); +julia> f2 = R(6*y^3); julia> hasse_derivatives([f1, f2]) 2-element Vector{Vector{ZZMPolyRingElem}}: - [3*x2^2, 6*x2, 3] - [6*x4^3, 18*x4^2, 18*x4, 6] + [3*x^2, 6*x, 3] + [6*y^3, 18*y^2, 18*y, 6] ``` """ function hasse_derivatives(v::Vector{<:MPolyRingElem}) @@ -223,6 +223,18 @@ julia> _hasse_derivatives([f1, f2]) [3*x2^2, 6*x2, 3] ``` """ -function _hasse_derivatives(v::Vector{Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) +function _hasse_derivatives(v::Vector{<:Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) + return _hasse_derivatives.(v) +end +function _hasse_derivatives(v::Vector{RingElem}) + return _hasse_derivatives.(v) +end +function _hasse_derivatives(v::Vector{MPolyQuoRingElem}) + return _hasse_derivatives.(v) +end +function _hasse_derivatives(v::Vector{Oscar.MPolyLocRingElem}) + return _hasse_derivatives.(v) +end +function _hasse_derivatives(v::Vector{Oscar.MPolyQuoLocRingElem}) return _hasse_derivatives.(v) end \ No newline at end of file diff --git a/test/HasseSchmidt/HasseSchmidtDerivative.jl b/test/HasseSchmidt/HasseSchmidtDerivative.jl index b23c0bfb65de..50d130c40b97 100644 --- a/test/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/test/HasseSchmidt/HasseSchmidtDerivative.jl @@ -1,25 +1,65 @@ -@testset "HasseSchmidt Derivatives MPolyRingElem" begin +@testset "hasse_derivatives" begin R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); - @test [x^3, 3x^2, 3x, R(1)] == hasse_derivatives(R(x^3)) @test [5x^2 + 3y^5, 15y^4, 30y^3, 30y^2, 15y, R(3), 10x, R(5)] == hasse_derivatives(R(5*x^2 + 3*y^5)) +end + +@testset "hasse_derivatives list" begin + R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); @test [[3*x^2, 6*x, R(3)], [6*y^3, 18*y^2, 18*y, R(6)]] == hasse_derivatives([R(3*x^2), R(6*y^3)]) end -@testset "HasseSchmidt Derivatives MPolyQuoRingElem" begin - +@testset "_hasse_derivatives MPolyQuoRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + I = ideal(R, [x^2 - 1]); + RQ, _ = quo(R, I); + @test [3*y^4, 12*y^3, 18*y^2, 12*y, RQ(3)] == _hasse_derivatives(RQ(3y^4)) +end +@testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + m = ideal(R, [x, y, z]); # max ideal + U = complement_of_prime_ideal(m); + RL, _ = localization(R, U); + f1 = RL(5x^3); + @test [5*x^3, 15*x^2, 15*x, RL(5)] == _hasse_derivatives(RL(5x^3)) +end +@testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + m = ideal(R, [x, y, z]); # max ideal + U = complement_of_prime_ideal(m); + RL, _ = localization(R, U); # loc at m + I = ideal(R, [x^2 - 1]); + RQ, _ = quo(R, I); + RQL, _ = localization(RQ, U); + @test [2*z^5, 10*z^4, 20*z^3, 20*z^2, 10*z, RQL(2)] == _hasse_derivatives(RQL(2z^5)) end -@testset "HasseSchmidt Derivatives Oscar.MPolyLocRingElem" begin - +@testset "_hasse_derivatives list" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + m = ideal(R, [x, y, z]); # max ideal + U = complement_of_prime_ideal(m); + RL, _ = localization(R, U); # loc at m + I = ideal(R, [x^2 - 1]); + RQ, _ = quo(R, I); + RQL, _ = localization(RQ, U); - end -@testset "HasseSchmidt Derivatives Oscar.MPolyQuoLocRingElem" begin - - -end \ No newline at end of file +R, x = polynomial_ring(QQ, 4, "x"); +m = ideal(R, [x, y, z]); +I = ideal(R, [x[1]^3 - 1]); +RQ, _ = quo(R, I); +p = ideal(R, [x[2]]); +U = complement_of_prime_ideal(p); +RQL, _ = localization(RQ, U); +f1 = RQ(4*x[3]^3); +f2 = RQL(3*x[2]^2); +_hasse_derivatives([f1, f2]) + +f1 = RL(5x^3); +f2 = RQ(3y^4); +f3 = RQL(2z^5); +_hasse_derivatives([f1, f2, f3]) \ No newline at end of file From 7b982119d9f85bfb89c149c309a096d8cdd7deea Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Wed, 3 Jul 2024 17:45:50 +0200 Subject: [PATCH 12/21] test for every function, type problem avoided for now --- .../HasseSchmidt/HasseSchmidtDerivative.jl | 16 ++----------- test/HasseSchmidt/HasseSchmidtDerivative.jl | 23 ++++--------------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index 4367d1cd69e1..835e5e9ce08b 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -195,7 +195,7 @@ end # for a list of elements (internal, expert use only) @doc raw""" - _hasse_derivatives(v::Vector{Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) + _hasse_derivatives(v::Vector{RingElem}}) For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lifted numerator of `f`. @@ -223,18 +223,6 @@ julia> _hasse_derivatives([f1, f2]) [3*x2^2, 6*x2, 3] ``` """ -function _hasse_derivatives(v::Vector{<:Union{MPolyQuoRingElem, Oscar.MPolyLocRingElem, Oscar.MPolyQuoLocRingElem}}) +function _hasse_derivatives(v::Vector{RingElem}) # type of input has not to be very strict, because it gets checked for each element of v return _hasse_derivatives.(v) end -function _hasse_derivatives(v::Vector{RingElem}) - return _hasse_derivatives.(v) -end -function _hasse_derivatives(v::Vector{MPolyQuoRingElem}) - return _hasse_derivatives.(v) -end -function _hasse_derivatives(v::Vector{Oscar.MPolyLocRingElem}) - return _hasse_derivatives.(v) -end -function _hasse_derivatives(v::Vector{Oscar.MPolyQuoLocRingElem}) - return _hasse_derivatives.(v) -end \ No newline at end of file diff --git a/test/HasseSchmidt/HasseSchmidtDerivative.jl b/test/HasseSchmidt/HasseSchmidtDerivative.jl index 50d130c40b97..4b1b18166550 100644 --- a/test/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/test/HasseSchmidt/HasseSchmidtDerivative.jl @@ -2,6 +2,8 @@ R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); @test [x^3, 3x^2, 3x, R(1)] == hasse_derivatives(R(x^3)) @test [5x^2 + 3y^5, 15y^4, 30y^3, 30y^2, 15y, R(3), 10x, R(5)] == hasse_derivatives(R(5*x^2 + 3*y^5)) + @test [x^2*y^3, 2*x*y^3, y^3, 3*x^2*y^2, 6*x*y^2, 3*y^2, 3*x^2*y, 6*x*y, 3*y, x^2, 2*x, R(1)] == hasse_derivatives(R(x^2*y^3)) + @test [y^2 + z^4, 4*z^3, 6*z^2, 4*z, R(1), 2*y, R(1)] == hasse_derivatives(R(z^4 + y^2)) end @testset "hasse_derivatives list" begin @@ -44,22 +46,5 @@ end I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); RQL, _ = localization(RQ, U); - -end - - -R, x = polynomial_ring(QQ, 4, "x"); -m = ideal(R, [x, y, z]); -I = ideal(R, [x[1]^3 - 1]); -RQ, _ = quo(R, I); -p = ideal(R, [x[2]]); -U = complement_of_prime_ideal(p); -RQL, _ = localization(RQ, U); -f1 = RQ(4*x[3]^3); -f2 = RQL(3*x[2]^2); -_hasse_derivatives([f1, f2]) - -f1 = RL(5x^3); -f2 = RQ(3y^4); -f3 = RQL(2z^5); -_hasse_derivatives([f1, f2, f3]) \ No newline at end of file + @test [[5*x^3, 15*x^2, 15*x, 5], [3*y^4, 12*y^3, 18*y^2, 12*y, 3], [2*z^5, 10*z^4, 20*z^3, 20*z^2, 10*z, 2]] == _hasse_derivatives([RL(5x^3), RQ(3y^4), RQL(2z^5)]) +end \ No newline at end of file From 22b3e59101795476dfd68feae350dc2469d1ce84 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 4 Jul 2024 13:28:06 +0200 Subject: [PATCH 13/21] removed some comments --- experimental/HasseSchmidt/HasseSchmidtDerivative.jl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index 835e5e9ce08b..925a1cb2777e 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -34,18 +34,15 @@ julia> hasse_derivatives(f) function hasse_derivatives(f::MPolyRingElem) R = parent(f) n = ngens(R) - # degreef = maximum(degrees(f)) # define new ring with more variables: R[x1, ..., xn] -> R[x1, ..., xn, t1, ..., tn] Rtemp, _ = polynomial_ring(R, "y" => 1:n, "t" => 1:n) # replace f(x_i) -> f(y_i + t_i) F = evaluate(f, gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) - # i = 1 # counter to iterate though degrees of monomials - # HasseDerivativesList = empty([f]) - HasseDerivativesList = [f] + HasseDerivativesList = [f] # initializing with the zero'th HS derivative: f itself varR = vcat(gens(R), ones(typeof(base_ring(R)(1)), n)) # getting hasse derivs without extra attention on ordering for term in terms(F) - if sum(degrees(term)[n+1:2n]) != 0 + if sum(degrees(term)[n+1:2n]) != 0 # # hasse derivatives are the factors in front of the monomial in t push!(HasseDerivativesList, evaluate(term, varR)) end From 4403f50be2bdab2aeaac8d0f6a4a1ec57b83cfe0 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 4 Jul 2024 15:56:28 +0200 Subject: [PATCH 14/21] pull ready --- experimental/HasseSchmidt/HasseSchmidtDerivative.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl index 925a1cb2777e..bfbb9fb7361e 100644 --- a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/HasseSchmidtDerivative.jl @@ -69,7 +69,7 @@ end @doc raw""" hasse_derivatives(v::Vector{MPolyRingElem}) -For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lifted numerator of `f`. +For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of `f`. # Examples ```jldoctest From df1b725795a72ceb8643b772682034a333dd7834 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 4 Jul 2024 19:00:33 +0200 Subject: [PATCH 15/21] added folders 'src' and 'test' --- experimental/HasseSchmidt/{ => src}/HasseSchmidtDerivative.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename experimental/HasseSchmidt/{ => src}/HasseSchmidtDerivative.jl (100%) diff --git a/experimental/HasseSchmidt/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl similarity index 100% rename from experimental/HasseSchmidt/HasseSchmidtDerivative.jl rename to experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl From 8d54ae567749cfa38d8368c561ac2c36c5f2f8ce Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 11 Jul 2024 19:50:55 +0200 Subject: [PATCH 16/21] implemented changes suggested in comments (multiindices, tests in GF(p)[x,y], etc.) --- ...seSchmidtDerivative.jl => HasseSchmidt.jl} | 153 ++++++------------ test/HasseSchmidt/HasseSchmidt.jl | 110 +++++++++++++ test/HasseSchmidt/HasseSchmidtDerivative.jl | 50 ------ 3 files changed, 156 insertions(+), 157 deletions(-) rename experimental/HasseSchmidt/src/{HasseSchmidtDerivative.jl => HasseSchmidt.jl} (53%) create mode 100644 test/HasseSchmidt/HasseSchmidt.jl delete mode 100644 test/HasseSchmidt/HasseSchmidtDerivative.jl diff --git a/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl b/experimental/HasseSchmidt/src/HasseSchmidt.jl similarity index 53% rename from experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl rename to experimental/HasseSchmidt/src/HasseSchmidt.jl index bfbb9fb7361e..c949ba009581 100644 --- a/experimental/HasseSchmidt/src/HasseSchmidtDerivative.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidt.jl @@ -11,24 +11,24 @@ export hasse_derivatives @doc raw""" hasse_derivatives(f::MPolyRingElem) -Return Hasse-Schmidt derivatives of `f`. +Return a list of Hasse-Schmidt derivatives of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. # Examples ```jldoctest julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); -julia> f = R(5*x^2 + 3*y^5); +julia> f = 5*x^2 + 3*y^5; julia> hasse_derivatives(f) -9-element Vector{ZZMPolyRingElem}: - 5*x^2 + 3*y^5 - 15*y^4 - 30*y^3 - 30*y^2 - 15*y - 3 - 10*x - 5 +8-element Vector{Vector{Any}}: + [[0, 0], 5*x^2 + 3*y^5] + [[0, 1], 15*y^4] + [[0, 2], 30*y^3] + [[0, 3], 30*y^2] + [[0, 4], 15*y] + [[0, 5], 3] + [[1, 0], 10*x] + [[2, 0], 5] ``` """ function hasse_derivatives(f::MPolyRingElem) @@ -38,13 +38,13 @@ function hasse_derivatives(f::MPolyRingElem) Rtemp, _ = polynomial_ring(R, "y" => 1:n, "t" => 1:n) # replace f(x_i) -> f(y_i + t_i) F = evaluate(f, gens(Rtemp)[1:n] + gens(Rtemp)[n+1:2n]) - HasseDerivativesList = [f] # initializing with the zero'th HS derivative: f itself - varR = vcat(gens(R), ones(typeof(base_ring(R)(1)), n)) + HasseDerivativesList = [[zeros(Int64, n), f]] # initializing with the zero'th HS derivative: f itself + varR = vcat(gens(R), fill(base_ring(R)(1), n)) # getting hasse derivs without extra attention on ordering for term in terms(F) if sum(degrees(term)[n+1:2n]) != 0 # # hasse derivatives are the factors in front of the monomial in t - push!(HasseDerivativesList, evaluate(term, varR)) + push!(HasseDerivativesList, [degrees(term)[n+1:2n], evaluate(term, varR)]) end end return HasseDerivativesList @@ -63,33 +63,6 @@ function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) end -################################################################################ -### HASSE-SCHMIDT derivatives for a list of polynomials - -@doc raw""" - hasse_derivatives(v::Vector{MPolyRingElem}) - -For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of `f`. - -# Examples -```jldoctest -julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); - -julia> f1 = R(3*x^2); - -julia> f2 = R(6*y^3); - -julia> hasse_derivatives([f1, f2]) -2-element Vector{Vector{ZZMPolyRingElem}}: - [3*x^2, 6*x, 3] - [6*y^3, 18*y^2, 18*y, 6] -``` -""" -function hasse_derivatives(v::Vector{<:MPolyRingElem}) - return hasse_derivatives.(v) -end - - ################################################################################ @@ -99,57 +72,57 @@ end @doc raw""" _hasse_derivatives(f::MPolyQuoRingElem) -Return Hasse-Schmidt derivatives of lifted numerator of `f`. +Return a list of Hasse-Schmidt derivatives of lift of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. # Examples ```jldoctest -julia> R, x = polynomial_ring(ZZ, 4, "x"); +julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); -julia> I = ideal(R, [x[2] - 1]); +julia> I = ideal(R, [x - 1]); julia> RQ, _ = quo(R, I); -julia> f = RQ(2*x[2]^4); +julia> f = RQ(2*y^4); julia> _hasse_derivatives(f) -5-element Vector{ZZMPolyRingElem}: - 2*x2^4 - 8*x2^3 - 12*x2^2 - 8*x2 - 2 +5-element Vector{Vector{Any}}: + [[0, 0], 2*y^4] + [[0, 1], 8*y^3] + [[0, 2], 12*y^2] + [[0, 3], 8*y] + [[0, 4], 2] ``` """ function _hasse_derivatives(f::MPolyQuoRingElem) - return hasse_derivatives(lifted_numerator(f)) + return hasse_derivatives(lift(f)) end # Oscar.MPolyLocRingElem (internal, expert use only) @doc raw""" _hasse_derivatives(f::Oscar.MPolyLocRingElem) -Return Hasse-Schmidt derivatives of numerator of `f`. +Return a list of Hasse-Schmidt derivatives of numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. # Examples ```jldoctest -julia> R, x = polynomial_ring(QQ, 4, "x"); +julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]); -julia> m = ideal(R, [x[1] - 3, x[2] - 2, x[3] + 2, x[4]]); +julia> m = ideal(R, [x - 3, y - 2, z + 1]); julia> U = complement_of_prime_ideal(m); julia> Rloc, _ = localization(R, U); -julia> f = Rloc(2*x[4]^5); +julia> f = Rloc(2*z^5); julia> _hasse_derivatives(f) -9-element Vector{QQMPolyRingElem}: - 2*x4^5 - 10*x4^4 - 20*x4^3 - 20*x4^2 - 10*x4 - 2 +6-element Vector{Vector{Any}}: + [[0, 0, 0], 2*z^5] + [[0, 0, 1], 10*z^4] + [[0, 0, 2], 20*z^3] + [[0, 0, 3], 20*z^2] + [[0, 0, 4], 10*z] + [[0, 0, 5], 2] ``` """ function _hasse_derivatives(f::Oscar.MPolyLocRingElem) @@ -160,66 +133,32 @@ end @doc raw""" _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) -Return Hasse-Schmidt derivatives of lifted numerator of `f`. +Return a list of Hasse-Schmidt derivatives of lifted numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. # Examples ```jldoctest -julia> R, x = polynomial_ring(QQ, 4, "x"); +julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]); -julia> I = ideal(R, [x[1]^3 - 1]); +julia> I = ideal(R, [x^3 - 1]); julia> RQ, _ = quo(R, I); -julia> p = ideal(R, [x[2]]); +julia> p = ideal(R, [z]); julia> U = complement_of_prime_ideal(p); julia> RQL, _ = localization(RQ, U); -julia> f = RQL(4*x[3]^3); +julia> f = RQL(4*y^3); julia> _hasse_derivatives(f) -4-element Vector{QQMPolyRingElem}: - 4*x3^3 - 12*x3^2 - 12*x3 - 4 +4-element Vector{Vector{Any}}: + [[0, 0, 0], 4*y^3] + [[0, 1, 0], 12*y^2] + [[0, 2, 0], 12*y] + [[0, 3, 0], 4] ``` """ function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) return hasse_derivatives(lifted_numerator(f)) end - -# for a list of elements (internal, expert use only) -@doc raw""" - _hasse_derivatives(v::Vector{RingElem}}) - -For every `f` in `v`: Return a list of all Hasse-Schmidt derivatives of the lifted numerator of `f`. - -# Examples -```jldoctest -julia> R, x = polynomial_ring(QQ, 4, "x"); - -julia> I = ideal(R, [x[1]^3 - 1]); - -julia> RQ, _ = quo(R, I); - -julia> p = ideal(R, [x[2]]); - -julia> U = complement_of_prime_ideal(p); - -julia> RQL, _ = localization(RQ, U); - -julia> f1 = RQ(4*x[3]^3); - -julia> f2 = RQL(3*x[2]^2); - -julia> _hasse_derivatives([f1, f2]) -2-element Vector{Vector{QQMPolyRingElem}}: - [4*x3^3, 12*x3^2, 12*x3, 4] - [3*x2^2, 6*x2, 3] -``` -""" -function _hasse_derivatives(v::Vector{RingElem}) # type of input has not to be very strict, because it gets checked for each element of v - return _hasse_derivatives.(v) -end diff --git a/test/HasseSchmidt/HasseSchmidt.jl b/test/HasseSchmidt/HasseSchmidt.jl new file mode 100644 index 000000000000..724208299a97 --- /dev/null +++ b/test/HasseSchmidt/HasseSchmidt.jl @@ -0,0 +1,110 @@ +###### Stil missing ################################################ +# Examples for polynomial rings over fintie fields +# +# R, (x, y) = polynomial_ring(GF(2), ["x", "y"]) +# f = x^2 + y^2 +# +# R, (x, y, z) = polynomial_ring(GF(3), ["x", "y", "z"]) +# f = x^2*y + z^6 +# +# x^2+y^2 in GF(2)[x,y] or x^2y+z^6 in GF(3)[x,y,z] +#################################################################### + +@testset "hasse_derivatives" begin + R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); + @test + [ [[0, 0], x^3], + [[1, 0], 3*x^2], + [[2, 0], 3*x], + [[3, 0], 1] ] == hasse_derivatives(x^3) + @test + [ [[0, 0], 5*x^2 + 3*y^5], + [[0, 1], 15*y^4], + [[0, 2], 30*y^3], + [[0, 3], 30*y^2], + [[0, 4], 15*y], + [[0, 5], 3], + [[1, 0], 10*x], + [[2, 0], 5] ] == hasse_derivatives(5*x^2 + 3*y^5) + @test + [ [[0, 0], x^2*y^3], + [[1, 0], 2*x*y^3], + [[2, 0], y^3], + [[0, 1], 3*x^2*y^2], + [[1, 1], 6*x*y^2], + [[2, 1], 3*y^2], + [[0, 2], 3*x^2*y], + [[1, 2], 6*x*y], + [[2, 2], 3*y], + [[0, 3], x^2], + [[1, 3], 2*x], + [[2, 3], 1] ] == hasse_derivatives(x^2*y^3) + @test + [ [[0, 0], x^4 + y^2], + [[1, 0], 4*x^3], + [[2, 0], 6*x^2], + [[3, 0], 4*x], + [[4, 0], 1], + [[0, 1], 2*y], + [[0, 2], 1] ] == hasse_derivatives(x^4 + y^2) +end + +@testset "hasse_derivatives finite fields" begin + R, (x, y, z) = polynomial_ring(GF(3), ["x", "y", "z"]); + @test + [ [[0, 0, 0], x^2 + y^2], + [[1, 0, 0], 2*x], + [[2, 0, 0], 1], + [[0, 1, 0], 2*y], + [[0, 2, 0], 1] ] == hasse_derivatives(x^2 + y^2) + @test + [ [[0, 0, 0], x^2*y + z^6], + [[0, 0, 3], 2*z^3], + [[0, 0, 6], 1], + [[1, 0, 0], 2*x*y], + [[2, 0, 0], y], + [[0, 1, 0], x^2], + [[1, 1, 0], 2*x], + [[2, 1, 0], 1] ] == hasse_derivatives(x^2*y + z^6) +end + +@testset "_hasse_derivatives MPolyQuoRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + I = ideal(R, [x^2 - 1]); + RQ, _ = quo(R, I); + @test + [ [[0, 0, 0], 3*y^4], + [[0, 1, 0], 12*y^3], + [[0, 2, 0], 18*y^2], + [[0, 3, 0], 12*y], + [[0, 4, 0], 3] ] == _hasse_derivatives(RQ(3y^4)) +end + +@testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + m = ideal(R, [x, y, z]); # max ideal + U = complement_of_prime_ideal(m); + RL, _ = localization(R, U); + @test + [ [[0, 0, 0], 5*x^3], + [[1, 0, 0], 15*x^2], + [[2, 0, 0], 15*x], + [[3, 0, 0], 5] ] == _hasse_derivatives(RL(5x^3)) +end + +@testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin + R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); + I = ideal(R, [x^2 - 1]); + RQ, _ = quo(R, I); + m = ideal(R, [x, y, z]); # max ideal + U = complement_of_prime_ideal(m); + RQL, _ = localization(RQ, U); + @test + [ [[0, 0, 0], 2*z^5], + [[0, 0, 1], 10*z^4], + [[0, 0, 2], 20*z^3], + [[0, 0, 3], 20*z^2], + [[0, 0, 4], 10*z], + [[0, 0, 5], 2] ] == _hasse_derivatives(RQL(2z^5)) +end + diff --git a/test/HasseSchmidt/HasseSchmidtDerivative.jl b/test/HasseSchmidt/HasseSchmidtDerivative.jl deleted file mode 100644 index 4b1b18166550..000000000000 --- a/test/HasseSchmidt/HasseSchmidtDerivative.jl +++ /dev/null @@ -1,50 +0,0 @@ -@testset "hasse_derivatives" begin - R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); - @test [x^3, 3x^2, 3x, R(1)] == hasse_derivatives(R(x^3)) - @test [5x^2 + 3y^5, 15y^4, 30y^3, 30y^2, 15y, R(3), 10x, R(5)] == hasse_derivatives(R(5*x^2 + 3*y^5)) - @test [x^2*y^3, 2*x*y^3, y^3, 3*x^2*y^2, 6*x*y^2, 3*y^2, 3*x^2*y, 6*x*y, 3*y, x^2, 2*x, R(1)] == hasse_derivatives(R(x^2*y^3)) - @test [y^2 + z^4, 4*z^3, 6*z^2, 4*z, R(1), 2*y, R(1)] == hasse_derivatives(R(z^4 + y^2)) -end - -@testset "hasse_derivatives list" begin - R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); - @test [[3*x^2, 6*x, R(3)], [6*y^3, 18*y^2, 18*y, R(6)]] == hasse_derivatives([R(3*x^2), R(6*y^3)]) -end - -@testset "_hasse_derivatives MPolyQuoRingElem" begin - R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); - I = ideal(R, [x^2 - 1]); - RQ, _ = quo(R, I); - @test [3*y^4, 12*y^3, 18*y^2, 12*y, RQ(3)] == _hasse_derivatives(RQ(3y^4)) -end - -@testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin - R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); - m = ideal(R, [x, y, z]); # max ideal - U = complement_of_prime_ideal(m); - RL, _ = localization(R, U); - f1 = RL(5x^3); - @test [5*x^3, 15*x^2, 15*x, RL(5)] == _hasse_derivatives(RL(5x^3)) -end - -@testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin - R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); - m = ideal(R, [x, y, z]); # max ideal - U = complement_of_prime_ideal(m); - RL, _ = localization(R, U); # loc at m - I = ideal(R, [x^2 - 1]); - RQ, _ = quo(R, I); - RQL, _ = localization(RQ, U); - @test [2*z^5, 10*z^4, 20*z^3, 20*z^2, 10*z, RQL(2)] == _hasse_derivatives(RQL(2z^5)) -end - -@testset "_hasse_derivatives list" begin - R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); - m = ideal(R, [x, y, z]); # max ideal - U = complement_of_prime_ideal(m); - RL, _ = localization(R, U); # loc at m - I = ideal(R, [x^2 - 1]); - RQ, _ = quo(R, I); - RQL, _ = localization(RQ, U); - @test [[5*x^3, 15*x^2, 15*x, 5], [3*y^4, 12*y^3, 18*y^2, 12*y, 3], [2*z^5, 10*z^4, 20*z^3, 20*z^2, 10*z, 2]] == _hasse_derivatives([RL(5x^3), RQ(3y^4), RQL(2z^5)]) -end \ No newline at end of file From 9b0cb6d37c38e0c6842d8bcaacbe04bbd7b9d00c Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Tue, 16 Jul 2024 16:11:16 +0200 Subject: [PATCH 17/21] changed the structure to how it's stated at https://docs.oscar-system.org/dev/Experimental/intro/ --- .../HasseSchmidt.jl => experimental/HasseSchmidt/test/runtests.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/HasseSchmidt/HasseSchmidt.jl => experimental/HasseSchmidt/test/runtests.jl (100%) diff --git a/test/HasseSchmidt/HasseSchmidt.jl b/experimental/HasseSchmidt/test/runtests.jl similarity index 100% rename from test/HasseSchmidt/HasseSchmidt.jl rename to experimental/HasseSchmidt/test/runtests.jl From e1ae42986f52e574c580c0571c3763a143dca80d Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 18 Jul 2024 15:34:10 +0200 Subject: [PATCH 18/21] changed @test to right syntax (added variables for clarity) --- experimental/HasseSchmidt/test/runtests.jl | 145 +++++++++++---------- 1 file changed, 77 insertions(+), 68 deletions(-) diff --git a/experimental/HasseSchmidt/test/runtests.jl b/experimental/HasseSchmidt/test/runtests.jl index 724208299a97..cfc99d5967ef 100644 --- a/experimental/HasseSchmidt/test/runtests.jl +++ b/experimental/HasseSchmidt/test/runtests.jl @@ -12,72 +12,79 @@ @testset "hasse_derivatives" begin R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); - @test - [ [[0, 0], x^3], - [[1, 0], 3*x^2], - [[2, 0], 3*x], - [[3, 0], 1] ] == hasse_derivatives(x^3) - @test - [ [[0, 0], 5*x^2 + 3*y^5], - [[0, 1], 15*y^4], - [[0, 2], 30*y^3], - [[0, 3], 30*y^2], - [[0, 4], 15*y], - [[0, 5], 3], - [[1, 0], 10*x], - [[2, 0], 5] ] == hasse_derivatives(5*x^2 + 3*y^5) - @test - [ [[0, 0], x^2*y^3], - [[1, 0], 2*x*y^3], - [[2, 0], y^3], - [[0, 1], 3*x^2*y^2], - [[1, 1], 6*x*y^2], - [[2, 1], 3*y^2], - [[0, 2], 3*x^2*y], - [[1, 2], 6*x*y], - [[2, 2], 3*y], - [[0, 3], x^2], - [[1, 3], 2*x], - [[2, 3], 1] ] == hasse_derivatives(x^2*y^3) - @test - [ [[0, 0], x^4 + y^2], - [[1, 0], 4*x^3], - [[2, 0], 6*x^2], - [[3, 0], 4*x], - [[4, 0], 1], - [[0, 1], 2*y], - [[0, 2], 1] ] == hasse_derivatives(x^4 + y^2) + + result_a1 = [ [[0, 0], x^3], + [[1, 0], 3*x^2], + [[2, 0], 3*x], + [[3, 0], 1]] + @test result_a1 == hasse_derivatives(x^3) + + result_a2 = [ [[0, 0], 5*x^2 + 3*y^5], + [[0, 1], 15*y^4], + [[0, 2], 30*y^3], + [[0, 3], 30*y^2], + [[0, 4], 15*y], + [[0, 5], 3], + [[1, 0], 10*x], + [[2, 0], 5]] + @test result_a2 == hasse_derivatives(5*x^2 + 3*y^5) + + result_a3 = [ [[0, 0], x^2*y^3], + [[1, 0], 2*x*y^3], + [[2, 0], y^3], + [[0, 1], 3*x^2*y^2], + [[1, 1], 6*x*y^2], + [[2, 1], 3*y^2], + [[0, 2], 3*x^2*y], + [[1, 2], 6*x*y], + [[2, 2], 3*y], + [[0, 3], x^2], + [[1, 3], 2*x], + [[2, 3], 1]] + @test result_a3 == hasse_derivatives(x^2*y^3) + + result_a4 = [ [[0, 0], x^4 + y^2], + [[1, 0], 4*x^3], + [[2, 0], 6*x^2], + [[3, 0], 4*x], + [[4, 0], 1], + [[0, 1], 2*y], + [[0, 2], 1]] + @test result_a4 == hasse_derivatives(x^4 + y^2) end @testset "hasse_derivatives finite fields" begin R, (x, y, z) = polynomial_ring(GF(3), ["x", "y", "z"]); - @test - [ [[0, 0, 0], x^2 + y^2], - [[1, 0, 0], 2*x], - [[2, 0, 0], 1], - [[0, 1, 0], 2*y], - [[0, 2, 0], 1] ] == hasse_derivatives(x^2 + y^2) - @test - [ [[0, 0, 0], x^2*y + z^6], - [[0, 0, 3], 2*z^3], - [[0, 0, 6], 1], - [[1, 0, 0], 2*x*y], - [[2, 0, 0], y], - [[0, 1, 0], x^2], - [[1, 1, 0], 2*x], - [[2, 1, 0], 1] ] == hasse_derivatives(x^2*y + z^6) + + result_b1 = [ [[0, 0, 0], x^2 + y^2], + [[1, 0, 0], 2*x], + [[2, 0, 0], 1], + [[0, 1, 0], 2*y], + [[0, 2, 0], 1]] + @test result_b1 == hasse_derivatives(x^2 + y^2) + + result_b2 = [ [[0, 0, 0], x^2*y + z^6], + [[0, 0, 3], 2*z^3], + [[0, 0, 6], 1], + [[1, 0, 0], 2*x*y], + [[2, 0, 0], y], + [[0, 1, 0], x^2], + [[1, 1, 0], 2*x], + [[2, 1, 0], 1]] + @test result_b2 == hasse_derivatives(x^2*y + z^6) end @testset "_hasse_derivatives MPolyQuoRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); - @test - [ [[0, 0, 0], 3*y^4], - [[0, 1, 0], 12*y^3], - [[0, 2, 0], 18*y^2], - [[0, 3, 0], 12*y], - [[0, 4, 0], 3] ] == _hasse_derivatives(RQ(3y^4)) + + result_c1 = [ [[0, 0, 0], 3*y^4], + [[0, 1, 0], 12*y^3], + [[0, 2, 0], 18*y^2], + [[0, 3, 0], 12*y], + [[0, 4, 0], 3]] + @test result_c1 == _hasse_derivatives(RQ(3y^4)) end @testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin @@ -85,11 +92,12 @@ end m = ideal(R, [x, y, z]); # max ideal U = complement_of_prime_ideal(m); RL, _ = localization(R, U); - @test - [ [[0, 0, 0], 5*x^3], - [[1, 0, 0], 15*x^2], - [[2, 0, 0], 15*x], - [[3, 0, 0], 5] ] == _hasse_derivatives(RL(5x^3)) + + result_d1 = [ [[0, 0, 0], 5*x^3], + [[1, 0, 0], 15*x^2], + [[2, 0, 0], 15*x], + [[3, 0, 0], 5]] + @test result_d1 == _hasse_derivatives(RL(5x^3)) end @testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin @@ -99,12 +107,13 @@ end m = ideal(R, [x, y, z]); # max ideal U = complement_of_prime_ideal(m); RQL, _ = localization(RQ, U); - @test - [ [[0, 0, 0], 2*z^5], - [[0, 0, 1], 10*z^4], - [[0, 0, 2], 20*z^3], - [[0, 0, 3], 20*z^2], - [[0, 0, 4], 10*z], - [[0, 0, 5], 2] ] == _hasse_derivatives(RQL(2z^5)) + + result_e1 = [ [[0, 0, 0], 2*z^5], + [[0, 0, 1], 10*z^4], + [[0, 0, 2], 20*z^3], + [[0, 0, 3], 20*z^2], + [[0, 0, 4], 10*z], + [[0, 0, 5], 2]] + @test result_e1 == _hasse_derivatives(RQL(2z^5)) end From 4e269bb40031e95ee3da2f9cbcd8636a6a1e5f03 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Thu, 18 Jul 2024 21:40:18 +0200 Subject: [PATCH 19/21] added "Oscar." infront of every "_hasse_derivatives" --- experimental/HasseSchmidt/src/HasseSchmidt.jl | 24 +++++++++---------- experimental/HasseSchmidt/test/runtests.jl | 12 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/experimental/HasseSchmidt/src/HasseSchmidt.jl b/experimental/HasseSchmidt/src/HasseSchmidt.jl index c949ba009581..df8e9c1c204c 100644 --- a/experimental/HasseSchmidt/src/HasseSchmidt.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidt.jl @@ -51,15 +51,15 @@ function hasse_derivatives(f::MPolyRingElem) end function hasse_derivatives(f::MPolyQuoRingElem) - error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type MPolyQuoRingElem") + error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type MPolyQuoRingElem") end function hasse_derivatives(f::Oscar.MPolyLocRingElem) - error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") + error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") end function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) - error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") + error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") end @@ -70,7 +70,7 @@ end # MPolyQuoRingElem (internal, expert use only) @doc raw""" - _hasse_derivatives(f::MPolyQuoRingElem) + Oscar._hasse_derivatives(f::MPolyQuoRingElem) Return a list of Hasse-Schmidt derivatives of lift of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -84,7 +84,7 @@ julia> RQ, _ = quo(R, I); julia> f = RQ(2*y^4); -julia> _hasse_derivatives(f) +julia> Oscar._hasse_derivatives(f) 5-element Vector{Vector{Any}}: [[0, 0], 2*y^4] [[0, 1], 8*y^3] @@ -93,13 +93,13 @@ julia> _hasse_derivatives(f) [[0, 4], 2] ``` """ -function _hasse_derivatives(f::MPolyQuoRingElem) +function Oscar._hasse_derivatives(f::MPolyQuoRingElem) return hasse_derivatives(lift(f)) end # Oscar.MPolyLocRingElem (internal, expert use only) @doc raw""" - _hasse_derivatives(f::Oscar.MPolyLocRingElem) + Oscar._hasse_derivatives(f::Oscar.MPolyLocRingElem) Return a list of Hasse-Schmidt derivatives of numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -115,7 +115,7 @@ julia> Rloc, _ = localization(R, U); julia> f = Rloc(2*z^5); -julia> _hasse_derivatives(f) +julia> Oscar._hasse_derivatives(f) 6-element Vector{Vector{Any}}: [[0, 0, 0], 2*z^5] [[0, 0, 1], 10*z^4] @@ -125,13 +125,13 @@ julia> _hasse_derivatives(f) [[0, 0, 5], 2] ``` """ -function _hasse_derivatives(f::Oscar.MPolyLocRingElem) +function Oscar._hasse_derivatives(f::Oscar.MPolyLocRingElem) return hasse_derivatives(numerator(f)) end # Oscar.MPolyQuoLocRingElem (internal, expert use only) @doc raw""" - _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) + Oscar._hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) Return a list of Hasse-Schmidt derivatives of lifted numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -151,7 +151,7 @@ julia> RQL, _ = localization(RQ, U); julia> f = RQL(4*y^3); -julia> _hasse_derivatives(f) +julia> Oscar._hasse_derivatives(f) 4-element Vector{Vector{Any}}: [[0, 0, 0], 4*y^3] [[0, 1, 0], 12*y^2] @@ -159,6 +159,6 @@ julia> _hasse_derivatives(f) [[0, 3, 0], 4] ``` """ -function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) +function Oscar._hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) return hasse_derivatives(lifted_numerator(f)) end diff --git a/experimental/HasseSchmidt/test/runtests.jl b/experimental/HasseSchmidt/test/runtests.jl index cfc99d5967ef..c691a2f636ae 100644 --- a/experimental/HasseSchmidt/test/runtests.jl +++ b/experimental/HasseSchmidt/test/runtests.jl @@ -74,7 +74,7 @@ end @test result_b2 == hasse_derivatives(x^2*y + z^6) end -@testset "_hasse_derivatives MPolyQuoRingElem" begin +@testset "Oscar._hasse_derivatives MPolyQuoRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); @@ -84,10 +84,10 @@ end [[0, 2, 0], 18*y^2], [[0, 3, 0], 12*y], [[0, 4, 0], 3]] - @test result_c1 == _hasse_derivatives(RQ(3y^4)) + @test result_c1 == Oscar._hasse_derivatives(RQ(3y^4)) end -@testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin +@testset "Oscar._hasse_derivatives Oscar.MPolyLocRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); m = ideal(R, [x, y, z]); # max ideal U = complement_of_prime_ideal(m); @@ -97,10 +97,10 @@ end [[1, 0, 0], 15*x^2], [[2, 0, 0], 15*x], [[3, 0, 0], 5]] - @test result_d1 == _hasse_derivatives(RL(5x^3)) + @test result_d1 == Oscar._hasse_derivatives(RL(5x^3)) end -@testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin +@testset "Oscar._hasse_derivatives Oscar.MPolyQuoLocRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); @@ -114,6 +114,6 @@ end [[0, 0, 3], 20*z^2], [[0, 0, 4], 10*z], [[0, 0, 5], 2]] - @test result_e1 == _hasse_derivatives(RQL(2z^5)) + @test result_e1 == Oscar._hasse_derivatives(RQL(2z^5)) end From 47b4b091cf19bf3c4f7242ce4ed68f5a5c9f4a95 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 19 Jul 2024 11:05:47 +0200 Subject: [PATCH 20/21] removed "Oscar." again from "_hasse_derivatives" in HasseSchmidt.jl --- experimental/HasseSchmidt/src/HasseSchmidt.jl | 24 +++++++++---------- experimental/HasseSchmidt/test/runtests.jl | 6 ++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/experimental/HasseSchmidt/src/HasseSchmidt.jl b/experimental/HasseSchmidt/src/HasseSchmidt.jl index df8e9c1c204c..c949ba009581 100644 --- a/experimental/HasseSchmidt/src/HasseSchmidt.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidt.jl @@ -51,15 +51,15 @@ function hasse_derivatives(f::MPolyRingElem) end function hasse_derivatives(f::MPolyQuoRingElem) - error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type MPolyQuoRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type MPolyQuoRingElem") end function hasse_derivatives(f::Oscar.MPolyLocRingElem) - error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyLocRingElem") end function hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) - error("Not implemented. For experts, however, there is an internal function called Oscar._hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") + error("Not implemented. For experts, however, there is an internal function called _hasse_derivatives, which works for elements of type Oscar.MPolyQuoLocRingElem") end @@ -70,7 +70,7 @@ end # MPolyQuoRingElem (internal, expert use only) @doc raw""" - Oscar._hasse_derivatives(f::MPolyQuoRingElem) + _hasse_derivatives(f::MPolyQuoRingElem) Return a list of Hasse-Schmidt derivatives of lift of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -84,7 +84,7 @@ julia> RQ, _ = quo(R, I); julia> f = RQ(2*y^4); -julia> Oscar._hasse_derivatives(f) +julia> _hasse_derivatives(f) 5-element Vector{Vector{Any}}: [[0, 0], 2*y^4] [[0, 1], 8*y^3] @@ -93,13 +93,13 @@ julia> Oscar._hasse_derivatives(f) [[0, 4], 2] ``` """ -function Oscar._hasse_derivatives(f::MPolyQuoRingElem) +function _hasse_derivatives(f::MPolyQuoRingElem) return hasse_derivatives(lift(f)) end # Oscar.MPolyLocRingElem (internal, expert use only) @doc raw""" - Oscar._hasse_derivatives(f::Oscar.MPolyLocRingElem) + _hasse_derivatives(f::Oscar.MPolyLocRingElem) Return a list of Hasse-Schmidt derivatives of numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -115,7 +115,7 @@ julia> Rloc, _ = localization(R, U); julia> f = Rloc(2*z^5); -julia> Oscar._hasse_derivatives(f) +julia> _hasse_derivatives(f) 6-element Vector{Vector{Any}}: [[0, 0, 0], 2*z^5] [[0, 0, 1], 10*z^4] @@ -125,13 +125,13 @@ julia> Oscar._hasse_derivatives(f) [[0, 0, 5], 2] ``` """ -function Oscar._hasse_derivatives(f::Oscar.MPolyLocRingElem) +function _hasse_derivatives(f::Oscar.MPolyLocRingElem) return hasse_derivatives(numerator(f)) end # Oscar.MPolyQuoLocRingElem (internal, expert use only) @doc raw""" - Oscar._hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) + _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) Return a list of Hasse-Schmidt derivatives of lifted numerator of `f`, each with a multiindex `[a_1, ..., a_n]`, where `a_i` describes the number of times `f` was derived w.r.t. the `i`-th variable. @@ -151,7 +151,7 @@ julia> RQL, _ = localization(RQ, U); julia> f = RQL(4*y^3); -julia> Oscar._hasse_derivatives(f) +julia> _hasse_derivatives(f) 4-element Vector{Vector{Any}}: [[0, 0, 0], 4*y^3] [[0, 1, 0], 12*y^2] @@ -159,6 +159,6 @@ julia> Oscar._hasse_derivatives(f) [[0, 3, 0], 4] ``` """ -function Oscar._hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) +function _hasse_derivatives(f::Oscar.MPolyQuoLocRingElem) return hasse_derivatives(lifted_numerator(f)) end diff --git a/experimental/HasseSchmidt/test/runtests.jl b/experimental/HasseSchmidt/test/runtests.jl index c691a2f636ae..56c24d53c2d9 100644 --- a/experimental/HasseSchmidt/test/runtests.jl +++ b/experimental/HasseSchmidt/test/runtests.jl @@ -74,7 +74,7 @@ end @test result_b2 == hasse_derivatives(x^2*y + z^6) end -@testset "Oscar._hasse_derivatives MPolyQuoRingElem" begin +@testset "_hasse_derivatives MPolyQuoRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); @@ -87,7 +87,7 @@ end @test result_c1 == Oscar._hasse_derivatives(RQ(3y^4)) end -@testset "Oscar._hasse_derivatives Oscar.MPolyLocRingElem" begin +@testset "_hasse_derivatives Oscar.MPolyLocRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); m = ideal(R, [x, y, z]); # max ideal U = complement_of_prime_ideal(m); @@ -100,7 +100,7 @@ end @test result_d1 == Oscar._hasse_derivatives(RL(5x^3)) end -@testset "Oscar._hasse_derivatives Oscar.MPolyQuoLocRingElem" begin +@testset "_hasse_derivatives Oscar.MPolyQuoLocRingElem" begin R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"]); I = ideal(R, [x^2 - 1]); RQ, _ = quo(R, I); From 9a4bca6e8589215128d267e93922690dabe87195 Mon Sep 17 00:00:00 2001 From: KilianBruns Date: Fri, 19 Jul 2024 14:53:09 +0200 Subject: [PATCH 21/21] now defining elements f via maps given by definition of Quo- and Loc-Rings --- experimental/HasseSchmidt/src/HasseSchmidt.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/experimental/HasseSchmidt/src/HasseSchmidt.jl b/experimental/HasseSchmidt/src/HasseSchmidt.jl index c949ba009581..4c892ec735ce 100644 --- a/experimental/HasseSchmidt/src/HasseSchmidt.jl +++ b/experimental/HasseSchmidt/src/HasseSchmidt.jl @@ -80,9 +80,9 @@ julia> R, (x, y) = polynomial_ring(ZZ, ["x", "y"]); julia> I = ideal(R, [x - 1]); -julia> RQ, _ = quo(R, I); +julia> RQ, phi = quo(R, I); -julia> f = RQ(2*y^4); +julia> f = phi(2*y^4); julia> _hasse_derivatives(f) 5-element Vector{Vector{Any}}: @@ -111,9 +111,9 @@ julia> m = ideal(R, [x - 3, y - 2, z + 1]); julia> U = complement_of_prime_ideal(m); -julia> Rloc, _ = localization(R, U); +julia> Rloc, phi = localization(R, U); -julia> f = Rloc(2*z^5); +julia> f = phi(2*z^5); julia> _hasse_derivatives(f) 6-element Vector{Vector{Any}}: @@ -141,15 +141,15 @@ julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"]); julia> I = ideal(R, [x^3 - 1]); -julia> RQ, _ = quo(R, I); +julia> RQ, phi = quo(R, I); julia> p = ideal(R, [z]); julia> U = complement_of_prime_ideal(p); -julia> RQL, _ = localization(RQ, U); +julia> RQL, iota = localization(RQ, U); -julia> f = RQL(4*y^3); +julia> f = iota(phi(4*y^3)); julia> _hasse_derivatives(f) 4-element Vector{Vector{Any}}: