libpll(3)

๐Ÿ’– NAME ๐Ÿ’–

libpll โ€” the Phylogenetic Likelihood Library ๐Ÿงฌโœจ

okay so real talk, this is libpll(3), living in the Library Functions Manual, and it's basically the whole bestie toolkit for likelihood-based phylogenetics. no cap. ๐Ÿ’…


โœจ SYNOPSIS โœจ

bestie this is a LOT of functions and we're not skipping a single one, so buckle up. every signature below is exactly what it is, character for character, periodt. ๐Ÿ‘‘

๐ŸŒธ Partition management ๐ŸŒธ

the setup era. this is where a partition gets born and where it goes to rest. ๐ŸŽ€

pll_partition_t * pll_partition_create(unsigned int tips,
                                       unsigned int clv_buffers,
                                       unsigned int states,
                                       unsigned int sites,
                                       unsigned int rate_matrices,
                                       unsigned int prob_matrices,
                                       unsigned int rate_cats,
                                       unsigned int scale_buffers,
                                       unsigned int attributes);

void pll_partition_destroy(pll_partition_t * partition);

๐ŸŒธ Partition parameters setup ๐ŸŒธ

all the little knobs and dials, bestie. set the tip states, the tip CLVs, the pattern weights, the asc bias type, the asc state weights, the subst params, the frequencies, the category rates, the category weights. that's the whole lineup. ๐Ÿฆ‹

int pll_set_tip_states(pll_partition_t * partition,
                       unsigned int tip_index,
                       const unsigned int * map,
                       const char * sequence);

int pll_set_tip_clv(pll_partition_t * partition,
                    unsigned int tip_index,
                    const double * clv);

void pll_set_pattern_weights(pll_partition_t * partition,
                             const unsigned int * pattern_weights);

int pll_set_asc_bias_type(pll_partition_t * partition,
                          int asc_bias_type);

void pll_set_asc_state_weights(pll_partition_t * partition,
                               const unsigned int * state_weights);

void pll_set_subst_params(pll_partition_t * partition,
                          unsigned int params_index,
                          const double * params);

void pll_set_frequencies(pll_partition_t * partition,
                         unsigned int params_index,
                         const double * frequencies);

void pll_set_category_rates(pll_partition_t * partition,
                            const double * rates);

void pll_set_category_weights(pll_partition_t * partition,
                              const double * rate_weights);

๐ŸŒธ Transition probability matrices ๐ŸŒธ

the pmatrix era. update them, eigendecompose them, and yes, there's even a little function to show them off with a chosen float_precision because main character energy means being seen. ๐Ÿ‘‘

int pll_update_prob_matrices(pll_partition_t * partition,
                             const unsigned int * params_index,
                             const unsigned int * matrix_indices,
                             const double * branch_lengths,
                             unsigned int count);

int pll_update_eigen(pll_partition_t * partition,
                     unsigned int params_index);

void pll_show_pmatrix(pll_partition_t * partition,
                      unsigned int index,
                      unsigned int float_precision);

๐ŸŒธ Invariant sites ๐ŸŒธ

counting them, updating them, updating their proportion. it's giving very thorough. ๐Ÿ’œ

unsigned int pll_count_invariant_sites(pll_partition_t * partition,
                                       unsigned int * state_inv_count);

int pll_update_invariant_sites(pll_partition_t * partition);

int pll_update_invariant_sites_proportion(pll_partition_t * partition,
                                          unsigned int params_index,
                                          double prop_invar);

๐ŸŒธ Conditional probability vectors ๐ŸŒธ

the CLVs!! iconic. update the partials, or peek at a CLV with a float_precision of your choosing. ๐Ÿซถ

void pll_update_partials(pll_partition_t * partition,
                         const pll_operation_t * operations,
                         unsigned int count);

void pll_show_clv(pll_partition_t * partition,
                  unsigned int clv_index,
                  int scaler_index,
                  unsigned int float_precision);

