  POY 5.1.1 . A phylogenetic analysis program using Dynamic Homologies .       
  Copyright ( C ) 2014   ,   ,   , Ward Wheeler ,
  and the American Museum of Natural History .                                
(*                                                                            *)
(* This program is free software; you can redistribute it and/or modify       *)
  it under the terms of the GNU General Public License as published by       
  the Free Software Foundation ; either version 2 of the License , or          
(* (at your option) any later version.                                        *)
(*                                                                            *)
(* This program is distributed in the hope that it will be useful,            *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of             *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *)
(* GNU General Public License for more details.                               *)
(*                                                                            *)
  You should have received a copy of the GNU General Public License          
  along with this program ; if not , write to the Free Software                
  Foundation , Inc. , 51 Franklin Street , Fifth Floor , Boston ,       
  USA                                                                        


* Median module contains functions to create medians 
 *     between two lists of breakinv chracters
*    between two lists of breakinv chracters *)


val fprintf : out_channel -> ('a, out_channel, unit) format -> 'a
type breakinv_t = BreakinvAli.breakinv_t

* [ meds_t ] is a data structure for a list medians 
 * between two breakinv character lists
* between two breakinv character lists *)
type meds_t = {
    med_ls : breakinv_t list; (** breakinv list *)
    num_med : int; (** number of breakinv characters *)
    total_cost : int;   (** the cost to create this breakinv list *)
    total_recost : int; (** the recost to create this breakinv list *)
    breakinv_pam : Data.dyna_pam_t; (** breakinv paramenters used to create breakinv median *)
    gen_cost_mat_full : Cost_matrix.Two_D.m; 
    gen_cost_mat_original : Cost_matrix.Two_D.m; 
    pure_gen_cost_mat_full : int array array;
    pure_gen_cost_mat_original : int array array; 
    alpha : Alphabet.a 
}


val print : meds_t -> unit

* init_med seq gen_cost_mat alpha breakinv_pam ] returns 
 * a breakinv character list with only one element 
 * created from a sequence of general character [ seq ]
* a breakinv character list with only one element 
* created from a sequence of general character [seq]*)
val init_med :
  Sequence.s -> int list ->
  Cost_matrix.Two_D.m -> Cost_matrix.Two_D.m -> Alphabet.a -> Data.dyna_pam_t -> meds_t

