Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: documented and styled everything #20

Merged
merged 53 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
09c8918
chore: no limits needed in case study
ramonfmir Mar 1, 2024
3a08336
style: `throwChangeOfVariablesError`
ramonfmir Mar 3, 2024
3b242da
wip: starting to refactor DCP
ramonfmir Mar 4, 2024
d4e7572
refactor: positive orthant -> nonnegative orthant
ramonfmir Mar 4, 2024
cdf609e
doc: comment on `PosOrth`
ramonfmir Mar 4, 2024
1c9bdd2
doc: cone comments
ramonfmir Mar 4, 2024
902c94a
doc: conditional rewrites
ramonfmir Mar 4, 2024
4445208
doc: show variables
ramonfmir Mar 4, 2024
a09fd91
doc: unchecked DCP
ramonfmir Mar 4, 2024
8513c46
doc: all of `pre_dcp`
ramonfmir Mar 5, 2024
ee0a61d
fix: deprecated `SMul` lemma
ramonfmir Mar 5, 2024
bde294f
fix: use `ConvexSet` for cone atoms
ramonfmir Mar 5, 2024
27cc607
doc: cusotm trees
ramonfmir Mar 5, 2024
07f3bd7
doc: `OC`
ramonfmir Mar 5, 2024
2d3af0f
dpc: custom `DiscrTree`
ramonfmir Mar 5, 2024
499dd78
chore: better style checking
ramonfmir Mar 5, 2024
dc9d870
fix: check style for all Lean files in a directory
ramonfmir Mar 5, 2024
9102b67
chore: only print style errors
ramonfmir Mar 5, 2024
2d08823
style: long lines in `DiscrTree.lean`
ramonfmir Mar 5, 2024
795091b
fix: empty MOSEK path
ramonfmir Mar 5, 2024
9944600
chore: ignore MOSEK path file
ramonfmir Mar 5, 2024
11f62b9
doc: MOSEK path file
ramonfmir Mar 5, 2024
28fccde
style: all of `Command`
ramonfmir Mar 5, 2024
f38980e
fix: `OC.constr` -> `OC.constrs`
ramonfmir Mar 5, 2024
a383e3c
style: examples and demo
ramonfmir Mar 5, 2024
63b49c5
style: all of `Lib`
ramonfmir Mar 5, 2024
ec1cc57
style: all of `Meta`
ramonfmir Mar 5, 2024
4e1234d
style: all of `Syntax`
ramonfmir Mar 5, 2024
b189198
style: all `Tactic` except `DCP`
ramonfmir Mar 5, 2024
c76276b
chore: remove `Huber.py`
ramonfmir Mar 5, 2024
62d0fe7
style: all of `Test`
ramonfmir Mar 5, 2024
a2e153a
fix: simplify curvature elaboration
ramonfmir Mar 5, 2024
1d9763b
style: `README.md`
ramonfmir Mar 5, 2024
c34e982
style: `Tactic/DCP/AtomLibrary/*`
ramonfmir Mar 5, 2024
289fc3b
wip: cleaning up DCP
ramonfmir Mar 7, 2024
eff67b1
wip: splitting `declare_atom` files
ramonfmir Mar 7, 2024
88adb3f
doc: atom command elaborators for signature
ramonfmir Mar 7, 2024
fe7ba20
doc: atom command elaborators and multi-level support
ramonfmir Mar 7, 2024
9b42f49
doc: everything but `DCP`
ramonfmir Mar 7, 2024
1fc21ee
wip: split DCP
ramonfmir Mar 7, 2024
0f72d14
doc: all DCP makers
ramonfmir Mar 7, 2024
3444a3a
doc: all of `Tactic/DCP`
ramonfmir Mar 7, 2024
6da3ae5
fix: atom range in multi-level atom declarations
ramonfmir Mar 7, 2024
a9cd281
wip: fixing huber
ramonfmir Mar 7, 2024
ff0c4c6
fix: typo in error message
ramonfmir Mar 7, 2024
118014e
fix: solution in multi-level declarations
ramonfmir Mar 7, 2024
39222ad
chore: no logs in Huber atom
ramonfmir Mar 7, 2024
5314594
style: everything compliant with mathlib guidelines
ramonfmir Mar 7, 2024
4d50199
chore: remove path from `Tactic/Solver`
ramonfmir Mar 7, 2024
31b276d
chore: script to check style for all files
ramonfmir Mar 7, 2024
b8db885
chore: add style check to CI
ramonfmir Mar 7, 2024
351e248
fix: exit code 0 for sucessful style check
ramonfmir Mar 8, 2024
7732d64
chore: docs CI only on push
ramonfmir Mar 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ name: docs
on:
push:
branches: ["main"]

