1-- Passage to the leading direction at a squared-norm minimum.2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Complex.MinimumDirection8import Descent910def complexDotSequence (z u : Set) : Set:= addSequence(11 mulSequence(constantSequence(Euclidean.x(z)), complexSequenceX(u)),12 mulSequence(constantSequence(Euclidean.y(z)), complexSequenceY(u)))1314def normalizedNormSequence (z s u : Set) : Set:= addSequence(15 mulSequence(constantSequence((2:R)), complexDotSequence(z, u)),16 mulSequence(s, complexNormSequence(u)))1718section Complexes19notationring ℂ := (complexCarrier, complexAdd, complexZero, complexNeg, complexMul, complexOne)20notationring R := (ℝ, realAdd, realZero, realNeg, realMul, realOne)2122theorem complexDotSequence.sequence (z u : Set)23requires member : z ∈ ℂ24requires sequence : ComplexSequence(u)25shows RealSequence(complexDotSequence(z, u))26proof27have point := complex.point with*28have cx := constantSequence.sequence at Euclidean.x(z) with*29have cy := constantSequence.sequence at Euclidean.y(z) with*30have ux := complexSequenceX.sequence with*31have uy := complexSequenceY.sequence with*32have xx := mulSequence.sequence at constantSequence(Euclidean.x(z)), complexSequenceX(u) with*33have yy := mulSequence.sequence at constantSequence(Euclidean.y(z)), complexSequenceY(u) with*34unfold complexDotSequence35exact addSequence.sequence with*3637theorem complexDotSequence.value (z u : Set) (n : Nat)38requires member : z ∈ ℂ39requires sequence : ComplexSequence(u)40shows complexDotSequence(z, u)(n) = Euclidean.dot(z, u(n))41proof42have point := complex.point with*43have cx := constantSequence.sequence at Euclidean.x(z) with*44have cy := constantSequence.sequence at Euclidean.y(z) with*45have ux := complexSequenceX.sequence with*46have uy := complexSequenceY.sequence with*47have xx := mulSequence.sequence at constantSequence(Euclidean.x(z)), complexSequenceX(u) with*48have yy := mulSequence.sequence at constantSequence(Euclidean.y(z)), complexSequenceY(u) with*49have cxn := RealSequence.value at constantSequence(Euclidean.x(z)), n with*50have cyn := RealSequence.value at constantSequence(Euclidean.y(z)), n with*51have uxn := RealSequence.value at complexSequenceX(u), n with*52have uyn := RealSequence.value at complexSequenceY(u), n with*53have xxn := RealSequence.value at mulSequence(constantSequence(Euclidean.x(z)), complexSequenceX(u)), n with*54have yyn := RealSequence.value at mulSequence(constantSequence(Euclidean.y(z)), complexSequenceY(u)), n with*55unfold complexDotSequence56rw [addSequence.value, mulSequence.value, mulSequence.value, constantSequence.value, constantSequence.value, complexSequenceX.value, complexSequenceY.value]57unfold Euclidean.dot58rfl5960theorem ComplexConvergesTo.dot (z u a : Set)61requires member : z ∈ ℂ62requires converges : ComplexConvergesTo(u, a)63shows ConvergesTo(complexDotSequence(z, u), Euclidean.dot(z, a))64proof65obtain⟨sequence, center, horizontal, vertical⟩:= converges66have pointZ := complex.point at z with*67have pointA := complex.point at a with*68have cx := constantSequence.converges at Euclidean.x(z) with*69have cy := constantSequence.converges at Euclidean.y(z) with*70have xx := ConvergesTo.mul at constantSequence(Euclidean.x(z)), complexSequenceX(u), Euclidean.x(z), Euclidean.x(a) with*71have yy := ConvergesTo.mul at constantSequence(Euclidean.y(z)), complexSequenceY(u), Euclidean.y(z), Euclidean.y(a) with*72have sum := ConvergesTo.add at mulSequence(constantSequence(Euclidean.x(z)), complexSequenceX(u)), mulSequence(constantSequence(Euclidean.y(z)), complexSequenceY(u)), R[Euclidean.x(z) * Euclidean.x(a)], R[Euclidean.y(z) * Euclidean.y(a)] with*73unfold complexDotSequence74unfold Euclidean.dot75exact sum7677-- Cancel a positive step from the exact squared-norm expansion.78theorem complexNormSquared.minimum_step (z w : Set) (t : Real)79requires first : z ∈ ℂ80requires second : w ∈ ℂ81requires positive : realZero < t82requires minimum : complexNormSquared(z) ≤ complexNormSquared(ℂ[z + complexScale(t, w)])83shows realZero ≤ R[2* Euclidean.dot(z, w) + t * complexNormSquared(w)]84proof85have pointZ := complex.point at z with*86have pointW := complex.point at w with*87have identity := complexNormSquared.perturbation at z, complexScale(t, w) with*88rw [complexScale.dot_right, complexNormSquared.scale] at identity89rw identity at minimum90have shifted := realLe.add_right at complexNormSquared(z), R[complexNormSquared(z) +2* (t * Euclidean.dot(z, w)) + t * t * complexNormSquared(w)], R[-complexNormSquared(z)] with*91haveleft : R[complexNormSquared(z) + -complexNormSquared(z)] = R[0* t] byring92haveright : R[(complexNormSquared(z) +2* (t * Euclidean.dot(z, w)) + t * t * complexNormSquared(w)) + -complexNormSquared(z)] = R[(2* Euclidean.dot(z, w) + t * complexNormSquared(w)) * t]93ring94rw [left, right] at shifted95exact realLe.mul_right_cancel_positive at realZero, R[2* Euclidean.dot(z, w) + t * complexNormSquared(w)], t with*9697theorem normalizedNormSequence.converges (z s u a : Set)98requires member : z ∈ ℂ99requires steps : ConvergesTo(s, realZero)100requires directions : ComplexConvergesTo(u, a)101shows ConvergesTo(normalizedNormSequence(z, s, u), R[2* Euclidean.dot(z, a)])102proof103have center : a ∈ ℂ104obtain⟨sequence, center, horizontal, vertical⟩:= directions105exact center106have pointZ := complex.point at z with*107have pointA := complex.point at a with*108have two := constantSequence.converges at R[2] with*109have dot := ComplexConvergesTo.dot at z, u, a with*110have norm := ComplexConvergesTo.norm_squared with*111have linear := ConvergesTo.mul at constantSequence(R[2]), complexDotSequence(z, u), R[2], Euclidean.dot(z, a) with*112have quadratic := ConvergesTo.mul at s, complexNormSequence(u), realZero, complexNormSquared(a) with*113have sum := ConvergesTo.add at mulSequence(constantSequence(R[2]), complexDotSequence(z, u)), mulSequence(s, complexNormSequence(u)), R[2* Euclidean.dot(z, a)], R[0* complexNormSquared(a)] with*114rw [realMulValue.zero_left, realAddValue.zero_right] at sum115unfold normalizedNormSequence116exact sum117118theorem normalizedNormSequence.value (z s u : Set) (n : Nat)119requires member : z ∈ ℂ120requires steps : RealSequence(s)121requires directions : ComplexSequence(u)122shows normalizedNormSequence(z, s, u)(n) = R[2* Euclidean.dot(z, u(n)) + s(n) * complexNormSquared(u(n))]123proof124have two := constantSequence.sequence at R[2] with*125have dot := complexDotSequence.sequence with*126have norm : RealSequence(complexNormSequence(u))127unfold RealSequence128exact complexNormSequence.function with*129have linear := mulSequence.sequence at constantSequence(R[2]), complexDotSequence(z, u) with*130have quadratic := mulSequence.sequence at s, complexNormSequence(u) with*131have tn := RealSequence.value at constantSequence(R[2]), n with*132have dn := RealSequence.value at complexDotSequence(z, u), n with*133have sn := RealSequence.value at s, n with*134have nn := RealSequence.value at complexNormSequence(u), n with*135have ln := RealSequence.value at mulSequence(constantSequence(R[2]), complexDotSequence(z, u)), n with*136have qn := RealSequence.value at mulSequence(s, complexNormSequence(u)), n with*137unfold normalizedNormSequence138rw [addSequence.value, mulSequence.value, mulSequence.value, constantSequence.value, complexDotSequence.value, complexNormSequence.value]139rfl140141-- Varying directions are allowed: their limit controls the first-order sign.142theorem complexNormSquared.minimum_direction (z s u a : Set)143requires member : z ∈ ℂ144requires steps : ConvergesTo(s, realZero)145requires directions : ComplexConvergesTo(u, a)146requires positive : ∀ n ∈ ℕ, realZero < s(n)147requires minimum : ∀ n ∈ ℕ, complexNormSquared(z) ≤ complexNormSquared(ℂ[z + complexScale(s(n), u(n))])148shows realZero ≤ Euclidean.dot(z, a)149proof150have limit := normalizedNormSequence.converges with*151have stepSequence := ConvergesTo.sequence at s, realZero with*152obtain⟨sequence, center, horizontal, vertical⟩:= directions153have function : u : ℕ → ℂ byexact sequence154have pointZ := complex.point at z with*155have pointA := complex.point at a with*156have nonnegative : NonnegativeTerms(normalizedNormSequence(z, s, u))157intros n nIn158have nNat := nat.omega.backward at n with*159have sn := RealSequence.value with*160have un := FunctionBetween.apply_closed with*161have stepPositive := positive with n, nIn162have least := minimum with n, nIn163rw normalizedNormSequence.value164have bound := complexNormSquared.minimum_step with*165exact realLe.characterization.forward with bound166have doubled := ConvergesTo.nonnegative_of_nonnegative_terms with*167have twoPositive : (0:R) < 2bylinarith168haveleft : realZero = R[0*2] byring169haveright : R[2* Euclidean.dot(z, a)] = R[Euclidean.dot(z, a) *2] byring170rw [left, right] at doubled171exact realLe.mul_right_cancel_positive with*172173end Complexes174