axiom-developer
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Axiom-developer] CAD package from Renaud Rioboo


From: daly
Subject: [Axiom-developer] CAD package from Renaud Rioboo
Date: Sun, 7 Sep 2014 22:36:53 -0500

Waldek,

Here is Renaud's CAD package for your new release.

Tim

=======================================================================
)ab pack CADU CylindricalAlgebraicDecompositionUtilities

CylindricalAlgebraicDecompositionUtilities(R,P) : PUB == PRIV where

-- Tese are some standard tools which are needed to compute with univariate
-- polynomials. 
--
-- A gcd basis for a set of polynomials is a set of pairwise relatively prime 
-- polynomials which all divide the original set and whose product is the
-- same than the product of the original set.
--
-- A square free basis for a list of polynomials is just a list
-- of square free polynomials which are pairwise relatively primes and have
-- the same roots than the original polynomials.

  R : GcdDomain
  P : UnivariatePolynomialCategory(R)

  PUB == with
      squareFreeBasis : List(P) -> List(P)
        ++ 
      gcdBasis : List(P) -> List(P)
        ++ decompose a list of polynomials into pairwise relatively 
        ++ prime polynomials
      gcdBasisAdd : (P,List(P)) -> List(P)
        ++ add one polynomial to list of pairwise relatively prime polynomials

  PRIV == add

     squareFreeBasis(lpols) ==
       lpols = [] => []
       pol := first(lpols)
       sqpol := unitCanonical(squareFreePart(pol))
       gcdBasis(cons(sqpol,squareFreeBasis(rest(lpols))))
         
     gcdBasisAdd(p,lpols) ==
       (degree(p) = 0) => lpols
       null lpols => [unitCanonical p]
       p1 := first(lpols)
       g := gcd(p,p1)
       (degree(g) = 0) => cons(p1,gcdBasisAdd(p,rest lpols))
       p := (p exquo g)::P
       p1 := (p1 exquo g)::P
       basis := gcdBasisAdd(p,rest(lpols))
       if degree(p1) > 0 then basis := cons(p1,basis)
       gcdBasisAdd(g,basis)
       

     gcdBasis(lpols) ==
       (#lpols <= 1) => lpols
       basis := gcdBasis(rest lpols)
       gcdBasisAdd(first(lpols),basis)

)ab domain SCELL SimpleCell

-- This domain is made to work with one-dimensional semi-algebraic cells
-- ie either an algebraic point, either an interval. The point is specified as 
-- specification of an algebraic value.

SimpleCell(TheField,ThePols) : PUB == PRIV where
  TheField : RealClosedField
  ThePols : UnivariatePolynomialCategory(TheField)
  O           ==> OutputForm
  B           ==> Boolean
  Z           ==> Integer
  N           ==> NonNegativeInteger

