Skip to content

Commit

Permalink
Merge branch 'NumberFields' of https://github.com/Macaulay2/Workshop-…
Browse files Browse the repository at this point in the history
…2024-Utah into NumberFields
  • Loading branch information
jjgarzella committed Jun 5, 2024
2 parents 4538974 + 672fc5c commit 1292436
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 21 deletions.
8 changes: 8 additions & 0 deletions NumberFields/KarlsTestingFile.m2
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
restart
loadPackage "NumberFields"

R = QQ[x]/ideal(x^3-2)
S = R[y]/ideal(y^2+y+1)
remakeField S
U = (flattenRing)
T = QQ[x,y, Degrees=>{0,0}]/ideal(x^3-2,y^2+y+1)

K = numberField R
Expand All @@ -15,3 +18,8 @@ pushFwd(phi)

loadPackage("PushForward", DebuggingMode => true, Reload=>true)



R = QQ[x,y]/ideal(y^2-x*(x-1)*(x-2), x^2-y*(y-1)*(y-2))
psi = map(R, QQ)
pushFwd(psi)
119 changes: 99 additions & 20 deletions NumberFields/NumberFields.m2
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ export{
"splittingField",
"compositums",
"simpleExt",
"remakField",--this probably shouldn't be exposed to the user long term
"asExtensionOfBase"--this probably shouldn't be exposed to the user long term
"remakeField",--this probably shouldn't be exposed to the user long term
"minimalPolynomial"
};

NumberField = new Type of HashTable
Expand All @@ -49,12 +50,14 @@ remakeField(Ring) := opts -> R1 -> (
local amb;
local myIdeal;
a := local a;
if instance(R1, QuotientRing) then (amb = ambient R1; myIdeal = ideal R1) else (amb = R1; myIdeal = ideal(sub(0,R1)));
R2 := (flattenRing R1)#0;
if instance(R2, QuotientRing) then (amb = ambient R2; myIdeal = ideal R2) else (amb = R2; myIdeal = ideal(sub(0,R2)));
numVars := #(gens amb);

if opts.Variable === null then (var = local symbol a) else (var = opts.Variable);
newRing1 := QQ(monoid[(var_1..var_numVars)]);--we may want to think about the monomial order, we also might want to consider messing around with choosing a better presentation.
phi := map(R1, newRing1, gens amb);
if opts.Variable === null then (var = a) else (var = opts.Variable);
varList := {var_1..var_numVars};
newRing1 := QQ(monoid[varList]);--we may want to think about the monomial order, we also might want to consider messing around with choosing a better presentation.
phi := map(newRing1, amb, gens newRing1);

newRing1/phi(myIdeal)
)
Expand All @@ -68,37 +71,81 @@ numberField(RingElement) := opts -> f1 -> (

-- Verifies that the resulting quotient is a field.
if f1 == 0 then error("Expected nonzero polynomial.");
print(f1);
if not isPrime ideal(f1) then error("Expected an irreducible polynomial.");
--if not isPrime ideal(f1) then error("Expected an irreducible polynomial.");

new NumberField from {
ring => toField (R1/ideal(f1)),
cache => new CacheTable from {}
}
numberField(R1/ideal(f1))
)