๐ŸŒธ Evaluation of log-Likelihood ๐ŸŒธ

the moment we've all been waiting for. compute that log-likelihood, root-style or edge-style, and hand over a persite_lnl if you want the per-site tea too. ๐Ÿ”ฅ

double pll_compute_root_loglikelihood(pll_partition_t * partition,
                                      unsigned int clv_index,
                                      int scaler_index,
                                      const unsigned int * freqs_index,
                                      double * persite_lnl);

double pll_compute_edge_loglikelihood(pll_partition_t * partition,
                                      unsigned int parent_clv_index,
                                      int parent_scaler_index,
                                      unsigned int child_clv_index,
                                      int child_scaler_index,
                                      unsigned int matrix_index,
                                      const unsigned int * freqs_index,
                                      double * persite_lnl);

๐ŸŒธ Likelihood function derivatives ๐ŸŒธ

derivatives bestie, we're doing calculus now. update the sumtable, then compute those likelihood derivatives into d_f and dd_f. lowkey obsessed. ๐Ÿ“โœจ

int pll_update_sumtable(pll_partition_t * partition,
                        unsigned int parent_clv_index,
                        unsigned int child_clv_index,
                        const unsigned int * params_indices,
                        double * sumtable);

int pll_compute_likelihood_derivatives(pll_partition_t * partition,
                                       int parent_scaler_index,
                                       int child_scaler_index,
                                       double branch_length,
                                       const unsigned int * params_indices,
                                       const double * sumtable,
                                       double * d_f,
                                       double * dd_f);

๐ŸŒธ FASTA file handling ๐ŸŒธ

open it, getnext it, close it. also getfilesize, getfilepos, and rewind, because sometimes we need to go back. ๐Ÿ“

pll_fasta_t * pll_fasta_open(const char * filename,
                             const unsigned int * map);

int pll_fasta_getnext(pll_fasta_t * fd,
                      char ** head,
                      long * head_len,
                      char ** seq,
                      long * seq_len,
                      long * seqno);

void pll_fasta_close(pll_fasta_t * fd);

long pll_fasta_getfilesize(pll_fasta_t * fd);

long pll_fasta_getfilepos(pll_fasta_t * fd);

int pll_fasta_rewind(pll_fasta_t * fd);

๐ŸŒธ PHYLIP file handling ๐ŸŒธ

parse an MSA, then destroy it when you're done. that's the whole arc. ๐Ÿ’…

pll_msa_t * pll_phylip_parse_msa(const char * filename,
                                 unsigned int * msa_count);

void pll_msa_destroy(pll_msa_t * msa);

๐ŸŒธ Newick handling ๐ŸŒธ

newick trees, three ways: rooted from a file, unrooted from a file, or unrooted straight from a string. pick your fighter. ๐ŸŒˆ

pll_rtree_t * pll_rtree_parse_newick(const char * filename,
                                     unsigned int * tip_count);

pll_utree_t * pll_utree_parse_newick(const char * filename,
                                     unsigned int * tip_count);

pll_utree_t * pll_utree_parse_newick_string(char * s,
                                            unsigned int * tip_count);

๐ŸŒธ Unrooted tree structure manipulation ๐ŸŒธ

the unrooted tree glow-up era. destroy it, show it as ascii, export it as newick, traverse it, query tipnodes and innernodes, create operations, check integrity, clone it, unroot an rtree into a utree, and pll_utree_every with a callback. so many options bestie. ๐Ÿฆ‹

void pll_utree_destroy(pll_utree_t * root);

void pll_utree_show_ascii(pll_utree_t * tree, int options);

char * pll_utree_export_newick(pll_utree_t * root);

int pll_utree_traverse(pll_utree_t * root,
                       int (*cbtrav)(pll_utree_t *),
                       pll_utree_t ** outbuffer,
                       unsigned int * trav_size);

