package lbvs_consent
Source file myList.ml
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201include BatList module Ht = BatHashtbl let avg (l: int list): float = (float (sum l)) /. (float (length l)) (* compute the average list of a list of list of ints *) let (l: int list list): float list = match l with | [] -> assert(false) | l1 :: _ -> let n = float (length l) in let array_len = length l1 in let arr = Array.make array_len 0.0 in (* accumulate *) iter (fun li -> assert(length li = array_len); iteri (fun i x -> arr.(i) <- arr.(i) +. (float x) ) li ) l; (* average the accumulated *) let res = Array.map (fun x -> x /. n) arr in Array.to_list res let nfaverage (l: float list list): float list = match l with | [] -> assert(false) | l1 :: _ -> let n = float (length l) in let array_len = length l1 in let arr = Array.make array_len 0.0 in (* accumulate *) iter (fun li -> assert(length li = array_len); iteri (fun i x -> arr.(i) <- arr.(i) +. x ) li ) l; (* average the accumulated *) let res = Array.map (fun x -> x /. n) arr in Array.to_list res let singleton x = [x] let medianf (l: float list): float = let xs = Array.of_list l in Array.sort BatFloat.compare xs; let n = Array.length xs in if n mod 2 = 1 then xs.(n/2) else 0.5 *. (xs.(n/2) +. xs.(n/2 - 1)) (*$T medianf medianf [1.;2.;3.;4.;5.] = 3.0 medianf [1.;2.;3.;4.] = 2.5 *) let median (l: int list): float = let xs = Array.of_list l in Array.sort BatInt.compare xs; let n = Array.length xs in if n mod 2 = 1 then float xs.(n/2) else 0.5 *. float (xs.(n/2) + xs.(n/2 - 1)) (*$T median median [1;2;3;4;5] = 3.0 median [1;2;3;4] = 2.5 median [1] = 1.0 *) let nmedian (l: int list list): float list = match l with | [] -> assert(false) | _ -> let arrays = map Array.of_list l in let n = Array.length (hd arrays) in assert(for_all (fun a -> Array.length a = n) arrays); let res = Array.make n 0.0 in for i = 0 to n - 1 do res.(i) <- median (map (fun a -> Array.get a i) arrays) done; Array.to_list res (*$T nmedian nmedian [[1;2]; [3;4]] = [2.; 3.] *) exception Empty let hd_tl = function | x :: xs -> (x, xs) | [] -> raise Empty let nfmedian (l: float list list): float list = let rec loop acc xs = try let head_tails = map hd_tl xs in let heads, tails = split head_tails in loop (medianf heads :: acc) tails with | Empty -> rev acc in match l with | [] -> assert(false) | x :: _ -> let n = length x in assert(for_all (fun y -> n = length y) l); loop [] l (*$T nfmedian nfmedian [[1.;2.]; [3.;4.]] = [2.; 3.] *) module Internal = struct let robust_xmedian med_fun l = let maybe_head = function | x :: xs -> Some (x, xs) | [] -> None in let rec loop acc l = let heads = map maybe_head l in let heads = filter BatOption.is_some heads in if heads = [] then rev acc else let heads = map BatOption.get heads in let med = med_fun (map fst heads) in loop (med :: acc) (map snd heads) in loop [] l end (* nfmedian that works even when lists don't all have the same size *) let robust_nfmedian (l: float list list): float list = Internal.robust_xmedian medianf l (*$T robust_nfmedian robust_nfmedian [[0.;2.;5.;7.]; [1.;3.]; [2.;4.;6.]] = [1.;3.;5.5;7.] *) (* nmedian that works even when lists don't all have the same size *) let robust_nmedian (l: int list list): float list = Internal.robust_xmedian median l (*$T robust_nmedian robust_nmedian [[0;2;5;7]; [1;3]; [2;4;6]] = [1.;3.;5.5;7.] *) let variance (l: float list): float = let square x = x *. x in let sum = fsum l in let n = float (length l) in let avg = sum /. n in let x = fold_left (fun acc x -> acc +. square (x -. avg) ) 0.0 l in x /. n (*$T variance variance (map float [2;4;4;4;5;5;7;9]) = 4.0 *) (* standard deviation *) let sigma l = sqrt (variance l) (*$T sigma sigma (map float [2;4;4;4;5;5;7;9]) = 2.0 *) let stddev = sigma (* median absolute deviation (useful to detect outliers) returns (med, MAD) *) let mad l = let med = medianf l in let abs_devs = map (fun x -> abs_float (x -. med)) l in (med, medianf abs_devs) (*$T mad mad (map float [1;1;2;2;4;6;9]) = (2., 1.) *) let to_string to_str l = let buff = Buffer.create 80 in Buffer.add_char buff '['; iteri (fun i x -> if i > 0 then Buffer.add_char buff ';'; Buffer.add_string buff (to_str x); ) l; Buffer.add_char buff ']'; Buffer.contents buff let of_string of_str s = let s' = BatString.chop ~l:1 ~r:1 s in map of_str (BatString.split_on_string s' ~by:";") (* shuffle list in non reproducible way (except luck) *) let real_shuffle l = shuffle ~state:(BatRandom.State.make_self_init ()) l (* pad the end of 'l' with 'n' times value 'v' *) let pad l n v = l @ (make n v)