numberField(Ring) := opts -> R1 -> (
if R1===QQ then return new NumberField from {ring => R1};
if R1===QQ then return new NumberField from {
ring => R1,
pushFwd => pushFwd(map(QQ,QQ)),
cache => new CacheTable from {}
};

if not isPrime (ideal 0_R1) then error("Expected a field.");
if not dim R1 == 0 then error("Expected a field.");

if char R1 != 0 then error("Expected characteristic 0.");

flattenedR1 := (flattenRing(R1))#0;
iota := map(flattenedR1,QQ);
try pushFwd(iota) else error("Not finite dimensional over QQ");
outputRing := remakeField(R1);
iota := map(outputRing,QQ);
local myPushFwd;
try myPushFwd = pushFwd(iota) else error("Not finite dimensional over QQ");
genMinPolys := apply(gens outputRing, h->minimalPolynomial(h));

genList := gens outputRing;
genCt := #genList;
i := 0;
deg := degree outputRing;

myStr := "Number Field, degree ";
myStr = myStr | toString(deg) | " / Q, generated by:";
if genCt == 0 then myStr = myStr + " nothing";
while (i < genCt) do (
myStr = myStr | " " | toString(genList#i) | " (" | toString (genMinPolys#i) | ")";
i = i+1;
if (i < genCt) then myStr = myStr | ", ";
);

new NumberField from {
ring => toField (flattenedR1),
cache => new CacheTable from {}
ring => toField outputRing,
pushFwd => myPushFwd,
String => myStr,
minimalPolynomial => genMinPolys, --a list of min polys of gens, for display purposes
cache => new CacheTable from {degree => deg}
}
)

internalNumberFieldConstructor := R1 -> (

);

--*****************************
--NumberField display
--*****************************


net NumberField := nf -> (
-*
myStr := "Number Field, degree ";
myStr = myStr | toString(degree nf) | " / Q, generated by:";
i := 0;
genCt := #(gens ring nf);
genList := gens ring nf;
if genCt == 0 then myStr = myStr + " nothing";
while (i < genCt) do (
myStr = myStr | " " | toString(genList#i) | " (" | toString (nf#minimalPolynomial#i) | ")";
i = i+1;
if (i < genCt) then myStr = myStr + ", ";
);
--do some code
*-

nf#String
)

--****************************
--NumberField basic operations
--****************************
Expand Down Expand Up @@ -156,6 +203,14 @@ degree(NumberFieldExtension) := nfe -> (
rk
)

norm(RingElement) := (elt) ->(
S := ring elt;
return det pushFwd(map(S^1, S^1, {{elt}}));
);
trace(RingElement) := (elt) -> (
S := ring elt;
return trace pushFwd(map(S^1, S^1, {{elt}}));
);
--*************************
--Methods
--*************************
Expand All @@ -179,6 +234,7 @@ isGalois(NumberFieldExtension) := opts -> iota -> (
isGalois(RingMap) := opts -> iota -> (
isGalois(numberFieldExtension iota)
)

-- splittingField method
splittingField = method(Options => {})
splittingField(RingElement) := opts -> f1 -> (
Expand Down Expand Up @@ -221,21 +277,44 @@ simpleExt(NumberField) := opts -> nf ->(
D := degree K;
--We find an element that produces a degree D field extension.
d := 0;
c := 0;
while d < D do
(
r := random(1, K);
xx := local xx;
R := QQ[xx];
phi := map( K, R, {r});
if isPrime (kernel phi) then (
I := kernel phi *sub (( 1/(((coefficients (first entries gens kernel phi)_0)_1)_0)_0), QQ);
I := kernel phi *sub (( 1/(((coefficients (first entries gens kernel phi)_0)_1)_0)_0), R);
simpleExt := numberField(R / I);
d := degree simpleExt;
d = degree simpleExt;
);
);
return simpleExt;
)

minimalPolynomial = method(Options => {})
minimalPolynomial(RingElement) := opts -> f1 -> (
R1 := ring f1;
S1 := (coefficientRing(R1))[local y];
P1 := pushFwd(map(R1, coefficientRing(R1)));
A1 := (P1#2)(1_R1);
pow1 := 1;
while gens(kernel(A1))==0 do (
A1 = A1|(P1#2)(f1^pow1);
pow1 += 1;
);
M1 := matrix({{1_S1}});
for i1 from 1 to (pow1-1) do (
M1 |= y^i1;
);
(entries (M1*(gens(kernel(A1)))))#0#0
)
minimalPolynomial(List) := opts -> L1 -> (
apply(L1, i -> minimalPolynomial(i))
)


--*****************************
--Documentation
--*****************************
Expand Down
64 changes: 64 additions & 0 deletions NumberFields/minimalPolynomial.m2
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
loadPackage ("NumberFields", Reload=>true)

-- Nicholas' minimal polynomial file.
-- Method to compute minimal polynomial via pushFwd.
-- Eventually extend to also compute minimal polynomials for a list of elements.
minimalPolynomialViaPushFwd = method(Options => {})
minimalPolynomialViaPushFwd(RingElement) := opts -> f1 -> (
R1 := ring f1;
S1 := (coefficientRing(R1))[y];
P1 := pushFwd(map(R1, QQ));
A1 := (P1#2)(1_R1);
pow1 := 1;
while not gens(kernel(A1))==0 do (
A1 |= (P1#2)(f1^pow1);
pow1 += 1;
);
M := matrix({{1_S1}});
for i1 from 1 to pow1 do (
M |= y^i1;
);
(entries (M*K))#0#0
)

loadPackage ("NumberFields", Reload=>true)
R1 = QQ[x]/(x^3-2)
S1 = (coefficientRing(R1))[y]
elt1 = x
--phi1 = map(R1, QQ)
P1 = pushFwd(map(R1, QQ))
g1 = (P1#2)(1_R1)
g2 = (P1#2)(elt1)
g3 = (P1#2)(elt1^2)
g4 = (P1#2)(elt1^3)
A = g1|g2|g3|g4
K = gens(kernel(A))
M = matrix({{1, y, y^2, y^3}})
(entries (M*K))#0#0

--****************
--Tests
--****************

loadPackage ("NumberFields", Reload=>true)
-- This one should return y^3 - 2
R1 = QQ[x]/(x^3-2)
f = x
minimalPolynomial f

-- This one should return y^3 - 4
f = x^2
minimalPolynomial f

-- This one should return y^3 - 6*y - 6
f = x^2+x
minimalPolynomial f

minimalPolynomial {x, x^2, x^2+x}

-- This one should return y^4 - 2*y^2 + 9
R1 = QQ[x,y]/(x^2+1,y^2-2)
f = x+y
minimalPolynomial f

simpleExt numberField R1
2 changes: 2 additions & 0 deletions NumberFields/norm.m2
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ norm(RingElement) := (elt) ->(
S = ring elt;
return det pushFwd(map(S^1, S^1, {{elt}}));
);
R = QQ[x]/(x^3-2)
norm(1_R)

93 changes: 92 additions & 1 deletion NumberFields/splittingField.m2
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,95 @@ S = splittingField f1
T = (ring target S)[y]
f11 = (map(T, R, {y})) f1
L2 = decompose ideal f11
polynomialSplits f11
polynomialSplits f11

-- Let's try to see what's going on here.
R1 = ring f1
S1 = R1;
K1 = coefficientRing R1
K2 = coefficientRing R1
variableIndex = 1
-- Begin for loop
L1 = decompose ideal f1
currentEntry = (entries gens L1#0)#0
length(currentEntry)==1 and max(degree(currentEntry#0))==1
degree(currentEntry#0)
K1 = R1/(L1#0)
describe K1
S1 = K1[a_variableIndex]
describe S1
phi1 = map(S1, R1, {a_variableIndex})
f1 = phi1(f1)
f1 = f1//(a_variableIndex-x)
R1 = S1
describe R1
describe K1
variableIndex += 1
-- Second iteration of for loop
L1 = decompose ideal f1
currentEntry = (entries gens L1#0)#0
K1 = R1/(L1#0)
describe K1

-- My simpleExt idea
(flattenRing K1)#0
NF1 = numberField K1
NF2 = simpleExt NF1
K1 = ring NF2

-- Back to the original loop
S1 = K1[a_variableIndex]
describe S1
phi1 = map(S1, R1, {a_variableIndex})
f1 = phi1(f1)
f1 //= (a_variableIndex-a_(variableIndex-1))
R1 = S1
describe R1
describe K1
variableIndex += 1

--(flattenRing K1)#0
--NF1 = numberField K1
--NF2 = simpleExt NF1
--K2 = ring NF2
--L1 = decompose ideal f1
--L1#0
--describe S1

-- Third iteration of for loop
L1 = decompose ideal f1
currentEntry = (entries gens L1#0)#0
degree currentEntry#0
K1 = R1/(L1#0)
describe K1

-- Another simpleExt
NF1 = numberField K1
NF2 = simpleExt NF1
K1 = ring NF2

S1 = K1[a_variableIndex]
describe S1
phi1 = map(S1, R1, {a_variableIndex})
f1 = phi1(f1)
f1 //= (a_variableIndex-a_(variableIndex-1))
R1 = S1
describe R1
describe K1
variableIndex += 1
-- Fourth iteration of for loop
-- Note: the below line is where things take too long. Need to figure out a way to get decompose running more quickly.
L1 = decompose ideal f1
currentEntry = (entries gens L1#0)#0
degree currentEntry#0
K1 = R1/(L1#0)
describe K1
S1 = K1[a_variableIndex]
describe S1
phi1 = map(S1, R1, {a_variableIndex})
f1 = phi1(f1)
f1 //= (a_variableIndex-a_(variableIndex-1))
R1 = S1
describe R1
describe K1
variableIndex += 1
3 changes: 3 additions & 0 deletions NumberFields/trace.m2
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ trace(RingElement) := (elt) -> (
S = ring elt;
return trace pushFwd(map(S^1, S^1, {{elt}}));
);
R = QQ[x]/(x^3-2)
trace(x)

0 comments on commit 1292436

Please sign in to comment.