-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatistics.ml
More file actions
141 lines (120 loc) · 4.58 KB
/
Copy pathstatistics.ml
File metadata and controls
141 lines (120 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
open Ast
module type CFU_sig = sig
val operation_list : (string * ( value list -> value )) list
end
module type Statistics_Funcs = sig
val mean : value list -> value
val median : value list -> value
val standard_deviation : value list -> value
val range : value list -> value
val minimum : value list -> value
val maximum : value list -> value
val permutations : value list -> value
val combinations : value list -> value
end
module Statistics_Functions : Statistics_Funcs = struct
(** [unwrap_float v] is the float extracted from value [v] *)
let unwrap_float (v : value) =
match v with
| VFloat x -> x
| _ -> failwith "This cannot occur - matrix.ml"
(** [unwrap_row v] is the row extracted from value [v] *)
let unwrap_row (v : value) : float array =
match v with
| VRow x -> x
| _ -> failwith "This cannot occur - matrix.ml"
(** [mean_unwrap f] evaluates the mean of a float list [f] *)
let mean_unwrap (f : float list) =
(List.fold_left (fun acc x -> acc +. x) 0. f) /.
(float_of_int(List.length f))
let mean (v : value list) =
match v with
| hd::tl -> let s = (hd |> unwrap_row |> Array.to_list) in
VFloat ((List.fold_left (fun acc x -> acc +. x) 0. s) /.
(float_of_int(List.length s)))
| _ -> failwith "InvalidInput"
let median (v : value list) =
match v with
| hd::tl -> let s = (hd |> unwrap_row |> Array.to_list) in
let s_new = List.sort compare s in
let len = List.length s_new in
let mid = List.nth s_new (len/2) in
if (len mod 2<>0) then VFloat mid else
let mid2 = List.nth s_new ((len-1)/2) in
VFloat ((mid+.mid2)/.2.)
| _ -> failwith "InvalidInput"
let standard_deviation (v : value list) =
match v with
| hd::tl -> let s = (hd |> unwrap_row |> Array.to_list)in
let m = (v |> mean |> unwrap_float) in
VFloat (s
|> List.map (fun x -> (x -. m) *. (x -. m))
|> mean_unwrap
|> Float.sqrt)
| _ -> failwith "InvalidInput"
(** [min_helper s min_acc] goes through [s] and finds the minimum value within
it *)
let rec min_helper (s : float list) min_acc=
match s with
| [] -> min_acc
| h::t -> if (h<min_acc) then min_helper t h else min_helper t min_acc
let minimum (v : value list) =
match v with
| hd::tl -> let s = (hd |> unwrap_row |> Array.to_list) in
VFloat (min_helper s max_float)
| _ -> failwith "InvalidInput"
(** [max_helper s min_acc] goes through [s] and finds the maximum value within
it *)
let rec max_helper (s : float list) max_acc=
match s with
| [] -> max_acc
| h::t -> if (h>max_acc) then max_helper t h else max_helper t max_acc
let maximum (v : value list) =
match v with
| hd::tl -> let s = (hd |> unwrap_row |> Array.to_list) in
VFloat (max_helper s min_float)
| _ -> failwith "InvalidInput"
let range (v : value list) =
match v with
| hd::tl ->
VFloat ((unwrap_float (maximum v)) -. (unwrap_float (minimum v)))
| _ -> failwith "InvalidInput"
(** [factorial n] calculates n! (n factorial) *)
let rec factorial (n : float) =
match n with
| 0. -> 1.
| _ -> n *. (factorial (n -. 1.))
let permutations (v : value list) =
match v with
|[] -> failwith "wrong number of arguments"
|h1::[] -> failwith "wrong number of arguments"
|n::r::[] -> if ((unwrap_float n)<(unwrap_float r)) then
failwith "First argument must be greater"
else VFloat ((factorial (unwrap_float n)) /.
(factorial ((unwrap_float n) -. (unwrap_float r))))
|_ -> failwith "wrong number of arguments"
let combinations (v : value list) =
match v with
|[] -> failwith "wrong number of arguments"
|h1::[] -> failwith "wrong number of arguments"
|n::r::[] -> if ((unwrap_float n)<(unwrap_float r)) then
failwith "First argument must be greater" else
VFloat ((factorial (unwrap_float n)) /.
((factorial ((unwrap_float n) -.
(unwrap_float r))) *.
(factorial (unwrap_float r))))
|_ -> failwith "wrong number of arguments"
end
module Statistics_CFU = struct
type primitive = float
let operation_list = [
("mean", Statistics_Functions.mean);
("median", Statistics_Functions.median);
("stdev", Statistics_Functions.standard_deviation);
("min", Statistics_Functions.minimum);
("max", Statistics_Functions.maximum);
("range", Statistics_Functions.range);
("perm", Statistics_Functions.permutations);
("comb", Statistics_Functions.combinations)
]
end