Skip to content

Commit b8113f6

Browse files
committed
Test HasGaussian
1 parent 71605d2 commit b8113f6

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

‎Test/Computable_test.lean‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
module
2+
3+
public import RandomDo
4+
public meta import RandomDo
5+
6+
set_option linter.style.header false
7+
8+
open MeasureTheory ProbabilityTheory NumLean
9+
10+
universe v
11+
12+
variable {m : (α : Type) → [MeasurableSpace α] → Type v} [MeasurableSpaceMonad m]
13+
14+
/-! ## Une capacité dont le type de valeur est le même des deux côtés
15+
16+
Le crochet de la `MeasurableSpace` peut rester implicite dans le paramètre de la classe : Lean la
17+
synthétise alors dans le type du champ, et `(by infer_instance)` devient inutile. -/
18+
19+
/-- Tirer un bit. -/
20+
class HasBit (m : (α : Type) → [MeasurableSpace α] → Type v) where
21+
/-- Le tirage. -/
22+
bit : m Bool
23+
24+
noncomputable instance : HasBit Measure where
25+
bit := bernoulliMeasure true false ⟨(1 : ℝ) / 2, by norm_num⟩
26+
27+
/-- Un programme qui ne dit pas dans quelle monade il vit. -/
28+
def sampleBitsArray [HasBit m] (n : ℕ) : m (Array Bool) := rdo
29+
let mut xs : Array Bool := #[]
30+
for _ in List.range n rdo
31+
let b ← HasBit.bit (m := m)
32+
xs := xs.push b
33+
return xs
34+
35+
/-! ## La même chose pour la gaussienne
36+
37+
`Bool` est le même objet dans les deux mondes, mais les réels ne le sont pas : une mesure vit sur
38+
`ℝ`, un échantillonneur rend un `Float`. La classe laisse donc le type des scalaires libre, et c'est
39+
chaque instance qui le fixe. -/
40+
41+
/-- Un espace mesurable sur `Float` : il est fini, donc toutes ses parties sont mesurables. -/
42+
instance : MeasurableSpace Float := ⊤
43+
44+
/-- Tirer une gaussienne de moyenne et de variance données, à valeurs dans `R`. -/
45+
class HasGaussian (m : (α : Type) → [MeasurableSpace α] → Type v)
46+
(R : Type) [MeasurableSpace R] where
47+
/-- Le tirage, de moyenne le premier argument et de variance le second. -/
48+
gaussian : R → R → m R
49+
50+
noncomputable instance : HasGaussian Measure ℝ where
51+
gaussian μ v := gaussianReal μ v.toNNReal
52+
53+
/-- La monade qui échantillonne, vue comme une `MeasurableSpaceMonad` comme les autres. -/
54+
abbrev RandM := Monad.toMeasurableSpaceMonad (RandPCG IO)
55+
56+
instance : HasGaussian RandM Float where
57+
gaussian μ v := normal' μ v
58+
59+
/- Les scalaires sur lesquels un programme compte : de quoi écrire `0` et `+`. Les lois ne sont
60+
pas demandées, seulement les opérations, ce qui laisse `Float` passer. -/
61+
variable {R : Type} [MeasurableSpace R] [Add R] [OfNat R 0] [OfNat R 1]
62+
63+
/-- Un seul programme, écrit une fois. -/
64+
def ex1 [HasGaussian m R] : m R := rdo
65+
let mut x : R := 0
66+
for _ in List.range 10 rdo
67+
let y ← HasGaussian.gaussian (m := m) 0 1
68+
x := x + y
69+
return x
70+
71+
/-- Lu comme une mesure. -/
72+
noncomputable example : Measure ℝ := ex1
73+
74+
/- Lu comme un échantillonneur, et il tourne. -/
75+
run_cmd do
76+
let x ← (IO.runRandPCGWith 42 (ex1 (m := RandM) (R := Float)) : IO Float)
77+
Lean.logInfo m!"ex1 échantillonné (seed 42) = {x}"

0 commit comments

Comments
 (0)