(** [keep chrom_pam med_ls] returns a sublist of median list
* [med_ls] to be kept to process further based on the customs's defined paramaters *)
val keep : Data.dyna_pam_t -> 'a list -> 'a list

* [ find_meds2   ] returns a list of 
 * breakinv character medians created for two lists of medians 
 * [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
 * where xi and yj are medians . For each pair ( xi , yj ) we have 
 * a list of medians z_ij with the same cost   
 * Find z*_ij = minargv(z_ij ) ( c_ij )
* breakinv character medians created for two lists of medians 
* [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
* where xi and yj are medians. For each pair (xi, yj) we have 
* a list of medians z_ij with the same cost c_ij. 
* Find z*_ij = minargv(z_ij )(c_ij) *)
val find_meds2 : meds_t -> meds_t -> meds_t


val get_extra_cost_for_root : meds_t -> int

* [ cmp_min_pair_cost ] returns the minimum cost 
 * between two lists of medians [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
  * where xi and yj are medians . For each pair ( xi , yj ) we have 
  * a list of medians z_ij with the same cost c_ij . 
  * Find c*_ij = min ( c_ij )
* between two lists of medians [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
 * where xi and yj are medians. For each pair (xi, yj) we have 
 * a list of medians z_ij with the same cost c_ij. 
 * Find c*_ij = min (c_ij) *)
val cmp_min_pair_cost : meds_t -> meds_t -> int * int

* [ cmp_max_pair_cost ] returns the maximum cost 
 * between two lists of medians [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
  * where xi and yj are medians . For each pair ( xi , yj ) we have 
  * a list of medians z_ij with the same cost c_ij . 
  * Find c*_ij = min ( c_ij )
* between two lists of medians [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
 * where xi and yj are medians. For each pair (xi, yj) we have 
 * a list of medians z_ij with the same cost c_ij. 
 * Find c*_ij = min (c_ij) *)
val cmp_max_pair_cost : meds_t -> meds_t -> int * int


* [ find_meds3 medsp   ] returns 
 * the median of three lists of medians [ medsp=(x1, ... ,xk ) ] , [ meds1=(y1, ... ,yt ) ] 
  * and [ meds2=(z1, ... ,zq ) ] where xi , yj , and zp are medians . 
  * For each triplet ( xi , yj , zp ) we have 
  * a list of medians w_ijp with the same cost c_ijp . 
  * Find w*ijp = minargv_(w_ijp ) ( c_ijp )
* the median of three lists of medians [medsp=(x1,...,xk)], [meds1=(y1,...,yt)]
 * and [meds2=(z1,...,zq)] where xi, yj, and zp are medians. 
 * For each triplet (xi, yj, zp) we have 
 * a list of medians w_ijp with the same cost c_ijp. 
 * Find w*ijp = minargv_(w_ijp) (c_ijp) *)
val find_meds3 : meds_t -> meds_t -> meds_t -> meds_t

(*
val find_meds3_albert : meds_t -> meds_t -> meds_t -> meds_t
*)

* [ readjust_3d ch1  mine c2 c3 parent ] readjusts 
 * the breakinv median [ mine ] of three breakinv medians 
 * [ ch1 ] , [ ch2 ] and [ parent ]
* the breakinv median [mine] of three breakinv medians 
* [ch1], [ch2] and [parent] *) 
val readjust_3d : meds_t -> meds_t -> meds_t -> 'a -> 'b -> meds_t -> int * int * meds_t * bool

* [ compare meds1 meds2 ] returns 0 if breakinv list [ meds1 ] 
 * is the same as breakinv list [ meds2 ] , otherwise ( -1 ) or ( 1 )
* is the same as breakinv list [meds2], otherwise (-1) or (1) *)
val compare : meds_t -> meds_t -> int

(** [get_active_ref_code meds] return active reference codes
* of breakinv medians [meds] *)
val get_active_ref_code : meds_t -> int * int * int

val update_medst : meds_t -> Sequence.s -> int list -> meds_t

val single_to_multi : meds_t -> meds_t list

val transform_matrix : int array array -> int -> int array array

                                                                            
 This program is free software; you can redistribute it and/or modify       
 (at your option) any later version.                                        
                                                                            
 This program is distributed in the hope that it will be useful,            
 but WITHOUT ANY WARRANTY; without even the implied warranty of             
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              
 GNU General Public License for more details.                               
                                                                            
* breakinv list 
* number of breakinv characters 
* the cost to create this breakinv list 
* the recost to create this breakinv list 
* breakinv paramenters used to create breakinv median 
* [keep chrom_pam med_ls] returns a sublist of median list
* [med_ls] to be kept to process further based on the customs's defined paramaters 

val find_meds3_albert : meds_t -> meds_t -> meds_t -> meds_t

* [get_active_ref_code meds] return active reference codes
* of breakinv medians [meds] 
  POY 5.1.1 . A phylogenetic analysis program using Dynamic Homologies .       
  Copyright ( C ) 2014   ,   ,   , Ward Wheeler ,
  and the American Museum of Natural History .                                
  it under the terms of the GNU General Public License as published by       
  the Free Software Foundation ; either version 2 of the License , or          
  You should have received a copy of the GNU General Public License          
  along with this program ; if not , write to the Free Software                
  Foundation , Inc. , 51 Franklin Street , Fifth Floor , Boston ,       
  USA                                                                        


* Median module contains functions to create medians 
 *     between two lists of breakinv chracters
*    between two lists of breakinv chracters *)


val fprintf : out_channel -> ('a, out_channel, unit) format -> 'a
type breakinv_t = BreakinvAli.breakinv_t

* [ meds_t ] is a data structure for a list medians 
 * between two breakinv character lists
* between two breakinv character lists *)
type meds_t = {
    gen_cost_mat_full : Cost_matrix.Two_D.m; 
    gen_cost_mat_original : Cost_matrix.Two_D.m; 
    pure_gen_cost_mat_full : int array array;
    pure_gen_cost_mat_original : int array array; 
    alpha : Alphabet.a 
}


val print : meds_t -> unit

* init_med seq gen_cost_mat alpha breakinv_pam ] returns 
 * a breakinv character list with only one element 
 * created from a sequence of general character [ seq ]
