added comments

This commit is contained in:
Nelynx 2025-02-27 14:44:33 +01:00
parent e73335cf6b
commit 38e7c8af19

View File

@ -196,36 +196,9 @@ proc NormalOYModule(matrix GOX, matrix GOY, list #)
}
//print(V);//
T = T + freemodule(a*m) * V;
/* Infierno infernal
// "T";T;//
string RName=nameof(basering);
// "show basering"; execute("show("+RName+")");//
// "Raux 1"; Raux; //
print("ring rred = " + charstr(basering) + ",X(1.." + string(p) + "),ds");//
execute("export("+ RName + ")");
export(T);
execute("ring rred = " + charstr(basering) + ",X(1.." + string(p) + "),ds");
print("def T = imap("+RName+",T)");//
"Raux 2"; execute(RName);
execute("def T = imap(" + RName + ",T)");
"T=";T;//
*/
module N = kbase(std(T));
/*
execute("setring("+ RName + ")");
def N = imap(rred, N);
print("N = "); print(N); //
*/
T = T + freemodule(a*m) * V; // This should be done by switching to a new ring with only X(1..p)
module N = kbase(std(T));
int CodimT = ncols(N);
//print("vector N[1] ="); VectorToMatrix(N[1],a,m);//
@ -257,6 +230,9 @@ proc GenerateOYModule(matrix GOX, matrix GOY, list #)
# is an optional ideal so that computations are made modulo this ideal.
*/
// Basic definitions
int i;
int j;
@ -266,21 +242,37 @@ proc GenerateOYModule(matrix GOX, matrix GOY, list #)
int nx = ncols(GOX);
int a = nrows(GOY);
module M = 0;
matrix col[a][1] = 0;
module M = 0; // This will be module with the same generators but over O_n
matrix col[a][1] = 0; // Auxiliar variable to store the particular vector to be transformed at each step
// This is needed because if a column ends in zeroes, SINGULAR cuts the last rows which
// are zero, and then after transforming to the Malgrange Normal Form they loose some components.
// This is also the reason to use matrices instead of vectors and modules.
// Convert GOY to an O_n - module
for (i=1; i<= ny; i++)
{
col = submat(GOY,intvec(1..a),intvec(i));
M = M + MatrixToVector(MalgrFormVect(col, #));
col = submat(GOY,intvec(1..a),intvec(i)); // Pick the next generator in GOY
M = M + MatrixToVector(MalgrFormVect(col, #)); // Convert to GOX
}
// Convert GOX to an O_n -module
/*
For each generator v of GOX, we need to compute the Malgrange normal
form of v * g for each g in Gens. The result generates the same module in O_n.
*/
for (i=1; i <= nx; i++)
{
col = submat(GOX,intvec(1..a),intvec(i));
col = submat(GOX,intvec(1..a),intvec(i)); // Pick the next generator in GOX
for (j=1; j<= m; j++)
{
M = M + MatrixToVector(MalgrFormVect(Gens[j]*col, #));
M = M + MatrixToVector(MalgrFormVect(Gens[j]*col, #)); // Compute each product of col times an element of Gens
}
}
@ -297,24 +289,27 @@ proc MalgrRing(ideal J, int n, ideal f)
*/
// Definitions
int i;
int p = ncols(f);
string RName=nameof(basering);
ideal w = f[1..n];
int i;
int p = ncols(f); // Total number of components of map
string RName=nameof(basering); // We need the name of the basering as string to later be able to extend it to a new ring with extra variables.
ideal w = f[1..n]; // Get a subset of components of f, which is expected to define a finite mapping.
// Compute generators of w_*O_X
ideal Gens = kbase(std(w+J));
ideal Gens = kbase(std(w+J)); // This is the set of generators of O_X as O_n-module.
int nGens = ncols(Gens);
ring R0 = changeord(list(list("dp",nvars(basering))));
// Create a ring with generators as variables and target variables.
string vaG ="G(";
def R1=extendring(nGens,vaG,"dp",1);
ring R0 = changeord(list(list("dp",nvars(basering)))); // Change ordering of basering to global. In local, computations fail since one of the generators of Gens is always a constant.
// ¿To Do: let user choose the local ordering?
string vaG ="G(";
def R1=extendring(nGens,vaG,"dp",1); // Add G variables so that G(i) corresponds to the i-th generator of Gens.
setring R1;
string vaX="X(";
def R2=extendring(p, vaX,"lp",1);
def R2=extendring(p, vaX,"lp",1); // Add X variables so that X(j) corresponds to the j-th component of f.
setring R2;
// Bring necessary information from source ring
@ -330,15 +325,17 @@ proc MalgrRing(ideal J, int n, ideal f)
for(i = 1; i<=nGens; i++)
{
G = G + ideal(Gens[i]- G(i));
G = G + ideal(Gens[i]- G(i)); // Make G(i) correspond to Gens[i]
}
for(i = 1; i<= n; i++)
{
W = W + ideal(f[i]- X(i));
W = W + ideal(f[i]- X(i)); // Make X(i) correspond to f[i], only for the finite mapping subset of components.
}
ideal GF = std(W+G+J);
ideal GF = std(W+G+J); // If the orderings are properly chosen, reducing any monomial in O_X with respect to this ideal
// should return a normal form which is a polynomial in X(1..n), G(1..nGens) in which the G's only appear
// as linear terms times polynomials in the X's. This is what we call the Malgrange Normal Form.
/* This is now moved to the MalgrFormPoly procedure
for (i=n+1; i <= p; i++)
@ -347,7 +344,8 @@ proc MalgrRing(ideal J, int n, ideal f)
}
*/
export(GF);
// Save variables in ring so that they survive outside of the procedure
export(GF);
export(Gens);
export(J);
@ -377,32 +375,51 @@ proc MalgrFormPoly(poly h, list #)
int i;
ideal K = GF;
// Prepare the ideal that reduces to the Malgrange Normal Form
ideal K = GF; // Save the GF ideal to a new variable since we are going to possibly modify it.
if (size(#)> 0)
{
K = std(#[1]+GF);
K = std(#[1]+GF); // Work modulo an ideal, if requested.
}
for (i=dimX+1; i <= size(mappingf); i++)
{
K = K + ideal(X(i) - reduce(mappingf[i], K));
K = K + ideal(X(i) - reduce(mappingf[i], K)); // Assign the components of f which do not give the finite mapping to variables in the target, if p > n.
}
poly hr = reduce(h,K); // Obtain Malgrange form as a sum
/* Caution: We do not compute again a standard basis of K since this would be equivalent to computing
the polynomial of the image when p > n and this is too computationally expensive. */
// Compute the Malgrange Normal Form of the requested polynomial
poly hr = reduce(h,K); // Obtain Malgrange form as a sum. This should be a polynomial only in X's and G's,
// and the G's should only appear as linear variables times polys in X.
poly c;
int nGens = ncols(Gens);
matrix v[1][nGens] = 0;
// Convert the Malgrange Normal Form of the polynomial to row matrix form.
/*
Since the G's are only linear in hr, they determine a vector with
coefficients only in the X's (one coefficient for each G(i)).
We only need to extract these coefficients and add them to the corresponding component in v.
*/
matrix v[1][nGens] = 0;
for (i=1; i<= nGens-1; i++)
{
c = hr - subst(hr,G(i),0); // Gens[i] term
hr = hr - c;
v[1,i] = c/G(i);
c = hr - subst(hr,G(i),0); // This is the coefficient of G(i) in hr
hr = hr - c; // Remove the G(i) and its coefficient from hr.
v[1,i] = c/G(i); // The i'th component of v is the coefficient of G(i) in hr.
}
v[1,nGens] = hr;
v[1,nGens] = hr; // The variable G(nGens) corresponds to the generator 1 in Gens,
// hence it does not appear in the Malgrange Normal Form.
// Since its coefficient is the remaining part of the previous loop, we add it manually.
return(v);
}
@ -425,11 +442,13 @@ proc MalgrFormVect(matrix v, list #)
int i;
def m = MalgrFormPoly(v[1,1], #);
def m = MalgrFormPoly(v[1,1], #); // We need to manually compute the first component outside of the loop
// so that the first row of the matrix already has the correct information
// (else, the first row would be made of all zeroes and later we would need to remove that row)
for (i=2; i <= a; i++)
{
m = transpose(concat(transpose(m),transpose(MalgrFormPoly(v[i,1], #))));
m = transpose(concat(transpose(m),transpose(MalgrFormPoly(v[i,1], #)))); // compute the Malgrange Normal Form row of the next entry of v and add it to the matrix.
}
return(m);
@ -439,6 +458,11 @@ proc MalgrFormVect(matrix v, list #)
proc MatrixToVector(matrix M)
{
/*
This procedure converts an a x b matrix M into an (a*b) x 1 matrix v, where
the (i-1)*b + j entry in v with 1 <= j <= b, 1 <= i <= a corresponds to the (i, j) entry in M
*/
int a = nrows(M);
int b = ncols(M);
@ -462,6 +486,11 @@ proc MatrixToVector(matrix M)
proc VectorToMatrix(vector v, int a, int b)
{
/*
Converts a vector of length a*b into an a*b matrix by chopping the adequate
number of components in v.
*/
int i;
int j;
@ -482,6 +511,19 @@ proc VectorToMatrix(vector v, int a, int b)
proc MalgrFormToOX(matrix M)
{
/*
WARNING:
This procedure only works inside the ring generated by MalgrRing, containing
ideal J, ideal Gens, ideal GF, mappingf and the appropriate variables.
Given a matrix with number of columns equal to nGens and entries in X(1..p),
returns the corresponding vector with entries in O_X
TO DO: we should use the InvMalgrPoly procedure for this instead of repeating
everything again.
*/
int i;
int j;
int p = ncols(mappingf);
@ -522,6 +564,15 @@ proc SplitMap(ideal f)
proc InvMalgrPoly(matrix v, ideal Gens, ideal w)
{
/*
WARNING:
This procedure only works inside the ring generated by MalgrRing, containing
ideal J, ideal Gens, ideal GF, and the appropriate variables.
Converts a row matrix corresponding to a Malgrange Normal Form into its
original polynomial form in O_X
*/
int n=ncols(w);
int i;
poly h=0;