(**
 	Module: Aux
	Description: all auxiliary functions
	@author WANG Haisheng	
	Created: 12/08/2013	Modified: 13/08/2013
*)

let array_map2 = fun f -> fun a -> fun b ->
  let n1 = Array.length a in
  let n2 = Array.length b in
  if n1 = n2 then Array.init n1 (fun i -> f a.(i) b.(i))
  else raise (Invalid_argument "Array.map2 size not matched.");;

let array_map3 = fun f -> fun a -> fun b -> fun c ->
  let n1 = Array.length a in
  let n2 = Array.length b in
  let n3 = Array.length c in
  if n1 = n2 && n1 = n3 then Array.init n1 (fun i -> f a.(i) b.(i) c.(i))
  else raise (Invalid_argument "Array.map3 size not matched.");;

let decorate = fun s -> "    Faustine -> " ^ s ^ "\n";;

let xor : bool -> bool -> bool =
  fun a -> fun b -> (a || b) && (not (a && b));;

let rint : float -> float = 
  fun f -> 
    if (f -. (floor f)) >= 0.5 then ceil f
    else floor f;;

let remainder_float : float -> float -> float = 
  fun f1 -> fun f2 ->
    let r = mod_float f1 f2 in
    if (abs_float r) > ((abs_float f2) /. 2.) then
      (if r *. f2 > 0. then (r -. f2) else (r +. f2))
    else r;;

let format_of_file : string -> string = 
  fun (path : string) ->
    let fragments = Str.split (Str.regexp "\.") path in
	let n = List.length fragments in
	List.nth fragments (n - 1);;

let transpose : int -> 'a array array -> 'a array array = 
  fun width -> fun matrix ->
    let get_element = fun i -> fun array -> array.(i) in
    let get_column = fun m -> fun i -> Array.map (get_element i) m in
    Array.init width (get_column matrix);;