unsigned int pll_utree_query_tipnodes(pll_utree_t * root,
                                      pll_utree_t ** node_list);

unsigned int pll_utree_query_innernodes(pll_utree_t * root,
                                        pll_utree_t ** node_list);

void pll_utree_create_operations(pll_utree_t ** trav_buffer,
                                 unsigned int trav_buffer_size,
                                 double * branches,
                                 unsigned int * pmatrix_indices,
                                 pll_operation_t * ops,
                                 unsigned int * matrix_count,
                                 unsigned int * ops_count);

int pll_utree_check_integrity(pll_utree_t * root);

pll_utree_t * pll_utree_clone(pll_utree_t * root);

pll_utree_t * pll_rtree_unroot(pll_rtree_t * root);

int pll_utree_every(pll_utree_t * node,
                    int (*cb)(pll_utree_t *));

๐ŸŒธ Rooted tree structure manipulation ๐ŸŒธ

same vibe, but rooted. destroy, show ascii, export newick, traverse, query tipnodes, query innernodes, create operations, and then the two special parsimony ones: pll_rtree_create_pars_buildops and pll_rtree_create_pars_recops. ๐ŸŒธ

void pll_rtree_destroy(pll_rtree_t * root);

void pll_rtree_show_ascii(pll_rtree_t * tree, int options);

char * pll_rtree_export_newick(pll_rtree_t * root);

int pll_rtree_traverse(pll_rtree_t * root,
                       int (*cbtrav)(pll_rtree_t *),
                       pll_rtree_t ** outbuffer,
                       unsigned int * trav_size);

unsigned int pll_rtree_query_tipnodes(pll_rtree_t * root,
                                      pll_rtree_t ** node_list);

unsigned int pll_rtree_query_innernodes(pll_rtree_t * root,
                                        pll_rtree_t ** node_list);

void pll_rtree_create_operations(pll_rtree_t ** trav_buffer,
                                 unsigned int trav_buffer_size,
                                 double * branches,
                                 unsigned int * pmatrix_indices,
                                 pll_operation_t * ops,
                                 unsigned int * matrix_count,
                                 unsigned int * ops_count);

void pll_rtree_create_pars_buildops(pll_rtree_t ** trav_buffer,
                                    unsigned int trav_buffer_size,
                                    pll_pars_buildop_t * ops,
                                    unsigned int * ops_count);

void pll_rtree_create_pars_recops(pll_rtree_t ** trav_buffer,
                                  unsigned int trav_buffer_size,
                                  pll_pars_recop_t * ops,
                                  unsigned int * ops_count);

๐ŸŒธ Topological rearrangement moves ๐ŸŒธ

moving branches around!! spr, spr_safe, nni, and rollback to undo. it's giving tree parkour. ๐ŸŒณ๐Ÿ’จ

int pll_utree_spr(pll_utree_t * p,
                  pll_utree_t * r,
                  pll_utree_rb_t * rb,
                  double * branch_lengths,
                  unsigned int * matrix_indices);

int pll_utree_spr_safe(pll_utree_t * p,
                       pll_utree_t * r,
                       pll_utree_rb_t * rb,
                       double * branch_lengths,
                       unsigned int * matrix_indices);

int pll_utree_nni(pll_utree_t * p,
                  int type,
                  pll_utree_rb_t * rb);

int pll_utree_rollback(pll_utree_rb_t * rollback,
                       double * branch_lengths,
                       unsigned int * matrix_indices);

๐ŸŒธ Parsimony functions ๐ŸŒธ

parsimony era!! set the sequence, create the thing, build it, reconstruct it, score it, destroy it. six whole functions and every one of them matters. ๐Ÿ‘‘

int pll_set_parsimony_sequence(pll_parsimony_t * pars,
                               unsigned int tip_index,
                               const unsigned int * map,
                               const char * sequence);

