1-- Block sums of a family of cube functions: continuity, nonnegativity, the2-- bound of a sum by any of its terms, sums of vanishing terms, and how the3-- block sum of a point changes when a common real shift is scaled4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.FixedPoint.WeightedSums10import BlockSums1112-- Sums over the first m coordinates of S of the values W(i)(x).13defgraph prefixWeighted (n S W m : Set) (x ∈ unitCube(n)) : ℝ := realPartialSum(maskedPoint(n, S, assembledPoint(n, W, x)), m)14requires nNat : Nat(n)15requires mNat : Nat(m)16requires functions : ∀ i ∈ n, CubeFunction(W(i), n)17proof18have values := assembledPoint.function at n, W, x with functions, member19have sequence := maskedPoint.sequence at n, S, assembledPoint(n, W, x) with values20exact realPartialSum.real at maskedPoint(n, S, assembledPoint(n, W, x)), m with sequence2122theorem prefixWeighted.continuous (n : Nat) (S W : Set) (m : Nat)23requires family : ∀ i ∈ n, CubeFunctionContinuous(W(i), n)24shows m ∈ succ(n) → CubeFunctionContinuous(prefixWeighted(n, S, W, m), n)25proof26induction m27| zero =>28intro hm29have functions : ∀ i ∈ n, CubeFunction(W(i), n)30intros i hi31exact CubeFunctionContinuous.function with (family with hi)32have zeroIn : (0:R) ∈ ℝ bytypecheck33have constant := constantCube.continuous at n, (0:R) with zeroIn34have function : CubeFunction(prefixWeighted(n, S, W, 0), n)35exact prefixWeighted.function at n, S, W, 0with*36apply CubeFunctionContinuous.congr with function, constant37intros x hx38have value := prefixWeighted.value at n, S, W, 0, x with*39have constantValue := constantFunction.apply at unitCube(n), ℝ, x, (0:R) with hx, zeroIn40rw [value, constantValue]41exact realPartialSum.zero at maskedPoint(n, S, assembledPoint(n, W, x))42| succ(j) using ih =>43intro hm44have functions : ∀ i ∈ n, CubeFunction(W(i), n)45intros i hi46exact CubeFunctionContinuous.function with (family with hi)47have jNat : Nat(j) bytypecheck48have jIn : j ∈ succ(n)49have less := Less.of_membership with hm50have below : j < succ(n) byarith51exact membership.of_Less with below52have jInN : j ∈ n53have less := Less.of_membership with hm54have below : j < n byarith55exact membership.of_Less with below56have previous := ih with jIn57have weightNat := indicator.natural at S, j58have weightReal := realNat.real at indicator(S, j)59have weightIn : (realNat(indicator(S, j)):R) ∈ ℝ bytypecheck60have constant := constantCube.continuous at n, (realNat(indicator(S, j)):R) with weightIn61have component := family with jInN62have term := mulCube.continuous with constant, component63have total := addCube.continuous with previous, term64have function : CubeFunction(prefixWeighted(n, S, W, succ(j)), n)65exact prefixWeighted.function at n, S, W, succ(j) with*66apply CubeFunctionContinuous.congr with function, total67intros x hx68have values := assembledPoint.function at n, W, x with functions, hx69have previousFunction := CubeFunctionContinuous.function with previous70have termFunction := CubeFunctionContinuous.function with term71have constantFunction2 := CubeFunctionContinuous.function with constant72have componentFunction := CubeFunctionContinuous.function with component73have value := prefixWeighted.value at n, S, W, succ(j), x with*74have previousValue := prefixWeighted.value at n, S, W, j, x with*75have sumValue := addCube.value at n, prefixWeighted(n, S, W, j), mulCube(n, constantFunction(unitCube(n), ℝ, (realNat(indicator(S, j)):R)), W(j)), x with previousFunction, termFunction, hx76have termValue := mulCube.value at n, constantFunction(unitCube(n), ℝ, (realNat(indicator(S, j)):R)), W(j), x with constantFunction2, componentFunction, hx77have constantValue := constantFunction.apply at unitCube(n), ℝ, x, (realNat(indicator(S, j)):R) with hx, weightIn78have componentValue := assembledPoint.value at n, W, x, j with functions, hx, jInN79have step := realPartialSum.succ at maskedPoint(n, S, assembledPoint(n, W, x)), j80have masked := maskedPoint.coordinate at n, S, assembledPoint(n, W, x), j with values, jInN81have sequence := maskedPoint.sequence at n, S, assembledPoint(n, W, x) with values82have componentReal := CubeFunction.value with componentFunction, hx83rw [value, sumValue, previousValue, termValue, constantValue, step, masked, componentValue]84linarith8586-- The block sum of the family over S.87def weightedSum (n S W : Set) : Set:= prefixWeighted(n, S, W, n)8889theorem weightedSum.definition (n S W : Set)90shows weightedSum(n, S, W) = prefixWeighted(n, S, W, n)91proof92unfold weightedSum93rfl9495theorem weightedSum.continuous (n : Nat) (S W : Set)96requires family : ∀ i ∈ n, CubeFunctionContinuous(W(i), n)97shows CubeFunctionContinuous(weightedSum(n, S, W), n)98proof99have all := prefixWeighted.continuous at n, S, W, n with family100have same := weightedSum.definition at n, S, W101rw same102exact all with (bootstrap.succ.self at n)103104theorem weightedSum.function (n : Nat) (S W : Set)105requires functions : ∀ i ∈ n, CubeFunction(W(i), n)106shows CubeFunction(weightedSum(n, S, W), n)107proof108have same := weightedSum.definition at n, S, W109rw same110exact prefixWeighted.function at n, S, W, n with*111112theorem weightedSum.value (n : Nat) (S W x : Set)113requires functions : ∀ i ∈ n, CubeFunction(W(i), n)114requires hx : x ∈ unitCube(n)115shows weightedSum(n, S, W)(x) = realPartialSum(maskedPoint(n, S, assembledPoint(n, W, x)), n)116proof117have same := weightedSum.definition at n, S, W118rw same119exact prefixWeighted.value at n, S, W, n, x with*120121theorem weightedSum.real (n : Nat) (S W x : Set)122requires functions : ∀ i ∈ n, CubeFunction(W(i), n)123requires hx : x ∈ unitCube(n)124shows weightedSum(n, S, W)(x) ∈ ℝ125proof126exact CubeFunction.value with (weightedSum.function at n, S, W with functions), hx127128-- Masked terms of a nonnegative family are nonnegative.129theorem maskedPoint.nonnegative_of (n : Nat) (S w k : Set)130requires wFunction : w : n → ℝ131requires hk : k ∈ n132requires nonnegative : (0:R) ≤ (w(k):R)133shows (0:R) ≤ (maskedPoint(n, S, w)(k):R)134proof135have alternatives : k ∈ S ∨¬k ∈ S bytauto136cases alternatives with inBlock | outside137 . have same := maskedPoint.on_block with wFunction, hk, inBlock138 rwa same139 . have same := maskedPoint.off_block with wFunction, hk, outside140rw same141linarith142143theorem weightedSum.terms_nonnegative (n : Nat) (S W x : Set)144requires functions : ∀ i ∈ n, CubeFunction(W(i), n)145requires hx : x ∈ unitCube(n)146requires nonnegative : ∀ i ∈ n, (0:R) ≤ (W(i)(x):R)147shows∀ k ∈ n, (0:R) ≤ (maskedPoint(n, S, assembledPoint(n, W, x))(k):R)148proof149intros k hk150have values := assembledPoint.function with functions, hx151have value := assembledPoint.value with functions, hx, hk152have bound := nonnegative with hk153have termNonneg : (0:R) ≤ (assembledPoint(n, W, x)(k):R) by rwa value154exact maskedPoint.nonnegative_of with values, hk, termNonneg155156theorem weightedSum.nonnegative (n : Nat) (S W x : Set)157requires functions : ∀ i ∈ n, CubeFunction(W(i), n)158requires hx : x ∈ unitCube(n)159requires nonnegative : ∀ i ∈ n, (0:R) ≤ (W(i)(x):R)160shows (0:R) ≤ (weightedSum(n, S, W)(x):R)161proof162have values := assembledPoint.function with functions, hx163have sequence := maskedPoint.sequence at n, S, assembledPoint(n, W, x) with values164have value := weightedSum.value at n, S, W, x with functions, hx165have terms := weightedSum.terms_nonnegative at n, S, W, x with functions, hx, nonnegative166have bound := realPartialSum.nonnegative_prefix with sequence167rw value168exact bound with terms169170theorem weightedSum.ge_term (n : Nat) (S W x j : Set)171requires functions : ∀ i ∈ n, CubeFunction(W(i), n)172requires hx : x ∈ unitCube(n)173requires nonnegative : ∀ i ∈ n, (0:R) ≤ (W(i)(x):R)174requires hj : j ∈ n175requires inBlock : j ∈ S176shows (W(j)(x):R) ≤ (weightedSum(n, S, W)(x):R)177proof178have values := assembledPoint.function with functions, hx179have sequence := maskedPoint.sequence at n, S, assembledPoint(n, W, x) with values180have value := weightedSum.value at n, S, W, x with functions, hx181have terms := weightedSum.terms_nonnegative at n, S, W, x with functions, hx, nonnegative182have bounds := realPartialSum.term_le_prefix with sequence183have forAll := bounds with terms184have bound := forAll with hj185have same := maskedPoint.on_block with values, hj, inBlock186have component := assembledPoint.value with functions, hx, hj187rw value188 rwa [same, component] at bound189190-- A partial sum of vanishing terms vanishes.191theorem realPartialSum.zero_terms (u : Set) (m : Nat)192requires sequence : RealSequence(u)193shows (∀ k ∈ m, u(k) = (0:R)) → realPartialSum(u, m) = (0:R)194proof195induction m196| zero =>197intro terms198exact realPartialSum.zero at u199| succ(j) using ih =>200intro terms201have jNat : Nat(j) bytypecheck202have last := terms with (bootstrap.succ.self at j)203have smaller : ∀ k ∈ j, u(k) = (0:R)204intros k hk205have kNat := natural.member at j with hk206have less := Less.of_membership with hk207have below : k < succ(j) byarith208have inSucc : k ∈ succ(j)209exact membership.of_Less with below210exact terms with inSucc211have previous := ih with smaller212have step := realPartialSum.succ at u, j213have lastReal := RealSequence.value at u, j with sequence214rw step215linarith216217-- When the selected coordinates of z are those of x shifted by a real218-- function w and scaled by C, so is the block sum.219theorem sumCube.scaled_sum (n : Nat) (S x z w : Set) (C : Real)220requires hx : x ∈ unitCube(n)221requires hz : z ∈ unitCube(n)222requires wFunction : w : n → ℝ223requires shifted : ∀ j ∈ n, j ∈ S → z(j) = ((x(j):R) + (w(j):R)) * C224shows sumCube(n, S)(z) = ((sumCube(n, S)(x):R) + (realPartialSum(maskedPoint(n, S, w), n):R)) * C225proof226have xFunction := unitCube.point with hx227have zFunction := unitCube.point with hz228have maskedX := maskedPoint.sequence at n, S, x with xFunction229have maskedW := maskedPoint.sequence at n, S, w with wFunction230have maskedZ := maskedPoint.sequence at n, S, z with zFunction231have constantC := constantSequence.sequence at C232have inner := addSequence.sequence with maskedX, maskedW233have agree : ∀ k ∈ ℕ, k < n → maskedPoint(n, S, z)(k) = mulSequence(constantSequence(C), addSequence(maskedPoint(n, S, x), maskedPoint(n, S, w)))(k)234intros k hk hkn235have kNat : Nat(k) bytypecheck236have hkIn : k ∈ n byexact membership.of_Less with hkn237have xReal := RealSequence.value at maskedPoint(n, S, x), k with maskedX238have wReal := RealSequence.value at maskedPoint(n, S, w), k with maskedW239have cReal := RealSequence.value at constantSequence(C), k with constantC240have cValue := constantSequence.value at C, k241have innerValue := addSequence.value with maskedX, maskedW, xReal, wReal242have innerReal := RealSequence.value at addSequence(maskedPoint(n, S, x), maskedPoint(n, S, w)), k with inner243have outerValue := mulSequence.value with constantC, inner, cReal, innerReal244rw [outerValue, innerValue, cValue]245have alternatives : k ∈ S ∨¬k ∈ S bytauto246cases alternatives with inBlock | outside247 . have zSame := maskedPoint.on_block with zFunction, hkIn, inBlock248have xSame := maskedPoint.on_block with xFunction, hkIn, inBlock249have wSame := maskedPoint.on_block with wFunction, hkIn, inBlock250have zValue := shifted with hkIn, inBlock251have xk := unitCube.coordinate_real with hx, hkIn252have wk := FunctionBetween.apply_closed with wFunction, hkIn253rw [zSame, xSame, wSame, zValue]254ring255 . have zSame := maskedPoint.off_block with zFunction, hkIn, outside256have xSame := maskedPoint.off_block with xFunction, hkIn, outside257have wSame := maskedPoint.off_block with wFunction, hkIn, outside258rw [zSame, xSame, wSame]259ring260have outer := mulSequence.sequence with constantC, inner261have equal := realPartialSum.eq_prefix with maskedZ, outer, agree262have scaleC := realPartialSum.scale with inner263have addXW := realPartialSum.add with maskedX, maskedW264have zValue := sumCube.value at n, S, z with hz265have xValue := sumCube.value at n, S, x with hx266rw [zValue, xValue, equal, scaleC, addXW]267ring268