Documentation

HexRealRootsMathlib.SturmChainDefs

noncomputable def Sturm.countSignChanges :

Count the sign changes of a real list: the number of adjacent pairs whose product is negative. Callers first drop the zero entries (see Sturm.signVariations), so on a zero-free list this is exactly the number of adjacent opposite-sign pairs.

Equations
Instances For
    theorem Sturm.countSignChanges_cons_cons (a b : ) (rest : List ) :
    countSignChanges (a :: b :: rest) = (if a * b < 0 then 1 else 0) + countSignChanges (b :: rest)
    noncomputable def Sturm.signVariations (l : List ) :

    Zero-skipping sign variations of a real list: drop the zeros, then count the adjacent opposite-sign pairs. This is the variation count that both the pointwise chain evaluations and the leading-coefficient signs at ±∞ feed into.

    Equations
    Instances For
      @[simp]

      Prepending a zero entry does not change the sign variations.

      theorem Sturm.signVariations_cons_ne (a : ) (l : List ) (ha : a 0) :
      signVariations (a :: l) = countSignChanges (a :: List.filter (fun (v : ) => decide (v 0)) l)

      A nonzero first entry survives removal of zero entries.

      noncomputable def Sturm.sturmVar (chain : List (Polynomial )) (x : ) :

      Zero-skipping sign variations of the chain chain evaluated at x: the sign variations of the list of evaluations chain.map (·.eval x).

      Equations
      Instances For
        @[simp]
        theorem Sturm.sturmVar_nil (x : ) :
        theorem Sturm.sturmVar_cons_zero {q : Polynomial } {x : } (h : Polynomial.eval x q = 0) (chain : List (Polynomial )) :
        sturmVar (q :: chain) x = sturmVar chain x

        A chain element that vanishes at x contributes no variation at x: sturmVar ignores it.

        theorem Sturm.countSignChanges_congr {l₁ l₂ : List } (h : List.Forall₂ (fun (u v : ) => SignType.sign u = SignType.sign v) l₁ l₂) :

        Two real lists whose entries have pointwise equal signs have equal countSignChanges: the sign-change count reads only the signs of the entries.

        theorem Sturm.signVariations_congr {l₁ l₂ : List } (h : List.Forall₂ (fun (u v : ) => SignType.sign u = SignType.sign v) l₁ l₂) :

        signVariations reads only the signs of the entries: two real lists whose entries are pointwise sign-equal have equal sign variations.

        noncomputable def Sturm.firstSign (l : List ) :

        The sign of the first nonzero entry of a real list, or 0 if every entry is zero.

        Equations
        Instances For
          @[simp]
          theorem Sturm.firstSign_cons_ne {a : } (l : List ) (ha : a 0) :

          Prepending a nonzero entry a adds one variation exactly when its sign is opposite the sign of the next surviving entry.

          noncomputable def Sturm.sturmVarPosInf (chain : List (Polynomial )) :

          Sign variations of the chain at +∞: the sign of each element there is the sign of its leading coefficient, so this is the zero-skipping variation count of the leading coefficients. The zero polynomial contributes leading coefficient 0, which the zero-skipping convention drops.

          Equations
          Instances For
            noncomputable def Sturm.sturmVarNegInf (chain : List (Polynomial )) :

            Sign variations of the chain at −∞: the sign of an element there is the sign of its leading coefficient times (-1) ^ degree, so this is the zero-skipping variation count of leadingCoeff · (-1) ^ natDegree.

            Equations
            Instances For
              structure Sturm.IsSturmChain (p : Polynomial ) (chain : List (Polynomial )) :

              A generalized Sturm chain for a real polynomial.

              At a root of the first polynomial, the product of the first two entries changes from negative to positive. At a root of an interior entry, its neighbors have opposite signs. The last entry has no real roots, and every entry is nonzero.

              These conditions allow the one-element chain of a nonzero constant polynomial.

              Instances For
                theorem Sturm.IsSturmChain.nonempty {p : Polynomial } {chain : List (Polynomial )} (h : IsSturmChain p chain) :
                chain []

                A Sturm chain is nonempty.

                theorem Sturm.IsSturmChain.head_mem {p : Polynomial } {chain : List (Polynomial )} (h : IsSturmChain p chain) :
                p chain

                The polynomial counted by a Sturm chain is its first entry.

                theorem Sturm.IsSturmChain.ne_zero {p : Polynomial } {chain : List (Polynomial )} (h : IsSturmChain p chain) :
                p 0

                A polynomial admitting a Sturm chain is nonzero.