pll_parsimony_t * pll_parsimony_create(unsigned int * tips,
                                       unsigned int states,
                                       unsigned int sites,
                                       double * score_matrix,
                                       unsigned int score_buffers,
                                       unsigned int ancestral_buffers);

double pll_parsimony_build(pll_parsimony_t * pars,
                           pll_pars_buildop_t * operations,
                           unsigned int count);

void pll_parsimony_reconstruct(pll_parsimony_t * pars,
                               const unsigned int * map,
                               pll_pars_recop_t * operations,
                               unsigned int count);

double pll_parsimony_score(pll_parsimony_t * pars,
                           unsigned int score_buffer_index);

void pll_parsimony_destroy(pll_parsimony_t * pars);

๐ŸŒธ Auxiliary functions ๐ŸŒธ

the little helpers that hold everything together ๐Ÿฅบ โ€” gamma categories, aligned alloc, aligned free, and compressing site patterns. ๐ŸŽ€

int pll_compute_gamma_cats(double alpha,
                           unsigned int categories,
                           double * output_rates);

void * pll_aligned_alloc(size_t size, size_t alignment);

void pll_aligned_free(void * ptr);

unsigned int * pll_compress_site_patterns(char ** sequence,
                                          const unsigned int * map,
                                          int count,
                                          int * length);

๐ŸŒธ Core functions ๐ŸŒธ

THE core. this is the deep engine room, bestie. create the lookup, update partials (tt, ti, ii โ€” every combo), and update the sumtable. these are the ones doing the actual heavy lifting. ๐Ÿ’ช๐Ÿ”ฅ

void pll_core_create_lookup(unsigned int states,
                            unsigned int rate_cats,
                            double * lookup,
                            const double * left_matrix,
                            const double * right_matrix,
                            unsigned int * tipmap,
                            unsigned int tipmap_size,
                            unsigned int attrib);

void pll_core_update_partial_tt(unsigned int states,
                                unsigned int sites,
                                unsigned int rate_cats,
                                double * parent_clv,
                                unsigned int * parent_scaler,
                                const unsigned char * left_tipchars,
                                const unsigned char * right_tipchars,
                                const unsigned int * tipmap,
                                unsigned int tipmap_size,
                                const double * lookup,
                                unsigned int attrib);

void pll_core_update_partial_ti(unsigned int states,
                                unsigned int sites,
                                unsigned int rate_cats,
                                double * parent_clv,
                                unsigned int * parent_scaler,
                                const unsigned char * left_tipchars,
                                const double * right_clv,
                                const double * left_matrix,
                                const double * right_matrix,
                                const unsigned int * right_scaler,
                                const unsigned int * tipmap,
                                unsigned int attrib);

void pll_core_update_partial_ii(unsigned int states,
                                unsigned int sites,
                                unsigned int rate_cats,
                                double * parent_clv,
                                unsigned int * parent_scaler,
                                const double * left_clv,
                                const double * right_clv,
                                const double * left_matrix,
                                const double * right_matrix,
                                const unsigned int * left_scaler,
                                const unsigned int * right_scaler,
                                unsigned int attrib);

int pll_core_update_sumtable_ti(unsigned int states,
                                unsigned int sites,
                                unsigned int rate_cats,
                                const double * parent_clv,
                                const unsigned char * left_tipchars,
                                double ** eigenvecs,
                                double ** inv_eigenvecs,
                                double ** freqs,
                                unsigned int * tipmap,
                                double * sumtable,
                                unsigned int attrib);

okay that's the SYNOPSIS and the NAME, and there's so much more coming โ€” we are not done, bestie, stay tuned. ๐Ÿฆ‹๐Ÿ’–

...and the synopsis just keeps going, bestie, she has more to say ๐Ÿ’… here's the rest of the function roster:

