Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

build open-axiom

54510 views
)abbrev category ACF AlgebraicallyClosedField
++ Author: Manuel Bronstein
++ Date Created: 22 Mar 1988
++ Date Last Updated: 27 November 1991
++ Description:
++   Model for algebraically closed fields.
++ Keywords: algebraic, closure, field.

AlgebraicallyClosedField(): Category == Join(Field,RadicalCategory) with
    rootOf: Polynomial $ -> $
      ++ rootOf(p) returns y such that \spad{p(y) = 0}.
      ++ Error: if p has more than one variable y.
    rootOf: SparseUnivariatePolynomial $ -> $
      ++ rootOf(p) returns y such that \spad{p(y) = 0}.
    rootOf: (SparseUnivariatePolynomial $, Symbol) -> $
      ++ rootOf(p, y) returns y such that \spad{p(y) = 0}.
      ++ The object returned displays as \spad{'y}.
    rootsOf: Polynomial $ -> List $
      ++ rootsOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
      ++ Note: the returned symbols y1,...,yn are bound in the
      ++ interpreter to respective root values.
      ++ Error: if p has more than one variable y.
    rootsOf: SparseUnivariatePolynomial $ -> List $
      ++ rootsOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
      ++ Note: the returned symbols y1,...,yn are bound in the interpreter
      ++ to respective root values.
    rootsOf: (SparseUnivariatePolynomial $, Symbol) -> List $
      ++ rootsOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0};
      ++ The returned roots display as \spad{'y1},...,\spad{'yn}.
      ++ Note: the returned symbols y1,...,yn are bound in the interpreter
      ++ to respective root values.
    zeroOf: Polynomial $ -> $
      ++ zeroOf(p) returns y such that \spad{p(y) = 0}.
      ++ If possible, y is expressed in terms of radicals.
      ++ Otherwise it is an implicit algebraic quantity.
      ++ Error: if p has more than one variable y.
    zeroOf: SparseUnivariatePolynomial $ -> $
      ++ zeroOf(p) returns y such that \spad{p(y) = 0};
      ++ if possible, y is expressed in terms of radicals.
      ++ Otherwise it is an implicit algebraic quantity.
    zeroOf: (SparseUnivariatePolynomial $, Symbol) -> $
      ++ zeroOf(p, y) returns y such that \spad{p(y) = 0};
      ++ if possible, y is expressed in terms of radicals.
      ++ Otherwise it is an implicit algebraic quantity which
      ++ displays as \spad{'y}.
    zerosOf: Polynomial $ -> List $
      ++ zerosOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
      ++ The yi's are expressed in radicals if possible.
      ++ Otherwise they are implicit algebraic quantities.
      ++ The returned symbols y1,...,yn are bound in the interpreter
      ++ to respective root values.
      ++ Error: if p has more than one variable y.
    zerosOf: SparseUnivariatePolynomial $ -> List $
      ++ zerosOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
      ++ The yi's are expressed in radicals if possible, and otherwise
      ++ as implicit algebraic quantities.
      ++ The returned symbols y1,...,yn are bound in the interpreter
      ++ to respective root values.
    zerosOf: (SparseUnivariatePolynomial $, Symbol) -> List $
      ++ zerosOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
      ++ The yi's are expressed in radicals if possible, and otherwise
      ++ as implicit algebraic quantities
      ++ which display as \spad{'yi}.
      ++ The returned symbols y1,...,yn are bound in the interpreter
      ++ to respective root values.
 add
    SUP ==> SparseUnivariatePolynomial $

    assign  : (Symbol, $) -> $
    allroots: (SUP, Symbol, (SUP, Symbol) -> $) -> List $
    binomialRoots: (SUP, Symbol, (SUP, Symbol) -> $) -> List $

    zeroOf(p:SUP)            == assign(x := new(), zeroOf(p, x))
    rootOf(p:SUP)            == assign(x := new(), rootOf(p, x))
    zerosOf(p:SUP)           == zerosOf(p, new())
    rootsOf(p:SUP)           == rootsOf(p, new())
    rootsOf(p:SUP, y:Symbol) == allroots(p, y, rootOf)
    zerosOf(p:SUP, y:Symbol) == allroots(p, y, zeroOf)
    assign(x, f)             ==
      assignSymbol(x, f, $)$Foreign(Builtin)
      f

    zeroOf(p:Polynomial $) ==
      empty?(l := variables p) => error "zeroOf: constant polynomial"
      zeroOf(univariate p, first l)

    rootOf(p:Polynomial $) ==
      empty?(l := variables p) => error "rootOf: constant polynomial"
      rootOf(univariate p, first l)

    zerosOf(p:Polynomial $) ==
      empty?(l := variables p) => error "zerosOf: constant polynomial"
      zerosOf(univariate p, first l)

    rootsOf(p:Polynomial $) ==
      empty?(l := variables p) => error "rootsOf: constant polynomial"
      rootsOf(univariate p, first l)

    zeroOf(p:SUP, y:Symbol) ==
      zero?(d := degree p) => error "zeroOf: constant polynomial"
      zero? coefficient(p, 0) => 0
      a := leadingCoefficient p
      d = 2 =>
        b := coefficient(p, 1)
        (sqrt(b**2 - 4 * a * coefficient(p, 0)) - b) / (2 * a)
      (r := retractIfCan(reductum p)@Union($,"failed")) case "failed" =>
        rootOf(p, y)
      nthRoot(- (r::$ / a), d)

    binomialRoots(p, y, fn) ==
     -- p = a * x**n + b
      alpha := assign(x := new(y)$Symbol, fn(p, x))
      one?(n := degree p) =>  [ alpha ]
      cyclo := cyclotomic(n, monomial(1,1)$SUP)$NumberTheoreticPolynomialFunctions(SUP)
      beta := assign(x := new(y)$Symbol, fn(cyclo, x))
      [alpha*beta**i for i in 0..(n-1)::NonNegativeInteger]

    import PolynomialDecomposition(SUP,$)

    allroots(p, y, fn) ==
      zero? p => error "allroots: polynomial must be nonzero"
      zero? coefficient(p,0) =>
         concat(0, allroots(p quo monomial(1,1), y, fn))
      zero?(p1:=reductum p) => empty()
      zero? reductum p1 => binomialRoots(p, y, fn)
      decompList := decompose(p)
      # decompList > 1 =>
          h := last decompList
          g := leftFactor(p,h) :: SUP
          groots := allroots(g, y, fn)
          "append"/[allroots(h-r::SUP, y, fn) for r in groots]
      ans := nil()$List($)
      while not ground? p repeat
        alpha := assign(x := new(y)$Symbol, fn(p, x))
        q     := monomial(1, 1)$SUP - alpha::SUP
        if not zero?(p alpha) then
          p   := p quo q
          ans := concat(alpha, ans)
        else while zero?(p alpha) repeat
          p   := (p exquo q)::SUP
          ans := concat(alpha, ans)
      reverse! ans