--  VARS ==> VariationsPackage(TheField,ThePols)
  VARS ==> RealPolynomialUtilitiesPackage(TheField,ThePols)
  LF ==> List(TheField)

  PUB == CoercibleTo(O) with

     allSimpleCells : (ThePols,Symbol) -> List %
     allSimpleCells : (List(ThePols),Symbol) -> List %
     hasDimension? : % -> B
     samplePoint : % -> TheField
     stablePol : % -> ThePols
     variableOf : % -> Symbol
     separe : (LF,TheField,TheField) -> LF
     pointToCell : (TheField,B,Symbol) -> %

  PRIV == add

     Rep := Record(samplePoint:TheField,
                   hasDim:B,
                   varOf:Symbol)

     samplePoint(c) == c.samplePoint

     stablePol(c) == error "Prout"

     hasDimension?(c) == c.hasDim

     variableOf(c) == c.varOf

     coerce(c:%):O ==
       o : O := ((c.varOf)::O) = ((c.samplePoint)::O)
       brace [o,(c.hasDim)::O]

     separe(liste,gauche,droite) ==
       milieu : TheField := (gauche + droite) / (2::TheField)
       liste = [] => [milieu]
       #liste = 1 => [gauche,first(liste),droite]
       nbe := first(liste)
       lg :List(TheField) := []
       ld :List(TheField) := rest(liste)
       sg := sign(milieu-nbe)
       while sg > 0 repeat
         lg := cons(nbe,lg)
         ld = [] => return(separe(reverse(lg),gauche,milieu))
         nbe := first(ld)
         sg := sign(milieu-nbe)
         ld := rest(ld)
       sg < 0 =>
         append(separe(reverse(lg),gauche,milieu),
                rest(separe(cons(nbe,ld),milieu,droite)))
       newDroite := (gauche+milieu)/(2::TheField)
       null lg =>
           newGauche := (milieu+droite)/(2::TheField)
           while newGauche >= first(ld) repeat
             newGauche := (milieu+newGauche)/(2::TheField)
           append([gauche,milieu],separe(ld,newGauche,droite))
       while newDroite <= first(lg) repeat
         newDroite := (newDroite+milieu)/(2::TheField)
       newGauche := (milieu+droite)/(2::TheField)
       null ld => append(separe(reverse(lg),gauche,newDroite),[milieu,droite])
       while newGauche >= first(ld) repeat
         newGauche := (milieu+newGauche)/(2::TheField)
       append(separe(reverse(lg),gauche,newDroite),
              cons(milieu,separe(ld,newGauche,droite)))

     pointToCell(sp,hasDim?,varName) ==
       [sp,hasDim?,varName]$Rep

     allSimpleCells(p:ThePols,var:Symbol) ==
       allSimpleCells([p],var)

     PACK ==> CylindricalAlgebraicDecompositionUtilities(TheField,ThePols)
     allSimpleCells(lp:List(ThePols),var:Symbol) ==
       lp1 := gcdBasis(lp)$PACK
       null(lp1) => [pointToCell(0,true,var)]
       b := ("max" / [ boundOfCauchy(p)$VARS for p in lp1 ])::TheField
       l := "append" / [allRootsOf(makeSUP(unitCanonical(p))) for p in lp1]
       l := sort(l)
       l1 := separe(l,-b,b)
       res : List(%) := [pointToCell(first(l1),true,var)]
       l1 := rest(l1)
       while not(null(l1)) repeat
         res := cons(pointToCell(first(l1),false,var),res)
         l1 := rest(l1)
         l1 = [] => return(error "Liste vide")
         res := cons(pointToCell(first(l1),true,var),res)
         l1 := rest(l1)
       reverse! res

)ab domain CELL Cell

Cell(TheField) : PUB == PRIV where
  TheField : RealClosedField

  ThePols ==> Polynomial(TheField)

  O           ==> OutputForm
  B           ==> Boolean
  Z           ==> Integer
  N           ==> NonNegativeInteger
  BUP         ==> SparseUnivariatePolynomial(TheField)
  SCELL       ==> SimpleCell(TheField,BUP)


  PUB == CoercibleTo(O) with

     samplePoint : % -> List(TheField)
     dimension : % -> N
     hasDimension? :  (%,Symbol) -> B
     makeCell : List(SCELL) -> %
     makeCell : (SCELL,%) -> %
     mainVariableOf : % -> Symbol
     variablesOf : % -> List Symbol
     projection : % -> Union(%,"failed")
     


  PRIV == add

    Rep := List(SCELL)

    coerce(c:%):O == 
      paren [sc::O for sc in c]

    projection(cell) ==
      null cell => error "projection: should not appear"
      r := rest(cell)
      null r => "failed"
      r

    makeCell(l:List(SCELL)) == l

    makeCell(scell,toAdd) == cons(scell,toAdd)

    mainVariableOf(cell) == 
      null(cell) => 
        error "Should not appear"
      variableOf(first(cell))

    variablesOf(cell) ==
      null(cell) => []
      cons(mainVariableOf(cell),variablesOf(rest(cell)::%))

    dimension(cell) ==
      null(cell) => 0
      hasDimension?(first(cell)) => 1+dimension(rest(cell))
      dimension(rest(cell))

    hasDimension?(cell,var) ==
      null(cell) => 
        error "Should not appear"
      sc : SCELL := first(cell)
      v := variableOf(sc)
      v = var => hasDimension?(sc)
      v < var => false
      v > var => true
      error "Caca Prout"

    samplePoint(cell) ==
      null(cell) => []
      cons(samplePoint(first(cell)),samplePoint(rest(cell)))

)ab pack CAD CylindricalAlgebraicDecompositionPackage