int pll_core_likelihood_derivatives(unsigned int states, unsigned int sites, unsigned int rate_cats, const double * rate_weights, const unsigned int * parent_scaler, const unsigned int * child_scaler, const int * invariant, const unsigned int * pattern_weights, double branch_length, const double * prop_invar, double ** freqs, const double * rates, double ** eigenvals, const double * sumtable, double  * d_f, double * dd_f, unsigned int attrib);
double pll_core_edge_loglikelihood_ii(unsigned int states, unsigned int sites, unsigned int rate_cats, const double * parent_clv, const unsigned int * parent_scaler, const double * child_clv, const unsigned int * child_scaler, const double * pmatrix, double ** frequencies, const double * rate_weights, const unsigned int * pattern_weights, const double * invar_proportion, const int * invar_indices, const unsigned int * freqs_indices, double * persite_lnl, unsigned int attrib);
double pll_core_edge_loglikelihood_ti(unsigned int states, unsigned int sites, unsigned int rate_cats, const double * parent_clv, const unsigned int * parent_scaler, const unsigned char * tipchars, const unsigned int * tipmap, const double * pmatrix, double ** frequencies, const double * rate_weights, const unsigned int * pattern_weights, const double * invar_proportion, const int * invar_indices, const unsigned int * freqs_indices, double * persite_lnl, unsigned int attrib);
int pll_core_update_pmatrix(double * pmatrix, unsigned int states, double rate, double prop_invar, double branch_length, double * eigenvals, double * eigenvecs, double * inv_eigenvecs, unsigned int attrib);

โœจ DESCRIPTION โœจ

okay so here's the tea: libpll is a library for phylogenetics. that's the whole vibe. tree stuff. math stuff. slay ๐Ÿ’–

๐ŸŒธ pll_partition_create

pll_partition_t * pll_partition_create(unsigned int tips, unsigned int clv_buffers, unsigned int states, unsigned int sites, unsigned int rate_matrices, unsigned int prob_matrices, unsigned int rate_cats, unsigned int scale_buffers, unsigned int attributes);

This one creates a partition, bestie โ€” and depending on attributes, it'll have either tips character arrays or tips CLV arrays (go peek at Partition Attributes for that). On top of that it sets up clv_buffers CLV vectors, which is where your conditional probabilities for the inner nodes live.