pull_request:
branches: ["main"]

workflow_dispatch:

Expand Down Expand Up @@ -34,10 +31,11 @@ jobs:
with:
repository: verified-optimization/CvxLean
path: CvxLean
- name: Build egg-pre-dcp and CvxLean
- name: Build egg-pre-dcp, CvxLean, and CvxLeanTest
working-directory: CvxLean
run: |
./build.sh
lake build CvxLeanTest
- name: Create dummy docs project
run: |
# Taken from https://github.com/leanprover-community/mathlib4_docs
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ jobs:
- name: Build egg-pre-dcp and CvxLean
run: |
./build.sh
- name: Check style
run: |
./scripts/style/check_style_all.sh
- name: Test egg-pre-dcp
working-directory: egg-pre-dcp
run: |
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
/scripts/evaluation/data
/plots

/CvxLean/Tactic/Solver/Mosek/Path.lean
/CvxLean/Command/Solve/Mosek/Path.lean
11 changes: 6 additions & 5 deletions CvxLean/Command/Solve/Conic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ unsafe def solutionDataFromProblemData (minExpr : MinimizationExpr) (data : Prob
| Except.error err => throwSolveError err

/-- -/
unsafe def exprFromSolutionData (minExpr : MinimizationExpr) (solData : SolutionData) : MetaM Expr := do
unsafe def exprFromSolutionData (minExpr : MinimizationExpr) (solData : SolutionData) :
MetaM Expr := do
let vars ← decomposeDomainInstantiating minExpr

-- Generate solution of the correct shape.
Expand All @@ -114,7 +115,7 @@ unsafe def exprFromSolutionData (minExpr : MinimizationExpr) (solData : Solution
let exprs := (solPointExprArrayRaw.drop i).take n

-- TODO: Code repetition.
let arrayExpr ← Lean.Expr.mkArray (mkConst ``Real) exprs
let arrayExpr ← Expr.mkArray (mkConst ``Real) exprs
let arrayList ← mkAppM ``Array.toList #[arrayExpr]
let v ← withLocalDeclD `i' (← mkAppM ``Fin #[toExpr n]) fun i' => do
let i'' := mkApp2 (mkConst ``Fin.val) (toExpr n) i'
Expand All @@ -128,12 +129,12 @@ unsafe def exprFromSolutionData (minExpr : MinimizationExpr) (solData : Solution
-- Matrix.
let mut exprs := #[]
for j in [:m] do
let arrayExpr ← Lean.Expr.mkArray (mkConst ``Real) ((solPointExprArrayRaw.drop (i + j * n)).take n)
let arrayExpr ← Expr.mkArray (mkConst ``Real)
((solPointExprArrayRaw.drop (i + j * n)).take n)
let listExpr ← mkAppM ``Array.toList #[arrayExpr]
exprs := exprs.push listExpr

let arrayListExpr ←
Lean.Expr.mkArray (← mkAppM ``List #[mkConst ``Real]) exprs
let arrayListExpr ← Expr.mkArray (← mkAppM ``List #[mkConst ``Real]) exprs

-- List of list representing the matrix.
let listListExpr ← mkAppM ``Array.toList #[arrayListExpr]
Expand Down
13 changes: 7 additions & 6 deletions CvxLean/Command/Solve/Float/Coeffs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,16 @@ unsafe def unrollVectors (constraints : Expr) : MetaM (Array Expr) := do
let idxExpr ← mkFinIdxExpr i n
let ei := mkApp e idxExpr
res := res.push (← mkAppM ``Real.zeroCone #[ei])
-- Vector positive orthant cone.
| .app (.app (.app (.const ``Real.Vec.posOrthCone _) (.app (.const ``Fin _) n)) _) e =>
-- Vector nonnegative orthant cone.
| .app (.app (.app (.const ``Real.Vec.nonnegOrthCone _) (.app (.const ``Fin _) n)) _) e =>
let n : Nat ← evalExpr Nat (mkConst ``Nat) n
for i in [:n] do
let idxExpr ← mkFinIdxExpr i n
let ei := mkApp e idxExpr
res := res.push (← mkAppM ``Real.posOrthCone #[ei])
res := res.push (← mkAppM ``Real.nonnegOrthCone #[ei])
-- Vector exponential cone.
| .app (.app (.app (.app (.app (.const ``Real.Vec.expCone _) (.app (.const ``Fin _) n)) _) a) b) c =>
| .app (.app (.app (.app (.app
(.const ``Real.Vec.expCone _) (.app (.const ``Fin _) n)) _) a) b) c =>
let n : Nat ← evalExpr Nat (mkConst ``Nat) n
for i in [:n] do
let idxExpr ← mkFinIdxExpr i n
Expand Down Expand Up @@ -277,7 +278,7 @@ unsafe def determineCoeffsFromExpr (minExpr : MinimizationExpr) :
let res ← determineScalarCoeffsAux e p floatDomain
data := data.addZeroConstraint res.1 res.2
idx := idx + 1
| .app (.const ``Real.posOrthCone _) e => do
| .app (.const ``Real.nonnegOrthCone _) e => do
let e ← realToFloat e
let res ← determineScalarCoeffsAux e p floatDomain
data := data.addPosOrthConstraint res.1 res.2
Expand Down Expand Up @@ -312,7 +313,7 @@ unsafe def determineCoeffsFromExpr (minExpr : MinimizationExpr) :
let (ea, eb) ← determineScalarCoeffsAux e p floatDomain
data := data.addSOConstraint ea eb
idx := idx + 1
| .app (.app (.app (.app (.app (.const ``Real.Matrix.posOrthCone _)
| .app (.app (.app (.app (.app (.const ``Real.Matrix.nonnegOrthCone _)
(.app (.const ``Fin _) m)) (.app (.const ``Fin _) n)) _) _) e => do
let m : Nat ← evalExpr Nat (mkConst ``Nat) m
let n : Nat ← evalExpr Nat (mkConst ``Nat) n
Expand Down
6 changes: 4 additions & 2 deletions CvxLean/Command/Solve/Float/ProblemData.lean
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ The procedure that creates `ProblemData` from an optimization problem can be fou

namespace CvxLean

/-- Cones admitting scalar affine constraints. Note that the only cone that admits matrix affine
constraints is the PSD cone. -/
/-- Cones admitting scalar affine constraints. The `PosOrth` type actually corresponds to the
nonnegative orthant, but at the solver level, it is usually called the positive orthant, so we use
that terminology here. Note that the only cone that admits matrix affine constraints is the PSD
cone. -/
inductive ScalarConeType
| Zero | PosOrth | Exp | Q | QR

Expand Down
12 changes: 6 additions & 6 deletions CvxLean/Command/Solve/Float/RealToFloatCmd.lean
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ partial def realToFloat (e : Expr) : MetaM Expr := do
environment extension. -/
@[command_elab addRealToFloatCommand]
def elabAddRealToFloatCommand : CommandElab
| `(add_real_to_float : $real := $float) =>
liftTermElabM do
let real ← elabTermAndSynthesize real.raw none
let float ← elabTermAndSynthesize float.raw none
addRealToFloatData { real := real, float := float }
| _ => throwUnsupportedSyntax
| `(add_real_to_float : $real := $float) =>
liftTermElabM do
let real ← elabTermAndSynthesize real.raw none
let float ← elabTermAndSynthesize float.raw none
addRealToFloatData { real := real, float := float }
| _ => throwUnsupportedSyntax

macro_rules
| `(add_real_to_float $idents:funBinder* : $real := $float) => do
Expand Down
5 changes: 2 additions & 3 deletions CvxLean/Command/Solve/Mosek/CBF.lean
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,8 @@ def addScalarConstraintsShiftCoord (p : Problem) (i : Nat) (v : Float) : Problem
{ p with scalarConstraintsShiftCoord :=
p.scalarConstraintsShiftCoord.stack ev}

def addPSDConstraintsScalarVariablesCoord
(p : Problem) (i : Nat) (eml : EncodedMatrixList)
: Problem :=
def addPSDConstraintsScalarVariablesCoord (p : Problem) (i : Nat) (eml : EncodedMatrixList) :
Problem :=
let emll := EncodedMatrixListList.fromIndexAndEncodedMatrixList i eml
{ p with PSDConstraintsScalarVariablesCoord :=
p.PSDConstraintsScalarVariablesCoord.stack emll }
Expand Down
7 changes: 4 additions & 3 deletions CvxLean/Command/Solve/Mosek/Path.lean
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-- Change this to the location of the Mosek binary, e.g.
-- /Users/alice/mosek/10.0/tools/platform/osxaarch64/bin
def mosekBinPath := "/Users/ramonfernandezmir/Documents/PhD-code/optimization/mosek/10.0/tools/platform/osxaarch64/bin"
/-! Change this to the location of the Mosek binary, e.g.
`/Users/alice/mosek/10.0/tools/platform/osxaarch64/bin` -/

def mosekBinPath := ""
3 changes: 2 additions & 1 deletion CvxLean/Command/Solve/Mosek/Sol.lean
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ instance : ToString Result where
"INDEX | NAME | AT | ACTIVITY | LOWER LIMIT | UPPER LIMIT | DUAL LOWER | DUAL UPPER \n" ++
(res.constraints.foldl (fun acc s => acc ++ (toString s) ++ "\n") "") ++ "\n" ++
"VARIABLES \n" ++
"INDEX | NAME | AT | ACTIVITY | LOWER LIMIT | UPPER LIMIT | DUAL LOWER | DUAL UPPER | CONIC DUAL \n" ++
"INDEX | NAME | AT | ACTIVITY | LOWER LIMIT | UPPER LIMIT | DUAL LOWER | DUAL UPPER | " ++
"CONIC DUAL \n" ++
(res.vars.foldl (fun acc s => acc ++ (toString s) ++ "\n") "") ++ "\n" ++
"SYMMETRIC MATRIX VARIABLES \n" ++
"INDEX | NAME | I | J | PRIMAL | DUAL \n" ++
Expand Down
15 changes: 10 additions & 5 deletions CvxLean/Command/Util/TimeCmd.lean
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import Lean

/-!
Place `time_cmd` before any command to print the time taken by the command. Useful for simple
profiling.
-/

open Lean Elab Command

syntax (name := time_cmd) "time_cmd " command : command

@[command_elab «time_cmd»]
def evalTimeCmd : CommandElab := fun stx => match stx with
| `(time_cmd $cmd) => do
let before ← BaseIO.toIO IO.monoMsNow
elabCommand cmd
let after ← BaseIO.toIO IO.monoMsNow
let diff := after - before
dbg_trace s!"Command time: {diff} ms"
let before ← BaseIO.toIO IO.monoMsNow
elabCommand cmd
let after ← BaseIO.toIO IO.monoMsNow
let diff := after - before
dbg_trace s!"Command time: {diff} ms"
| _ => throwUnsupportedSyntax
8 changes: 5 additions & 3 deletions CvxLean/Demos/LT2024.lean
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import CvxLean

/-!
This demo was used for Lean Together 2024, see the video here:
<https://www.youtube.com/watch?v=GNOXmt5A_MQ>
-/

namespace LT2024

noncomputable section
Expand Down Expand Up @@ -70,9 +75,6 @@ def p₃ (Awall Aflr α β γ δ : ℝ) :=
c8 : γ ≤ d / w
c9 : d / w ≤ δ


set_option trace.Meta.debug true

equivalence* eqv₃/q₃ : p₃ 100 10 0.5 2 0.5 2 := by
change_of_variables! (h') (h ↦ exp h')
change_of_variables! (w') (w ↦ exp w')
Expand Down
6 changes: 3 additions & 3 deletions CvxLean/Examples/CovarianceEstimation.lean
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ solve covEstimationConvex nₚ Nₚ αₚ yₚ
-- -(-(Nₚ • log (sqrt ((2 * π) ^ nₚ)) + Nₚ • (-Vec.sum t.0 / 2)) +
-- -(↑Nₚ * trace ((covarianceMatrix fun i => yₚ i) * Rᵀ) / 2))
-- subject to
-- _ : Real.posOrthCone (αₚ - sum T.2)
-- _ : Real.nonnegOrthCone (αₚ - sum T.2)
-- _ : Vec.expCone t.0 1 (diag Y.1)
-- _ :
-- PSDCone
-- (let Z := toUpperTri Y.1;
-- let D := diagonal (diag Y.1);
-- let X := fromBlocks D Z Zᵀ R;
-- X)
-- _ : Matrix.posOrthCone (T.2 - R)
-- _ : Matrix.posOrthCone (T.2 + R)
-- _ : Matrix.nonnegOrthCone (T.2 - R)
-- _ : Matrix.nonnegOrthCone (T.2 + R)

#eval covEstimationConvex.status -- "PRIMAL_AND_DUAL_FEASIBLE"
#eval covEstimationConvex.value -- 14.124098
Expand Down
22 changes: 11 additions & 11 deletions CvxLean/Examples/FittingSphere.lean
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def mean {n : ℕ} (a : Fin n → ℝ) : ℝ := (1 / n) * ∑ i, (a i)
`leastSquares_optimal_eq_mean`, following Marty Cohen's answer in
https://math.stackexchange.com/questions/2554243. -/
lemma leastSquares_alt_objFun {n : ℕ} (hn : 0 < n) (a : Fin n → ℝ) (x : ℝ) :
(∑ i, ((a i - x) ^ 2)) = n * ((x - mean a) ^ 2 + (mean (a ^ 2) - (mean a) ^ 2)) := by
(∑ i, ((a i - x) ^ 2)) = n * ((x - mean a) ^ 2 + (mean (a ^ 2) - (mean a) ^ 2)) := by
calc
-- 1) Σ (aᵢ - x)² = Σ (aᵢ² - 2aᵢx + x²)
_ = ∑ i, ((a i) ^ 2 - 2 * (a i) * x + (x ^ 2)) := by
Expand All @@ -40,7 +40,7 @@ lemma leastSquares_alt_objFun {n : ℕ} (hn : 0 < n) (a : Fin n → ℝ) (x :

/-- Key result about least squares: `x* = mean a`. -/
lemma leastSquares_optimal_eq_mean {n : ℕ} (hn : 0 < n) (a : Fin n → ℝ) (x : ℝ)
(h : (leastSquares a).optimal x) : x = mean a := by
(h : (leastSquares a).optimal x) : x = mean a := by
simp [optimal, feasible, leastSquares] at h
replace h : ∀ y, (x - mean a) ^ 2 ≤ (y - mean a) ^ 2 := by
intros y
Expand All @@ -60,7 +60,7 @@ def leastSquaresVec {n : ℕ} (a : Fin n → ℝ) :=

/-- Same as `leastSquares_optimal_eq_mean` in vector notation. -/
lemma leastSquaresVec_optimal_eq_mean {n : ℕ} (hn : 0 < n) (a : Fin n → ℝ) (x : ℝ)
(h : (leastSquaresVec a).optimal x) : x = mean a := by
(h : (leastSquaresVec a).optimal x) : x = mean a := by
apply leastSquares_optimal_eq_mean hn a
simp [leastSquaresVec, leastSquares, optimal, feasible] at h ⊢
intros y
Expand Down Expand Up @@ -96,7 +96,7 @@ equivalence* eqv/fittingSphereT (n m : ℕ) (x : Fin m → Fin n → ℝ) : fitt
equivalence_step =>
apply ChangeOfVariables.toEquivalence
(fun (ct : (Fin n → ℝ) × ℝ) => (ct.1, sqrt (ct.2 + ‖ct.1‖ ^ 2)))
. rintro _ h; exact le_of_lt h
· rintro _ h; exact le_of_lt h
rename_vars [c, t]
-- Clean up.
conv_constr h₁ => dsimp
Expand Down Expand Up @@ -128,21 +128,21 @@ lemma vec_squared_norm_error_eq_zero_iff {n m : ℕ} (a : Fin m → Fin n →
simp [rpow_two]
rw [sum_eq_zero_iff_of_nonneg (fun _ _ => sq_nonneg _)]
constructor
. intros h i
· intros h i
have hi := h i (by simp)
rwa [sq_eq_zero_iff, norm_eq_zero, sub_eq_zero] at hi
. intros h i _
· intros h i _
rw [sq_eq_zero_iff, norm_eq_zero, sub_eq_zero]
exact h i

/-- This tells us that solving the relaxed problem is sufficient for optimal points if the solution
is non-trivial. -/
lemma optimal_convex_implies_optimal_t (hm : 0 < m) (c : Fin n → ℝ) (t : ℝ)
(h_nontrivial : x ≠ Vec.const m c)
(h_opt : (fittingSphereConvex n m x).optimal (c, t)) : (fittingSphereT n m x).optimal (c, t) := by
(h_nontrivial : x ≠ Vec.const m c) (h_opt : (fittingSphereConvex n m x).optimal (c, t)) :
(fittingSphereT n m x).optimal (c, t) := by
simp [fittingSphereT, fittingSphereConvex, optimal, feasible] at h_opt ⊢
constructor
. let a := Vec.norm x ^ 2 - 2 * mulVec x c
· let a := Vec.norm x ^ 2 - 2 * mulVec x c
have h_ls : optimal (leastSquaresVec a) t := by
refine ⟨trivial, ?_⟩
intros y _
Expand Down Expand Up @@ -177,12 +177,12 @@ lemma optimal_convex_implies_optimal_t (hm : 0 < m) (c : Fin n → ℝ) (t : ℝ
exfalso
rw [h_t_add_c2_eq, zero_eq_mul] at h_t_add_c2_eq_zero
rcases h_t_add_c2_eq_zero with (hc | h_sum_eq_zero)
. simp at hc; linarith
· simp at hc; linarith
rw [vec_squared_norm_error_eq_zero_iff] at h_sum_eq_zero
apply h_nontrivial
funext i
exact h_sum_eq_zero i
. intros c' x' _
· intros c' x' _
exact h_opt c' x'

/-- We express the nontriviality condition only in terms of `x` so that it can be checked. -/
Expand Down
12 changes: 6 additions & 6 deletions CvxLean/Examples/TrussDesign.lean
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ equivalence* eqv₁/trussDesignGP (hmin hmax wmin wmax Rmax σ F₁ F₂ : ℝ)
apply ChangeOfVariables.toEquivalence
(fun (hwrA : ℝ × ℝ × ℝ × ℝ) =>
(hwrA.1, hwrA.2.1, hwrA.2.2.1, sqrt (hwrA.2.2.2 / (2 * π) + hwrA.2.2.1 ^ 2)))
. rintro ⟨h, w, r, R⟩ ⟨c_r, _, _, _, _, _, _, c_R_lb, _⟩; dsimp at *
· rintro ⟨h, w, r, R⟩ ⟨c_r, _, _, _, _, _, _, c_R_lb, _⟩; dsimp at *
simp [ChangeOfVariables.condition]
have h_r_le : r ≤ 1.1 * r := (le_mul_iff_one_le_left c_r).mpr (by norm_num)
exact le_trans (le_of_lt c_r) (le_trans h_r_le c_R_lb)
Expand Down Expand Up @@ -122,12 +122,12 @@ equivalence* eqv₂/trussDesignConvex (hmin hmax : ℝ) (hmin_pos : 0 < hmin)
apply ChangeOfVariables.toEquivalence
(fun (hwrA : ℝ × ℝ × ℝ × ℝ) =>
(exp hwrA.1, exp hwrA.2.1, exp hwrA.2.2.1, exp hwrA.2.2.2))
. rintro ⟨h, w, r, A⟩ ⟨c_r, _, _, c_hmin, _, c_wmin, _, c_A_lb, _⟩; dsimp at *
· rintro ⟨h, w, r, A⟩ ⟨c_r, _, _, c_hmin, _, c_wmin, _, c_A_lb, _⟩; dsimp at *
split_ands
. exact lt_of_lt_of_le hmin_pos c_hmin
. exact lt_of_lt_of_le wmin_pos c_wmin
. exact c_r
. have h_A_div_2π_pos : 0 < A / (2 * π) := lt_of_lt_of_le (by positivity) c_A_lb
· exact lt_of_lt_of_le hmin_pos c_hmin
· exact lt_of_lt_of_le wmin_pos c_wmin
· exact c_r
· have h_A_div_2π_pos : 0 < A / (2 * π) := lt_of_lt_of_le (by positivity) c_A_lb
rwa [lt_div_iff (by positivity), zero_mul] at h_A_div_2π_pos
conv_opt => dsimp
rename_vars [h', w', r', A']
Expand Down
Loading
Loading