0 | module Statistics.Distribution.GSL
 1 |
 2 | import public Data.Vect
 3 |
 4 | ||| Container for a GSL RNG seed
 5 | public export
 6 | data GslRng : Type where
 7 |   MkGslRng : AnyPtr -> GslRng
 8 |
 9 | ||| Initialise a GSL RNG seed
10 | %foreign "C:init_gsl_rng,distribution"
11 | init_gsl_rng_c : AnyPtr
12 |
13 | export
14 | init_gsl_rng : GslRng
15 | init_gsl_rng = MkGslRng init_gsl_rng_c
16 |
17 | ||| Initialise (alloc) an array of doubles of length 'n'
18 | %foreign "C:init_array, distribution"
19 | init_array_c : (n : Int) -> AnyPtr
20 |
21 | export
22 | init_array : (n : Nat) -> AnyPtr
23 | init_array = init_array_c . cast
24 |
25 | ||| Set base_ptr[idx] to val, and return base_ptr
26 | %foreign "C:assign_array, distribution"
27 | assign_array_c : (base_ptr : AnyPtr) -> (idx : Int) -> (val : Double) -> AnyPtr
28 |
29 | ||| Print an n-sized array of doubles 
30 | %foreign "C:print_array, distribution"
31 | print_array_c : (base_ptr : AnyPtr) -> (n : Int) -> PrimIO ()
32 |
33 | ||| Get the double value at base_ptr[idx]
34 | %foreign "C:index_array, distribution"
35 | index_array_c : (base_ptr : AnyPtr) -> (idx : Int) -> Double 
36 |
37 | export
38 | rangeTo : (n : Nat) -> Vect n Nat
39 | rangeTo Z = []
40 | rangeTo (S n) = snoc (rangeTo n) (n)
41 |
42 | ||| Translate a vector to an array of doubles.
43 | export
44 | to_array : {n : Nat} -> Vect (S n) Double -> AnyPtr
45 | to_array xs = 
46 |   let ptr = init_array_c (cast (S n))
47 |       f  : Vect (S n) AnyPtr = map (\(x, idx) => assign_array_c ptr (cast idx) x ) (zip xs (rangeTo (S n)))
48 |   in  head f
49 |
50 | ||| Read an array of doubles to a vector.
51 | export
52 | from_array : {n : Nat} -> AnyPtr -> Vect (S n) Double
53 | from_array ptr =
54 |   map (\idx => index_array_c ptr (cast idx)) (rangeTo (S n))
55 |
56 |
57 | testArray : IO ()
58 | testArray = do
59 |   let p = to_array [0, 1, 2, 3]
60 |   primIO (print_array_c p 4)
61 |