The partition structure gets built for states number of states โ€” think 4 for nucleotide data, 20 for amino-acid data โ€” and enough space gets allocated to host an alignment of size sites*tips. The number of rate matrices you can use is rate_matrices. And not me forgetting the bonus features: the function also allocates space for hosting rate_matrices arrays of substitution parameters, frequencies, and auxiliary eigen-decomposition arrays (all transparent to you, so don't stress ๐Ÿซถ).

prob_matrices dictates how many probability matrices get space. Usually you set this to the number of branches your tree has โ€” like 2n-3 for unrooted and 2n-2 for rooted, where n is the number of tips/leaves. libpll will automatically make space for prob_matrices*rate_cats, where rate_cats is the number of different rate categories. The array of probability matrices is indexed from 0 to prob_matrices-1. Each matrix entry has enough space to accommodate rate_cats matrices, and those are stored consecutively in memory.

โš ๏ธ important: libpll will not allocate space for the different substitution matrices specified by rate_matrices. You have to tell libpll yourself by multiplying prob_matrices with the corresponding factor. ikykyk ๐Ÿ˜Œ

Finally, scale_buffers sets the number of scaling buffers to be allocated, and attributes states the hardware acceleration options to use (again, Partition Attributes). The function returns a pointer to the allocated pll_partition_t structure. And ngl, rate_matrices is what you use to address heterotachy โ€” i.e. transition probability matrices computed from different rate matrices. For more, see Updating transition probability matrices. ๐ŸŒˆ

๐ŸŽ€ pll_partition_destroy

void pll_partition_destroy(pll_partition_t * partition);

Deallocates all the data tied to the partition that partition points at. bye bestie, you were iconic ๐Ÿ‘‹๐Ÿ’–

๐Ÿฆ‹ pll_set_tip_states

int pll_set_tip_states(pll_partition_t * partition, unsigned int tip_index, const unsigned int * map, const char * sequence);

Sets the tip CLV (or the tip character array, depending on your setup) with index tip_index on the partition instance, following the character sequence sequence and the conversion table map โ€” which translates (maps) characters into states. Want an example? See Setting CLV vectors at tips from sequences and maps. โœจ

๐Ÿงš pll_set_tip_clv

int pll_set_tip_clv(pll_partition_t * partition, unsigned int tip_index, const double * clv);

Sets the tip CLV with index tip_index on the partition instance to whatever's in the array clv. Example time? Setting CLV vectors manually. ๐Ÿซถ

๐Ÿ™ˆ heads up: this function cannot be used together with the PLL_ATTRIB_PATTERN_TIP (check Partition Attributes). no mixing, bestie.

๐Ÿ’œ pll_set_subst_params

void pll_set_subst_params(pll_partition_t * partition, unsigned int params_index, const double * params);

Sets the parameters for the substitution model with index params_index, where params_index ranges from 0 to rate_matrices-1 โ€” exactly like you specified in the pll_partition_create() call. The array params should contain exactly (states*states-states)/2 parameters of type double. Those values correspond to the upper triangle elements (above the main diagonal) of the rate matrix. math girlies rise ๐Ÿงฎ๐Ÿ’…

๐Ÿ“ pll_set_frequencies

void pll_set_frequencies(pll_partition_t * partition,  unsigned int params_index, const double * frequencies);

Sets the base frequencies for the substitution model with index params_index, ranging from 0 to rate_matrices-1, as specified in the pll_partition_create() call. The array of base frequencies (frequencies) gets copied into the instance.

The order of bases in the array depends on the encoding you used when converting tip sequences to CLV. For example, if the pll_map_nt map was used with the pll_set_tip_states() function to describe nucleotide data, then the order is A, C, G, T. But like โ€” it can be arbitrarily set by adjusting the map you provide. your order, your rules ๐Ÿ‘‘โœจ

๐ŸŒธ pll_set_pattern_weights

void pll_set_pattern_weights(pll_partition_t * partition, const unsigned int * pattern_weights);

Sets the vector of pattern weights (pattern_weights) for partition. It reads and copies the first partition->sites elements of pattern_weights into partition->pattern_weights. cute, fast, done ๐Ÿ’–

๐ŸŒˆ pll_set_category_rates

void pll_set_category_rates(pll_partition_t * partition, const double * rates);

Sets the rate categories for partition. Reads and copies the first partition->rate_cats elements of the array rates into partition->rates. periodt โญ

๐Ÿซถ pll_update_invariant_sites

int pll_update_invariant_sites(pll_partition_t * partition);

Updates the invariant sites array partition->invariant, according to the sequences in the partition. This one gets implicitly called by pll_update_invariant_sites_proportion() when the specified proportion of invariant sites is greater than zero โ€” but if your sequences change, you must call it explicitly from your client code. no skipping, bestie ๐Ÿ’€

๐ŸŽ€ pll_update_invariant_sites_proportion

int pll_update_invariant_sites_proportion(pll_partition_t * partition, unsigned int params_index, double prop_invar);

Updates the proportion of invariant sites for the partition rate matrix with index params_index.

โš ๏ธ lowkey important: this call will not implicitly update the transition probability matrices computed from that particular rate matrix. You gotta do that yourself, explicitly โ€” for example with a call to pll_update_prob_matrices(). ๐Ÿ‘‘

๐Ÿ”ฅ pll_update_prob_matrices

int pll_update_prob_matrices(pll_partition_t * partition, const unsigned int * params_index, const unsigned int * matrix_indices, const double * branch_lengths, unsigned int count);

Computes the transition probability matrices specified by the count indices in matrix_indices, for all rate categories. A matrix with index matrix_indices[i] gets computed using the branch length branch_lengths[i]. To compute the matrix for rate category j, the function uses the rate matrix with index params_indices[j].

Matrices are stored in partition->pmatrix[matrix_indices[i]]. And note โ€” each such entry holds the matrices for all rate categories, stored consecutively in memory. slay, organized queen ๐Ÿ’…โœจ

๐Ÿ’œ pll_update_eigen

int pll_update_eigen(pll_partition_t * partition, unsigned int params_index);

Updates the eigenvectors (partition->eigenvecs[params_index]), inverse eigenvectors (partition->eigenvecs[params_index]), and eigenvalues (partition->eigenvals[params_index]) using the substitution parameters (partition->subst_params[params_index]) and base frequencies (partition->frequencies[params_index]) specified by params_index. math is mathing ๐Ÿงฎ๐Ÿ’–

๐ŸŒŸ pll_show_pmatrix

void pll_show_pmatrix(pll_partition_t * partition, unsigned int index, unsigned int float_precision);

Prints the transition probability matrices for each rate category of partition associated with index to standard output. The floating point precision is dictated by float_precision. peek at your matrices, bestie, they're cute ๐Ÿ”โœจ

๐Ÿฆ‹ pll_count_invariant_sites

unsigned int pll_count_invariant_sites(pll_partition_t * partition, unsigned int * state_inv_count);

Returns the number of invariant sites in the sequence alignment from partition. The array state_inv_count must be of size partition->states, and it gets filled such that entry i contains the count of invariant sites for state i. bestie really said "let me count for you" ๐Ÿฅน๐Ÿ’–

๐Ÿซถ pll_update_invariant_sites

int pll_update_invariant_sites(pll_partition_t * partition);

Updates the invariant sites array partition->invariant, according to the sequences in the partition. This function is implicitly called by pll_update_invariant_sites_proportion() when the specified proportion of invariant sites is greater than zero, but it must be explicitly called by the client code if the sequences change. (yes she's back, she's that iconic, we love a repeat appearance ๐Ÿ‘‘)

๐ŸŽ€ pll_update_invariant_sites_proportion

int pll_update_invariant_sites_proportion(pll_partition_t * partition, unsigned int params_index, double prop_invar);

Updates the proportion of invariant sites for the rate matrix of partition with index params_index.

โš ๏ธ and again for the people in the back: this call will not implicitly update the transition probability matrices computed from that particular rate matrix โ€” you must do it explicitly, like with a call to pll_update_prob_matrices(). ๐Ÿ’…
  • void pll_update_partials(pll_partition_t * partition, const pll_operation_t * operations, unsigned int count); โ€” bestie this one updates count conditional probability vectors (CPVs for short, we love an acronym) โ€” the ones spelled out by the entries of operations, and it does them in the exact order they show up in that array ๐Ÿซถ. Every single operations entry describes one CPV from partition. Also go peek at pll_operation_t if you wanna know what's in there, iykyk ๐Ÿ’…
  • void pll_show_clv(pll_partition_t * partition, unsigned int clv_index, int scaler_index, unsigned int float_precision); โ€” okay so this is the show me the vibes function โœจ It prints the conditional probability vector for index clv_index from partition straight to standard output, using the scale buffer with index scaler_index. And listen: if no scale buffer was used at all, then scaler_index must be handed the value PLL_SCALE_BUFFER_NONE โ€” no cap, that's mandatory ๐Ÿ™ˆ. How many digits after the decimal point you get is dictated by float_precision. The output is decorated with brackets, curly braces and round brackets, and those separate the values as sites, rate categories and states related, respectively ๐ŸŽ€ (it's giving very structured, very demure).
  • double pll_compute_root_loglikelihood(pll_partition_t * partition, unsigned int clv_index, int scaler_index, const unsigned int * freqs_index, double * persite_lnl); โ€” this one evaluates the log-likelihood of a rooted tree ๐ŸŒณ, and it needs the vector of conditional probabilities (partials) with index clv_index, the scale buffer with index scaler_index (or PLL_SCALE_BUFFER_NONE, you know the drill), and the base frequencies arrays with indices freqs_index (that's one per rate category, periodt). And if persite_lnl is not NULL, then bestie it has to be big enough to hold partition->sites double-precision values, because it's gonna get absolutely filled with the per-site log-likelihoods ๐Ÿ’–
  • double pll_compute_edge_loglikelihood(pll_partition_t * partition, unsigned int parent_clv_index, int parent_scaler_index, unsigned int child_clv_index, int child_scaler_index, unsigned int matrix_index, const unsigned int * freqs_index, double * persite_lnl); โ€” and this icon evaluates the log-likelihood of an unrooted tree ๐ŸŒˆ by handing it the conditional probability vectors (partials) for two nodes that share an edge ๐Ÿฆ‹ โ€” with indices parent_clv_index and child_clv_index respectively, plus the scale buffers with indices parent_scaler_index and child_clv_index respectively (or PLL_SCALE_BUFFER_NONE), the transition probability matrix with index matrix_index, and the base frequencies arrays with indices freqs_index (again, one per rate category, we're consistent here). And yeah โ€” if persite_lnl is not NULL, it must be large enough to hold partition->sites double-precision values, and it will be filled with the per-site log-likelihoods ๐Ÿ”ฅ

โœจ AVAILABILITY โœจ

Source code and binaries are living their best lives at <https://github.com/xflouris/libpll> ๐Ÿซถ go get 'em.


Copyright (C) 2015-2017, Tomas Flouri, Diego Darriba

All rights reserved.

Contact: Tomas Flouri <Tomas.Flouri@h-its.org>, Scientific Computing, Heidelberg Insititute for Theoretical Studies, 69118 Heidelberg, Germany

This software is licensed under the terms of the GNU Affero General Public License version 3.

GNU Affero General Public License version 3

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.


๐ŸŒธ VERSION HISTORY ๐ŸŒธ

New features and important modifications of libpll โ€” heads up, short lived or minor bug releases may not be mentioned, so don't come for me ๐Ÿ’€

  • v0.2.0 released September 9th, 2016
    • First public release. Baby's first debut, iconic behavior ๐Ÿ‘‘
  • v0.3.0 released May 15th, 2017
    • Added faster vectorizations for 20-state and arbitrary-state models, unweighted parsimony functions, randomized stepwise addition, portable functions for parsing trees from C-strings, per-rate category scalers for preventing numerical underflows โšก
    • Modified newick exporting function to accept callbacks for custom printing ๐ŸŽ€
    • Fixed derivatives computation, parsing of branch lengths, invariant sites computation, log-likelihood computation for cases where we have scaling and patterns, ascertainment bias computation, per-site log-likelihood computation, memory leaks ๐Ÿงš
    • Added run-time detection of hardware ๐Ÿ’…
  • v0.3.1 released May 17th, 2017
    • Correct updating of paddded eigen-decomposition arrays for models with a number of states not being a power of two ๐Ÿ”ข
    • Added portable hardware detection for clang and GCC ๐Ÿ› ๏ธ
  • v0.3.2 released July 12th, 2017
    • Added optional per-rate category scalers for protein and generic kernels ๐Ÿ’–
    • Improved fix for negative transition probability matrices caused by numerics ๐Ÿ˜ญ
    • Fixed initialization of tip CLVs when using ascertainment bias correction with non-DNA sequences ๐ŸŒˆ
    • Fixed excessive memory allocation when compressing site patterns and issue with PHYLIP parsing when header ends with CRLF ๐Ÿฆ‹

and that's a wrap bestie ๐ŸŽ€ this page is from libpll 0.3.2, dated July 12, 2017, section libpll(3) โ€” go forth and compute those log-likelihoods, you absolute main character ๐Ÿ’…โœจ๐Ÿซถ