/usr/share/axiom-20170501/src/algebra/WFFINTBS.spad is in axiom-source 20170501-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | )abbrev package WFFINTBS WildFunctionFieldIntegralBasis
++ Authors: Victor Miller, Clifton Williamson
++ Date Created: 24 July 1991
++ Date Last Updated: 20 September 1994
++ Description:
++ In this package K is a finite field, R is a ring of univariate
++ polynomials over K, and F is a framed algebra over R. The package
++ provides a function to compute the integral closure of R in the quotient
++ field of F as well as a function to compute a "local integral basis"
++ at a specific prime.
WildFunctionFieldIntegralBasis(K,R,UP,F) : SIG == CODE where
K : FiniteFieldCategory
R : UnivariatePolynomialCategory K
UP : UnivariatePolynomialCategory R
F : FramedAlgebra(R,UP)
I ==> Integer
Mat ==> Matrix R
NNI ==> NonNegativeInteger
SAE ==> SimpleAlgebraicExtension
RResult ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
IResult ==> Record(basis: Mat, basisDen: R, basisInv:Mat,discr: R)
MATSTOR ==> StorageEfficientMatrixOperations
SIG ==> with
integralBasis : () -> RResult
++ \spad{integralBasis()} returns a record
++ \spad{[basis,basisDen,basisInv]} containing information regarding
++ the integral closure of R in the quotient field of F, where
++ F is a framed algebra with R-module basis \spad{w1,w2,...,wn}.
++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
++ the \spad{i}th element of the integral basis is
++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, the
++ \spad{i}th row of \spad{basis} contains the coordinates of the
++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
++ \spad{wi = sum(bij * vj, j = 1..n)}.
localIntegralBasis : R -> RResult
++ \spad{integralBasis(p)} returns a record
++ \spad{[basis,basisDen,basisInv]} containing information regarding
++ the local integral closure of R at the prime \spad{p} in the quotient
++ field of F, where F is a framed algebra with R-module basis
++ \spad{w1,w2,...,wn}.
++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
++ the \spad{i}th element of the local integral basis is
++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, the
++ \spad{i}th row of \spad{basis} contains the coordinates of the
++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
++ \spad{wi = sum(bij * vj, j = 1..n)}.
CODE ==> add
import IntegralBasisTools(R, UP, F)
import ModularHermitianRowReduction(R)
import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
import DistinctDegreeFactorize(K,R)
listSquaredFactors: R -> List R
listSquaredFactors px ==
-- returns a list of the factors of px which occur with
-- exponent > 1
ans : List R := empty()
factored := factor(px)$DistinctDegreeFactorize(K,R)
for f in factors(factored) repeat
if f.exponent > 1 then ans := concat(f.factor,ans)
ans
iLocalIntegralBasis: (Vector F,Vector F,Matrix R,Matrix R,R,R) -> IResult
iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime) ==
n := rank()$F; standardBasis := basis()$F
-- 'standardBasis' is the basis for F as a FramedAlgebra;
-- usually this is [1,y,y**2,...,y**(n-1)]
p2 := prime * prime; sae := SAE(K,R,prime)
p := characteristic()$F; q := size()$sae
lp := leastPower(q,n)
rb := scalarMatrix(n,1); rbinv := scalarMatrix(n,1)
-- rb = basis matrix of current order
-- rbinv = inverse basis matrix of current order
-- these are wrt the orginal basis for F
rbden : R := 1; index : R := 1; oldIndex : R := 1
-- rbden = denominator for current basis matrix
-- index = index of original order in current order
repeat
-- pows = [(w1 * rbden) ** q,...,(wn * rbden) ** q], where
-- bas = [w1,...,wn] is 'rbden' times the basis for the order B = 'rb'
for i in 1..n repeat
bi : F := 0
for j in 1..n repeat
bi := bi + qelt(rb,i,j) * qelt(standardBasis,j)
qsetelt_!(bas,i,bi)
qsetelt_!(pows,i,bi ** p)
coor0 := transpose coordinates(pows,bas)
denPow := rbden ** ((p - 1) :: NNI)
(coMat0 := coor0 exquo denPow) case "failed" =>
error "can't happen"
-- the jth column of coMat contains the coordinates of (wj/rbden)**q
-- with respect to the basis [w1/rbden,...,wn/rbden]
coMat := coMat0 :: Matrix R
-- the ith column of 'pPows' contains the coordinates of the pth power
-- of the ith basis element for B/prime.B over 'sae' = R/prime.R
pPows := map(reduce,coMat)$MatrixCategoryFunctions2(R,Vector R,
Vector R,Matrix R,sae,Vector sae,Vector sae,Matrix sae)
-- 'frob' will eventually be the Frobenius matrix for B/prime.B over
-- 'sae' = R/prime.R; at each stage of the loop the ith column will
-- contain the coordinates of p^k-th powers of the ith basis element
frob := copy pPows; tmpMat : Matrix sae := new(n,n,0)
for r in 2..leastPower(p,q) repeat
for i in 1..n repeat for j in 1..n repeat
qsetelt_!(tmpMat,i,j,qelt(frob,i,j) ** p)
times_!(frob,pPows,tmpMat)$MATSTOR(sae)
frobPow := frob ** lp
-- compute the p-radical
ns := nullSpace frobPow
for i in 1..n repeat for j in 1..n repeat qsetelt_!(tfm,i,j,0)
for vec in ns for i in 1.. repeat
for j in 1..n repeat
qsetelt_!(tfm,i,j,lift qelt(vec,j))
id := squareTop rowEchelon(tfm,prime)
-- id = basis matrix of the p-radical
idinv := UpTriBddDenomInv(id, prime)
-- id * idinv = prime * identity
-- no need to check for inseparability in this case
rbinv := idealiser(id * rb, rbinv * idinv, prime * rbden)
index := diagonalProduct rbinv
rb := rowEchelon LowTriBddDenomInv(rbinv,rbden * prime)
if divideIfCan_!(rb,matrixOut,prime,n) = 1
then rb := matrixOut
else rbden := rbden * prime
rbinv := UpTriBddDenomInv(rb,rbden)
indexChange := index quo oldIndex
oldIndex := index
disc := disc quo (indexChange * indexChange)
(not sizeLess?(1,indexChange)) or ((disc exquo p2) case "failed") =>
return [rb, rbden, rbinv, disc]
integralBasis() ==
traceMat := traceMatrix()$F; n := rank()$F
disc := determinant traceMat -- discriminant of current order
zero? disc => error "integralBasis: polynomial must be separable"
singList := listSquaredFactors disc -- singularities of relative Spec
runningRb := scalarMatrix(n,1); runningRbinv := scalarMatrix(n,1)
-- runningRb = basis matrix of current order
-- runningRbinv = inverse basis matrix of current order
-- these are wrt the original basis for F
runningRbden : R := 1
-- runningRbden = denominator for current basis matrix
empty? singList => [runningRb, runningRbden, runningRbinv]
bas : Vector F := new(n,0); pows : Vector F := new(n,0)
-- storage for basis elements and their powers
tfm : Matrix R := new(n,n,0)
-- 'tfm' will contain the coordinates of a lifting of the kernel
-- of a power of Frobenius
matrixOut : Matrix R := new(n,n,0)
for prime in singList repeat
lb := iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime)
rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
disc := lb.discr
-- update 'running integral basis' if newly computed
-- local integral basis is non-trivial
if sizeLess?(1,rbden) then
mat := vertConcat(rbden * runningRb,runningRbden * rb)
runningRbden := runningRbden * rbden
runningRb := squareTop rowEchelon(mat,runningRbden)
runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
[runningRb, runningRbden, runningRbinv]
localIntegralBasis prime ==
traceMat := traceMatrix()$F; n := rank()$F
disc := determinant traceMat -- discriminant of current order
zero? disc => error "localIntegralBasis: polynomial must be separable"
(disc exquo (prime * prime)) case "failed" =>
[scalarMatrix(n,1), 1, scalarMatrix(n,1)]
bas : Vector F := new(n,0); pows : Vector F := new(n,0)
-- storage for basis elements and their powers
tfm : Matrix R := new(n,n,0)
-- 'tfm' will contain the coordinates of a lifting of the kernel
-- of a power of Frobenius
matrixOut : Matrix R := new(n,n,0)
lb := iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime)
[lb.basis, lb.basisDen, lb.basisInv]
|