CylindricalAlgebraicDecompositionPackage(TheField) : PUB == PRIV where

  TheField : RealClosedField

  ThePols ==> Polynomial(TheField)
  P ==> ThePols
  BUP ==> SparseUnivariatePolynomial(TheField)
  RUP ==> SparseUnivariatePolynomial(ThePols)

  Z           ==> Integer
  N           ==> NonNegativeInteger

  CELL ==> Cell(TheField)
  SCELL ==> SimpleCell(TheField,BUP)

  PUB == with

      cylindricalDecomposition: List P ->        List CELL
      cylindricalDecomposition: (List(P),List(Symbol)) ->        List CELL
      projectionSet: (List RUP)                ->    List P
      coefficientSet: RUP                ->    List P
      discriminantSet : List RUP -> List(P)
      resultantSet :  List RUP -> List P 
      principalSubResultantSet : (RUP,RUP) -> List P
      specialise : (List(ThePols),CELL) -> List(BUP)

  PRIV == add

     cylindricalDecomposition(lpols) ==
       lv : List(Symbol) := []
       for pol in lpols repeat
         ground?(pol) => "next pol"
         lv := removeDuplicates(append(variables(pol),lv))
       lv := reverse(sort(lv))
       cylindricalDecomposition(lpols,lv)

     cylindricalDecomposition(lpols,lvars) ==
       lvars = [] => error("CAD: cylindricalDecomposition: empty list of vars")
       mv := first(lvars)
       lv := rest(lvars)
       lv = [] =>
         lp1 := [ univariate(pol) for pol in lpols ]
         scells := allSimpleCells(lp1,mv)$SCELL
         [ makeCell([scell]) for scell in scells ]
       lpols1 := projectionSet [univariate(pol,mv) for pol in lpols]
       previousCad := cylindricalDecomposition(lpols1,lv)
       res : List(CELL) := []
       for cell in previousCad repeat
         lspec := specialise(lpols,cell)
         scells := allSimpleCells(lspec,mv)
         res := append(res,[makeCell(scell,cell) for scell in scells])
       res


     PACK1 ==> CylindricalAlgebraicDecompositionUtilities(ThePols,RUP)
     PACK2 ==> CylindricalAlgebraicDecompositionUtilities(TheField,BUP)

     specialise(lpols,cell) ==
       lpols = [] => error("CAD: specialise: empty list of pols")
       sp := samplePoint(cell)
       vl := variablesOf(cell)
       res : List(BUP) := []
       for pol in lpols repeat
         p1 := univariate(eval(pol,vl,sp))
         degree(p1) = 0 => "next pol"
         res := cons(p1,res)
       res


     coefficientSet(pol) ==
       res : List(ThePols) := []
       for c in coefficients(pol) repeat
         ground?(c) => return(res)
         res := cons(c,res)
       res

     SUBRES ==> SubResultantPackage(ThePols,RUP)
     discriminantSet(lpols) ==
       res : List(ThePols) := []
       for p in lpols repeat
         v := subresultantVector(p,differentiate(p))$SUBRES
         not(zero?(degree(v.0))) => return(error "Bad discriminant")
         d : ThePols :=  leadingCoefficient(v.0)
         zero?(d) => return(error "Non Square Free polynomial")
         if not(ground? d) then res := cons(d,res)
       res

     principalSubResultantSet(p,q) ==
        if degree(p) < degree(q)
        then (p,q) := (q,p)
        if degree(p) = degree(q)
        then (p,q) := (q,pseudoRemainder(p, q))
        v := subresultantVector(p,q)$SUBRES
        [coefficient(v.i,i) for i in 0..(((#v)-2)::N)]

     resultantSet(lpols) ==
       res : List(ThePols) := []
       laux := lpols
       for p in lpols repeat
         laux := rest(laux)
         for q in laux repeat
           r : ThePols :=  first(principalSubResultantSet(p,q))
           zero?(r) => return(error "Non relatively prime polynomials")
           if not(ground? r) then res := cons(r,res)
       res

     projectionSet(lpols) ==
       res : List(ThePols) := []
       for p in lpols repeat
         c := content(p)
         ground?(c) => "next p"
         res := cons(c,res)
       lp1 := [primitivePart p for p in lpols]
       f : ((RUP,RUP) -> Boolean) := (degree(#1) <= degree(#2))
       lp1 := sort(f,lp1)
       lsqfrb := squareFreeBasis(lp1)$PACK1
       lsqfrb := sort(f,lsqfrb)
       for p in lp1 repeat
         res := append(res,coefficientSet(p))
       res := append(res,discriminantSet(lsqfrb))
       append(res,resultantSet(lsqfrb))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]