* a breakinv character list with only one element 
* created from a sequence of general character [seq]*)
val init_med :
  Sequence.s -> int list ->
  Cost_matrix.Two_D.m -> Cost_matrix.Two_D.m -> Alphabet.a -> Data.dyna_pam_t -> meds_t

val keep : Data.dyna_pam_t -> 'a list -> 'a list

* [ find_meds2   ] returns a list of 
 * breakinv character medians created for two lists of medians 
 * [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
 * where xi and yj are medians . For each pair ( xi , yj ) we have 
 * a list of medians z_ij with the same cost   
 * Find z*_ij = minargv(z_ij ) ( c_ij )
* breakinv character medians created for two lists of medians 
* [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
* where xi and yj are medians. For each pair (xi, yj) we have 
* a list of medians z_ij with the same cost c_ij. 
* Find z*_ij = minargv(z_ij )(c_ij) *)
val find_meds2 : meds_t -> meds_t -> meds_t


val get_extra_cost_for_root : meds_t -> int

* [ cmp_min_pair_cost ] returns the minimum cost 
 * between two lists of medians [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
  * where xi and yj are medians . For each pair ( xi , yj ) we have 
  * a list of medians z_ij with the same cost c_ij . 
  * Find c*_ij = min ( c_ij )
* between two lists of medians [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
 * where xi and yj are medians. For each pair (xi, yj) we have 
 * a list of medians z_ij with the same cost c_ij. 
 * Find c*_ij = min (c_ij) *)
val cmp_min_pair_cost : meds_t -> meds_t -> int * int

* [ cmp_max_pair_cost ] returns the maximum cost 
 * between two lists of medians [ meds1=(x1, ... ,xk ) ] and [ meds2=(y1, ... ,yt ) ] 
  * where xi and yj are medians . For each pair ( xi , yj ) we have 
  * a list of medians z_ij with the same cost c_ij . 
  * Find c*_ij = min ( c_ij )
* between two lists of medians [meds1=(x1,...,xk)] and [meds2=(y1,...,yt)]
 * where xi and yj are medians. For each pair (xi, yj) we have 
 * a list of medians z_ij with the same cost c_ij. 
 * Find c*_ij = min (c_ij) *)
val cmp_max_pair_cost : meds_t -> meds_t -> int * int


* [ find_meds3 medsp   ] returns 
 * the median of three lists of medians [ medsp=(x1, ... ,xk ) ] , [ meds1=(y1, ... ,yt ) ] 
  * and [ meds2=(z1, ... ,zq ) ] where xi , yj , and zp are medians . 
  * For each triplet ( xi , yj , zp ) we have 
  * a list of medians w_ijp with the same cost c_ijp . 
  * Find w*ijp = minargv_(w_ijp ) ( c_ijp )
* the median of three lists of medians [medsp=(x1,...,xk)], [meds1=(y1,...,yt)]
 * and [meds2=(z1,...,zq)] where xi, yj, and zp are medians. 
 * For each triplet (xi, yj, zp) we have 
 * a list of medians w_ijp with the same cost c_ijp. 
 * Find w*ijp = minargv_(w_ijp) (c_ijp) *)
val find_meds3 : meds_t -> meds_t -> meds_t -> meds_t


* [ readjust_3d ch1  mine c2 c3 parent ] readjusts 
 * the breakinv median [ mine ] of three breakinv medians 
 * [ ch1 ] , [ ch2 ] and [ parent ]
* the breakinv median [mine] of three breakinv medians 
* [ch1], [ch2] and [parent] *) 
val readjust_3d : meds_t -> meds_t -> meds_t -> 'a -> 'b -> meds_t -> int * int * meds_t * bool

* [ compare meds1 meds2 ] returns 0 if breakinv list [ meds1 ] 
 * is the same as breakinv list [ meds2 ] , otherwise ( -1 ) or ( 1 )
* is the same as breakinv list [meds2], otherwise (-1) or (1) *)
val compare : meds_t -> meds_t -> int

val get_active_ref_code : meds_t -> int * int * int

val update_medst : meds_t -> Sequence.s -> int list -> meds_t

val single_to_multi : meds_t -> meds_t list

val transform_matrix : int array array -> int -> int array array
