This file is indexed.

/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]